Upgrade to Pro — share decks privately, control downloads, hide ads and more …

RubyKaigi2015: Building CLI Apps For Everyone

7fe945668a4fc098e886e20dea71d2ee?s=47 Zachary Scott
December 12, 2015

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. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak Building

    CLI Apps For Everyone
  2. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak

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

  4. Zachary Scott @_zzak

  5. Zachary Scott @_zzak

  6. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak @zzak_jp

  7. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak バーモント

    Vermont
  8. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak

  9. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak 作られない!!

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

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

  12. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak Terence

    Lee @hone02
  13. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak

  14. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak Austin,

    TX
  15. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak #rubykaraoke

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

    #rubykaraoke Sat, 12 Dec 2015 22:00 カラオケパセラ銀座店 東京都中央区銀座 6-13-16銀座ウォールビル 1F
  17. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak Agenda

    1. Packaging in Ruby 2. Why mruby? 3. What is mruby-cli?
  18. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak Packaging

    Landscape
  19. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak story

    of the heroku toolbelt
  20. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak gem

    install heroku
  21. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak Requires

    Ruby to be installed
  22. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak Can't

    guarantee same version of ruby locally
  23. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak

  24. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak Packaging

    was a nightmare
  25. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak

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

  27. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak require

    in ruby is slow
  28. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak

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

  30. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak Shoes.rb

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

  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/
  33. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak Traveling

    Ruby
  34. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak

  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
  36. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak No

    great packaging story
  37. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak We

    want to build things in Ruby
  38. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak Ruby

    shouldn't be a Technical Limitation
  39. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak Why

    mruby?
  40. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak The

    Pitch
  41. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak no

    built in File Socket I/O threads fork
  42. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak Keep

    the core small
  43. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak procs

    blocks DHH freedom patching meta programming literals
  44. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak It's

    still Ruby
  45. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak Usage

    in the Wild
  46. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak

  47. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak Dashboard

  48. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak Internet

    of Things
  49. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak

  50. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak openwrt-mruby

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

  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
  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
  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
  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
  56. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak mgem

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

    mruby-json mruby-httprequest mruby-io mruby-onig-regexp mruby’s most wanted
  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
  59. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak

  60. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak mruby

    build system
  61. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak

  62. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak Ahead

    of Time...
  63. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak

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

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

    ./mruby/build/host/bin/mrbc -Bhello_kaigi hello.rb
  66. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak

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

  68. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak libmruby

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

    build
  70. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak Limitations

  71. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak Can't

    leverage Rubygems
  72. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak Porting

    Existing Gems Nontrivial
  73. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak mrbgems

    that have native extensions need to support cross compiling
  74. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak

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

  76. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak What

    is mruby-cli?
  77. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak writing

    in ruby
  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
  79. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak performance

    is a feature
  80. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak MRI

    # hello_world.rb puts 'Hello World'
  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
  82. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak mruby-cli

    # mrblib/hello.rb def __main__(argv) puts "Hello World" end
  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
  84. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak a

    single binary for every major platform
  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 ================================================
  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 ================================================
  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 ================================================
  88. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak $

    ls -nlh mruby-cli | awk '{print $5}' 421K
  89. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak platform

    to build CLI apps
  90. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak simple

    setup
  91. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak

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

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

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

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

  96. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak What

    you see is what you get
  97. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak build_config.rb

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

  99. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak 64

    bit and 32 bit Linux binaries
  100. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak

  101. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak 64

    bit and 32 bit OS X binaries
  102. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak

  103. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak 64

    bit and 32 bit Windows binaries
  104. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak build_config.rb

  105. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak build_config.rb

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

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

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

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

  110. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak tools/hello-world/hello-world.c

  111. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak tools/hello-world/hello-world.c

    1. Initialize VM 2. Setup ARGV 3. Pass args to `__main__`
  112. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak mrblib/hello-world.rb

  113. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak The

    Tale of Two Tests
  114. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak test/test_hello-world.rb

  115. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak MTest::Unit

  116. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak bintest/hello-world.rb

  117. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak run_bintest

  118. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak run_bintest

    使い方は?
  119. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak Rakefile

  120. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak Rakefile

    気にしないで!
  121. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak rake

    -T
  122. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak それダメです!

    rake -T
  123. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak

  124. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak Workflow

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

  126. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak docker-compose.yml

  127. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak Dockerfile

    FROM hone/mruby-cli
  128. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak mruby-cli-docker

  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
  130. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak docker-compose

    run compile
  131. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak docker-compose

    run compile
  132. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak docker-compose

    run compile
  133. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak docker-compose

    run compile Linux OS X Windows
  134. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak $

    ./mruby/build/ARCH/bin/hello-world Hello World
  135. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak docker-compose

    run test
  136. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak •

    docker-compose run mtest • docker-compose run bintest
  137. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak Iterate

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

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

    mruby-cli we have a platform for packaging CLI ruby applications
  140. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak We’re

    not the first to package Ruby
  141. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak Now

    mruby-cli is a target to build for
  142. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak Real

    World
  143. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak jruby-launcher

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

    -- bin/
  145. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak jruby/jruby-launcher

  146. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak jruby/jruby-launcher

    6 years
  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
  148. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak mjruby

    https://github.com/jkutner/mjruby
  149. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak

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

  151. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak 329

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

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

  154. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak Roadmap

  155. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak Build

    System
  156. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak Expand

    the ecosystem
  157. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak mruby-docopt

  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)
  159. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak Let's

    build things in Ruby
  160. Building CLI Apps for Everyone RubyKaigi2015 @hone02 + @_zzak Thank

    You!!!