bently 0.0.0 → 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.
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
1
  source "http://rubygems.org"
2
2
 
3
- # Specify your gem's dependencies in vimgolf.gemspec
4
- # gemspec
3
+ # Specify your gem's dependencies in the gemspec
4
+ gemspec
data/Gemfile.lock CHANGED
@@ -1,8 +1,26 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ bently (0.0.0)
5
+ thor (>= 0.14.6)
6
+
1
7
  GEM
2
8
  remote: http://rubygems.org/
3
9
  specs:
10
+ diff-lcs (1.1.3)
11
+ rspec (2.11.0)
12
+ rspec-core (~> 2.11.0)
13
+ rspec-expectations (~> 2.11.0)
14
+ rspec-mocks (~> 2.11.0)
15
+ rspec-core (2.11.1)
16
+ rspec-expectations (2.11.3)
17
+ diff-lcs (~> 1.1.3)
18
+ rspec-mocks (2.11.2)
19
+ thor (0.16.0)
4
20
 
5
21
  PLATFORMS
6
22
  ruby
7
23
 
8
24
  DEPENDENCIES
25
+ bently!
26
+ rspec (~> 2.6)
data/README.md CHANGED
@@ -0,0 +1,123 @@
1
+ Bently allows you to create executable "recipes" for file and command-line operations that you do a lot.
2
+
3
+ You can think of it as a Homebrew for Ruby gems.
4
+
5
+ I created it for quickly settings up and deploying Rails applications.
6
+
7
+ Installation
8
+ ============
9
+
10
+ You'll probably want to add your own custom recipes so I recommend cloning into an easy-to-find directory and build and install the gem from there.
11
+
12
+ You can install the Gem if you'd prefer.
13
+
14
+ gem install bently
15
+
16
+
17
+ Example
18
+ =======
19
+
20
+ I start a new project that needs user authentication so I want to use Devise.
21
+ Looking at the Devise README on GitHub I find the necessary steps for installing and configuring Devise.
22
+
23
+ add "gem 'devise'" to Gemfile
24
+ bundle install
25
+ rails g devise:install
26
+ rails g devise user
27
+
28
+ As a Bently recipe, this would look like:
29
+
30
+ module Bently
31
+ class Devise < Recipe
32
+ step :append, :file => 'Gemfile', :with => "gem 'devise'"
33
+ step :shell, 'bundle install'
34
+ step :shell, 'rails g devise:install'
35
+ step :shell, 'rails g devise user'
36
+ end
37
+ end
38
+
39
+ And executing it is as simple as:
40
+
41
+ bently bake devise
42
+
43
+ Or if I just want a readout without executing:
44
+
45
+ bently read devise
46
+
47
+ Recipes
48
+ =======
49
+
50
+ A recipe defines a series of steps. There are seven kinds of steps:
51
+
52
+ Shell
53
+
54
+ execute a command
55
+
56
+ step :shell, 'echo hello'
57
+
58
+ Touch
59
+
60
+ create a file with some content
61
+
62
+ step :touch, :file => 'file.rb', :with => 'content'
63
+
64
+ Modify
65
+
66
+ change a part of a file to something else
67
+
68
+ step :modify, :file => 'file.rb', :from => /old_text/, :to => 'new_text'
69
+
70
+ Append
71
+
72
+ add content to the end of a file
73
+
74
+ step :append, :file => 'file.rb', :with => 'put this at the bottom'
75
+
76
+ Prepend
77
+
78
+ add content to beginning of a file
79
+
80
+ step :prepend, :file => 'file.rb', :with => 'put this at the top'
81
+
82
+ Insert
83
+
84
+ add content before or after some part of a file
85
+
86
+ step :insert, :file => 'file.rb', :with => 'insert this', :after => 'after this'
87
+
88
+ Remove
89
+
90
+ remove a file
91
+
92
+ step :remove, :file => 'delete_me.txt'
93
+
94
+
95
+ You can also define custom steps that reduce to one of the above.
96
+
97
+ step :add_gem, "gem 'rails'"
98
+
99
+ def add_gem gem
100
+ append :file => 'Gemfile', :with => gem
101
+ end
102
+
103
+ Recipe Templates
104
+ ================
105
+
106
+ Recipe templates can be created to encapsulate steps used across multiple recipes.
107
+
108
+ module Bently
109
+ class RailsRecipe < Recipe
110
+ GEMFILE = 'Gemfile'
111
+
112
+ def add_gem gem
113
+ append :file => GEMFILE, :with => gem
114
+ end
115
+
116
+ end
117
+ end
118
+
119
+ To use a template, inherit from the template class instead of Recipe.
120
+
121
+ class Devise < RailsRecipe
122
+
123
+ Fork and accumulate your own collection of recipes.
data/bently.gemspec CHANGED
@@ -1,6 +1,9 @@
1
+ $:.unshift File.expand_path("../lib", __FILE__)
2
+ require "bently/version"
3
+
1
4
  Gem::Specification.new do |s|
