Skip to content

Commit 2ec15c1

Browse files
authored
Merge pull request #165 from electron/cut-snapshot
v1: Cut mksnapshot, update dependencies, promisify
2 parents 108fab1 + f567bcf commit 2ec15c1

File tree

13 files changed

+3190
-1321
lines changed

13 files changed

+3190
-1321
lines changed

bin/asar.js

Lines changed: 52 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -3,73 +3,68 @@ var asar = require('../lib/asar')
33
var program = require('commander')
44

55
program.version('v' + require('../package.json').version)
6-
.description('Manipulate asar archive files')
6+
.description('Manipulate asar archive files')
77

88
program.command('pack <dir> <output>')
9-
.alias('p')
10-
.description('create asar archive')
11-
.option('--ordering <file path>', 'path to a text file for ordering contents')
12-
.option('--unpack <expression>', 'do not pack files matching glob <expression>')
13-
.option('--unpack-dir <expression>', 'do not pack dirs matching glob <expression> or starting with literal <expression>')
14-
.option('--snapshot', 'create snapshot')
15-
.option('--exclude-hidden', 'exclude hidden files')
16-
.option('--sv <version>', '(snapshot) version of Electron')
17-
.option('--sa <arch>', '(snapshot) arch of Electron')
18-
.option('--sb <builddir>', '(snapshot) where to put downloaded files')
19-
.action(function (dir, output, options) {
20-
options = {
21-
unpack: options.unpack,
22-
unpackDir: options.unpackDir,
23-
snapshot: options.snapshot,
24-
ordering: options.ordering,
25-
version: options.sv,
26-
arch: options.sa,
27-
builddir: options.sb,
28-
dot: !options.excludeHidden
29-
}
30-
asar.createPackageWithOptions(dir, output, options, function (error) {
31-
if (error) {
32-
console.error(error.stack)
33-
process.exit(1)
34-
}
35-
})
36-
})
9+
.alias('p')
10+
.description('create asar archive')
11+
.option('--ordering <file path>', 'path to a text file for ordering contents')
12+
.option('--unpack <expression>', 'do not pack files matching glob <expression>')
13+
.option('--unpack-dir <expression>', 'do not pack dirs matching glob <expression> or starting with literal <expression>')
14+
.option('--exclude-hidden', 'exclude hidden files')
15+
.action(function (dir, output, options) {
16+
options = {
17+
unpack: options.unpack,
18+
unpackDir: options.unpackDir,
19+
ordering: options.ordering,
20+
version: options.sv,
21+
arch: options.sa,
22+
builddir: options.sb,
23+
dot: !options.excludeHidden
24+
}
25+
asar.createPackageWithOptions(dir, output, options, function (error) {
26+
if (error) {
27+
console.error(error.stack)
28+
process.exit(1)
29+
}
30+
})
31+
})
3732

3833
program.command('list <archive>')
39-
.alias('l')
40-
.description('list files of asar archive')
41-
.option('-i, --is-pack', 'each file in the asar is pack or unpack')
42-
.action(function (archive, options) {
43-
options = {
44-
isPack: options.isPack
45-
}
46-
var files = asar.listPackage(archive, options)
47-
for (var i in files) {
48-
console.log(files[i])
49-
}
50-
// This is in order to disappear help
51-
process.exit(0)
52-
})
34+
.alias('l')
35+
.description('list files of asar archive')
36+
.option('-i, --is-pack', 'each file in the asar is pack or unpack')
37+
.action(function (archive, options) {
38+
options = {
39+
isPack: options.isPack
40+
}
41+
var files = asar.listPackage(archive, options)
42+
for (var i in files) {
43+
console.log(files[i])
44+
}
45+
// This is in order to disappear help
46+
process.exit(0)
47+
})
5348

5449
program.command('extract-file <archive> <filename>')
55-
.alias('ef')
56-
.description('extract one file from archive')
57-
.action(function (archive, filename) {
58-
require('fs').writeFileSync(require('path').basename(filename),
59-
asar.extractFile(archive, filename))
60-
})
50+
.alias('ef')
51+
.description('extract one file from archive')
52+
.action(function (archive, filename) {
53+
require('fs').writeFileSync(require('path').basename(filename),
54+
asar.extractFile(archive, filename))
55+
})
6156

6257
program.command('extract <archive> <dest>')
63-
.alias('e')
64-
.description('extract archive')
65-
.action(function (archive, dest) {
66-
asar.extractAll(archive, dest)
67-
})
58+
.alias('e')
59+
.description('extract archive')
60+
.action(function (archive, dest) {
61+
asar.extractAll(archive, dest)
62+
})
6863

6964
program.command('*')
70-
.action(function (cmd) {
71-
console.log('asar: \'%s\' is not an asar command. See \'asar --help\'.', cmd)
72-
})
65+
.action(function (cmd) {
66+
console.log('asar: \'%s\' is not an asar command. See \'asar --help\'.', cmd)
67+
})
7368

