yapm
Version:
package manager for io.js (npm fork)
185 lines (155 loc) • 4.01 kB
JavaScript
var status_bar = require('status-bar')
var URL = require('url')
var streams = []
var storage = [" B", " kB", " MB", " GB", " TB", " PB", " EB", " ZB", " YB"]
var have_progressbar = false
function format_storage(b) {
var unit = function (n, arr, pow) {
if (n < pow) return n + arr[0]
var i = 1
while (i < 9) {
n /= pow
var decimals = n < 100 ? 1 : 0
if (n < pow) return n.toFixed(decimals) + arr[i]
i++
}
return ">=" + pow + arr[7]
}
return unit (~~b, storage, 1024)
}
function format_speed(b, decimals) {
var str = format_storage(b, decimals) + '/s'
return Array(Math.max(10-str.length, 0)).join(' ') + str
}
function update() {
if (!module.exports.enabled) return
if (requests_total === requests_finished) {//!requests_count) {
if (have_progressbar) write('\033[2K\r')
have_progressbar = false
return
}
var res = streams.map(function(s) {
if (!s) return
if (s._render) return s._render(s._stats)
}).filter(function(x){return !!x}).join(' ')
write('\033[2K\r' + res.substr(0, process.stdout.columns - 1))
have_progressbar = true
}
var cs = {}
var control = status_bar.create({
total: Infinity,
render: function (stats) {
return format_speed(stats.speed) + ' [' + requests_finished + '/' + requests_total + ']'
}
})
streams.push(control)
function new_stream(name, total) {
var bar = status_bar.create({
total: total,
render: function (stats) {
return '[' +
name + ': ' +
format_storage(stats.currentSize) +
'/' +
format_storage(stats.totalSize) +
']'
}
})
streams.push(bar)
bar.update(0)
return bar
}
function shorten(url) {
url = url.href.replace(/.*\//g, '')
if (url.match(/\.tgz$/)) {
url = url.replace(/\.tgz$/, '').split('-')
url.pop()
url = url.join('-')
}
return url
}
var requests_count = 0
var requests_finished = 0
var requests_total = 0
module.exports.enabled = false
module.exports.wrap = function(url, req) {
var bar, is_index = false, counted
requests_total++
if (url.href.match(/\/-\/all$/)) {
var JSONStream = require('JSONStream')
var stream = JSONStream.parse('*')
req.pipe(stream)
var last = 0
stream.on('data', function(pkg) {
if (!pkg.name) return
var name = pkg.name.toLowerCase()
var curr = (name.charCodeAt(0)-97 || 0) * 26 + (name.charCodeAt(1)-97 || 0)
if (curr < 0) curr = 0
if (curr < last) return
bar.update(curr - last)
last = curr
})
stream.on('error', end)
bar = status_bar.create({
total: 26*26,
render: function (stats) {
return '[' +
this.format.progressBar(stats.percentage) +
'] ' +
this.format.time(stats.remainingTime)
},
progressBarLength: 53,
})
streams.push(bar)
is_index = true
}
req.on('response', function(res) {
requests_count++
counted = true
if (res.headers && res.headers['content-length'] && !is_index) {
bar = new_stream(shorten(url), res.headers['content-length'])
}
})
req.on('data', function(data) {
control.update(data)
if (bar && !is_index) {
bar.update(data)
}
})
req.on('end', end)
req.on('error', end)
function end() {
requests_finished++
if (counted) {
counted = false
requests_count--
}
if (!bar) return
bar.cancel()
streams.splice(streams.indexOf(bar), 1)
bar = null
}
}
var our_stdout = false
var old_stdout_write = process.stdout.write
process.stdout.write = function() {
if (!our_stdout) if (have_progressbar) write('\033[2K\r')
old_stdout_write.apply(process.stdout, arguments)
if (!our_stdout) if (have_progressbar) update()
}
var old_stderr_write = process.stderr.write
process.stderr.write = function() {
if (!our_stdout) if (have_progressbar) write('\033[2K\r')
old_stderr_write.apply(process.stderr, arguments)
if (!our_stdout) if (have_progressbar) update()
}
function write(arg) {
our_stdout = true
process.stdout.write(arg)
our_stdout = false
}
setInterval(update, 100).unref()
process.on('exit', function exit() {
if (have_progressbar) update()
if (have_progressbar) write('\n')
})