RubyKaigi2015: Building CLI Apps For Everyone

RubyKaigi2015: Building CLI Apps For Everyone

Many projects rely on command-line tools to provide an efficient and powerful interface to work.

Building tools for everyone can be difficult, because of conflicting environment or OS.

How can we build command-line apps that work for everyone and still write Ruby?

This talk will discuss how to use mruby-cli to build cross-platform apps in Ruby.

Our goal will be to build a CLI app using mruby and produce a self-contained binary that can be shipped to end users.

Since mruby is designed to be embedded and statically compiled, it's also really good at packaging ruby code.

7fe945668a4fc098e886e20dea71d2ee?s=128

Zachary Scott

December 12, 2015
Tweet

Transcript

  1. 16.

    Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak RubyKaigi

    #rubykaraoke Sat, 12 Dec 2015 22:00 カラオケパセラ銀座店 東京都中央区銀座 6-13-16銀座ウォールビル 1F
  2. 17.

    Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak Agenda

    1. Packaging in Ruby 2. Why mruby? 3. What is mruby-cli?
  3. 22.
  4. 32.

    Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak “Why

    rewrite?”, you might ask. Well Shoes3 is more of a C- project than a Ruby project. ... It’s really hard to maintain. Unfortunately there are some bugs that make the install fail on some systems, a shot at a dependency upgrade was basically a frustrating story for everybody involved, packaging (sadly) is mostly broken etc. JRuby Shoes https://pragtob.wordpress.com/2013/07/17/shoes-4-a-progress-report/
  5. 35.

    Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak Traveling

    Ruby • No need to rewrite your app • Packages your app as a directory • Runtime packaging is taken care of • Leverage rubygems ecosystem • Native gems limited to precompiled exts
  6. 41.
  7. 43.

    Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak procs

    blocks DHH freedom patching meta programming literals
  8. 52.

    Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak mrbgem.rake

    MRuby::Gem::Specification.new('hello') do |spec| spec.license = 'MIT' spec.authors = ['Terence Lee'] spec.summary = 'hello world' spec.bins = ['hello'] spec.add_dependency 'mruby-print', :core => 'mruby-print' spec.add_dependency 'mruby-mtest', :mgem => 'mruby-mtest' spec.add_dependency 'mruby-yaml', :github => 'hone/mruby- yaml' end
  9. 53.

    Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak mrbgem.rake

    MRuby::Gem::Specification.new('hello') do |spec| spec.license = 'MIT' spec.authors = ['Terence Lee'] spec.summary = 'hello world' spec.bins = ['hello'] spec.add_dependency 'mruby-print', :core => 'mruby-print' spec.add_dependency 'mruby-mtest', :mgem => 'mruby-mtest' spec.add_dependency 'mruby-yaml', :github => 'hone/mruby- yaml' end
  10. 54.

    Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak core

    mrbgems ├── [4.0K] mruby-array-ext ├── [4.0K] mruby-bin-debugger ├── [4.0K] mruby-bin-mirb ├── [4.0K] mruby-bin-mrbc ├── [4.0K] mruby-bin-mruby ├── [4.0K] mruby-bin-mruby-config ├── [4.0K] mruby-bin-strip ├── [4.0K] mruby-compiler ├── [4.0K] mruby-enumerator
  11. 55.

    Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak mrbgem.rake

    MRuby::Gem::Specification.new('hello') do |spec| spec.license = 'MIT' spec.authors = ['Terence Lee'] spec.summary = 'hello world' spec.bins = ['hello'] spec.add_dependency 'mruby-print', :core => 'mruby-print' spec.add_dependency 'mruby-mtest', :mgem => 'mruby-mtest' spec.add_dependency 'mruby-yaml', :github => 'hone/mruby- yaml' end
  12. 57.

    Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak mruby-yaml

    mruby-json mruby-httprequest mruby-io mruby-onig-regexp mruby’s most wanted
  13. 58.

    Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak mrbgem.rake

    MRuby::Gem::Specification.new('hello') do |spec| spec.license = 'MIT' spec.authors = ['Terence Lee'] spec.summary = 'hello world' spec.bins = ['hello'] spec.add_dependency 'mruby-print', :core => 'mruby-print' spec.add_dependency 'mruby-mtest', :mgem => 'mruby-mtest' spec.add_dependency 'mruby-yaml', :github => 'hone/mruby- yaml' end
  14. 65.

    Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak $

    ./mruby/build/host/bin/mrbc -Bhello_kaigi hello.rb
  15. 73.

    Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak mrbgems

    that have native extensions need to support cross compiling
  16. 78.

    Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak mrblib

    ├── [4.0K] mrblib │ ├── [4.0K] mruby-cli │ │ ├── [ 697] cli.rb │ │ ├── [ 424] help.rb │ │ ├── [ 403] option.rb │ │ ├── [1022] options.rb │ │ ├── [8.0K] setup.rb │ │ ├── [ 238] util.rb │ │ └── [ 206] version.rb │ └── [ 53] mruby-cli.rb
  17. 81.

    Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak MRI

    # hello_world.rb puts 'Hello World' $ time ruby hello.rb Hello World real 0m0.041s user 0m0.028s sys 0m0.008s
  18. 82.

    Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak mruby-cli

    # mrblib/hello.rb def __main__(argv) puts "Hello World" end
  19. 83.

    Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak mruby-cli

    # mrblib/hello.rb def __main__(argv) puts "Hello World" end $ time mruby/build/host/bin/hello Hello World real 0m0.003s user 0m0.000s sys 0m0.000s
  20. 84.
  21. 85.

    Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak $

    docker-compose run compile Build summary: ================================================ Config Name: x86_64-pc-linux-gnu Output Directory: build/host Included Gems: mruby-print - standard print/puts/p mruby-sprintf - standard Kernel#sprintf method mruby-time - standard Time class mruby-io mruby-mtest hello - hello - Binaries: hello ================================================
  22. 86.

    Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak ================================================

    Config Name: x86_64-apple-darwin14 Output Directory: build/x86_64-apple-darwin14 Included Gems: mruby-print - standard print/puts/p mruby-sprintf - standard Kernel#sprintf method mruby-time - standard Time class mruby-io mruby-mtest hello - hello - Binaries: hello ================================================
  23. 87.

    Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak ================================================

    Config Name: x86_64-w64-mingw32 Output Directory: build/x86_64-w64-mingw32 Included Gems: mruby-print - standard print/puts/p mruby-sprintf - standard Kernel#sprintf method mruby-time - standard Time class mruby-io mruby-mtest hello - hello - Binaries: hello ================================================
  24. 88.

    Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak $

    ls -nlh mruby-cli | awk '{print $5}' 421K
  25. 111.
  26. 129.

    Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak 1.

    apt-get install dependencies a. gcc + 32 bit linux libs b. mingw 64/32 bit compilers 2. Ruby 2.x 3. OS X Cross Compiler mruby-cli-docker
  27. 134.

    Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak $

    ./mruby/build/ARCH/bin/hello-world Hello World
  28. 136.

    Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak •

    docker-compose run mtest • docker-compose run bintest
  29. 139.

    Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak With

    mruby-cli we have a platform for packaging CLI ruby applications
  30. 147.

    Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak jruby.cpp

    /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 1997-2008, 2010 Sun Microsystems, Inc. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2
  31. 158.

    Building a CLI App • download the mruby-cli binary •

    install Docker Toolbox • mruby-cli --setup calculator • add new functionality ◦ modify to build a calculator or just start with addition • docker-compose run compile • modify, recompile • tweet at us (@hone02 + @_zzak)