Merge pull request #13 from kdabir/has

`has` is new `master`
This commit is contained in:
Kunal Dabir 2017-08-28 22:12:50 +05:30 committed by GitHub
commit abf5c53474
53 changed files with 159 additions and 390 deletions

19
.hastest.bats Normal file
View File

@ -0,0 +1,19 @@
#!/usr/bin/env bats
@test "works with single command check" {
result=$(bash has git)
[[ $result == *"✔ git"* ]]
}
@test "safely tells about tools not configured" {
result=$(bash has something-missing)
[[ $result == *"✘ something-missing not understood"* ]]
}
@test "env lets override safety check" {
result=$(HAS_ALLOW_UNSAFE=y bash has something-missing)
[[ $result == *"✘ something-missing"* ]]
}

9
.travis.yml Normal file
View File

@ -0,0 +1,9 @@
language: bash
before_install:
- sudo add-apt-repository ppa:duggan/bats --yes
- sudo apt-get update -qq
- sudo apt-get install -qq bats
install:
- sudo apt-get install -qq bc
script:
- bats .hastest.bats

View File

@ -1,8 +0,0 @@
source 'https://rubygems.org'
ruby '2.1.2'
gem 'rack'
gem 'thin'
gem 'guillotine'
gem 'mongo'
gem 'bson_ext'

View File

@ -1,36 +0,0 @@
GEM
remote: https://rubygems.org/
specs:
addressable (2.3.7)
bson (1.12.0)
bson_ext (1.12.0)
bson (~> 1.12.0)
daemons (1.1.9)
eventmachine (1.0.3)
guillotine (1.4.2)
addressable (~> 2.3.0)
sinatra (~> 1.4.0)
mongo (1.12.0)
bson (= 1.12.0)
rack (1.5.2)
rack-protection (1.5.3)
rack
sinatra (1.4.5)
rack (~> 1.4)
rack-protection (~> 1.4)
tilt (~> 1.3, >= 1.3.4)
thin (1.6.2)
daemons (>= 1.0.9)
eventmachine (>= 1.0.0)
rack (>= 1.0.0)
tilt (1.4.1)
PLATFORMS
ruby
DEPENDENCIES
bson_ext
guillotine
mongo
rack
thin

View File

@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2015 Kunal Dabir, Saager Mhatre
Copyright (c) 2014-2017 Kunal Dabir, Saager Mhatre
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in

View File

@ -1 +0,0 @@
web: bundle exec thin -p $PORT -e $RACK_ENV start

View File

@ -1,93 +1,16 @@
# dq
# has
Check how developer friendly is your machine!
`has` helps you check presence of various command line tools on path.
## How ?
Just fire the following from the Terminal
Download the `has` file. There is no dependency apart from `bash` itself
curl -sL https://dqhub.herokuapp.com/dq?check=*/java,*/ruby,*/python,*/git,*/node | bash`
Should produce output like:
✔ git 2.3.0
✔ java 1.8.0
✔ node 0.12.0
✔ python 2.7.6
✔ ruby 2.1.2
Your dq is 5 / 5
We have checks for more than 40 commands,
## Sharable url?
The urls like above look bit long and scary. They are not 'share' friendly. We've got you covered. You can shorten
the url either using dqhub itself (and give a logical name too) or any third party url-shortner.
We have already done for the check that we did above:
curl -sL https://dqhub.herokuapp.com/check/minimal | bash
**Feeling courageous**, see what all you have got :
curl -sL https://dqhub.herokuapp.com/check/all | bash
This checks for about 40 commands on your box
## More configurable DQ
You can edit the query params to make dq check for only those commands that you care about:
https://dqhub.herokuapp.com/dq?check=frontend/*
Check the lib directory structure, `check` query param should be comma separated list of globs (path)
## Running Locally
`cd` in to directory and just do a `bundle install` once and then to start server `rackup`.
## Rolling out your own locally
When you need to mix and match, it's equally simple. Checkout the repo, and execute from the root:
`ruby build.rb <command_patterns> | sh`
For example, if you develop frontend apps with node/ruby and use some typical databases
`ruby build.rb "db/*,frontend/*,ruby/*" | sh`
Or, you develop server side java/groovy and use some common databases
`ruby build.rb "java/*,groovy/*,db/*" | sh`
There no external gem dependency, you just need to have `ruby` though.
## Deploying to heroku
heroku addons:add mongolab
## #noserver
checkout bash-only branch, it's maintained by awesome @dexterous.
## About
Ever got onto a new machine or a remote server ? If you develop, you almost certainly need to check availability of your
tool-chain on command line. DQ is intended to relieve you from pain of checking each command individually.
It was named DQ as Developer Quotient (or Developer Friendliness Quotient of a machine), which may not be the most
apt name but that was the best name I could think of.
## Contributing
Please submit more command checks, it's very easy to do so. Fork the repo and send PR.
Issues and feedback welcome.
## Paranoid ?
Don't want to run `curl` piping to `bash`. Understandably, you might be concerned. Worry not.
- If you still want to check, do a `curl -sL <url> | cat` first.
(replacing `bash` with `cat`, to see the content of the file )
$ bash has node npm java git gradle
✔ node 8.2.1
✔ npm 5.3.0
✔ java 1.8.0
✔ git 2.14.1
✔ gradle 4.0.1
### ♥

