Jun 23, 2017 Tags: devblog, kbsecret, programming, ruby
This post is at least a year old.
I released KBSecret 0.5.0 earlier today, followed in quick succession by 0.5.1 through 0.5.4 for refinements and minor bug fixes. This post will detail this big changes made since 0.4.x.
Getting KBSecret built into common distro package formats has been a goal
since the very beginning, but was hampered severely by the complexity and
opacity of the deb
and RPM formats. PKGBUILD
for Arch is substantially simpler
than both of them, but I don’t currently run Arch on any of my desktop computers.
KBSecret’s future looked increasingly bound to RubyGems for distribution… until I found fpm.
Not only does fpm
provide a single interface for building debs, RPMs, and pacman
packages (among others),
but it can also automatically download the latest version of a gem from RubyGems
and convert it into an installable package in a matter of seconds.
Oh, and it’s written in Ruby. And gem install
-able:
1
2
3
4
5
$ gem install fpm
$ fpm -s gem -t deb kbsecret
Created package {:path=>"rubygem-kbsecret_0.5.2_all.deb"}
$ ls *.deb
rubygem-kbsecret_0.5.2_all.deb
How awesome is that?
Of course, there is one downside: each KBSecret dependency needs its own package, meaning that a fully-working-package-manager-installed KBSecret requires (as of writing this) no less than 15 individual packages:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ ls pkg/deb/rubygem-*
pkg/deb/rubygem-clipboard_1.1.1_all.deb
pkg/deb/rubygem-necromancer_0.3.0_all.deb
pkg/deb/rubygem-colored2_3.1.2_all.deb
pkg/deb/rubygem-pastel_0.7.1_all.deb
pkg/deb/rubygem-dreck_0.0.4_all.deb
pkg/deb/rubygem-slop_4.5.0_all.deb
pkg/deb/rubygem-equatable_0.5.0_all.deb
pkg/deb/rubygem-tty-color_0.4.2_all.deb
pkg/deb/rubygem-faraday_0.12.1_all.deb
pkg/deb/rubygem-tty-cursor_0.3.0_all.deb
pkg/deb/rubygem-kbsecret_0.5.2_all.deb
pkg/deb/rubygem-tty-prompt_0.10.1_all.deb
pkg/deb/rubygem-keybase-unofficial_0.0.8_all.deb
pkg/deb/rubygem-wisper_1.6.1_all.deb
pkg/deb/rubygem-multipart-post_2.0.0_all.deb
I’ll be looking into ways to merge this into one or two “god” packages.
Until that happens, sudo dpkg -i *.deb
(or your manager of choice) should work
just fine.
I haven’t figured out how (or whether) I actually want to distribute these packages, since managing an apt repository seems like a bit of a pain. I may just end up hosting the built packages statically on my keybase.pub, bringing us full circle.
In the mean time, you can build the packages for yourself with the project’s
Makefile
:
1
2
3
4
# packages will appear under ./pkg/<target>
$ bundle exec make deb
$ bundle exec make rpm
$ bundle exec make pacman
The vast majority of kbsecret
commands have a signature like this:
1
kbsecret <command> <--options> <arguments>
The command is followed by options either in short (-s
) or long (--session
)
format, with possible values (--foo bar
), finally followed by one or more arguments.
KBSecret uses Slop for option parsing, which dumps
the trailing arguments into the
args
array in the returned result.
This works just fine when when a command has only one argument, but quickly becomes
ugly for variable-argument commands like kbsecret new
:
1
kbsecret new <options> <type> <label> <field1 field2 ...>
which used to break down into something like this:
1
2
3
4
5
6
7
8
type, label = opts.args.shift 2
# some logic to validate the type
# some logic to validate the label
fields = opts.args
# some logic to ensure that fields were passed
I didn’t really like how ad-hoc this was, and I couldn’t find a good library for handling only trailing arguments. So I wrote my own, Dreck1.
Dreck takes the arguments remaining after a successful option-parsing, gives them names, and typechecks them:
1
2
3
4
5
6
7
8
9
args = Dreck.parse opts.args do
string :type
string :label
list :string, :fields
end
args[:type] # => "login"
args[:label] # => "netflix"
args[:fields] # => ["bob", "hunter2"]
KBSecret currently only uses the string
and list
(of string
) types, but
Dreck provides
many others.
I also plan to add support for custom types at some point.
Since Dreck needs to leech off of the state returned by a successful Slop.parse
call, I encapsulated both of them in instances of the new KBSecret::CLI
class
(previously a module).
Per-command argument parsing now looks like this:
1
2
3
4
5
6
7
8
9
10
11
12
cmd = KBSecret::CLI.new do
slop do |o|
o.bool "-f", "--foo", "toggle foo"
end
dreck do
string :bar
end
end
cmd.opts.foo? # => true
cmd.args[:bar] # => "baz"
This extra level of checking makes for some much nicer error messages:
1
2
$ kbsecret new
Fatal: Too few arguments given (0, expected >=2).
I lied a bit. There only relatively minor stuff for 0.5.x releases besides packages and trailing argument parsing:
KBSecret::VERSION
is now in its own file, because…Gemfile
has been replaced with a gemspec
call.gemspec
, and the
documentation has been updated to reflect the need for bundle exec
.Thanks for reading!
- William
I named it “dreck” in reference to the Yiddish word for garbage, but I’ve been told that it has a slightly more vulgar connotation in other Germanic languages. ↩