Skip to content

Commit

Permalink
🎨 Closes #315 (7-zip 15.x progress bar), Closes #309 (support install…
Browse files Browse the repository at this point in the history
…-shield self-extracting thingies), Closes #311 (phase out win-spawn)
  • Loading branch information
fasterthanlime committed Jan 5, 2016
1 parent 81c755b commit 6012e13
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 47 deletions.
26 changes: 19 additions & 7 deletions app/tasks/install/archive.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ let is_tar = async function (path) {
}

let self = {
sevenzip_list: async function (logger, archive_path) {
sevenzip_list: async function (version, logger, archive_path) {
let opts = {logger}
let sizes = {}
let total_size = 0
Expand All @@ -43,18 +43,26 @@ let self = {
return {sizes, total_size}
},

sevenzip_extract: async function (logger, archive_path, dest_path, onprogress) {
sevenzip_extract: async function (version, logger, archive_path, dest_path, onprogress) {
let opts = {logger}
let err_state = false
let err

let EXTRACT_RE = /^Extracting\s+(.+)$/
let additional_args = []

if (/^15/.test(version)) {
EXTRACT_RE = /^-\s(.+)$/
additional_args.push('-bb1')
}

await mkdirp(dest_path)
await spawn({
command: '7za',
args: ['x', archive_path, '-o' + dest_path, '-y'],
args: ['x', archive_path, '-o' + dest_path, '-y'].concat(additional_args),
split: '\n',
ontoken: (token) => {
log(opts, `7za extract: ${token}`)
log(opts, `extract: ${token}`)
if (err_state) {
if (!err) err = token
return
Expand All @@ -64,7 +72,7 @@ let self = {
return
}

let matches = token.match(/^Extracting\s+(.*)$/)
let matches = EXTRACT_RE.exec(token)
if (!matches) return

let item_path = path.normalize(matches[1])
Expand All @@ -84,10 +92,14 @@ let self = {

log(opts, `Extracting archive '${archive_path}' to '${dest_path}' with 7-Zip`)

let ibrew = require('../../util/ibrew')
let version = await ibrew.get_local_version('7za')
log(opts, `Running 7-zip ${version}`)

let extracted_size = 0
let total_size = 0

let info = await self.sevenzip_list(logger, archive_path)
let info = await self.sevenzip_list(version, logger, archive_path)
total_size = info.total_size
log(opts, `Archive contains ${Object.keys(info.sizes).length} files, ${total_size} total`)

Expand All @@ -96,7 +108,7 @@ let self = {
let percent = extracted_size / total_size * 100
onprogress({ extracted_size, total_size, percent })
}
await self.sevenzip_extract(logger, archive_path, dest_path, sevenzip_progress)
await self.sevenzip_extract(version, logger, archive_path, dest_path, sevenzip_progress)

log(opts, `Done extracting ${archive_path}`)
let files = await glob(`${dest_path}/**/*`, {nodir: true})
Expand Down
35 changes: 24 additions & 11 deletions app/util/ibrew.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ let self = {
},

normalize_version: (version) => {
if (!version) return version
return version.replace(/^v/, '')
},

Expand Down Expand Up @@ -129,11 +130,30 @@ let self = {
return reject(err || `status code: ${res.statusCode}`)
}
let version = res.body.toString('utf8').replace(/\s/g, '')
resolve(version)
resolve(self.normalize_version(version))
})
})
},

get_local_version: async (name) => {
let formula = self.formulas[name]

let check = Object.assign({}, {
args: ['-V'],
parser: /([a-zA-Z0-9\.]+)/
}, formula.version_check || {})

console.log(`Getting ${name}'s version with check ${JSON.stringify(check, null, 2)}'`)

try {
let info = await os.check_presence(name, check.args, check.parser)
console.log(`Got info ${JSON.stringify(info, null, 2)}`)
return self.normalize_version(info.parsed)
} catch (err) {
return null
}
},

fetch: async (opts, name) => {
let noop = () => null
let onstatus = opts.onstatus || noop
Expand All @@ -152,7 +172,7 @@ let self = {
let download_version = async (version) => {
let archive_name = self.archive_name(name)
let archive_path = path.join(self.bin_path(), archive_name)
let archive_url = `${channel}/${version}/${archive_name}`
let archive_url = `${channel}/v${version}/${archive_name}`
onstatus('login.status.dependency_install', 'download', {name, version})
log(opts, `${name}: downloading '${version}' from ${archive_url}`)

Expand All @@ -170,21 +190,14 @@ let self = {
onstatus('login.status.dependency_check', 'stopwatch')
let get_latest_version = partial(self.get_latest_version, channel)

let check = Object.assign({
args: ['-V'],
parser: /([a-zA-Z0-9\.]+)/
}, formula.version_check || {})
let info
let local_version = await self.get_local_version(name)

try {
info = await os.check_presence(name, check.args, check.parser)
} catch (err) {
if (!local_version) {
if (formula.on_missing) formula.on_missing()
log(opts, `${name}: missing, downloading latest`)
return await download_version(await get_latest_version())
}

let local_version = info.parsed
log(opts, `${name}: have local version '${local_version}'`)

let latest_version
Expand Down
49 changes: 22 additions & 27 deletions app/util/os.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@


let Promise = require('bluebird')
let spawn = require('win-spawn')
let spawn = require('./spawn')

let self = {
platform: function () {
Expand Down Expand Up @@ -38,37 +36,34 @@ let self = {
return process.argv
},

check_presence: function (command, args, parser) {
check_presence: async function (command, args, parser) {
if (typeof args === 'undefined') {
args = []
}

return new Promise((resolve, reject) => {
let child = spawn(command, args)

let stdout = ''
child.stdout.on('data', (data) => stdout += data)
let stdout = ''
let stderr = ''

let stderr = ''
child.stderr.on('data', (data) => stderr += data)
let spawn_opts = {
command,
args,
ontoken: (tok) => stdout += tok,
onerrtoken: (tok) => stderr += tok
}
let code = await spawn(spawn_opts)
if (code !== 0) {
throw new Error(`${command} exited with code ${code}\n${stdout}\n${stderr}`)
}

child.on('error', (e) => null)
child.on('close', (code) => {
if (code === 0) {
let parsed = null
if (parser) {
let matches = (stdout + '\n' + stderr).match(parser)
if (matches) {
parsed = matches[1]
}
}
let parsed = null
if (parser) {
let matches = parser.exec(stdout + '\n' + stderr)
if (matches) {
parsed = matches[1]
}
}

resolve({code, stdout, stderr, parsed})
} else {
reject(new Error(`${command} exited with code ${code}\n${stdout}\n${stderr}`))
}
})
})
return {code, stdout, stderr, parsed}
}
}

Expand Down
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,7 @@
"stream-splitter": "^0.3.2",
"streamsearch": "^0.1.2",
"underscore": "^1.8.3",
"walk": "^2.3.9",
"win-spawn": "^2.0.0"
"walk": "^2.3.9"
},
"devDependencies": {
"babel-plugin-syntax-async-functions": "^6.3.13",
Expand Down

0 comments on commit 6012e13

Please sign in to comment.