-
Notifications
You must be signed in to change notification settings - Fork 51
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit b856619
Showing
3 changed files
with
252 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
#!/usr/bin/env node | ||
require('coffee-script/register'); | ||
require('./caniuse.coffee'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,213 @@ | ||
data = require 'caniuse-db/data.json' | ||
colors = require 'colors' | ||
linewrap = require 'linewrap' | ||
open = require 'open' | ||
|
||
argv = require 'yargs' | ||
.option 'short', | ||
type: 'boolean' | ||
default: undefined | ||
describe: "Short output: show browsers on one line and don't display notes or description (default when displaying multiple results)" | ||
.option 'long', | ||
type: 'boolean' | ||
default: undefined | ||
describe: "Long output: show more information (default when displaying a single result)" | ||
.option 'oneline', | ||
type: 'boolean' | ||
default: false | ||
describe: "One-line output: just global percentages, no per-browser info" | ||
.option 'oneline-browser', | ||
type: 'boolean' | ||
default: false | ||
describe: "One-line output with browser info, implies --abbrev and --current" | ||
.option 'abbrev', | ||
type: 'boolean' | ||
default: false | ||
describe: "Abbreviate browser names" | ||
.option 'percentages', | ||
type: 'boolean' | ||
default: false | ||
describe: "Include browser version usage percentages" | ||
.option 'future', | ||
type: 'boolean' | ||
default: false | ||
describe: "Include future browser versions" | ||
.option 'current', | ||
type: 'boolean' | ||
default: false | ||
describe: "Don't include old browser versions, equivalent to --era e0" | ||
.option 'era', | ||
type: 'string' | ||
describe: "How many versions back to go, e0 to #{Object.keys(data.eras)[0]}" | ||
.option 'mobile', | ||
type: 'boolean' | ||
default: false | ||
describe: "Include mobile browsers" | ||
.option 'desktop', | ||
type: 'boolean' | ||
default: true | ||
describe: "Include desktop browsers" | ||
.option 'browser', | ||
type: 'string' | ||
describe: "Show results for these browsers, comma-separated (#{Object.keys(data.agents)})" | ||
.option 'web', | ||
type: 'boolean' | ||
default: false | ||
describe: "Go to the search page on caniuse.com" | ||
|
||
.help 'help' | ||
.argv | ||
|
||
if argv.web | ||
return open "http://caniuse.com/#search=#{encodeURIComponent argv._.join ' '}" | ||
|
||
searchkey = argv._.join('').toLowerCase().replace(/\W*/g, '') | ||
agents = data.agents | ||
|
||
xwrap = linewrap (process.stdout.columns or 80), | ||
skipScheme: 'ansi-color' | ||
whitespace: 'line' | ||
tabWidth: 2 | ||
wrapLineIndent: 0 | ||
wrapLineIndentBase: /\S/ | ||
|
||
# Replace our scary braille spaces with real spaces | ||
wrap = (str) -> xwrap(str).replace(/\u2800/g, ' ') | ||
|
||
if argv["oneline-browser"] | ||
argv.abbrev = true | ||
argv.short = true | ||
argv.current = true | ||
|
||
|
||
types = [] | ||
types.push 'desktop' if argv.desktop | ||
types.push 'mobile' if argv.mobile | ||
|
||
eras = Object.keys(data.eras) | ||
currentVersion = eras.indexOf("e0") | ||
versionrange = [0, currentVersion] | ||
versionrange[1] = Infinity if argv.future | ||
versionrange[0] = currentVersion if argv.current | ||
versionrange[0] = eras.indexOf(argv.era) if argv.era | ||
|
||
resultmap = y: "✔", n: "✘", a: "◒", u: "‽" | ||
supernums = "⁰¹²³⁴⁵⁶⁷⁸⁹" | ||
|
||
# Generate the text for a single version result | ||
# FIXME: gross output parameter | ||
makeResult = (result, nums={}) -> | ||
support = result.support[0] | ||
out = '' | ||
# \u2800 is a braille space - the only kind of space I could find that | ||
# doesn't get split by the word wrapper | ||
out += (resultmap[support] || support) + "\u2800" | ||
out += result.version if result.version | ||
out += "ᵖ" if "x" in result.support | ||
if note = result.support.match(/#(\d+)/)?[1] | ||
nums[note] = true | ||
out += supernums[note] | ||
|
||
if argv.percentages and result.usage | ||
out += " " unless out.slice(-1) is "\u2800" | ||
out += "(#{Math.round(result.usage*1)/1}%)" | ||
out += ' ' | ||
switch support | ||
when "y" then out.green | ||
when "n" then out.red | ||
when "a" then out.yellow | ||
else out | ||
|
||
# Generate an array of version results for a browser | ||
makeResults = (browser, stats) -> | ||
results = [] | ||
current = {} | ||
for version, i in browser.versions when version and versionrange[0] <= i <= versionrange[1] | ||
support = stats[version] | ||
usage = browser.usage_global[version] || 0 | ||
version += '+' if browser.versions[i + 1] | ||
|
||
# 'p' means no-but-polyfill-available, which we can treat as no | ||
if support[0] == "p" | ||
support = "n" + support.slice(1) | ||
|
||
# Only add a new version result when browser support changes | ||
if !current.version || current.support != support | ||
current = version: version, support: support, usage: 0 | ||
results.push current | ||
|
||
current.usage += usage | ||
|
||
results | ||
|
||
# Display a single feature's browser support | ||
showFeature = (result, opts={}) -> | ||
opts.long ?= !opts.short | ||
opts.short ?= !opts.long | ||
|
||
percentages = [] | ||
percentages.push "✔ #{result.usage_perc_y}%".green if result.usage_perc_y | ||
percentages.push "◒ #{result.usage_perc_a}%".yellow if result.usage_perc_y | ||
percentages = percentages.join(' ') | ||
|
||
status = if opts.long then " [#{data.statuses[result.status]}]" else '' | ||
headerSep = if opts["oneline-browser"] then ": " else "\n" | ||
process.stdout.write "#{result.title.bold} #{percentages}#{status}" + headerSep | ||
|
||
return if opts.oneline | ||
|
||
if opts.long | ||
tags = result.categories.map((x) -> '#'+x.replace(/\W/g,'')).join(' ') | ||
console.log wrap '\t' + result.description.trim() + ' ' + tags + '\n' | ||
|
||
out = [] | ||
# console.log "columns", process.stdout.columns | ||
out.push '\t' if opts.short && !opts["oneline-browser"] | ||
|
||
filter = (browser) -> | ||
if opts.browser | ||
browser in opts.browser.split(',') | ||
else | ||
agents[browser].type in types | ||
|
||
# Store which notes have been used in a result | ||
need_note = {} | ||
|
||
for browser, stats of result.stats when filter browser | ||
out.push "\t" unless opts.short | ||
if opts.abbrev | ||
out.push "#{agents[browser].abbr} " | ||
else | ||
out.push "#{agents[browser].browser} " | ||
|
||
results = makeResults(agents[browser], stats) | ||
if results.length == 1 | ||
results[0].version = null | ||
|
||
out.push "#{makeResult res, need_note}" for res in results | ||
out.push "\n" unless opts.short | ||
|
||
console.log wrap out.join('') | ||
|
||
unless opts.short | ||
for num, note of result.notes_by_num when need_note[num] | ||
console.log wrap "\t\t#{supernums[num].yellow}#{note}" | ||
console.log wrap "\tⓘ #{result.notes.replace(/[\r\n]+/g, ' ')}" if result.notes | ||
|
||
|
||
slowFind = (query) -> | ||
results = [] | ||
for key, {title, description, keywords, categories} of data.data | ||
matcher = (key + title + description + keywords + categories).toLowerCase().replace(/\W*/g, '') | ||
results.push key if matcher.match(query) | ||
results | ||
|
||
|
||
do -> | ||
if feat = data.data[searchkey] | ||
showFeature feat, argv | ||
else if (features = slowFind searchkey).length > 0 | ||
argv.short ?= features.length > 1 | ||
showFeature data.data[feat], argv for feat in features | ||
else | ||
console.error "#{searchkey}: not found" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
{ | ||
"name": "caniuse-cmd", | ||
"version": "1.0.0", | ||
"description": "caniuse for the command line", | ||
"scripts": { | ||
"test": "mocha" | ||
}, | ||
"preferGlobal": true, | ||
"bin": { | ||
"caniuse": "./bin.js" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/sgentle/caniuse-cmd.git" | ||
}, | ||
"keywords": [ | ||
"caniuse" | ||
], | ||
"author": "Sam Gentle <sam@samgentle.com>", | ||
"license": "MIT", | ||
"bugs": { | ||
"url": "https://github.com/sgentle/caniuse-cmd/issues" | ||
}, | ||
"homepage": "https://github.com/sgentle/caniuse-cmd", | ||
"dependencies": { | ||
"caniuse-db": "~1.0.0", | ||
"coffee-script": "=1.9.1", | ||
"colors": "^1.0.3", | ||
"linewrap": "^0.2.1", | ||
"open": "0.0.5", | ||
"yargs": "~3.5.4" | ||
}, | ||
"devDependencies": { | ||
"mocha": "^2.2.1" | ||
} | ||
} |