7469
program.parse(process.argv)
7570

lib/asar.js

Lines changed: 40 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,39 @@
11
'use strict'
2+
3+
const pify = require('pify')
4+
25
const fs = process.versions.electron ? require('original-fs') : require('fs')
36
const path = require('path')
47
const minimatch = require('minimatch')
5-
const mkdirp = require('mkdirp')
8+
const mkdirp = pify(require('mkdirp'))
69

710
const Filesystem = require('./filesystem')
811
const disk = require('./disk')
912
const crawlFilesystem = require('./crawlfs')
10-
const createSnapshot = require('./snapshot')
11-
12-
// Return whether or not a directory should be excluded from packing due to
13-
// "--unpack-dir" option
14-
//
15-
// @param {string} path - diretory path to check
16-
// @param {string} pattern - literal prefix [for backward compatibility] or glob pattern
17-
// @param {array} unpackDirs - Array of directory paths previously marked as unpacked
18-
//
19-
const isUnpackDir = function (path, pattern, unpackDirs) {
20-
if (path.indexOf(pattern) === 0 || minimatch(path, pattern)) {
21-
if (unpackDirs.indexOf(path) === -1) {
22-
unpackDirs.push(path)
13+
14+
/**
15+
* Whether a directory should be excluded from packing due to the `--unpack-dir" option.
16+
*
17+
* @param {string} dirPath - directory path to check
18+
* @param {string} pattern - literal prefix [for backward compatibility] or glob pattern
19+
* @param {array} unpackDirs - Array of directory paths previously marked as unpacked
20+
*/
21+
function isUnpackedDir (dirPath, pattern, unpackDirs) {
22+
if (dirPath.startsWith(pattern) || minimatch(dirPath, pattern)) {
23+
if (!unpackDirs.includes(dirPath)) {
24+
unpackDirs.push(dirPath)
2325
}
2426
return true
2527
} else {
26-
for (let i = 0; i < unpackDirs.length; i++) {
27-
if (path.indexOf(unpackDirs[i]) === 0) {
28-
return true
29-
}
30-
}
31-
return false
28+
return unpackDirs.some(unpackDir => dirPath.startsWith(unpackDir))
3229
}
3330
}
3431

35-
module.exports.createPackage = function (src, dest, callback) {
36-
return module.exports.createPackageWithOptions(src, dest, {}, callback)
32+
module.exports.createPackage = function (src, dest) {
33+
return module.exports.createPackageWithOptions(src, dest, {})
3734
}
3835

39-
module.exports.createPackageWithOptions = function (src, dest, options, callback) {
36+
module.exports.createPackageWithOptions = function (src, dest, options) {
4037
const globOptions = options.globOptions ? options.globOptions : {}
4138
globOptions.dot = options.dot === undefined ? true : options.dot
4239

@@ -45,10 +42,8 @@ module.exports.createPackageWithOptions = function (src, dest, options, callback
4542
pattern = src + options.pattern
4643
}
4744

48-
return crawlFilesystem(pattern, globOptions, function (error, filenames, metadata) {
49-
if (error) { return callback(error) }
50-
module.exports.createPackageFromFiles(src, dest, filenames, metadata, options, callback)
51-
})
45+
return crawlFilesystem(pattern, globOptions)
46+
.then(([filenames, metadata]) => module.exports.createPackageFromFiles(src, dest, filenames, metadata, options))
5247
}
5348

5449
/*
@@ -58,9 +53,8 @@ dest: Archive filename (& path).
5853
filenames: Array of filenames relative to src.
5954
metadata: Object with filenames as keys and {type='directory|file|link', stat: fs.stat} as values. (Optional)
6055
options: The options.
61-
callback: The callback function. Accepts (err).
6256
*/
63-
module.exports.createPackageFromFiles = function (src, dest, filenames, metadata, options, callback) {
57+
module.exports.createPackageFromFiles = function (src, dest, filenames, metadata, options) {
6458
if (typeof metadata === 'undefined' || metadata === null) { metadata = {} }
6559
if (typeof options === 'undefined' || options === null) { options = {} }
6660

@@ -112,67 +106,58 @@ module.exports.createPackageFromFiles = function (src, dest, filenames, metadata
112106
filenamesSorted = filenames
113107
}
114108

115-
const handleFile = function (filename, done) {
109+
const handleFile = function (filename) {
116110
let file = metadata[filename]
117111
let type
118112
if (!file) {
119113
const stat = fs.lstatSync(filename)
120114
if (stat.isDirectory()) { type = 'directory' }
121115
if (stat.isFile()) { type = 'file' }
122116
if (stat.isSymbolicLink()) { type = 'link' }
123-
file = {stat, type}
117+
file = { stat, type }
124118
metadata[filename] = file
125119
}
126120

127121
let shouldUnpack
128122
switch (file.type) {
129123
case 'directory':
130-
shouldUnpack = options.unpackDir
131-
? isUnpackDir(path.relative(src, filename), options.unpackDir, unpackDirs)
132-
: false
124+
if (options.unpackDir) {
125+
shouldUnpack = isUnpackedDir(path.relative(src, filename), options.unpackDir, unpackDirs)
126+
} else {
127+
shouldUnpack = false
128+
}
133129
filesystem.insertDirectory(filename, shouldUnpack)
134130
break
135131
case 'file':
136132
shouldUnpack = false
137133
if (options.unpack) {
138-
shouldUnpack = minimatch(filename, options.unpack, {matchBase: true})
134+
shouldUnpack = minimatch(filename, options.unpack, { matchBase: true })
139135
}
140136
if (!shouldUnpack && options.unpackDir) {
141137
const dirName = path.relative(src, path.dirname(filename))
142-
shouldUnpack = isUnpackDir(dirName, options.unpackDir, unpackDirs)
138+
shouldUnpack = isUnpackedDir(dirName, options.unpackDir, unpackDirs)
143139
}
144-
files.push({filename: filename, unpack: shouldUnpack})
145-
filesystem.insertFile(filename, shouldUnpack, file, options, done)
146-
return
140+
files.push({ filename: filename, unpack: shouldUnpack })
141+
return filesystem.insertFile(filename, shouldUnpack, file, options)
147142
case 'link':
148143
filesystem.insertLink(filename, file.stat)
149144
break
150145
}
151-
return process.nextTick(done)
146+
return Promise.resolve()
152147
}
153148

154149
const insertsDone = function () {
155-
return mkdirp(path.dirname(dest), function (error) {
156-
if (error) { return callback(error) }
157-
return disk.writeFilesystem(dest, filesystem, files, metadata, function (error) {
158-
if (error) { return callback(error) }
159-
if (options.snapshot) {
160-
return createSnapshot(src, dest, filenames, metadata, options, callback)
161-
} else {
162-
return callback(null)
163-
}
164-
})
165-
})
150+
return mkdirp(path.dirname(dest))
151+
.then(() => disk.writeFilesystem(dest, filesystem, files, metadata))
166152
}
167153

168154
const names = filenamesSorted.slice()
169155

170156
const next = function (name) {
171157
if (!name) { return insertsDone() }
172158

173-
return handleFile(name, function () {
174-
return next(names.shift())
175-
})
159+
return handleFile(name)
160+
.then(() => next(names.shift()))
176161
}
177162

178163
return next(names.shift())
@@ -203,7 +188,7 @@ module.exports.extractAll = function (archive, dest) {
203188
mkdirp.sync(dest)
204189

205190
return filenames.map((filename) => {
206-
filename = filename.substr(1) // get rid of leading slash
191+
filename = filename.substr(1) // get rid of leading slash
207192
const destFilename = path.join(dest, filename)
208193
const file = filesystem.getFile(filename, followLinks)
209194
if (file.files) {

lib/crawlfs.js

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,37 @@
11
'use strict'
2-
const fs = process.versions.electron ? require('original-fs') : require('fs')
3-
const glob = require('glob')
42

5-
module.exports = function (dir, options, callback) {
6-
const metadata = {}
7-
return glob(dir, options, function (error, filenames) {
8-
if (error) { return callback(error) }
9-
for (const filename of filenames) {
10-
const stat = fs.lstatSync(filename)
3+
const pify = require('pify')
4+
5+
const fs = pify(process.versions.electron ? require('original-fs') : require('fs'))
6+
const glob = pify(require('glob'))
7+
8+
function determineFileType (filename) {
9+
return fs.lstat(filename)
10+
.then(stat => {
1111
if (stat.isFile()) {
12-
metadata[filename] = {type: 'file', stat: stat}
12+
return [filename, { type: 'file', stat: stat }]
1313
} else if (stat.isDirectory()) {
14-
metadata[filename] = {type: 'directory', stat: stat}
14+
return [filename, { type: 'directory', stat: stat }]
1515
} else if (stat.isSymbolicLink()) {
16-
metadata[filename] = {type: 'link', stat: stat}
16+
return [filename, { type: 'link', stat: stat }]
17+
}
18+
19+
return [filename, undefined]
20+
})
21+
}
22+
23+
module.exports = function (dir, options) {
24+
const metadata = {}
25+
return glob(dir, options)
26+
.then(filenames => Promise.all(filenames.map(filename => determineFileType(filename))))
27+
.then(results => {
28+
const filenames = []
29+
for (const [filename, type] of results) {
30+
filenames.push(filename)
31+
if (type) {
32+
metadata[filename] = type
33+
}
1734
}
18-
}
19-
return callback(null, filenames, metadata)
20-
})
35+
return [filenames, metadata]
36+
})
2137
}

0 commit comments

Comments
 (0)