kapost-bootstrapper 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/Gemfile +9 -0
- data/Guardfile +70 -0
- data/README.md +121 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/kapost-bootstrapper.gemspec +23 -0
- data/lib/kapost/bootstrapper/version.rb +5 -0
- data/lib/kapost/bootstrapper.rb +103 -0
- metadata +97 -0
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
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
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
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,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,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: []
|