├── .gitignore ├── .npmignore ├── .travis.yml ├── HISTORY.md ├── README.md ├── bin └── mozilla-download ├── index.js ├── package.json ├── src ├── detectos.js ├── detecturl.js ├── download.js ├── extract.js ├── main.js ├── moz_build_info.js └── temp.js └── test ├── detectos_test.js ├── detecturl_test.js ├── download_test.js ├── entrypoint.js ├── extract_test.js ├── fixtures ├── archive.tar.bz2 ├── b2g │ └── random └── index.html ├── main_test.js └── mocha.opts /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.log 3 | 4 | /build 5 | /node_modules 6 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.log 3 | 4 | /node_modules 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - node 4 | - 9 5 | -------------------------------------------------------------------------------- /HISTORY.md: -------------------------------------------------------------------------------- 1 | # 1.0.0-alpha 2 | - Rewritten to use taskcluster index instead of mozilla ftp 3 | 4 | # 0.3.0 5 | - use mozilla-get-url 6 | 7 | # 0.2.1 8 | - oops! tell npm about the new binary 9 | 10 | # 0.2.0 11 | - add binary mozilla-download 12 | - don't attempt to clobber existing directories with error-less 13 | and error resolving modes (new .strict option). 14 | 15 | # 0.1.0 16 | - make .download API eaiser to use with default autodetection and less 17 | required params 18 | 19 | # 0.0.1 20 | - initial release 21 | - download support for any url firefox-get can find 22 | - unpacking support for linux & mac 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Mozilla Download 2 | 3 | ## DEPRECATED: please use [MozDownload](https://github.com/mozilla/mozdownload). 4 | 5 | [![Build Status](https://travis-ci.org/mozilla-b2g/mozilla-download.png?branch=master)](https://travis-ci.org/mozilla-b2g/marionette-download) 6 | 7 | Helper utility for downloading various mozilla products. Handles operating system detection (win32, mac, linux-i686, linux-x86\_64) and extraction of files (.tar.bz2, .dmg, .zip). 8 | 9 | ### Usage 10 | 11 | ```js 12 | let download = require('mozilla-download/build/main'); 13 | 14 | // basic 15 | download({ 16 | product: 'firefox', 17 | os: 'linux-x86_64', 18 | branch: 'mozilla-central', 19 | dest: '/where/this/should/go' 20 | }) 21 | .then(() => { 22 | // Go look in /where/this/should/go for ff 23 | }); 24 | 25 | // crash reporter symbols 26 | download({ 27 | product: 'firefox', 28 | os: 'mac64', 29 | branch: 'mozilla-central', 30 | fileSuffix: 'crashreporter-symbols.zip', 31 | dest: '/where/to/put/symbols' 32 | }); 33 | ``` 34 | 35 | ### CLI Usage 36 | 37 | ```sh 38 | ./node_modules/.bin/mozilla-download /path/to/put/extracted/folder 39 | --branch mozilla-central \ 40 | --product firefox 41 | ``` 42 | 43 | ### License 44 | 45 | The MIT License (MIT) 46 | 47 | Copyright (c) 2015 Gareth Aye, Sahaja James Lal 48 | 49 | Permission is hereby granted, free of charge, to any person obtaining a copy 50 | of this software and associated documentation files (the "Software"), to deal 51 | in the Software without restriction, including without limitation the rights 52 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 53 | copies of the Software, and to permit persons to whom the Software is 54 | furnished to do so, subject to the following conditions: 55 | 56 | The above copyright notice and this permission notice shall be included in 57 | all copies or substantial portions of the Software. 58 | 59 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 60 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 61 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 62 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 63 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 64 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 65 | THE SOFTWARE. 66 | -------------------------------------------------------------------------------- /bin/mozilla-download: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | require('../index'); 4 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | require('babel/polyfill'); 2 | require('./build/main')(); 3 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mozilla-download", 3 | "version": "1.1.0", 4 | "description": "Download firefox/b2g-desktop runtimes", 5 | "license": "MIT", 6 | "main": "bin/mozilla-download", 7 | 8 | "bin": { 9 | "mozilla-download": "./bin/mozilla-download" 10 | }, 11 | 12 | "contributors": [ 13 | "Gareth Aye [:gaye] ", 14 | "James Lal [:lightsofapollo] " 15 | ], 16 | 17 | "dependencies" : { 18 | "argparse": "1.0.2", 19 | "babel": "4.7.16", 20 | "debug": "2.1.3", 21 | "dmg": "0.0.3", 22 | "lodash": "3.6.0", 23 | "mz": "1.3.0", 24 | "ncp": "0.4.2", 25 | "promise": "6.1.0", 26 | "request": "2.54.0", 27 | "taskcluster-client": "0.21.2", 28 | "tmp": "0.0.25" 29 | }, 30 | 31 | "devDependencies": { 32 | "chai": "2.1.2", 33 | "mocha": "2.2.1", 34 | "node-static": "0.7.6" 35 | }, 36 | 37 | "repository": { 38 | "type": "git", 39 | "url": "https://github.com/mozilla-b2g/mozilla-download.git" 40 | }, 41 | 42 | "scripts": { 43 | "prepublish": "mkdir -p build && ./node_modules/.bin/babel src --experimental --modules common --out-dir build --source-maps", 44 | "test": "./node_modules/.bin/mocha" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/detectos.js: -------------------------------------------------------------------------------- 1 | export default function detectOS(target=process) { 2 | let platform = target.platform; 3 | switch (platform) { 4 | case 'darwin': 5 | return 'mac64'; 6 | case 'linux': 7 | let arch = target.arch; 8 | return arch === 'x64' ? 'linux-x86_64' : 'linux-i686'; 9 | case 'win32': 10 | return 'win32'; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/detecturl.js: -------------------------------------------------------------------------------- 1 | import taskcluster from 'taskcluster-client'; 2 | import { format } from 'url'; 3 | import * as buildinfo from './moz_build_info'; 4 | 5 | const TC_CLIENT_OPTS = { timeout: 30 * 1000 }; 6 | 7 | /** 8 | * Options: 9 | * 10 | * (String) product 11 | * (String) os 12 | * (String) branch 13 | * (String) revision 14 | * (String) fileSuffix 15 | */ 16 | export default async function detectURL(options) { 17 | // Figure out the appropriate index namespace. 18 | let nsparts = ['buildbot', 'branches', options.branch]; 19 | let buildname = buildinfo.buildname(options); 20 | nsparts.push(buildname); 21 | let ns = nsparts.join('.'); 22 | 23 | // Find task in namespace. 24 | let index = new taskcluster.Index(TC_CLIENT_OPTS); 25 | let task = await index.findTask(ns); 26 | 27 | // List task artifacts. 28 | let queue = new taskcluster.Queue(TC_CLIENT_OPTS); 29 | let { artifacts } = await queue.listLatestArtifacts(task.taskId); 30 | 31 | // Default to downloading the build archive for our os. 32 | let os = options.os; 33 | let product = options.product; 34 | let suffix = !!options.fileSuffix ? 35 | options.fileSuffix : 36 | buildinfo.archiveFileSuffix(product, os); 37 | 38 | // Filter through namespace artifacts. 39 | let artifact = artifacts.find(art => art.name.indexOf(suffix) !== -1); 40 | if (!artifact) { 41 | return Promise.reject(new Error('Could not find appropriate artifact')); 42 | } 43 | 44 | // Url for build is 45 | // https://queue.taskcluster.net/v1/task/{taskId}/artifacts/{artifact} 46 | return format({ 47 | protocol: 'https', 48 | host: 'queue.taskcluster.net', 49 | pathname: '/v1/task/' + task.taskId + '/artifacts/' + artifact.name 50 | }); 51 | } 52 | -------------------------------------------------------------------------------- /src/download.js: -------------------------------------------------------------------------------- 1 | import debug from 'debug'; 2 | import fs from 'fs'; 3 | import { throttle } from 'lodash'; 4 | import request from 'request'; 5 | import { tempfile } from './temp'; 6 | 7 | debug = debug('mozilla-download/download'); 8 | 9 | export default async function download(url, options) { 10 | let path = await tempfile({ prefix: 'mozilla-download-' + options.os }); 11 | debug('Will open http connection, download to', path); 12 | let get = request.get(url); 13 | let stream = fs.createWriteStream(path); 14 | await pipeResponseToStream(get, stream); 15 | return path; 16 | } 17 | 18 | function pipeResponseToStream(req, stream) { 19 | return new Promise((accept, reject) => { 20 | req.on('error', reject); 21 | stream.on('error', reject); 22 | req.pipe(stream); 23 | let ondata = throttle(() => process.stdout.write('.'), 1000); 24 | req.on('data', ondata); 25 | stream.on('finish', () => { 26 | req.removeListener('data', ondata); 27 | process.stdout.write('\n'); 28 | accept(); 29 | }); 30 | }); 31 | } 32 | -------------------------------------------------------------------------------- /src/extract.js: -------------------------------------------------------------------------------- 1 | import Promise from 'promise'; 2 | import dmg from 'dmg'; 3 | import { exec } from 'mz/child_process'; 4 | import fs from 'fs'; 5 | import { ncp } from 'ncp'; 6 | import { tempdir } from './temp'; 7 | 8 | dmg.mount = Promise.denodeify(dmg.mount); 9 | dmg.unmount = Promise.denodeify(dmg.unmount); 10 | ncp = Promise.denodeify(ncp); 11 | 12 | const productDirname = { 13 | 'b2g-desktop': 'b2g', 14 | 'firefox': 'firefox', 15 | 'mulet': 'firefox' 16 | }; 17 | 18 | /** 19 | * @fileoverview Extracts firefox or b2g runtime from a compressed format. 20 | * 21 | * Options: 22 | * 23 | * (String) product 24 | * (String) filetype 25 | * (String) source 26 | * (String) dest 27 | */ 28 | export default async function extract(options) { 29 | let dest = options.dest; 30 | let path = await tempdir(); 31 | // Extract to temporary location. 32 | options.dest = path; 33 | switch (options.filetype) { 34 | case 'dmg': 35 | await extractDmg(options); 36 | break; 37 | case 'tar.gz': 38 | case 'tar.bz2': 39 | await extractTarball(options); 40 | break; 41 | case 'zip': 42 | await extractZipball(options); 43 | break; 44 | default: 45 | // Default to no extraction if we don't understand filetype. 46 | options.dest = dest; 47 | break; 48 | } 49 | 50 | // Copy to destination. 51 | await ncp(options.dest, dest); 52 | } 53 | 54 | async function extractDmg(options) { 55 | let path = await dmg.mount(options.source); 56 | let files = fs.readdirSync(path); 57 | let target = files.find(file => /\.app/.test(file)); 58 | let source = path + '/' + target; 59 | let dest = options.dest + '/' + productDirname[options.product]; 60 | fs.mkdirSync(dest); 61 | await ncp(source, dest); 62 | await dmg.unmount(path); 63 | } 64 | 65 | function extractTarball(options) { 66 | return exec(['tar', '-xf', options.source, '-C', options.dest].join(' ')); 67 | } 68 | 69 | function extractZipball(options) { 70 | return exec(['unzip', options.source, '-d', options.dest].join(' ')); 71 | } 72 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import { ArgumentParser } from 'argparse'; 2 | import debug from 'debug'; 3 | import detectOS from './detectos'; 4 | import detectURL from './detecturl'; 5 | import download from './download'; 6 | import extract from './extract'; 7 | import { readdir } from 'mz/fs'; 8 | import * as buildinfo from './moz_build_info'; 9 | 10 | debug = debug('mozilla-download/main'); 11 | 12 | let parser = new ArgumentParser({ 13 | version: require('../package').version, 14 | description: 'Utility to download gecko builds from taskcluster index', 15 | addHelp: false 16 | }); 17 | 18 | parser.addArgument(['--product'], { 19 | type: 'string', 20 | help: 'Name for gecko build (ie b2g-desktop, mulet)', 21 | defaultValue: 'b2g-desktop' 22 | }); 23 | 24 | parser.addArgument(['--os'], { 25 | type: 'string', 26 | help: 'OS to download build for (ie linux-x86_64)', 27 | defaultValue: detectOS() 28 | }); 29 | 30 | parser.addArgument(['--branch'], { 31 | type: 'string', 32 | help: 'Release version (ie mozilla-central)', 33 | defaultValue: 'mozilla-central' 34 | }); 35 | 36 | parser.addArgument(['--debug'], { 37 | type: 'int', 38 | defaultValue: 0 39 | }); 40 | 41 | parser.addArgument(['--file-suffix'], { 42 | type: 'string', 43 | help: 'File extensions for extraction of files (ie .tar.bz2, .dmg, .zip)', 44 | dest: 'fileSuffix' 45 | }); 46 | 47 | parser.addArgument(['dest'], { 48 | type: 'string' 49 | }); 50 | 51 | export default async function main(args=parser.parseArgs()) { 52 | try { 53 | // Bail if thing exists 54 | try { 55 | let contents = await readdir(args.dest); 56 | if (contents && contents.length) { 57 | // We have dest dir and it has contents 58 | debug('Found b2g at dest', args.dest); 59 | return; 60 | } 61 | } catch (error) { 62 | } 63 | 64 | debug('No b2g found. Will download to', args.dest); 65 | let url = await detectURL(args); 66 | debug('Artifact url', url); 67 | let path = await download(url, args); 68 | debug('Download to', path); 69 | let product = args.product; 70 | let extractOpts = { source: path, dest: args.dest, product: product }; 71 | if (args.fileSuffix) { 72 | let parts = args.fileSuffix.split('.'); 73 | extractOpts.filetype = parts[parts.length - 1]; 74 | } else { 75 | // They want the regular old build archive. 76 | let os = args.os; 77 | extractOpts.filetype = buildinfo.archiveFiletype(os, product); 78 | } 79 | 80 | await extract(extractOpts); 81 | } catch (error) { 82 | console.error(error.toString()); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/moz_build_info.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @return filetype the filetype mozilla uses for build archives on a given os. 3 | */ 4 | export function archiveFiletype(os, product) { 5 | if (product.indexOf('emulator') !== -1) { 6 | return 'tar.gz'; 7 | } 8 | switch (os) { 9 | case 'mac64': 10 | return 'dmg'; 11 | case 'linux-i686': 12 | case 'linux-x86_64': 13 | return 'tar.bz2'; 14 | case 'win32': 15 | return 'zip'; 16 | default: 17 | throw new Error('Unsupported os ' + os); 18 | } 19 | } 20 | 21 | /** 22 | * @return suffix end of filename (including filetype) for build archive. 23 | */ 24 | export function archiveFileSuffix(product, os) { 25 | let ospart = (product === 'firefox' && os === 'mac64') ? 'mac' : os; 26 | let filetype = archiveFiletype(os, product); 27 | if (product.indexOf('emulator') !== -1) { 28 | // emulator doesn't have os in filename 29 | return filetype; 30 | } 31 | return `${ospart}.${filetype}`; 32 | } 33 | 34 | /** 35 | * Options: 36 | * 37 | * (String) debug 38 | * (String) product 39 | * (String) os 40 | * 41 | * @return name of build for os. 42 | */ 43 | export function buildname(options) { 44 | let result; 45 | switch (options.os) { 46 | case 'mac64': 47 | result = 'macosx64'; 48 | break; 49 | case 'linux-i686': 50 | result = 'linux'; 51 | break; 52 | case 'linux-x86_64': 53 | result = 'linux64'; 54 | break; 55 | case 'win32': 56 | result = 'win32'; 57 | break; 58 | default: 59 | throw new Error(`Unsupported os ${options.os}`); 60 | } 61 | 62 | switch (options.product) { 63 | case 'b2g-desktop': 64 | result += '_gecko'; 65 | break; 66 | case 'firefox': 67 | break; 68 | case 'mulet': 69 | result += '-mulet'; 70 | break; 71 | case 'emulator': 72 | case 'emulator-ics': 73 | result = 'emulator-ics'; 74 | break; 75 | case 'emulator-kk': 76 | result = 'emulator-kk'; 77 | break; 78 | default: 79 | throw new Error(`Unknown product ${options.product}`); 80 | } 81 | 82 | if (options.debug) { 83 | result += '-debug'; 84 | } 85 | 86 | return result; 87 | } 88 | -------------------------------------------------------------------------------- /src/temp.js: -------------------------------------------------------------------------------- 1 | import tmp from 'tmp'; 2 | 3 | /** 4 | * @fileoverview Thin promise wrapper around node-tmp. 5 | */ 6 | export function tempfile(options) { 7 | return wrap('file', options); 8 | } 9 | 10 | export function tempdir(options) { 11 | return wrap('dir', options); 12 | } 13 | 14 | function wrap(fnName, options) { 15 | return new Promise((accept, reject) => { 16 | tmp[fnName](options, (err, path) => { 17 | if (err) return reject(err); 18 | accept(path); 19 | }); 20 | }); 21 | } 22 | -------------------------------------------------------------------------------- /test/detectos_test.js: -------------------------------------------------------------------------------- 1 | import { assert } from 'chai'; 2 | import detectOS from '../src/detectos'; 3 | 4 | suite('detectOS', function() { 5 | test('darwin', function() { 6 | assert.equal(detectOS({ platform: 'darwin' }), 'mac64'); 7 | }); 8 | 9 | test('x86_64', function() { 10 | assert.equal(detectOS({ platform: 'linux', arch: 'x64' }), 'linux-x86_64'); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /test/detecturl_test.js: -------------------------------------------------------------------------------- 1 | import { assert } from 'chai'; 2 | import detectURL from '../src/detecturl'; 3 | 4 | suite('detectURL', function() { 5 | test('x86_64 b2g-desktop opt', async function() { 6 | let options = { 7 | product: 'b2g-desktop', 8 | os: 'linux-x86_64', 9 | branch: 'mozilla-central', 10 | }; 11 | 12 | let url = await detectURL(options); 13 | assert.match( 14 | url, 15 | new RegExp( 16 | '^https:\/\/queue\.taskcluster\.net\/v1\/task\/[A-Za-z0-9_\-]+\/' + 17 | 'artifacts\/public\/build\/.+linux-x86_64\.tar\.bz2$' 18 | ) 19 | ); 20 | }); 21 | 22 | test('fileSuffix specified', async function() { 23 | let options = { 24 | product: 'firefox', 25 | os: 'linux-x86_64', 26 | branch: 'mozilla-central', 27 | fileSuffix: 'crashreporter-symbols.zip' 28 | }; 29 | 30 | let url = await detectURL(options); 31 | assert.match( 32 | url, 33 | new RegExp( 34 | new RegExp( 35 | '^https:\/\/queue\.taskcluster\.net\/v1\/task\/[A-Za-z0-9_\-]+\/' + 36 | 'artifacts\/public\/build\/firefox.+crashreporter-symbols\.zip$' 37 | ) 38 | ) 39 | ); 40 | }); 41 | 42 | test('bogus fileSuffix', async function() { 43 | let options = { 44 | product: 'b2g-desktop', 45 | os: 'linux-x86_64', 46 | branch: 'mozilla-central', 47 | fileSuffix: 'totalrando' 48 | }; 49 | 50 | try { 51 | await detectURL(options); 52 | } catch (error) { 53 | assert.equal(error.message, 'Could not find appropriate artifact'); 54 | } 55 | }); 56 | 57 | test('emulator-kk', async function() { 58 | let options = { 59 | product: 'emulator-kk', 60 | os: 'linux-x86_64', 61 | branch: 'mozilla-central' 62 | }; 63 | 64 | let url = await detectURL(options); 65 | assert.match( 66 | url, 67 | new RegExp( 68 | '^https:\/\/queue\.taskcluster\.net\/v1\/task\/[A-Za-z0-9_\-]+\/' + 69 | 'artifacts\/public\/build\/emulator\.tar\.gz$' 70 | ) 71 | ); 72 | }); 73 | }); 74 | -------------------------------------------------------------------------------- /test/download_test.js: -------------------------------------------------------------------------------- 1 | import { assert } from 'chai'; 2 | import { readFileSync } from 'fs'; 3 | import { exec } from 'mz/child_process'; 4 | import { Server } from 'node-static'; 5 | import download from '../src/download'; 6 | import http from 'http'; 7 | 8 | suite('download', function() { 9 | let server; 10 | 11 | setup(function() { 12 | let file = new Server(__dirname + '/fixtures'); 13 | server = http.createServer((request, response) => { 14 | request.addListener('end', () => file.serve(request, response)).resume(); 15 | }); 16 | 17 | server.listen(8080); 18 | }); 19 | 20 | teardown(done => server.close(done)); 21 | 22 | test('should download file to temp path', async function() { 23 | let path = await download('http://localhost:8080/index.html', { 24 | os: 'linux-x87_64' 25 | }); 26 | 27 | let original = __dirname + '/fixtures/index.html'; 28 | let diff = await exec(['diff', original, path].join(' ')); 29 | assert.match(diff[0], /^\s*$/, 'downloaded file should match original'); 30 | 31 | let size = await fileSize(path); 32 | assert.match(size, /^[1-9]\d*/, 'size of test download not gt 0'); 33 | }); 34 | }); 35 | 36 | async function fileSize(path) { 37 | let du = await exec(['du', '-h', path].join(' ')); 38 | return du[0].split(/\s+/)[0]; 39 | } 40 | -------------------------------------------------------------------------------- /test/entrypoint.js: -------------------------------------------------------------------------------- 1 | require('babel/register')({ cache: true, experimental: true }); 2 | -------------------------------------------------------------------------------- /test/extract_test.js: -------------------------------------------------------------------------------- 1 | import { assert } from 'chai'; 2 | import { exec } from 'mz/child_process'; 3 | import extract from '../src/extract'; 4 | import { tempdir } from '../src/temp'; 5 | 6 | suite('extract', function() { 7 | test('tar.bz2', function() { 8 | let archive = __dirname + '/fixtures/archive.tar.bz2'; 9 | let file1, file2; 10 | return tempdir() 11 | .then(path => { 12 | file1 = path + '/file.txt'; 13 | file2 = path + '/file2.txt'; 14 | return extract({ filetype: 'tar.bz2', source: archive, dest: path }); 15 | }) 16 | .then(() => exec(['cat', file1, file2].join(' '))) 17 | .then(res => { 18 | assert.match(res, /lol\s*cats/); 19 | }); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /test/fixtures/archive.tar.bz2: -------------------------------------------------------------------------------- 1 | ./0000755000175000017500000000000012506313114010515 5ustar garethgareth./file.txt0000664000175000017500000000000412506312643012177 0ustar garethgarethlol 2 | ./file2.txt0000664000175000017500000000000512506312650012260 0ustar garethgarethcats 3 | -------------------------------------------------------------------------------- /test/fixtures/b2g/random: -------------------------------------------------------------------------------- 1 | wha 2 | -------------------------------------------------------------------------------- /test/fixtures/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | pwn3d 7 | 8 | 9 | -------------------------------------------------------------------------------- /test/main_test.js: -------------------------------------------------------------------------------- 1 | import { assert } from 'chai'; 2 | import fs from 'fs'; 3 | import detectOS from '../src/detectos'; 4 | import main from '../src/main'; 5 | import { tempdir } from '../src/temp'; 6 | 7 | suite('main', function() { 8 | let cases = [ 9 | { 10 | name: 'already exists', 11 | args: { 12 | product: 'b2g-desktop', 13 | os: 'linux-x86_64', 14 | branch: 'mozilla-central', 15 | dest: `${__dirname}/fixtures/b2g` 16 | }, 17 | verify: function() { 18 | assert.deepEqual(fs.readdirSync(`${__dirname}/fixtures/b2g`), ['random']); 19 | } 20 | }, 21 | { 22 | name: 'mozilla-central linux-x86_64 b2g-desktop opt', 23 | args: { 24 | product: 'b2g-desktop', 25 | os: 'linux-x86_64', 26 | branch: 'mozilla-central' 27 | }, 28 | 29 | verify: function() { 30 | let dir = `${this.args.dest}/b2g`; 31 | assert.ok(fs.existsSync(dir), `No b2g dir in ${this.args.dest}`); 32 | let contents = fs.readdirSync(dir); 33 | assert.include(contents, 'b2g', `No b2g bin in ${contents.join(',')}`); 34 | } 35 | }, 36 | 37 | { 38 | name: 'mozilla-aurora firefox crash reporter symbols', 39 | args: { 40 | product: 'firefox', 41 | os: 'linux-x86_64', 42 | branch: 'mozilla-aurora', 43 | fileSuffix: 'crashreporter-symbols.zip' 44 | }, 45 | 46 | verify: function() { 47 | let dir = this.args.dest; 48 | let contents = fs.readdirSync(dir); 49 | assert.operator(contents.length, '>', 0); 50 | } 51 | }, 52 | 53 | { 54 | name: 'osx b2g-desktop debug', 55 | args: { 56 | product: 'b2g-desktop', 57 | os: 'mac64', 58 | branch: 'mozilla-central', 59 | debug: '1' 60 | }, 61 | 62 | verify: function() { 63 | let dir = `${this.args.dest}/b2g`; 64 | assert.ok(fs.existsSync(dir), `No b2g dir in ${this.args.dest}`); 65 | let contents = fs.readdirSync(dir); 66 | assert.include(contents, 'Contents', `No contents in ${dir}`); 67 | } 68 | }, 69 | 70 | { 71 | name: 'linux x86_64 mulet', 72 | args: { 73 | product: 'mulet', 74 | os: 'linux-x86_64', 75 | branch: 'mozilla-central' 76 | }, 77 | 78 | verify: function() { 79 | let dir = `${this.args.dest}/firefox`; 80 | assert.ok(fs.existsSync(dir), `No mulet dir in ${this.args.dest}`); 81 | let contents = fs.readdirSync(dir); 82 | assert.include(contents, 'firefox', `No ff in ${contents.join(',')}`); 83 | } 84 | }, 85 | 86 | { 87 | name: 'mozilla-central osx firefox', 88 | args: { 89 | product: 'firefox', 90 | os: 'mac64', 91 | branch: 'mozilla-central' 92 | }, 93 | 94 | verify: function() { 95 | let dir = `${this.args.dest}/firefox`; 96 | assert.ok(fs.existsSync(dir), `No firefox dir in ${this.args.dest}`); 97 | let contents = fs.readdirSync(dir); 98 | assert.include(contents, 'Contents', `No contents in ${dir}`); 99 | } 100 | } 101 | ] 102 | 103 | cases.forEach(testCase => { 104 | test(testCase.name, async function() { 105 | let os = detectOS(); 106 | if (isMac(os) && isLinux(testCase.args.os) || 107 | isLinux(os) && isMac(testCase.args.os)) { 108 | return; 109 | } 110 | 111 | let dest = await tempdir(); 112 | testCase.args.dest = testCase.args.dest || dest; 113 | await main(testCase.args); 114 | testCase.verify(); 115 | }); 116 | }); 117 | }); 118 | 119 | function isLinux(os) { 120 | return os.indexOf('linux') !== -1; 121 | } 122 | 123 | function isMac(os) { 124 | return os.indexOf('mac') !== -1; 125 | } 126 | -------------------------------------------------------------------------------- /test/mocha.opts: -------------------------------------------------------------------------------- 1 | --reporter spec 2 | --require test/entrypoint 3 | --timeout 300s 4 | --ui tdd 5 | --------------------------------------------------------------------------------