View File

@ -1,31 +0,0 @@
# encoding: utf-8
# Usage:
# ruby build.rb <pattern1> <pattern2>... | bash
# valid patterns:
# `dir_name/command_name`
# `dir_name/*`
# `*/command_name`
# `*/*`
#
# dir/command name can be found in `lib/`
# do not include sh in command name
# pattern can contain commas to include multiple patterns
# debugging tip:
# use `.tap(&tap_it)` at any point in chain to print the values
# tap_it writes to `stderr`
# `ruby build.rb > /dev/null` to exclude the stdout of the script
def build *args
tap_it = Proc.new { |it| $stderr.puts "tapped - #{it}" }
content = args.collect { |it| it.split(',')}.flatten # comma seperated or multiple args
.select { |pattern| File.fnmatch('lib/*/*.sh', "lib/#{pattern}.sh", File::FNM_PATHNAME)} # can potentially do ..
.collect { |pattern| Dir["lib/#{pattern}.sh"] }.flatten.uniq # get all files
.sort { |x, y| File.basename(x) <=> File.basename(y) } # sort alphabetically
.collect { |file| File.read(file) }.join("\n") # concat
[File.read("include/setup.sh"), content, File.read("include/report.sh")].join("\n\n")
end
puts build *ARGV unless ARGV.empty?

View File

@ -1,35 +0,0 @@
# encoding: UTF-8
require './build'
require 'mongo'
require 'guillotine'
HEADERS_FOR_SHELL = {'Content-Type' => 'text/plain'}
## accepts only one parameter `check` with path patterns accepted by build
map '/dq' do
run Proc.new { |env|
commands_to_check = Rack::Request.new(env).params[:check.to_s] || "core/*"
puts "processing: [#{commands_to_check}]"
[200, HEADERS_FOR_SHELL, [build(commands_to_check)]]
}
end
class Shorty < Guillotine::App
adapter = begin
mongo_uri = ENV['MONGOLAB_URI'] || 'mongodb://localhost:27017/dq'
db_name = mongo_uri[%r{/([^/\?]+)(\?|$)}, 1]
collection = Mongo::MongoClient.from_uri(mongo_uri).db(db_name).collection("shorty")
Guillotine::MongoAdapter.new(collection)
rescue
Guillotine::MemoryAdapter.new
end
set :service => Guillotine::Service.new(adapter, :strip_query => false,
:required_host => ENV['DOMAIN_RESTRICTION'])
end
map '/check' do
run Shorty
end

121
has Normal file
View File

@ -0,0 +1,121 @@
#!/usr/bin/env bash
## Important so that version is not extracted for failed commands (not found)
set -o pipefail
PASS='✔'
FAIL='✘'
REGEX_SIMPLE_VERSION="([[:digit:]]+\.?){2,3}"
__dynamic_detect(){
cmd=$1
params=$2
version=$(eval ${cmd} ${params} "2>&1" | egrep -o "$REGEX_SIMPLE_VERSION" | head -1)
status=$?
}
# commands that use `--version` flag
__dynamic_detect--version(){
__dynamic_detect $1 "--version"
}
## commands that use `-version` flag
__dynamic_detect-version(){
__dynamic_detect $1 "-version"
}
# commands that use `-v` flag
__dynamic_detect-v(){
__dynamic_detect $1 "-v"
}
__detect(){
name=$1
# setup aliases
case ${name} in
golang) command="go" ;;
jre) command="java" ;;
jdk) command="javac" ;;
nodejs) command="node" ;;
goreplay) command="gor";;
*) command=${name} ;;
esac
case ${command} in
go)
version=$(go version 2>&1| egrep -o "$REGEX_SIMPLE_VERSION" | head -1)
status=$?
;;
hugo)
version=$(hugo version 2>&1| egrep -o "$REGEX_SIMPLE_VERSION" | head -1)
status=$?
;;
ab)
version=$(ab -V 2>&1 | egrep -o "$REGEX_SIMPLE_VERSION" | head -1)
status=$?
;;
gor)
version=$(gor version 2>&1 | egrep -o "$REGEX_SIMPLE_VERSION" | head -1)
if [ $? -eq 1 ]; then status=0; else status=1; fi
;;
# those that need -version flag
ant|java|javac) __dynamic_detect-version ${command} ;;
# those that need --version flag
git|node|npm|ruby|gem|rake) __dynamic_detect--version ${command} ;;
groovy|gradle) __dynamic_detect--version ${command} ;;
*)
## Can allow dynamic checking here
if [[ "${HAS_ALLOW_UNSAFE}" == "y" ]]; then
__dynamic_detect--version ${command}
else
status="-1"
fi
;;
esac
if [ "$status" -eq "-1" ]; then
echo ${FAIL} ${command} "not understood"
elif [ $status -eq 127 ]; then
echo ${FAIL} ${command}
elif [ ${status} -eq 0 ]; then
echo ${PASS} ${command} ${version}
else
echo ${PASS} ${command}
fi
}
# if no arguments passed to script
if [ "$#" -eq 0 ]; then
# print help
echo "${0} v1.0"
echo "USAGE: ${0} <command-names>.."
echo "EXAMPLE: ${0} git curl node"
else
# for each arg
for cmd in "$@"; do
__detect $cmd
done
fi