2
5
  s.name = 'bently'
3
- s.version = '0.0.0'
6
+ s.version = Bently::VERSION
4
7
  s.date = '2012-09-15'
5
8
  s.summary = "Bently executes (bakes) predefined formulas (recipes)"
6
9
  s.description = "Bently executes (bakes) predefined formulas (recipes) for trivial stuff you do a lot"
@@ -9,6 +12,7 @@ Gem::Specification.new do |s|
9
12
  s.homepage = 'http://github.com/bonsaiben/bently'
10
13
 
11
14
  s.add_dependency "thor", ">= 0.14.6"
15
+ s.add_development_dependency "rspec", "~> 2.6"
12
16
 
13
17
  s.files = `git ls-files`.split("\n")
14
18
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
data/bin/bently CHANGED
@@ -4,9 +4,5 @@ lib = File.expand_path(File.dirname(__FILE__) + '/../lib')
4
4
  $LOAD_PATH.unshift(lib) if File.directory?(lib) && !$LOAD_PATH.include?(lib)
5
5
 
6
6
  require 'bently'
7
- #begin
8
- Bently::CLI.start
9
- #rescue
10
- # puts "Unexpected error. Quitting..."
11
- # exit(1)
12
- #end
7
+
8
+ Bently::Himself.start
data/lib/bently/clo.rb ADDED
@@ -0,0 +1,33 @@
1
+ module Bently
2
+
3
+ module CLO
4
+ TAB_SPACES = 6
5
+
6
+ protected
7
+
8
+ # prompt arrow
9
+ def bullet(text); puts "#{magenta('==>')} #{bold(text)}" end
10
+ def listout(text,num); puts magenta("#{num}. #{text}") end
11
+
12
+ # blockquote
13
+ def blockquote text
14
+ text = text.split("\n") unless text.is_a?(Array)
15
+ text.each do |text|
16
+ puts tab(text)
17
+ end
18
+ end
19
+
20
+ # colorizes text
21
+ def colorize(text, color_code)
22
+ "#{color_code}#{text}\033[0m"
23
+ end
24
+
25
+ def red(text); colorize(text, "\033[31m"); end
26
+ def green(text); colorize(text, "\033[32m"); end
27
+ def magenta(text); colorize(text, "\033[35m"); end
28
+ def light_green(text); colorize(text, "\033[32m"); end
29
+ def bold(text); "\033[1m#{text}\033[22m"; end
30
+ def tab(text); "#{' '*TAB_SPACES}#{text}" end
31
+ end
32
+
33
+ end
@@ -0,0 +1,105 @@
1
+ module Bently
2
+
3
+ class Himself < Thor
4
+ include Thor::Actions
5
+ include CLO
6
+
7
+ desc 'list', 'list recipes'
8
+ def list
9
+ RecipeBook.all.each {|f| puts f }
10
+ end
11
+
12
+ desc 'read [RECIPE]', 'display a recipe'
13
+ def read recipe
14
+ recipe = RecipeBook.find(recipe).new
15
+ recipe.steps.each_with_index do |step,i|
16
+ read_step step, i+1
17
+ end
18
+ end
19
+
20
+ desc 'bake [RECIPE]', 'execute a recipe'
21
+ def bake recipe
22
+ recipe = RecipeBook.find(recipe).new
23
+ recipe.steps.each_with_index do |step,i|
24
+ read_step step, i+1
25
+ if confirmed_step? step
26
+ bake_step step
27
+ else
28
+ cancel_step
29
+ exit if step.fail_on_skip?
30
+ end
31
+ end
32
+ end
33
+
34
+ protected
35
+
36
+ def read_step step, num
37
+ text = step.description.split("\n")
38
+ listout text.shift, num
39
+ blockquote text if text.any?
40
+ end
41
+
42
+ def confirmed_step? step
43
+ yes? tab(magenta("#{step.action}?"))
44
+ end
45
+
46
+ def cancel_step
47
+ puts red(tab('skipped'))
48
+ end
49
+
50
+ def bake_step step
51
+ if step.is_a?(StepShell)
52
+ execute step
53
+ elsif step.is_a?(StepTouch)
54
+ touch step
55
+ elsif step.is_a?(StepModify)
56
+ modify step
57
+ elsif step.is_a?(StepAppend)
58
+ append step
59
+ elsif step.is_a?(StepPrepend)
60
+ prepend step
61
+ elsif step.is_a?(StepInsert)
62
+ insert step
63
+ elsif step.is_a?(StepRemove)
64
+ remove step
65
+ end
66
+ end
67
+
68
+ def execute step
69
+ command = step.command
70
+ if command.is_a?(Proc)
71
+ resp = ask(tab(magenta(step.question)))
72
+ command = command.yield(resp)
73
+ end
74
+ puts `#{command}`
75
+ end
76
+
77
+ def touch step
78
+ create_file(step.file, step.data)
79
+ end
80
+
81
+ def modify step
82
+ gsub_file step.file, step.pattern, step.replacement
83
+ end
84
+
85
+ def append step
86
+ create_file(step.file) unless File.exists? step.file
87
+ append_to_file step.file, "#{step.data}\n"
88
+ end
89
+
90
+ def prepend step
91
+ create_file(step.file) unless File.exists? step.file
92
+ prepend_to_file step.file, "\n#{step.data}"
93
+ end
94
+
95
+ def insert step
96
+ insert_into_file step.file, step.data, step.options
97
+ end
98
+
99
+ def remove step
100
+ remove_file step.file
101
+ end
102
+
103
+ end
104
+
105
+ end
@@ -0,0 +1,82 @@
1
+ module Bently
2
+
3
+ class ActionMailer < RailsRecipe
4
+
5
+ step :shell, 'rails g mailer UserMailer'
6
+ step :add_welcome_email_method
7
+ step :touch_welcome_email_html
8
+ step :touch_welcome_email_text
9
+
10
+ protected
11
+
12
+ def add_welcome_email_method
13
+ insert(
14
+ :file => 'app/mailers/user_mailer.rb',
15
+ :with => welcome_email_method,
16
+ :after => /^.*default.*$/
17
+ )
18
+ end
19
+
20
+ def touch_welcome_email_html
21
+ touch(
22
+ :file => './app/views/user_mailer/welcome_email.html.erb',
23
+ :with => welcome_email_html
24
+ )
25
+ end
26
+
27
+ def touch_welcome_email_text
28
+ touch(
29
+ :file => './app/views/user_mailer/welcome_email.text.erb',
30
+ :with => welcome_email_text
31
+ )
32
+ end
33
+
34
+ def welcome_email_method
35
+ %{
36
+ # def welcome_email(user)
37
+ # @user = user
38
+ # @url = "http://example.com/login"
39
+ # mail(:to => user.email, :subject => "Welcome to My Awesome Site")
40
+ # end
41
+ }
42
+ end
43
+
44
+ def welcome_email_html
45
+ %{
46
+ <!DOCTYPE html>
47
+ <html>
48
+ <head>
49
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
50
+ </head>
51
+ <body>
52
+ <h1>Welcome to example.com, <%= @user.name %></h1>
53
+ <p>
54
+ You have successfully signed up to example.com,
55
+ your username is: <%= @user.login %>.<br/>
56
+ </p>
57
+ <p>
58
+ To login to the site, just follow this link: <%= @url %>.
59
+ </p>
60
+ <p>Thanks for joining and have a great day!</p>
61
+ </body>
62
+ </html>
63
+ }
64
+ end
65
+
66
+ def welcome_email_text
67
+ %{
68
+ Welcome to example.com, <%= @user.name %>
69
+ ===============================================
70
+
71
+ You have successfully signed up to example.com,
72
+ your username is: <%= @user.login %>.
73
+
74
+ To login to the site, just follow this link: <%= @url %>.
75
+
76
+ Thanks for joining and have a great day!
77
+ }
78
+ end
79
+
80
+ end
81
+
82
+ end
@@ -1,18 +1,20 @@
1
1
  module Bently
