mattly / bork Goto Github PK
View Code? Open in Web Editor NEWthe Bash-Operated Reconciling Kludge
License: Other
the Bash-Operated Reconciling Kludge
License: Other
When running bork types
I get the following error from the defaults
type:
bret-mbr:install bret$ bork types
...
/usr/local/Cellar/bork/HEAD/types/defaults.sh: line 21: [: =: unary operator expected
defaults: asserts settings for OS X's 'defaults' system
* defaults domain key type value
> defaults com.apple.dock autohide bool true
Running GNU bash, version 4.3.42(1)-release (x86_64-apple-darwin15.0.0)
from hombrew.
Is it a matter of just changing https://github.com/mattly/bork/blob/master/types/defaults.sh#L21 to
if [ "${desired_type:0:4}" = "dict" ]; then
?
I'm realizing I have a massive knowledge deficit regarding bash variable expansion syntax ๐ฌ
Most PRs have test failures in travis recently. Most of those are due to use of [
for checking output strings, examples:
โ did_install reflects $performed_install
โ did_upgrade reflects $performed_upgrade
โ did_update reflects both install/upgrade
โ include: maintains relative directories
โ ok: checks against core types
(in test file test/declare-ok.bats, line 11)
`[ "$BORK_SOURCE_DIR/types/directory.sh foo" = $output ]' failed with status 2
/tmp/bats.1655.src: line 11: [: too many arguments
โ ok: checks against stdlib_types
(in test file test/declare-ok.bats, line 17)
`[ "$BORK_SOURCE_DIR/types/brew.sh foo" = $output ]' failed with status 2
/tmp/bats.1655.src: line 17: [: too many arguments
โ ok: checks against local scripts
(in test file test/declare-ok.bats, line 23)
`[ "$BORK_SCRIPT_DIR/fixtures/custom.sh foo" = $output ]' failed with status 2
/tmp/bats.1655.src: line 23: [: too many arguments
โ ok: checks against registered types
(in test file test/declare-ok.bats, line 30)
`[ "$BORK_SCRIPT_DIR/fixtures/custom.sh foo" = $output ]' failed with status 2
/tmp/bats.1655.src: line 30: [: too many arguments
โ register: recognizes paths
โ register: exits 1 for non-valid values, does not add lib
โ lookup_type: when is_compiled, echoes type_$assertion
โ lookup_type: when assertion_types include type, echoes script
โ lookup_type: when references official assertion, echoes that
โ when missing and references local script, echoes that
โ get echoes a value when present
โ get echoes nothing when not present
โ get echoes 'true' when no equal sign
โ unknown command returns 1
โ bag: init creates variable
โ bag: init clears existing variable
โ bag: push appends to stack
โ bag: read echoes the read item
โ bag: pop removes top item from stack
(from function `bag' in file lib/helpers/bag.sh, line 27,
in test file test/help-bag.bats, line 40)
`bag pop foo' failed
/src/bork/lib/helpers/bag.sh: line 27: unset: `foo[1]=': not a valid identifier
โ bag: set appends key/value to stack
โ bag: set overwrites an existing key
โ bag: get returns a specified key
โ bag: filter echoes all lines matching a pattern
โ bag: index echoes index of first matching item
โ bag: find echoes first line matching a pattern
โ bag: print echoes each item line-by-line
โ http_head_cmd: with curl performs a head request
(in test file test/help-http.bats, line 11)
`[ 'curl -sI "https://foo.com"' = $output ]' failed with status 2
/tmp/bats.9975.src: line 11: [: too many arguments
โ http_header: extracting a header value
โ htpp_get: getting a file
(in test file test/help-http.bats, line 25)
`[ "curl -so \"$target\" \"$url\" &> /dev/null" = $output ]' failed with status 2
/tmp/bats.9975.src: line 25: [: too many arguments
โ md5cmd Darwin echoes 'md5'
โ md5cmd Darwin :file echoes 'md5 :file'
โ md5cmd Linux echoes md5sum with awk
โ md5cmd Linux :file echoes md5sum :file with awk
โ md5cmd BSD returns 1
โ needs_exec: returns $2 if exec found
โ needs_exec: returns $2 + 1 if exec not found, echoes message
โ is_platform: returns 0 if argument is for platform
โ is_platform: returns 1 if argument is not for platform
โ contains: returns 0 for full matches of items in a list
โ contains: returns 1 when no full matches
โ get_field: returns the field on a match
โ item_count: returns 0 for empty strings
โ item_count: counts items in the same line
โ item_count: counts items across lines
โ matches: returns 0 for regex matches of items in a list
โ matches: returns 1 on pattern misses
โ matches: recognizes extended patterns
โ matches: recognizes backslash patterns
โ replace: replaces the matched pattern with the result
โ replace: returns the input when the pattern does not match
โ apt status reports incorrect platform
โ apt status reports missing apt-get
โ apt status reports missing dpkg
โ apt status reports a package is missing
โ apt status reports a package is outdated
โ apt status reports a package is current
โ apt install runs 'apt-get install'
โ apt upgrade runs 'apt-get upgrade'
โ brew-tap status reports missing when untapped
โ brew-tap status reports partial when installed but missing pin status
โ brew-tap status reports partial when installed but has pin status when it shouldn't
โ brew-tap status reports ok when installed has correct no-pin status
โ brew-tap status reports ok when installed has correct yes-pin status
โ brew-tap install installs tap
โ brew-tap install installs tap with pin
(in test file test/type-brew-tap.bats, line 49)
`[ "brew tap homebrew/science" = ${lines[0]} ]' failed with status 2
/tmp/bats.23348.src: line 49: [: too many arguments
โ brew-tap upgrade with pin adds pin
โ brew-tap upgrade without pin remvoes pin
โ brew status reports unsupported platform
โ brew status reports missing brew exec
โ brew status reports a package is missing
โ brew status reports a package is outdated
โ brew status reports a packge is current
โ brew install runs 'install'
โ brew upgrade runs 'upgrade'
โ cask statups reports unsupported platforms
โ cask status reports missing brew exec
โ cask status reports missing cask package
โ cask status reports an app is missing
โ cask status reports an app is current
โ cask status reports an app is outdated
โ cask install runs 'install'
โ cask upgrade performs a force install and cleans up old versions
โ defaults status: returns FAILED_PRECODITION without defaults exec
โ defaults status: returns MISSING if no value for domain/key
โ defaults status: returns MISMATCH_UPGRADE when existing type doesn't match
โ defaults status: returns MISMATCH_UPGRADE when existing value doesn't match
โ defaults status: returns OK when existing type and value matches
โ defaults status: returns OK when type is int and value matches
โ defaults status: returns OK when type is dict and value matches
โ defaults upgrade: runs defaults write with: $domain $key -$type $value
โ defaults install|upgrade: handles dict with proper args
โ directory: status returns OK if directory is present
โ directory: status returns MISSING if directory isn't present
โ directory: status returns CONFLICT_CLOBBER if target is non-directory
โ directory: install creates target directory
โ download status: when file is MISSING
โ download status: without comparisons returns OK when file exists
โ download status: returns CONFLICT_UPGRADE when comparing size and it doesn't match
โ download status: returns OK when conditions match
โ download install: gets from remote
โ file status: returns MISSING when file is missing
โ file status: returns FAILED_ARGUMENTS when source file is missing
โ file status: returns CONFLICT_UPGRADE when sum doesn't match
(in test file test/type-file.bats, line 28)
`[ "${lines[0]}" = $expected ]' failed with status 2
/tmp/bats.29488.src: line 28: [: too many arguments
โ file status: returns OK when all is well
โ file install: creates directory, copies file
โ file install: ignores directory if not present
โ file status: returns MISMATCH_UPGRADE when target file has incorrect permissions
โ file install: sets permissions for file after copying
โ file status: returns FAILED_ARGUMENT_PRECONDITION when target user doesn't exist
โ file status: returns MISMATCH_UPGRADE when target file has incorrect owner
โ file status: returns OK with owner and all is well
โ file install: copies file as correct user
โ file compile: echoes base64 representation to screen
โ file compile: outputs warning to stderr on missing file
โ file status: if compiled, uses stored variable
โ file install: if compiled, uses stored variable
โ gem status: returns FAILED_PRECONDITION without gem exec
โ gem status: returns MISSING if gem isn't installed
โ gem status: returns OK if gem is installed
โ gem install: performs the installation
โ git install: bakes target dir, git clone
(in test file test/type-git.bats, line 106)
`[ "mkdir -p bork" = ${lines[0]} ]' failed with status 2
/tmp/bats.8295.src: line 106: [: too many arguments
โ git install: with target argument, performs clone
(in test file test/type-git.bats, line 114)
`[ "mkdir -p /Users/mattly/code/bork" = ${lines[0]} ]' failed with status 2
/tmp/bats.8295.src: line 114: [: too many arguments
โ git install: uses specified branch
(in test file test/type-git.bats, line 122)
`[ "mkdir -p bork" = ${lines[0]} ]' failed with status 2
/tmp/bats.8295.src: line 122: [: too many arguments
โ git upgrade: merges to new ref, echoes changelog
(in test file test/type-git.bats, line 130)
`[ "cd bork" = ${lines[0]} ]' failed with status 2
/tmp/bats.8295.src: line 130: [: too many arguments
โ github status: handles implicit target
โ github status: handles explicit target
โ github status: handles --ssh argument
โ github compile: outputs git type via include_assertion
(in test file test/type-github.bats, line 33)
`[ "${lines[n]}" = $line ]' failed โ go-get status: returns FAILED_PRECONDITION without go exec
โ go-get status: returns MISSING if package isn't installed
โ go-get status: returns OK if package is installed
โ go-get install: performs the installation
โ group status: returns FAILED_PRECONDITION when missing groupadd exec
โ group status: returns MISSING when group doesn't exist
โ group status: returns OK when group exists
โ group install: bakes 'groupadd'
โ iptables status: returns MISSING when rule is missing
โ iptables status: returns OK when rule is present
โ iptables install: bakes the -A command
โ mas status: returns FAILED_PRECONDITION without mas exec
โ mas status: returns MISSING when app not installed
โ mas status: returns OUTDATED when app upgrade pending
โ mas status: returns OK when app installed and up-to-date
โ mas install: performs install
โ mas upgrade: performs upgrade
โ npm status: returns FAILED_PRECONDITION without npm exec
โ npm status: returns MISSING if package isn't installed
โ npm status: returns OUTDATED if package npm reports new version
โ npm status: returns OK if package is installed
โ npm install: performs an installation
โ npm upgrade: performs an upgrade
โ pip status: returns FAILED_PRECONDITION without pip exec
โ pip status: returns MISSING if pkg isn't installed
โ pip status: returns OK if pkg is installed
โ pip install: performs installation
โ symlink: status returns OK if the source is symlinked in dest
โ symlink: status returns MISSING if the source is not symlinked in dest
โ symlink: status returns MISMATCH_UPGRADE if dest is symlinked to a non-source
โ symlink: status returns CONFLICT_CLOBBER if dest is a non-symlink
โ symlink: install creates the target symlink
(in test file test/type-symlink.bats, line 58)
`[ "ln -sf $sourcefile .README" = ${lines[0]} ]' failed with status 2
/tmp/bats.18214.src: line 58: [: too many arguments
โ user status: returns FAILED_PRECONDITION when useradd isn't found
โ user status: returns MISSING when user doesn't exist
โ user status: returns OK when user exists
โ user install: bakes 'useradd' with -m
โ user status: with shell, returns MISSING when user doesn't exist
โ user status: with shell, returns MISMATCHED_UPGRADE when user exists, wrong shell
โ user status: with shell, returns OK when user exists, right shell
โ user install: with shell, bakes 'useradd' with --shell
โ user upgrade: with shell, bakes 'chsh -s'
(in test file test/type-user.bats, line 70)
`[ "${lines[0]}" = $users_query ]' failed with status 2
/tmp/bats.18823.src: line 70: [: too many arguments
โ user status: with group, returns MISSING when user doesn't exist
โ user status: with group, returns PARTIAL when user belongs to none
โ user status: with group, returns PARTIAL when user belongs to some
โ user status: with group, returns OK when user belongs to all
โ user install: with group, bakes 'useradd' with --groups
โ user install: with group matching user handle, bakes 'useradd' with --groups and -g
โ user upgrade: with group, bakes 'adduser' with user and group for each group
(in test file test/type-user.bats, line 123)
`[ "${lines[0]}" = $users_query ]' failed with status 2
/tmp/bats.18823.src: line 123: [: too many arguments
โ yum status reports incorrect platform
โ yum status reports missing yum
โ yum status reports a package is missing
โ yum status reports a package is outdated
โ yum status reports a package is current
โ yum install runs 'yum install'
โ yum upgrade runs 'yum install'
200 tests, 17 failures, 1 skipped
This could be due to environment change on Travis, previously tests used to run on precise, maybe the version of bash/test were more forgiving there.
this breaks on vagrant:
ok apt iptables-persistent
Thanks to the crappy dialog thing that the iptables-persistent package brings up. There's apparently a flag for installing it without that dialog (still looking for this), but we'll need a way to pass it through.
or maybe there's a mode for when an error is encountered, it halts. Perhaps the script can set this mode.
Would you be interested in getting this added to homebrew? Either through the official taps, or a custom tap?
(Fantastic work btw! Love it!)
The Homebrew package for Bork is based off the v0.10.0 release from March 2016, which is missing a lot of the newer fixes including PR #88 which is fairly essential if you're installing through Homebrew.
Whilst it is possible to install with brew install --HEAD
, it's not best practice by any means, and prevents automatically updating via the brew upgrade
: Therefore it'd be helpful to have a versioned release with recent (stable) changes which can be packaged as usual.
-for config in code/mattly/dotfiles/configs/*; do
- ok symlink ".$(basename $config) $config"
+for config in $HOME/code/mattly/dotfiles/configs/*; do
+ ok symlink "$HOME/.$(basename $config)" $config
since it doesn't include the "git" assertion as well. hm...
I noticed that my npm borkfile takes about two or three minutes to finish all the the assertions. The culprit of this is line 19 in npm.sh, as well as line 22:
list=$(bake npm ls -g --depth 0)
outdated=$(bake npm outdated -g)
This first command alone takes about 4,5 seconds to finish:
โฏ time npm ls -g --depth 0
/Users/jonas/.npm-packages/lib
โโโ [email protected]
โโโ [email protected]
โโโ [email protected]
โโโ [email protected]
โโโ [email protected]
โโโ [email protected]
โโโ [email protected]
โโโ [email protected]
โโโ [email protected]
โโโ [email protected]
โโโ [email protected]
โโโ [email protected]
โโโ [email protected]
โโโ [email protected]
โโโ [email protected]
โโโ [email protected]
โโโ [email protected]
โโโ [email protected]
โโโ [email protected]
โโโ [email protected]
โโโ [email protected]
โโโ [email protected]
โโโ [email protected]
โโโ [email protected]
โโโ [email protected]
โโโ [email protected]
โโโ [email protected]
โโโ [email protected]
โโโ [email protected]
โโโ [email protected]
โโโ [email protected]
โโโ [email protected]
npm ls -g --depth 0 4,61s user 0,83s system 114% cpu 4,735 total
Let alone, a single assertion using Bork about 11 seconds:
โฏ time bork do ok npm diff-so-fancy
ok: npm diff-so-fancy
bork do ok npm diff-so-fancy 10,25s user 2,13s system 102% cpu 12,128 total
I would love to improve this somehow but I am not quite sure how to do it properly. I did some discussion with @bcomnes in the IRC channel yesterday and he had the idea to maybe just use ls
on the global node_modules, something like ls -1 $(npm config get prefix)/lib/node_module
.
When I run some timings on this, it takes about 0,33 seconds for both ls
and npm
to finish:
โฏ time ls -1 $(time npm config get prefix)/lib/node_modules
npm config get prefix 0,30s user 0,04s system 103% cpu 0,331 total
bower
canibekikked
cloudflare-cli
coffee-script
cordova
diff-so-fancy
electron-prebuilt
express-generator
ghost-to-md
gifify
git-hours
grunt
grunt-cli
gulp
gulp-cli
hastebin
hubot
init.js
json
ms
npm
npm-check
npm-check-updates
ntmjs
prettydiff
prettyjson
psi
sitespeed.io
stringstream
tlstools
twitgrab
updatr
ls -G -1 $(time npm config get prefix)/lib/node_modules 0,00s user 0,00s system 75% cpu 0,003 total
Only downside here is that we don't have the version information for each module. Also I have no clue how to replicate or improve the npm outdated
command.
Do you guys have any ideas / feedback on this?
Is there a reason that when a ok check
fails that it is handled with check_failed
instead of did_error
? They seem to serve a similar function.
I've been thinking for a while about what version 1.0 of bork will look like, and I think we're almost there. This project started off as a joke, a "can I even do this" and I guess if you think about a problem long enough, you figure it out. I'm humbled by the interest people have taken in it, and I'd like to open my plan up for comments by the small community that's developed here.
I just recently added outdated / update support and tests to npm, and there are more types where these are missing. I'd like to complete these.
ok
assertionThis is something I've been thinking about for a while, and in theory it's not terribly hard. Mostly it's come down to semantics for what the opposite of ok
is. So perhaps we alias ok
to should
or pass
and then provide should-not
or fail
. So for example pass brew
asserts the presence of homebrew, fail brew
asserts the absence of it.
I see this as a two-pronged effort:
I have borksh.com
and a SSG tool I like working with already, I just need to figure out the Info Architecture and start putting things together. I see this site as serving two purposes: Marketing and Documentation. Marketing is the what and why, and Documentation is the how. I could use the most input on the marketing side of things. I have a rough plan for the docs that include both guides (to help learn) and reference (to help remind), and some good docs-focused friends to ping ideas off of.
This will be the most controversial of the items here, but I've given it a lot of thought. The main thrust is, I see bork as something I would like to grow into a truly OSS alternative to commercial tools, and I feel that the GPL provides the best path to get there. I know many developers are GPL-averse because their employers are GPL-averse, but from talking to friends with successful side-projects, they all wish this is something they had tackled earlier. Many companies are GPL-averse for legal reasons and this is fine โ I see an opportunity to do something with turning licensing fees into something that can finance development and pay contributors. I don't have it fully sketched out yet but wanted to put it up for discussion.
ping @amerine and @jsullivan, I'd love your feedback, ignore if you want, no hard feelings. I'm thinking out loud here.
So now that bork has gone from "something I wrote to help me setup my laptop" to "something other people are using" and "something I'm using to setup VPSs", I'm starting to think about how to make this thing a bit more flexible while at the same time not turning it into the kitchen sink.
Here's a tidied up and perhaps idealized version of a config I put together for a VPS: https://gist.github.com/mattly/11091947
The process of creating this and its pieces has been pretty instructive. It necessitated building the "compile" feature of bork, which turns the config into a single shell script you can pass around and run, and the workflow I have is, I've got the main config and some specialized assertion helpers, and I compile a satisfy script that vagrant runs.
The assertion helpers could be grouped into separate "plugin packs" from the main bork program, and they could look like this:
and then you'd install the ones you want to work with, include them into your config. You can modify a local system like always with "bork satisfy config.sh" but could also compile the whole thing to "setup.sh" or whatever that you can download to get a new machine up and running.
Another benefit of this would be that specialized concerns could exist in their own place as opposed to the main bork repo. IDK though, maybe I'm putting the cart before the horse and should just include most of these in the stdlib assertions for now.
Zypper is the package manager for SUSE and derivatives (openSUSE, SLES, etc.).
thanks to @jsullivan for pointing it out.
herp derp derp
bake adduser $handle $group
pipsi (pip script installer) is like Homebrew for python packages - it installs python packages from PyPI (just like pip) in their own isolated virtualenvs and links their executables into a directory on PATH.
This way you can use many of the awesome python based apps straight from PyPI without the risk of messing up the system by having apps with conflicting dependencies / version requirements.
basically just have to write the logic for this
It didn't look like this project had an IRC channel yet. I grabbed #bork.sh on freenode if anyone else wants to join. (#bork was taken already, although we probably have precedence to take it due to freenode rules... but thats disruptive)
@mattly how do you feel about endorsing an IRC channel in the readme ?
the README isn't cutting it anymore
should document:
It's difficult enough keeping this stuff straight myself, and asking contributors to do that is perhaps a bit much. The CI process should run tests with both the GNU and BSD versions of common utilities.
Apparently due to npm/npm#12089 it's possible to install something newer than the latest with npm upgrade -g
and you should use npm install -g
instead.
Just noticed that bork do ok brew-tap <tap>
doesn't actually update the (indeed outdated) tap:
โฏ bork do ok brew-tap frdmn/formulas
ok: brew-tap frdmn/formulas
According to the Homebrew docs, the brew update
command is used to update them.
Can someone double check and maybe confirm this bug?
It would be very useful to be able to set/update ownership (owner, group) and permissions of directories using the directory
type.
something like
file status ~/user/.ssh/authorized_keys --from="wget https://github.com/user.keys"
โฏ mkdir github-test && cd github-test
โฏ echo "ok github ./dotfiles edrex/dotfiles" > github.sh
โฏ bork compile github.sh > github.c.sh
โฏ bash -x github.c.sh
+++ getDir githubc.sh
+++ fname=githubc.sh
+++ '[' -h githubc.sh ']'
+++++ dirname githubc.sh
++++ cd .
++++ pwd -P
+++ echo /Users/eric/test
++ cd /Users/eric/test/..
++ pwd -P
+ BORK_SOURCE_DIR=/Users/eric
+ BORK_SCRIPT_DIR=/Users/eric/test
+ BORK_WORKING_DIR=/Users/eric/test
+ operation=satisfy
+ case "$1" in
+ STATUS_OK=0
+ STATUS_FAILED=1
+ STATUS_MISSING=10
+ STATUS_OUTDATED=11
+ STATUS_PARTIAL=12
+ STATUS_MISMATCH_UPGRADE=13
+ STATUS_MISMATCH_CLOBBER=14
+ STATUS_CONFLICT_UPGRADE=20
+ STATUS_CONFLICT_CLOBBER=21
+ STATUS_CONFLICT_HALT=25
+ STATUS_BAD_ARGUMENTS=30
+ STATUS_FAILED_ARGUMENTS=31
+ STATUS_FAILED_ARGUMENT_PRECONDITION=32
+ STATUS_FAILED_PRECONDITION=33
+ STATUS_UNSUPPORTED_PLATFORM=34
++ uname -s
+ platform=Darwin
+ baking_platform=
+ bork_performed_install=0
+ bork_performed_upgrade=0
+ bork_performed_error=0
+ bork_any_updated=0
+ bag init include_directories
+ action=init
+ varname=include_directories
+ shift 2
+ '[' init '!=' init ']'
+ case "$action" in
+ eval 'include_directories=( )'
++ include_directories=()
+ bag push include_directories /Users/eric/test
+ action=push
+ varname=include_directories
+ shift 2
+ '[' push '!=' init ']'
++ eval 'echo ${#include_directories[*]}'
+++ echo 0
+ length=0
+ last=-1
+ case "$action" in
+ eval 'include_directories[0]="/Users/eric/test"'
++ include_directories[0]=/Users/eric/test
+ _bork_check_failed=0
+ _checked_len=0
+ bag init bork_assertion_types
+ action=init
+ varname=bork_assertion_types
+ shift 2
+ '[' init '!=' init ']'
+ case "$action" in
+ eval 'bork_assertion_types=( )'
++ bork_assertion_types=()
+ ok github ./dotfiles edrex/dotfiles
+ assertion=github
+ shift
+ _bork_check_failed=0
+ _changes_reset
+ bork_performed_install=0
+ bork_performed_upgrade=0
+ bork_performed_error=0
+ last_change_type=
++ _lookup_type github
++ assertion=github
++ is_compiled
++ return 0
++ echo type_github
++ return
+ fn=type_github
+ '[' -z type_github ']'
+ argstr='./dotfiles edrex/dotfiles'
+ quoted_argstr=
+ '[' -n ./dotfiles ']'
++ echo ' "./dotfiles"'
+ quoted_argstr=' "./dotfiles"'
+ shift
+ '[' -n edrex/dotfiles ']'
++ echo ' "./dotfiles" "edrex/dotfiles"'
+ quoted_argstr=' "./dotfiles" "edrex/dotfiles"'
+ shift
+ '[' -n '' ']'
+ case $operation in
+ _checking checking github ./dotfiles edrex/dotfiles
+ type=checking
+ shift
+ check_str='checking: github ./dotfiles edrex/dotfiles'
+ _checked_len=42
' echo -n 'checking: github ./dotfiles edrex/dotfiles
+++ _source_runner type_githubrex/dotfiles
+++ is_compiled
+++ return 0
+++ echo type_github
++ eval 'type_github status "./dotfiles" "edrex/dotfiles"'
+++ type_github status ./dotfiles edrex/dotfiles
+++ '[' -z '' ']'
+++ git_call='. /Users/eric/types/git.sh'
+++ is_compiled
+++ return 0
+++ git_call=git
+++ action=status
+++ repo=./dotfiles
+++ shift 2
+++ case $action in
+++ next=edrex/dotfiles
+++ target_dir=
+++ '[' -n edrex/dotfiles ']'
+++ '[' e '!=' - ']'
+++ target_dir=./dotfiles
+++ repo=edrex/dotfiles
+++ shift
+++ args=
++++ arguments get ssh
++++ op=get
++++ shift
++++ case $op in
++++ key=ssh
++++ shift
++++ value=
++++ '[' -n '' ']'
++++ '[' -n ']'
++++ echo ''
+++ '[' -n '' ']'
++++ echo edrex/dotfiles
+++ url=https://github.com/edrex/dotfiles.git
+++ eval 'git status ./dotfiles https://github.com/edrex/dotfiles.git '
++++ git status ./dotfiles https://github.com/edrex/dotfiles.git
fatal: Not a git repository (or any of the parent directories): .git
+ status_output=
+ status=128
++ _status_for 128
++ case "$1" in
++ echo 'unknown status: 128'
+ _checked 'unknown status: 128: github ./dotfiles edrex/dotfiles'
+ report='unknown status: 128: github ./dotfiles edrex/dotfiles'
+ (( pad=42 - 53 ))
+ i=1
+ '[' 1 -le -11 ']'
+ echo 'unknown status: 128: github ./dotfiles edrex/dotfiles'
unknown status: 128: github ./dotfiles edrex/dotfiles
+ case $status in
+ echo '-- sorry, bork doesn'\''t handle this response yet'
-- sorry, bork doesn't handle this response yet
+ echo ''
+ did_update
+ did_install
+ '[' 0 -eq 1 ']'
+ return 1
+ did_upgrade
+ '[' 0 -eq 1 ']'
+ return 1
+ return 1
The output is the same whether or not the dir exists.
The basic git
type works fine compiled.
ok brew-tap Caskroom/cask
will never succeed, it echoes back caskroom/cask
instead.
The upgrade
action of user
type prints an error (and continues) when --shell
argument wasn't specified:
partial: user foo --groups=bar
--groups: expected bar; missing bar
/bork/types/user.sh: line 22: [: /bin/bash: unary operator expected
Adding user `foo' to group `bar' ...
Adding user foo to group bar
Done.
verifying : user foo --groups=bar
* success
The following assertion fails:
ok download ~/.ssh/authorized_keys "https://github.com/bcomnes.keys" --size
because the http headers from this github request fails to return a Content-length
bret-mbr:.ssh bret$ bork status ~/.dotfiles/install/ssh.sh
conflict (upgradable): download authorized_keys https://github.com/bcomnes.keys
expected size: bytes
received size: bytes
bret-mbr:.ssh bret$ curl -sI https://github.com/bcomnes.keys
HTTP/1.1 200 OK
Server: GitHub.com
Date: Mon, 09 May 2016 00:13:04 GMT
Content-Type: text/plain; charset=utf-8
Status: 200 OK
Cache-Control: no-cache
Vary: X-PJAX
X-UA-Compatible: IE=Edge,chrome=1
Set-Cookie: logged_in=no; domain=.github.com; path=/; expires=Fri, 09 May 2036 00:13:04 -0000; secure; HttpOnly
X-Request-Id: d529280b38e3de27e17235e81f5cf091
X-Runtime: 0.008604
Content-Security-Policy: default-src 'none'; base-uri 'self'; block-all-mixed-content; child-src render.githubusercontent.com; connect-src 'self' uploads.github.com status.github.com api.github.com www.google-analytics.com github-cloud.s3.amazonaws.com api.braintreegateway.com client-analytics.braintreegateway.com wss://live.github.com; font-src assets-cdn.github.com; form-action 'self' github.com gist.github.com; frame-ancestors 'none'; frame-src render.githubusercontent.com; img-src 'self' data: assets-cdn.github.com identicons.github.com www.google-analytics.com collector.githubapp.com *.gravatar.com *.wp.com checkout.paypal.com *.githubusercontent.com; media-src 'none'; object-src assets-cdn.github.com; plugin-types application/x-shockwave-flash; script-src assets-cdn.github.com; style-src 'unsafe-inline' assets-cdn.github.com
Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
Public-Key-Pins: max-age=5184000; pin-sha256="WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18="; pin-sha256="RRM1dGqnDFsCJXBTHky16vi1obOlCgFFn/yOhI/y+ho="; pin-sha256="k2v657xBsOVe1PQRwOsHsw3bsGT2VzIqz5K+59sNQws="; pin-sha256="K87oWBWM9UZfyddvDfoxL+8lpNyoUB2ptGtn0fv6G2Q="; pin-sha256="IQBnNBEiFuhj+8x6X8XLgh01V9Ic5/V3IRQLNFFc7v4="; pin-sha256="iie1VXtL7HzAMF+/PVPR9xzT80kQxdZeJ+zduCB3uj0="; pin-sha256="LvRiGEjRqfzurezaWuj8Wie2gyHMrW5Q06LspMnox7A="; includeSubDomains
X-Content-Type-Options: nosniff
X-Frame-Options: deny
X-XSS-Protection: 1; mode=block
Vary: Accept-Encoding
X-Served-By: 1c0ce1a213af16e49d5419559ef44f50
X-GitHub-Request-Id: 499DD518:7DA5:9D56CB7:572FD60F
Not really sure what the right way to handle this. Obviously, this strategy shouldn't be used in this kind of scenario. Maybe some kind of alternative hashing comparison could be used instead? I found this when dealing with the #72 bug.
Right now, the download assertion always investigates the Content-length, even when the --size argument is omitted:
bret-mbr:.ssh bret$ bork do ok download authorized_keys "https://github.com/bcomnes.keys"
conflict (upgradable): download authorized_keys https://github.com/bcomnes.keys
expected size: bytes
received size: bytes
== Warning! Assertion: download authorized_keys https://github.com/bcomnes.keys
Attempting to satisfy has resulted in a conflict. Satisfying this may overwrite data.
Do you want to continue? (yes/no) yes
Resolving conflict...
verifying : download authorized_keys https://github.com/bcomnes.keys
* failed
conflict (upgradable)
expected size: bytes
received size: bytes
I'm still trying to track this one down, but if $(arguments get size); then
is always evaluating true for some reason.
You shouldn't run that script independently of bork and its presence there can be confusing
so, what's the point again of this:
destination $HOME/code/mattly
ok github mattly/dotfiles
versus
cd $HOME/code/mattly
ok github mattly/dotfiles
I'm sure that $destination served a good purpose at one point, but unsure now. I'm thinking about removing it (or just aliasing it to cd
for now)
Cask doesn't handle upgrades well at the moment, and whenever you try to upgrade a specific application using cask you have to reinstall it manually to "gain" said update.
I had some troubles understanding what the actually problem was in specific so I asked in the Gitter room, so here's the conversation with @adidalal:
frdmn: Good morning.
frdmn: Can someone help me out understand the current behaviour of upgrading apps using Cask?
frdmn: I have quite a bunch of apps installed using cask. However, I notice a lot of them are outdated. When I check using brew cask info [app] then, it shows a newer version number than currently installed locally and also mentions Not installed.
frdmn: When I attempt to install the (already existing, but outdated) cask using brew cask install <app>, it downloads and installs the newer version besides the currently existing one.
frdmn: Now brew cask info <app> shows the specific cask as installed, but forgot to uninstall or remove the obsolte version locally. Thus, Spotlight (or Alfred) display both versions, the old and the recently updated one. (http://up.frd.mn/chhmJvOj82.png).
frdmn: Can someone shed some light for me? Am I missing something here or is Cask just not able to handle updates properly at the current state of development?
adidalal: @frdmn The latter, currently. It's a common issue/feature request. Here's (https://github.com/caskroom/homebrew-cask/issues/16033#issuecomment-166510222) a good summary of the options and alternatives currently. Specifically, this (https://github.com/bgandon/brew-cask-outdated) and this (https://github.com/buo/brew-cask-upgrade) are unofficial scripts to do what you are asking for. (PRs welcome, naturally )
frdmn: @adidalal Thanks! I'm going to give the alternative scripts a shot.
I thought about this and came to the conclusion that bork would be perfect for this job.
Instead of just checking if the specific cask application is locally installed, an actual version check would be nice.
It would be nice if the output of satisfy
could be colorized based on the results: e.g. green for good/ok, yellow for upgradable/work, red for failed or conflict.
Bork, being minimal in terms of dependencies, etc. fits nicely in the world of containers, where Alpine Linux is very popular. Hence support for apk which is the package manager used there would be very handy.
status
will now return MISMATCH_UPGRADE
if the repository is on the wrong branch, and ok
will turn that into a call to upgrade
. However the git assertion's upgrade
action won't put it on the correct branch.
Before, status
would return a conflict, but since no actual data would be lost by resolving the issue, it's really a mismatch.
I'm trying to create a Homebrew formula for bork, but at the moment I'm stuck since bork, doesnt like to be executed when symlinked:
โฏ ~ ls -la /usr/local/bin/bork
lrwxr-xr-x 1 jonas staff 31 23 Mรคr 14:03 /usr/local/bin/bork -> ../Cellar/bork/a885baa/bin/bork
โฏ ~ bork
/usr/local/bin/bork: line 32: /usr/local/Cellar/bork/a885baa/bin/bork/lib/helpers/*.sh: Not a directory
/usr/local/bin/bork: line 32: /usr/local/Cellar/bork/a885baa/bin/bork/lib/declarations/*.sh: Not a directory
bork usage:
Perhaps you could adjust it so it returns the actual location instead of location of the symlink.
While testing around a bit, I've found out that $(realpath $0)
returns the expected path, but that binary doesn't come with OS X by default. (coreutils
brew package).
Any ideas how to solve this?
This bork file:
ok group http
ok user http --groups=http
Results in:
useradd: group http exists - if you want to add this user to that group, use -g.
This only happens when the user has the same name as the group. I think it's safe to explicitly set the -g option in all cases (to match the first group specified in --groups
). I'll send a PR shortly.
it doesn't like it if TEMPLATE has less than 6 X's, like:
baking_file=$(mktemp -t bork_test.XXXXX)
I need to specify a specific github brach/tag
something like:
ok github $bork_home/.emacs.d syl20bnr/spacemacs --branch release-0.200 --ssh
I can do conditional work with did_install
but when I run bork status
it will say the repo is mismatching because of the branch change.
In my dotfile wrapper I use a structure like this to include other bork files:
~/.dotfiles/borkfiles/_.bork
# Change into borkfile directory
destination $HOME/.dotfiles/borkfiles
# All UNIXes
include configs.bork
# OS specfic
case $OSTYPE in
darwin*)
include atom.bork
include brew.bork
include cask.bork
include osx.bork
include pip.bork ;;
esac
The other bork files are stored in the same directory as the _.bork
one.
Now when I'm trying to run this with bork it returns the following error:
โฏ ~ bork satisfy /Users/jonas/.dotfiles/borkfiles/_.bork
include: /Users/jonas/.dotfiles/configs.bork: No such file
Verbose output:
++ cat
+ BORK_SETUP_FUNCTION='getDir () {
fname=$1
while [ -h "$fname" ]; do
dir=$(cd -P "$(dirname "$fname")" && pwd)
fname=$(readlink $fname)
[[ $fname != /* ]] && fname="$dir/$fname"
done
echo "$(cd "$(dirname $fname)/.." && pwd -P)"
}
# used by loader to find core/ and stdlib/
BORK_SOURCE_DIR="$(getDir ${BASH_SOURCE[0]})"'
+ eval 'getDir () {
fname=$1
while [ -h "$fname" ]; do
dir=$(cd -P "$(dirname "$fname")" && pwd)
fname=$(readlink $fname)
[[ $fname != /* ]] && fname="$dir/$fname"
done
echo "$(cd "$(dirname $fname)/.." && pwd -P)"
}
# used by loader to find core/ and stdlib/
BORK_SOURCE_DIR="$(getDir ${BASH_SOURCE[0]})"'
+++ getDir /usr/local/bin/bork
+++ fname=/usr/local/bin/bork
+++ '[' -h /usr/local/bin/bork ']'
+++++ dirname /usr/local/bin/bork
++++ cd -P /usr/local/bin
++++ pwd
+++ dir=/usr/local/bin
++++ readlink /usr/local/bin/bork
+++ fname=../Cellar/bork/0.9.1/bin/bork
+++ [[ ../Cellar/bork/0.9.1/bin/bork != /* ]]
+++ fname=/usr/local/bin/../Cellar/bork/0.9.1/bin/bork
+++ '[' -h /usr/local/bin/../Cellar/bork/0.9.1/bin/bork ']'
+++++ dirname /usr/local/bin/../Cellar/bork/0.9.1/bin/bork
++++ cd /usr/local/bin/../Cellar/bork/0.9.1/bin/..
++++ pwd -P
+++ echo /usr/local/Cellar/bork/0.9.1
++ BORK_SOURCE_DIR=/usr/local/Cellar/bork/0.9.1
+ operation=satisfy
+ shift
+ BORK_SCRIPT_DIR=/Users/jonas
+ '[' -n /Users/jonas/.dotfiles/borkfiles/_.bork ']'
++ getDir /Users/jonas/.dotfiles/borkfiles/_.bork
++ fname=/Users/jonas/.dotfiles/borkfiles/_.bork
++ '[' -h /Users/jonas/.dotfiles/borkfiles/_.bork ']'
++++ dirname /Users/jonas/.dotfiles/borkfiles/_.bork
+++ cd /Users/jonas/.dotfiles/borkfiles/..
+++ pwd -P
++ echo /Users/jonas/.dotfiles
+ BORK_SCRIPT_DIR=/Users/jonas/.dotfiles
+ BORK_WORKING_DIR=/Users/jonas
+ for file in '$BORK_SOURCE_DIR/lib/helpers/*.sh' '$BORK_SOURCE_DIR/lib/declarations/*.sh'
+ . /usr/local/Cellar/bork/0.9.1/lib/helpers/arguments.sh
+ for file in '$BORK_SOURCE_DIR/lib/helpers/*.sh' '$BORK_SOURCE_DIR/lib/declarations/*.sh'
+ . /usr/local/Cellar/bork/0.9.1/lib/helpers/bag.sh
+ for file in '$BORK_SOURCE_DIR/lib/helpers/*.sh' '$BORK_SOURCE_DIR/lib/declarations/*.sh'
+ . /usr/local/Cellar/bork/0.9.1/lib/helpers/bake.sh
+ for file in '$BORK_SOURCE_DIR/lib/helpers/*.sh' '$BORK_SOURCE_DIR/lib/declarations/*.sh'
+ . /usr/local/Cellar/bork/0.9.1/lib/helpers/http.sh
+ for file in '$BORK_SOURCE_DIR/lib/helpers/*.sh' '$BORK_SOURCE_DIR/lib/declarations/*.sh'
+ . /usr/local/Cellar/bork/0.9.1/lib/helpers/md5cmd.sh
+ for file in '$BORK_SOURCE_DIR/lib/helpers/*.sh' '$BORK_SOURCE_DIR/lib/declarations/*.sh'
+ . /usr/local/Cellar/bork/0.9.1/lib/helpers/operations.sh
+ for file in '$BORK_SOURCE_DIR/lib/helpers/*.sh' '$BORK_SOURCE_DIR/lib/declarations/*.sh'
+ . /usr/local/Cellar/bork/0.9.1/lib/helpers/permission_cmd.sh
+ for file in '$BORK_SOURCE_DIR/lib/helpers/*.sh' '$BORK_SOURCE_DIR/lib/declarations/*.sh'
+ . /usr/local/Cellar/bork/0.9.1/lib/helpers/status_codes.sh
++ STATUS_OK=0
++ STATUS_FAILED=1
++ STATUS_MISSING=10
++ STATUS_OUTDATED=11
++ STATUS_PARTIAL=12
++ STATUS_MISMATCH_UPGRADE=13
++ STATUS_MISMATCH_CLOBBER=14
++ STATUS_CONFLICT_UPGRADE=20
++ STATUS_CONFLICT_CLOBBER=21
++ STATUS_CONFLICT_HALT=25
++ STATUS_BAD_ARGUMENTS=30
++ STATUS_FAILED_ARGUMENTS=31
++ STATUS_FAILED_ARGUMENT_PRECONDITION=32
++ STATUS_FAILED_PRECONDITION=33
++ STATUS_UNSUPPORTED_PLATFORM=34
+ for file in '$BORK_SOURCE_DIR/lib/helpers/*.sh' '$BORK_SOURCE_DIR/lib/declarations/*.sh'
+ . /usr/local/Cellar/bork/0.9.1/lib/helpers/system.sh
+++ uname -s
++ platform=Darwin
++ baking_platform=
+ for file in '$BORK_SOURCE_DIR/lib/helpers/*.sh' '$BORK_SOURCE_DIR/lib/declarations/*.sh'
+ . /usr/local/Cellar/bork/0.9.1/lib/helpers/text.sh
+ for file in '$BORK_SOURCE_DIR/lib/helpers/*.sh' '$BORK_SOURCE_DIR/lib/declarations/*.sh'
+ . /usr/local/Cellar/bork/0.9.1/lib/declarations/changes.sh
++ bork_performed_install=0
++ bork_performed_upgrade=0
++ bork_performed_error=0
++ bork_any_updated=0
+ for file in '$BORK_SOURCE_DIR/lib/helpers/*.sh' '$BORK_SOURCE_DIR/lib/declarations/*.sh'
+ . /usr/local/Cellar/bork/0.9.1/lib/declarations/destination.sh
++ BORK_DESTINATION=/Users/jonas
+ for file in '$BORK_SOURCE_DIR/lib/helpers/*.sh' '$BORK_SOURCE_DIR/lib/declarations/*.sh'
+ . /usr/local/Cellar/bork/0.9.1/lib/declarations/include.sh
++ bag init include_directories
++ action=init
++ varname=include_directories
++ shift 2
++ '[' init '!=' init ']'
++ case "$action" in
++ eval 'include_directories=( )'
+++ include_directories=()
++ bag push include_directories /Users/jonas/.dotfiles
++ action=push
++ varname=include_directories
++ shift 2
++ '[' push '!=' init ']'
+++ eval 'echo ${#include_directories[*]}'
++++ echo 0
++ length=0
++ last=-1
++ case "$action" in
++ eval 'include_directories[0]="/Users/jonas/.dotfiles"'
+++ include_directories[0]=/Users/jonas/.dotfiles
+ for file in '$BORK_SOURCE_DIR/lib/helpers/*.sh' '$BORK_SOURCE_DIR/lib/declarations/*.sh'
+ . /usr/local/Cellar/bork/0.9.1/lib/declarations/ok.sh
++ _bork_check_failed=0
++ _checked_len=0
+ for file in '$BORK_SOURCE_DIR/lib/helpers/*.sh' '$BORK_SOURCE_DIR/lib/declarations/*.sh'
+ . /usr/local/Cellar/bork/0.9.1/lib/declarations/register.sh
++ bag init bork_assertion_types
++ action=init
++ varname=bork_assertion_types
++ shift 2
++ '[' init '!=' init ']'
++ case "$action" in
++ eval 'bork_assertion_types=( )'
+++ bork_assertion_types=()
+ case "$operation" in
+ . /Users/jonas/.dotfiles/borkfiles/_.bork
++ destination /Users/jonas/.dotfiles/borkfiles
++ BORK_DESTINATION=/Users/jonas/.dotfiles/borkfiles
++ '[' '!' -d /Users/jonas/.dotfiles/borkfiles ']'
++ include configs.bork
+++ bag read include_directories
+++ action=read
+++ varname=include_directories
+++ shift 2
+++ '[' read '!=' init ']'
++++ eval 'echo ${#include_directories[*]}'
+++++ echo 1
+++ length=1
+++ last=0
+++ case "$action" in
+++ '[' 1 -gt 0 ']'
++++ eval 'echo ${include_directories[0]}'
+++++ echo /Users/jonas/.dotfiles
+++ echo /Users/jonas/.dotfiles
++ incl_script=/Users/jonas/.dotfiles/configs.bork
++ '[' -e /Users/jonas/.dotfiles/configs.bork ']'
++ echo 'include: /Users/jonas/.dotfiles/configs.bork: No such file'
include: /Users/jonas/.dotfiles/configs.bork: No such file
++ exit 1
Apparently it always looks into /Users/jonas/.dotfiles/
instead of the actually current working directory.
basically, this doesn't work:
ok brew foo
if did_update; then ...; fi
because it's running the if statement during the compile operation and it never makes it to the compiled script.
/usr/local/Homebrew
, though really we should check against brew config | grep HOMEBREW_REPOSITORY
and perhaps fall back to /usr/local
I'd like to assert that this has been configured:
defaults write com.runningwithcrayons.Alfred-Preferences hotkey.default -dict key -int 49 mod -int 1048576 string Space
So I tried converting it to:
ok defaults com.runningwithcrayons.Alfred-Preferences hotkey.default dictionary key -int 49 mod -int 1048576 string Space
and
ok defaults com.runningwithcrayons.Alfred-Preferences hotkey.default dictionary "{ key = 49; mod = 1048576; string = Space; }"
And both result in (something close to):
checking: defaults com.runningwithcrayons.Alfred-Preferences hotkey.default dictionmismatch (upgradable): defaults com.runningwithcrayons.Alfred-Preferences hotkey.default dictionary { key = 49; mod = 1048576; string = Space; }
expected value: {
received value: {
key = 49;
mod = 524288;
string = Space;
}
2014-07-17 15:41:05.862 defaults[2600:507] Unexpected argument {; leaving defaults unchanged.
* failure
I'm content to just set the value as a one-off after a did_install check, but wanted to bring it to your attention.
For example, using the symlink
borkfile:
$ touch "a a"
$ bork do ok symlink "b b" "a a"
missing: symlink b b a a
verifying : symlink b b a a
* failed
missing
when compiled, should eval md5 command:
sourcesum=$(echo "${!file_varname}" | base64 --decode | eval $md5c)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.