View File

@ -1,3 +0,0 @@
echo; echo Your dq is $OK / $(($OK+$KO))
exit $KO

View File

@ -1,35 +0,0 @@
OK=0
KO=0
PASS='✔'
FAIL='✘'
# by default show installed versions
NO_VERSION=1
if [[ "$1" == "--no-version" ]]; then
NO_VERSION=0
fi
SIMPLE_VERSIONING="([[:digit:]]+\.?){2,3}"
if [[ $TERM == xterm-*color ]]; then
PASS="\E[32m$PASS\E[0m"
FAIL="\E[31m$FAIL\E[0m"
fi
# $1 command name
# $2 0 OK, anything else KO
# $3 optional version string, should send in quotes
_dq_report () {
if [ "$2" -eq 0 ]; then
if [ "$NO_VERSION" -eq 0 ]; then
printf "$PASS $1\n"
else
printf "$PASS %-30s %s \n" "${1}" "${3}"
fi
OK=$(($OK+1))
else
printf "$FAIL $1\n"
KO=$(($KO+1))
fi
}

View File

@ -1,3 +0,0 @@
## surprisingly no option for version that i could find of
clj --help > /dev/null 2>&1
_dq_report 'clojure' $?

View File

@ -1,2 +0,0 @@
emacs --version > /dev/null 2>&1
_dq_report 'emacs' $?

View File

@ -1,2 +0,0 @@
lein -v > /dev/null 2>&1
_dq_report 'leiningen' $?

View File

@ -1,2 +0,0 @@
curl --version > /dev/null 2>&1
_dq_report 'curl' $?

View File

@ -1,6 +0,0 @@
command_name="git"
output=$(git --version 2>&1)
status=$?
version=$(echo "$output" | egrep -o "$SIMPLE_VERSIONING")
_dq_report "$command_name" $status "$version"

View File

@ -1,5 +0,0 @@
output=$(java -version 2>&1)
status=$?
version=$(echo "$output" | egrep -o "$SIMPLE_VERSIONING" | head -1)
_dq_report 'java' $status "$version"

View File

@ -1,6 +0,0 @@
command_name="node"
output=$(node --version 2>&1)
status=$?
version=$(echo "$output" | egrep -o "$SIMPLE_VERSIONING")
_dq_report "$command_name" $status "$version"

View File

@ -1,2 +0,0 @@
perl -v > /dev/null 2>&1
_dq_report 'perl' $?

View File

@ -1,5 +0,0 @@
output=$(python --version 2>&1)
status=$?
version=$(echo "$output" | egrep -o "$SIMPLE_VERSIONING" | head -1)
_dq_report 'python' $status "$version"

View File

@ -1,5 +0,0 @@
output=$(ruby --version 2>&1)
status=$?
version=$(echo "$output" | egrep -o "$SIMPLE_VERSIONING" | head -1)
_dq_report 'ruby' $status "$version"

View File

@ -1,2 +0,0 @@
vi --version > /dev/null 2>&1
_dq_report 'vi' $?

View File

@ -1,6 +0,0 @@
command_name="mongo-client"
output=$(mongo --version 2>&1)
status=$?
version=$(echo "$output" | egrep -o "$SIMPLE_VERSIONING" | head -1)
_dq_report "$command_name" $status "$version"

View File

@ -1,6 +0,0 @@
command_name="mongodb"
output=$(mongod --version 2>&1)
status=$?
version=$(echo "$output" | egrep -o "$SIMPLE_VERSIONING" | head -1)
_dq_report "$command_name" $status "$version"

View File

@ -1,2 +0,0 @@
mysql --version > /dev/null 2>&1
_dq_report 'mysql client' $?

