kapost-bootstrapper 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8e5522302446bcfaf58d7002c434604292e18b70
4
+ data.tar.gz: 318f1caef8803908f9514eed27233388eee37e03
5
+ SHA512:
6
+ metadata.gz: c7a11d08ba699dd4d37f61a0f988803ff8ea895df9bcc9313901cc15353ce870610fa493c61a56b509d7593cbcc938b2ffdfd362ce3fb7c515de060a4aa45627
7
+ data.tar.gz: 3a1e4d724f84650cf8c680e6484c960bad44b4760aad89c53f34628b210a3a9b3c92f019111bcf794e4515db0b2e071c8bbf8c6b70ed2dcc53d1a1fb3207d0b0
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.1
5
+ before_install: gem install bundler -v 1.12.5
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in kapost-bootstrapper.gemspec
4
+ gemspec
5
+
6
+ group :development, :test do
7
+ gem "guard"
8
+ gem "guard-rspec"
9
+ end
data/Guardfile ADDED
@@ -0,0 +1,70 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ ## Uncomment and set this to only include directories you want to watch
5
+ # directories %w(app lib config test spec features) \
6
+ # .select{|d| Dir.exists?(d) ? d : UI.warning("Directory #{d} does not exist")}
7
+
8
+ ## Note: if you are using the `directories` clause above and you are not
9
+ ## watching the project directory ('.'), then you will want to move
10
+ ## the Guardfile to a watched dir and symlink it back, e.g.
11
+ #
12
+ # $ mkdir config
13
+ # $ mv Guardfile config/
14
+ # $ ln -s config/Guardfile .
15
+ #
16
+ # and, you'll have to watch "config/Guardfile" instead of "Guardfile"
17
+
18
+ # Note: The cmd option is now required due to the increasing number of ways
19
+ # rspec may be run, below are examples of the most common uses.
20
+ # * bundler: 'bundle exec rspec'
21
+ # * bundler binstubs: 'bin/rspec'
22
+ # * spring: 'bin/rspec' (This will use spring if running and you have
23
+ # installed the spring binstubs per the docs)
24
+ # * zeus: 'zeus rspec' (requires the server to be started separately)
25
+ # * 'just' rspec: 'rspec'
26
+
27
+ guard :rspec, cmd: "bundle exec rspec" do
28
+ require "guard/rspec/dsl"
29
+ dsl = Guard::RSpec::Dsl.new(self)
30
+
31
+ # Feel free to open issues for suggestions and improvements
32
+
33
+ # RSpec files
34
+ rspec = dsl.rspec
35
+ watch(rspec.spec_helper) { rspec.spec_dir }
36
+ watch(rspec.spec_support) { rspec.spec_dir }
37
+ watch(rspec.spec_files)
38
+
39
+ # Ruby files
40
+ ruby = dsl.ruby
41
+ dsl.watch_spec_files_for(ruby.lib_files)
42
+
43
+ # Rails files
44
+ rails = dsl.rails(view_extensions: %w(erb haml slim))
45
+ dsl.watch_spec_files_for(rails.app_files)
46
+ dsl.watch_spec_files_for(rails.views)
47
+
48
+ watch(rails.controllers) do |m|
49
+ [
50
+ rspec.spec.call("routing/#{m[1]}_routing"),
51
+ rspec.spec.call("controllers/#{m[1]}_controller"),
52
+ rspec.spec.call("acceptance/#{m[1]}")
53
+ ]
54
+ end
55
+
56
+ # Rails config changes
57
+ watch(rails.spec_helper) { rspec.spec_dir }
58
+ watch(rails.routes) { "#{rspec.spec_dir}/routing" }
59
+ watch(rails.app_controller) { "#{rspec.spec_dir}/controllers" }
60
+
61
+ # Capybara features specs
62
+ watch(rails.view_dirs) { |m| rspec.spec.call("features/#{m[1]}") }
63
+ watch(rails.layouts) { |m| rspec.spec.call("features/#{m[1]}") }
64
+
65
+ # Turnip features and steps
66
+ watch(%r{^spec/acceptance/(.+)\.feature$})
67
+ watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) do |m|
68
+ Dir[File.join("**/#{m[1]}.feature")][0] || "spec/acceptance"
69
+ end
70
+ end
data/README.md ADDED
@@ -0,0 +1,121 @@
1
+ # Kapost::Bootstrapper
2
+
3
+ Used by Kapost apps to get themselves bootstrapped. To enhance developer happiness, every app should have a single command to get it set up (`./bin/setup`) and one command to run the whole thing (`./bin/run`). This gem attempts to help with the first script by encapsulating a useful set of helper functions that makes detecting and installing dependencies simpler.
4
+
5
+ ## Installation
6
+
7
+ Add a file to your project called `bin/setup` with these contents:
8
+
9
+ ```bash
10
+ #!/usr/bin/env bash
11
+
12
+ set -euvxo pipefail
13
+
14
+ gem which kapost-bootstrapper || gem install kapost-bootstrapper
15
+
16
+ ./bin/bootstrap
17
+ ```
18
+
19
+ Then, use the gem's helper functions in your file called `./bin/bootstrap`. See usage for examples.
20
+
21
+ ## Usage
22
+
23
+ Example `./bin/bootstrap`:
24
+
25
+ ```ruby
26
+ #!/usr/bin/env/ruby
27
+
28
+ require "pathname"
29
+
30
+ require "kapost/bootstrapper"
31
+
32
+ $LOAD_PATH << File.join(__dir__, "..", "lib")
33
+ app_root = Pathname.new File.expand_path("../../", __FILE__)
34
+
35
+ Kapost::Bootstrapper.new do
36
+ puts "== Checking application dependencies =="
37
+
38
+ # only run these commands on this platform. See also `#ubuntu`.
39
+ osx do
40
+
41
+ # `check` looks for the command specified by name, and prints the help if
42
+ # it isn't present.
43
+ check "brew", "Homebrew isn't installed. How did you even get this far?"
44
+ end
45
+
46
+ # The optional `version` attempts to do a substring match on `{cmd} --version`.
47
+ # Also note the use of HEREDOC for the help string.
48
+ required_ruby_version = File.read(app_root.join(".ruby-version")).strip
49
+ check "ruby", <<~HELP, version: required_ruby_version
50
+ Wrong Ruby version, please install #{required_ruby_version}, and make
51
+ sure it is the current Ruby. The DevOps team recommends
52
+ [chruby](https://github.com/postmodern/chruby#readme) and
53
+ [ruby-install](https://github.com/postmodern/ruby-install#readme). Both
54
+ are available in Homebrew.
55
+ HELP
56
+
57
+ # When `#check` is given a block, it is executed rather than the built-in check.
58
+ # If the block returns true-ish, it is assumed to have worked, and the bootstrap
59
+ # process continues. When false-ish, the help is printed and boostrap is halted.
60
+ check "elasticsearch" do
61
+ # The `#installed?` helper does the same as the default `#check`, and merely checks
62
+ # if the command is available.
63
+ if installed?("elasticsearch")
64
+ true
65
+ else
66
+ # Use `#sh` to execute shell commands.
67
+ osx { sh "brew install elasticsearch" }
68
+ ubuntu { sh "apt-get install elasticsearch" }
69
+ end
70
+ end
71
+
72
+ check "postgresql" do
73
+ if installed?("psql")
74
+ true
75
+ else
76
+ osx { sh "brew install postgresql" }
77
+ ubuntu { sh "apt-get install postgresql" }
78
+ end
79
+ end
80
+
81
+ # `#check_bundler` checks if Bundler is installed, and installs it if not.
82
+ # `#bundle` does exactly what you'd think.
83
+ check_bundler && bundle
84
+
85
+ # Test if an environment variable is present
86
+ check "env", <<~HELP do
87
+ You need to load the environment variables located in `.env` into your
88
+ local shell environment. The DevOps team recommends
89
+ [direnv](http://direnv.net/) (available in homebrew).
90
+ HELP
91
+ !ENV["PORT"].nil?
92
+ end
93
+
94
+ # Check different variables, with different instructions.
95
+ check "AWS tokens", <<~HELP do
96
+ You need to set "AWS_REGION", "AWS_ACCESS_KEY_ID" and
97
+ "AWS_SECRET_ACCESS_KEY" in your local shell environment. Contact the
98
+ #devops channel if you don't already have some. The DevOps team recommends
99
+ setting them in a `.env.local` file, and using [direnv](http://direnv.net/)
100
+ (available in homebrew) to load them.
101
+ HELP
102
+ !ENV["AWS_ACCESS_KEY_ID"].nil?
103
+ end
104
+
105
+ # At this point, all dependencies are assumed to be installed, and the app should be
106
+ # bootable. Do some further checks and setup, like verifying DB connections and
107
+ # migrating, etc...
108
+ sh "rake setup"
109
+ end
110
+ ```
111
+
112
+ ## Development
113
+
114
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
115
+
116
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
117
+
118
+ ## Contributing
119
+
120
+ Bug reports and pull requests are welcome on GitHub at https://github.com/kapost/kapost-bootstrapper.
121
+
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "kapost/bootstrapper"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'kapost/bootstrapper/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "kapost-bootstrapper"
8
+ spec.version = Kapost::Bootstrapper::VERSION
9
+ spec.authors = ["Paul Sadauskas"]
10
+ spec.email = ["paul@sadauskas.com"]
11
+
12
+ spec.summary = %q{A small helper utility for your app to declare and setup its system dependencies}
13
+ spec.homepage = "https://github.com/kapost/kapost-bootstrapper"
14
+
15
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
16
+ spec.bindir = "exe"
17
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_development_dependency "bundler", "~> 1.12"
21
+ spec.add_development_dependency "rake", "~> 10.0"
22
+ spec.add_development_dependency "rspec", "~> 3.0"
23
+ end
@@ -0,0 +1,5 @@
1
+ module Kapost
2
+ class Bootstrapper
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,103 @@
1
+ require "open3"
2
+
3
+ module Kapost
4
+ # Application dependency installer for this Rails application.
5
+ class Bootstrapper
6
+ def initialize(cli: Open3, printer: $stdout, platform: RUBY_PLATFORM, shell: Kernel, &block)
7
+ @cli = cli
8
+ @printer = printer
9
+ @platform = platform
10
+ @shell = shell
11
+
12
+ run(&block) if block_given?
13
+ end
14
+
15
+ def osx(&block)
16
+ instance_eval(&block) if os == :macosx
17
+ end
18
+
19
+ def check(command, help = nil, version: nil, &block)
20
+ success = say(label(command, version)) do
21
+ if block_given?
22
+ yield
23
+ else
24
+ installed?(command) and (!version or right_version?(command, version))
25
+ end
26
+ end
27
+
28
+ unless success
29
+ say(help) if help
30
+ shell.exit 1
31
+ end
32
+ end
33
+
34
+ def check_bundler
35
+ check "bundler" do
36
+ sh "gem install bundler --conservative", verbose: false
37
+ end
38
+ end
39
+
40
+ def bundle
41
+ check "gems" do
42
+ sh "bundle check || bundle install", verbose: false
43
+ end
44
+ end
45
+
46
+ def installed?(command)
47
+ _, status = cli.capture2e "type #{command}"
48
+ status.success?
49
+ end
50
+
51
+ def right_version?(command, expected_version)
52
+ version, status = cli.capture2e "#{command} --version"
53
+ status.success? && version.include?(expected_version)
54
+ end
55
+
56
+ def say(message)
57
+ if block_given?
58
+ # If we're given a block print a label with a success indicator
59
+ printer.print message.to_s
60
+ result = yield
61
+ result ? say("✓") : say("╳")
62
+ result
63
+ else
64
+ # Otherwise, just print the message
65
+ printer.puts message.to_s
66
+ end
67
+ end
68
+
69
+ def sh(*cmd)
70
+ options = (Hash === cmd.last) ? cmd.pop : {}
71
+ say(cmd.join(" ")) if options[:verbose]
72
+ result = system(*cmd)
73
+ status = $?
74
+ fail "Command `#{cmd.join(' ')}` failed with status #{status.exitstatus}" unless result
75
+ result
76
+ end
77
+
78
+ def run(&code)
79
+ instance_eval(&code)
80
+ end
81
+
82
+ private
83
+
84
+ attr_reader :cli, :printer, :platform, :shell
85
+
86
+ def label(text, version = nil)
87
+ "#{[text, version].compact.join(' ')}:".ljust(15)
88
+ end
89
+
90
+ def os
91
+ @os ||= case platform
92
+ when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
93
+ :windows
94
+ when /darwin|mac os/
95
+ :macosx
96
+ when /linux/
97
+ :linux
98
+ else
99
+ fail "unknown os: #{RUBY_PLATFORM.inspect}"
100
+ end
101
+ end
102
+ end
103
+ end
metadata ADDED
@@ -0,0 +1,97 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: kapost-bootstrapper
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Paul Sadauskas
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-06-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.12'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.12'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ description:
56
+ email:
57
+ - paul@sadauskas.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - ".rspec"
64
+ - ".travis.yml"
65
+ - Gemfile
66
+ - Guardfile
67
+ - README.md
68
+ - Rakefile
69
+ - bin/console
70
+ - bin/setup
71
+ - kapost-bootstrapper.gemspec
72
+ - lib/kapost/bootstrapper.rb
73
+ - lib/kapost/bootstrapper/version.rb
74
+ homepage: https://github.com/kapost/kapost-bootstrapper
75
+ licenses: []
76
+ metadata: {}
77
+ post_install_message:
78
+ rdoc_options: []
79
+ require_paths:
80
+ - lib
81
+ required_ruby_version: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ required_rubygems_version: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ requirements: []
92
+ rubyforge_project:
93
+ rubygems_version: 2.5.1
94
+ signing_key:
95
+ specification_version: 4
96
+ summary: A small helper utility for your app to declare and setup its system dependencies
97
+ test_files: []