2
2
 
3
- class Devise < Recipe
4
- GEMFILE_DEF = "gem 'devise'"
5
- RAILS_GENERATOR = "rails g devise:install"
6
- MODEL_GENERATOR = "rails g devise"
7
- ASK_MODEL_GENERATOR = "Model name:"
3
+ class Devise < RailsRecipe
4
+
5
+ step :add_gem, "gem 'devise'"
6
+ step :shell, 'bundle install'
7
+ step :shell, 'rails g devise:install'
8
+ step :generate_model
8
9
 
9
- def bake
10
- add_gem(GEMFILE_DEF) || return
11
- bundle_install
12
- command RAILS_GENERATOR
13
- ask_command("#{MODEL_GENERATOR} MODEL", ASK_MODEL_GENERATOR){|a| "#{MODEL_GENERATOR} #{a}" }
14
- super
10
+ def generate_model
11
+ shell(
12
+ lambda{|model| "rails g devise #{model}" },
13
+ :ask => "Enter a model name (ex. user):",
14
+ :description => "Execute:\nrails g devise MODEL"
15
+ )
15
16
  end
17
+
16
18
  end
17
19
 
18
20
  end
@@ -0,0 +1,35 @@
1
+ module Bently
2
+
3
+ class FactoryGirlRails < RailsRecipe
4
+
5
+ step :add_gem, 'gem "factory_girl_rails", "~> 4.0", :group => :test'
6
+ step :shell, 'bundle install'
7
+ step :sample_factory_file
8
+
9
+ protected
10
+
11
+ def sample_factory_file
12
+ touch :file => './spec/factories.rb', :with => factory_file
13
+ end
14
+
15
+ def factory_file
16
+ %{# # This will guess the User class
17
+ # FactoryGirl.define do
18
+ # factory :user do
19
+ # first_name "John"
20
+ # last_name "Doe"
21
+ # admin false
22
+ # end
23
+ #
24
+ # # This will use the User class (Admin would have been guessed)
25
+ # factory :admin, class: User do
26
+ # first_name "Admin"
27
+ # last_name "User"
28
+ # admin true
29
+ # end
30
+ # end}
31
+ end
32
+
33
+ end
34
+
35
+ end
@@ -0,0 +1,52 @@
1
+ module Bently
2
+
3
+ class GitignoreRails < Recipe
4
+
5
+ step :touch_gitignore
6
+
7
+ protected
8
+
9
+ def touch_gitignore
10
+ touch :file => '.gitignore', :with => gitignore
11
+ end
12
+
13
+ def gitignore
14
+ %{
15
+ # Configuration files
16
+ config/initializers/secret_token.rb
17
+ config/database.yml
18
+
19
+ # Generated files
20
+ log/*
21
+ coverage/*
22
+
23
+ #Documentation
24
+ .yardoc/
25
+ doc/
26
+
27
+ # Uploaded files and local files
28
+ public/uploads/*
29
+ public/assets/*
30
+ tmp/**/*
31
+ tmp/*
32
+ *.sqlite3
33
+ .env
34
+
35
+ # Temporary files of every sort
36
+ .sass-cache/*
37
+ .DS_Store
38
+ .idea
39
+ .rvmrc
40
+ *.swap
41
+ *.swo
42
+ *.swp
43
+ *~
44
+ *#
45
+ nbproject
46
+ dump.rdb
47
+ }
48
+ end
49
+
50
+ end
51
+
52
+ end
@@ -2,17 +2,22 @@ module Bently
2
2
 
3
3
  class Gitignore < Recipe
4
4
 
5
- GITIGNORE =
5
+ step :touch_gitignore
6
+
7
+ protected
8
+
9
+ def touch_gitignore
10
+ touch :file => '.gitignore', :with => gitignore
11
+ end
12
+
13
+ def gitignore
6
14
  %{.DS_Store
7
15
  .rvmrc
8
16
  *.swap
9
17
  *.swo
10
- *.swp
11
- }
12
-
13
- def bake
14
- create_file ".gitignore", GITIGNORE
15
- super
18
+ *.swp}
16
19
  end
20
+
17
21
  end
22
+
18
23
  end
@@ -0,0 +1,11 @@
1
+ module Bently
2
+
3
+ class GuardLivereload < RailsRecipe
4
+
5
+ step :add_gem, "gem 'guard-livereload', :group => :development"
6
+ step :shell, 'bundle install'
7
+ step :shell, 'guard init livereload'
8
+
9
+ end
10
+
11
+ end
@@ -0,0 +1,11 @@
1
+ module Bently
2
+
3
+ class Guard < RailsRecipe
4
+
5
+ step :add_gem, "gem 'guard', :group => :development"
6
+ step :shell, 'bundle install'
7
+ step :shell, 'guard init'
8
+
9
+ end
10
+
11
+ end
@@ -1,16 +1,11 @@
1
1
  module Bently
2
2
 
3
- class HamlRails < Recipe
3
+ class HamlRails < RailsRecipe
4
4
 
5
- GEM_DEF =
6
- %{gem 'haml'
7
- gem 'haml-rails'}
5
+ step :add_gem, "gem 'haml'"
6
+ step :add_gem, "gem 'haml-rails'"
7
+ step :shell, 'bundle install'
8
8
 
9
- def bake
10
- add_gem GEM_DEF
11
- bundle_install
12
- super
13
- end
14
9
  end
15
10
 
16
11
  end
@@ -0,0 +1,27 @@
1
+ module Bently
2
+
3
+ class HerokuCreate < Recipe
4
+
5
+ step :add_pg_gem
6
+ step :shell, 'bundle install'
7
+ step :shell, 'git add Gemfile Gemfile.lock'
8
+ step :shell, 'git commit -m "use pg instead of sqlite3"'
9
+ step :shell, 'heroku create'
10
+ step :shell, 'git push heroku master'
11
+ step :shell, 'heroku ps'
12
+ step :shell, 'heroku open'
13
+ step :shell, 'heroku run rake db:migrate'
14
+
15
+ protected
16
+
17
+ def add_pg_gem
18
+ modify(
19
+ :file => 'Gemfile',
20
+ :from => /gem 'sqlite3'/,
21
+ :to => "gem 'pg'"
22
+ )
23
+ end
24
+
25
+ end
26
+
27
+ end
@@ -0,0 +1,14 @@
1
+ module Bently
2
+
3
+ class HerokuProcfile < RailsRecipe
4
+
5
+ step :add_gem, "gem 'thin'"
6
+ step :shell, 'bundle install'
7
+ step :append, :file => 'Procfile', :with => 'web: bundle exec thin start -p $PORT -e $RACK_ENV'
8
+ step :shell, 'gem install foreman'
9
+ step :shell, 'echo "RACK_ENV=development" >>.env'
10
+ step :shell, 'foreman start'
11
+
12
+ end
13
+
14
+ end