View File

@ -1,2 +0,0 @@
psql --version > /dev/null 2>&1
_dq_report 'postgres client' $?

View File

@ -1,6 +0,0 @@
command_name="bower"
output=$(bower --version 2>&1)
status=$?
version=$(echo "$output" | egrep -o "$SIMPLE_VERSIONING")
_dq_report "$command_name" $status "$version"

View File

@ -1,6 +0,0 @@
command_name="coffee"
output=$(coffee --version 2>&1)
status=$?
version=$(echo "$output" | egrep -o "$SIMPLE_VERSIONING" | head -1)
_dq_report "$command_name" $status "$version"

View File

@ -1,6 +0,0 @@
command_name="grunt cli"
output=$(grunt --version 2>&1)
status=$?
version=$(echo "$output" | egrep -o "$SIMPLE_VERSIONING" | head -1)
_dq_report "$command_name" $status "$version"

View File

@ -1,6 +0,0 @@
command_name="npm"
output=$(npm --version 2>&1)
status=$?
version=$(echo "$output" | egrep -o "$SIMPLE_VERSIONING")
_dq_report "$command_name" $status "$version"

View File

@ -1,6 +0,0 @@
command_name="requirejs"
output=$(r.js -v 2>&1)
status=$?
version=$(echo "$output" | egrep -o "$SIMPLE_VERSIONING" | head -1)
_dq_report "$command_name" $status "$version"

View File

@ -1,6 +0,0 @@
command_name="sass"
output=$(sass --version 2>&1)
status=$?
version=$(echo "$output" | egrep -o "$SIMPLE_VERSIONING")
_dq_report "$command_name" $status "$version"

View File

@ -1,6 +0,0 @@
command_name="yeoman"
output=$(yo --version 2>&1)
status=$?
version=$(echo "$output" | egrep -o "$SIMPLE_VERSIONING")
_dq_report "$command_name" $status "$version"

View File

@ -1,5 +0,0 @@
output=$(groovy --version 2>&1)
status=$?
version=$(echo "$output" | egrep -o "$SIMPLE_VERSIONING" | head -1)
_dq_report 'groovy' $status "$version"

View File

@ -1,2 +0,0 @@
groovyc -version > /dev/null 2>&1
_dq_report 'groovyc' $?

View File

@ -1,2 +0,0 @@
lazybones --version > /dev/null 2>&1
_dq_report 'lazybones' $?

View File

@ -1,2 +0,0 @@
ant -version > /dev/null 2>&1
_dq_report 'ant' $?

View File

@ -1,6 +0,0 @@
command_name="gradle"
output=$(gradle -v 2>&1)
status=$?
version=$(echo "$output" | egrep -o "$SIMPLE_VERSIONING" | head -1)
_dq_report "$command_name" $status "$version"

View File

@ -1,4 +0,0 @@
# http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4380614
# jdk
javac -version > /dev/null 2>&1
_dq_report 'javac' $?

View File

@ -1,2 +0,0 @@
mvn -v > /dev/null 2>&1
_dq_report 'maven' $?

View File

@ -1,2 +0,0 @@
bundle -v > /dev/null 2>&1
_dq_report 'bundler' $?

View File

@ -1,2 +0,0 @@
gem -v > /dev/null 2>&1
_dq_report 'gem' $?

View File

@ -1,2 +0,0 @@
rake -V > /dev/null 2>&1
_dq_report 'rake' $?

View File

@ -1,2 +0,0 @@
rvm -v > /dev/null 2>&1
_dq_report 'rvm' $?

View File

@ -1,3 +0,0 @@
# this guy downloads the entire internet before telling its version
sbt sbt-version > /dev/null 2>&1
_dq_report 'sbt' $?

View File

@ -1,10 +0,0 @@
scala -version > /dev/null 2>&1
# this guy has its own idea of exit codes, fix it!
if [ $? -eq 1 ]; then
STATUS=0
else
STATUS=1
fi
_dq_report 'scala' $STATUS

View File

@ -1,2 +0,0 @@
scalac -version > /dev/null 2>&1
_dq_report 'scalac' $?

View File

@ -1,2 +0,0 @@
ack --version > /dev/null 2>&1
_dq_report 'ack' $?

View File

@ -1,2 +0,0 @@
autojump --version > /dev/null 2>&1
_dq_report 'autojump' $?

View File

@ -1,2 +0,0 @@
tree --version > /dev/null 2>&1
_dq_report 'tree' $?

View File

@ -1,2 +0,0 @@
wget --version > /dev/null 2>&1
_dq_report 'wget' $?

View File

@ -1,2 +0,0 @@
zsh --version > /dev/null 2>&1
_dq_report 'zsh' $?