relevance_rails 0.0.3 → 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.
Files changed (37) hide show
  1. data/.gitignore +2 -0
  2. data/.rvmrc +1 -0
  3. data/.travis.yml +7 -0
  4. data/CHANGELOG.md +24 -0
  5. data/README.md +101 -4
  6. data/Rakefile +10 -0
  7. data/aws_config.example.yml +15 -0
  8. data/bin/relevance_rails +2 -19
  9. data/lib/generators/deployment/deployment_generator.rb +31 -0
  10. data/lib/generators/fixtures/fixtures_generator.rb +44 -0
  11. data/lib/generators/provision_config/provision_config_generator.rb +56 -0
  12. data/lib/generators/provision_config/templates/authorized_keys.json.erb +6 -0
  13. data/lib/generators/relevance_file/relevance_file_generator.rb +14 -76
  14. data/lib/generators/relevance_file/templates/{Gemfile → Gemfile.erb} +11 -5
  15. data/lib/generators/relevance_file/templates/README.markdown.erb +36 -0
  16. data/lib/generators/relevance_file/templates/application.html.haml.erb +9 -0
  17. data/lib/generators/relevance_file/templates/database.example.yml.mysql.erb +17 -0
  18. data/lib/generators/relevance_file/templates/database.example.yml.postgresql.erb +15 -0
  19. data/lib/generators/relevance_file/templates/deploy.rb.erb +22 -0
  20. data/lib/relevance_rails.rb +26 -1
  21. data/lib/relevance_rails/chef_dna.rb +32 -0
  22. data/lib/relevance_rails/provision.rb +69 -0
  23. data/lib/relevance_rails/railtie.rb +9 -0
  24. data/lib/relevance_rails/relevance_rails_template.rb +18 -26
  25. data/lib/relevance_rails/runner.rb +24 -0
  26. data/lib/relevance_rails/version.rb +1 -1
  27. data/lib/tasks/provision.rake +8 -0
  28. data/relevance_rails.gemspec +7 -2
  29. data/script/ci +57 -0
  30. data/spec/acceptance_spec.rb +25 -0
  31. data/spec/lib/provision_config_generator_spec.rb +27 -0
  32. data/spec/lib/relevance_rails_spec.rb +15 -0
  33. data/spec/lib/runner_spec.rb +22 -0
  34. data/spec/spec_helper.rb +59 -0
  35. data/techdebt.md +15 -0
  36. metadata +115 -12
  37. data/lib/relevance_rails/template_injector.rb +0 -5
data/.gitignore CHANGED
@@ -2,3 +2,5 @@
2
2
  .bundle
3
3
  Gemfile.lock
4
4
  pkg/*
5
+ app_for_ci
6
+ *.swp
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm gemset use relevance_rails
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ script: rake spec
2
+ rvm:
3
+ - 1.8.7
4
+ - 1.9.3
5
+ branches:
6
+ only:
7
+ - master
data/CHANGELOG.md ADDED
@@ -0,0 +1,24 @@
1
+ *v0.1.0*
2
+
3
+ * Provisioning can be done on existing apps
4
+ * Support multiple rubies - 1.9 and ree
5
+ * Add unit tests
6
+ * Can run acceptance tests on generated apps - rails g fixtures
7
+ * From provision to deploy is a 2 step process - rake provision:ec2 and rails g deployment
8
+ * Add more error handling
9
+ * Tentative support for multiple databases - postgresql and mysql
10
+
11
+ *v0.0.4*
12
+
13
+ * Add support for generating EC2 deployment environments
14
+ * 'rails g deployment <environment>' to generate a new environment
15
+ * REQUIRES the presence of ~/.relevance_rails/aws_config.yml
16
+ * Template aws_config.yml included with this gem.
17
+ * Newly generates EC2 deployment environments will be wired up as new cap stages.
18
+
19
+ *v0.0.3*
20
+
21
+ * Add support for multiple public keys pushed to converged hosts.
22
+ * Public keys are fetched from a git repo.
23
+ * Git repo url is stored in ~/.relevance_rails/keys_git_url
24
+ * Only the top level keys from the repo will be pushed to new hosts.
data/README.md CHANGED
@@ -3,7 +3,7 @@ Relevance Rails
3
3
 
4
4
  Yo dawg, I heard you like automation, so I automated your automation so you can autopilot while you autopilot!
5
5
 
6
- Rails 3 projects with every fiddly bit convened rather than configured. Includes
6
+ Rails 3 projects with every fiddly bit convened rather than configured. Includes:
7
7
 
8
8
  * HAML and SCSS
9
9
  * RSpec 2 with Relevance config niceties
@@ -12,18 +12,115 @@ Rails 3 projects with every fiddly bit convened rather than configured. Includes
12
12
  * Capistrano deploy recipes
13
13
  * A VM deployment target under provision
14
14
 
15
+ [![Build Status](https://secure.travis-ci.org/relevance/relevance_rails.png?branch=master)](http://travis-ci.org/relevance/relevance_rails)
16
+
15
17
  Getting Started
16
18
  ---------------
17
19
 
20
+ For new projects:
21
+
18
22
  ````sh
19
- gem install relevance_rails
20
- relevance_rails new <your new project>
23
+ $ gem install relevance_rails
24
+ $ relevance_rails new <your new project>
21
25
  ````
22
26
 
27
+ For existing projects, first add to your Gemfile:
28
+
29
+ group :development, :test do
30
+ gem 'relevance_rails'
31
+ end
32
+
33
+ After a `bundle install`, pull in our chef recipes into provision/:
34
+
35
+ ```sh
36
+ # defaults to mysql
37
+ $ rails g provision_config app_name
38
+ # if using postgresql
39
+ $ rails g provision_config app_name postgresql
40
+ ```
41
+
42
+ Provisioning on EC2
43
+ -------------------
44
+
45
+ First create an aws config in ~/.relevance\_rails/aws\_config.yml.
46
+ An example config looks like this:
47
+
48
+ ```yaml
49
+ aws_credentials:
50
+ :aws_access_key_id: <your aws access key id>
51
+ :aws_secret_access_key: <your aws secret access key>
52
+
53
+ server:
54
+ creation_config:
55
+ :flavor_id: <instance type, e.g. 'm1.large'>
56
+ :image_id: <ami to bootstrap with. Must be some UBUNTU image. e.g. "ami-fd589594">
57
+ :groups: <security group to place the new deployment in, e.g. "default">
58
+ :key_name: <name of the public/private keypair to start instance with>
59
+ private_key: |
60
+ -----BEGIN RSA PRIVATE KEY-----
61
+ Include the RSA private key here. This should correspond to the keypair indicated
62
+ by :key_name above.
63
+ -----END RSA PRIVATE KEY-----
64
+ ```
65
+
66
+ Now just provision your instance:
67
+
68
+ ```sh
69
+ $ rake provision:ec2 NAME=qa
70
+ ...
71
+ Server IP: 1.1.1.1
72
+ # Pass IP from previous command as second argument
73
+ $ rails g deployment qa 1.1.1.1
74
+ $ cap qa deploy:setup deploy
75
+ ```
76
+
77
+ Provisioning with Vagrant
78
+ -------------------------
79
+
80
+ From your app's root directory:
81
+
82
+ ```sh
83
+ $ cd provision
84
+ # pull in vagrant and chef
85
+ $ bundle install
86
+ $ vagrant up
87
+ ```
88
+
89
+ Vagrant instance should be up at 172.25.5.5.
90
+
91
+ Supported Ruby Versions
92
+ -----------------------
93
+
94
+ Currently both Ruby 1.9.x and REE 1.8.7 are supported via RVM. relevance_rails
95
+ configures your Rails app (and Chef provisioning scripts) to require the version
96
+ of Ruby you used to invoke the relevance_rails executable.
97
+
98
+ Supported Databases
99
+ -------------------
100
+
101
+ Currently both MySQL and PostgreSQL are supported. By default relevance_rails configures
102
+ your Rails app (and Chef provisioning scripts) to use MySQL. However, if you use the
103
+ standard `--database=postgresql` Rails option, relevance_rails will use PostgreSQL.
104
+
105
+ Maintainer Notes
106
+ ----------------
107
+
108
+ When QAing or doing local development of this gem, the gem must be built and installed locally.
109
+
110
+ In order to test deployment, use the example below to package the relevance_rails gem:
111
+
112
+ # Given a relevance_rails app "app" lives in "~/src/app"
113
+ # And the relevance_rails source lives in "~/src/relevance_rails"
114
+ ~/src/relevance_rails $ gem build relevance_rails.gemspec
115
+ ~/src/relevance_rails $ cd ~/src/app
116
+ ~/src/app $ gem install ../relevance_rails/relevance_rails-0.0.7.gem
117
+ ~/src/app $ bundle package
118
+ ~/src/app $ git commit -m "Package gems" vendor/cache
119
+
23
120
  Caveats
24
121
  -------
25
122
 
26
- Only supports REE 1.8.7, Rails 3.1 and MySQL right now.
123
+ Currently we only support Ruby 1.9.x, REE 1.8.7, Rails 3.2, MySQL, and PostgreSQL installed on Ubuntu.
27
124
 
28
125
  Improvements
29
126
  ------------
data/Rakefile CHANGED
@@ -1 +1,11 @@
1
1
  require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new
5
+ task :default => :spec
6
+
7
+ desc 'Run the acceptance specs'
8
+ task :acceptance do
9
+ ENV["ACCEPTANCE"] = "true"
10
+ Rake::Task[:spec].invoke
11
+ end
@@ -0,0 +1,15 @@
1
+ aws_credentials:
2
+ :aws_access_key_id: <your aws access key id>
3
+ :aws_secret_access_key: <your aws secret access key>
4
+
5
+ server:
6
+ creation_config:
7
+ :flavor_id: <instance type, e.g. 'm1.large'>
8
+ :image_id: <ami to bootstrap with. Must be some UBUNTU image. e.g. "ami-fd589594">
9
+ :groups: <security group to place the new deployment in, e.g. "default">
10
+ :key_name: <name of the public/private keypair to start instance with>
11
+ private_key: |
12
+ -----BEGIN RSA PRIVATE KEY-----
13
+ Include the RSA private key here. This should correspond to the keypair indicated
14
+ by :key_name above.
15
+ -----END RSA PRIVATE KEY-----
data/bin/relevance_rails CHANGED
@@ -1,21 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
- #
3
- # This file was generated by RubyGems.
4
- #
5
- # The application 'railties' is installed as part of a gem, and
6
- # this file is here to facilitate running it.
7
- #
8
2
 
9
- require 'rubygems'
10
-
11
- version = ">= 0"
12
-
13
- if ARGV.first =~ /^_(.*)_$/ and Gem::Version.correct? $1 then
14
- version = $1
15
- ARGV.shift
16
- end
17
-
18
- require 'relevance_rails/template_injector'
19
-
20
- gem 'railties', version
21
- load Gem.bin_path('railties', 'rails', version)
3
+ require 'relevance_rails/runner'
4
+ RelevanceRails::Runner.start
@@ -0,0 +1,31 @@
1
+ class DeploymentGenerator < Rails::Generators::NamedBase
2
+ desc "Generates and updates capistrano config for a new deployment target"
3
+ argument :hostname, :type => :string
4
+
5
+ def write_stage_file
6
+ create_file "config/deploy/#{name}.rb", <<-DEPLOY_STAGE
7
+ set :user, 'deploy'
8
+
9
+ role :web, "#{hostname}"
10
+ role :app, "#{hostname}"
11
+ role :db, "#{hostname}", :primary => true
12
+ DEPLOY_STAGE
13
+ end
14
+
15
+ def inject_new_deployment_to_stages
16
+ new_contents = ""
17
+ File.new(Rails.root.join('config','deploy.rb')).readlines.each do |line|
18
+ unless line =~ /^set :stages, (.*)$/
19
+ new_contents << line
20
+ else
21
+ stages = eval($1)
22
+ stages << name
23
+ stage_array_contents = stages.map{|stage| "\"#{stage}\""}.join(', ')
24
+ new_contents << "set :stages, [#{stage_array_contents}]\n"
25
+ end
26
+ end
27
+ File.open(Rails.root.join('config','deploy.rb'),'w') do |file|
28
+ file.write new_contents
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,44 @@
1
+ class FixturesGenerator < Rails::Generators::Base
2
+ def create_controller
3
+ create_file "app/controllers/relevance_rails_controller.rb", <<-STR
4
+ class RelevanceRailsController < ApplicationController
5
+ end
6
+ STR
7
+ end
8
+
9
+ def create_views
10
+ create_file "app/views/relevance_rails/index.html.haml", <<-STR
11
+ %h1 WELCOME HOME
12
+ STR
13
+ create_file "app/views/relevance_rails/db.html.haml", <<-STR
14
+ %h1.database= ActiveRecord::Base.connection.current_database
15
+ STR
16
+ end
17
+
18
+ def create_coffee
19
+ create_file "app/assets/javascripts/relevance_rails.js.coffee", <<-STR
20
+ console.log 'Hello from Relevance, Inc!'
21
+ STR
22
+ end
23
+
24
+ def create_sass
25
+ create_file "app/assets/stylesheets/relevance_rails.css.scss", <<-STR
26
+ $background: blue;
27
+
28
+ h1.relevance {
29
+ background-color: $background;
30
+ }
31
+ STR
32
+ end
33
+
34
+ def modify_routes
35
+ insert_into_file "config/routes.rb", :after => "::Application.routes.draw do" do
36
+ <<-STR
37
+
38
+ # Required to test relevance_rails gem.
39
+ match '/relevance_rails' => 'relevance_rails#index'
40
+ match '/relevance_rails/db' => 'relevance_rails#db'
41
+ STR
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,56 @@
1
+ require 'relevance_rails'
2
+ require 'rails/generators'
3
+
4
+ class ProvisionConfigGenerator < Rails::Generators::NamedBase
5
+
6
+ desc "This generator configures the provision sub-directory with appropriate files."
7
+
8
+ source_root File.expand_path("../templates", __FILE__)
9
+
10
+ argument :database, :type => :string, :default => 'mysql'
11
+
12
+ attr_reader :authorized_keys
13
+
14
+ def fetch_elzar
15
+ git :remote => 'add -f elzar git://github.com/relevance/elzar.git'
16
+ git :merge => '-s ours --no-commit elzar/master'
17
+ git :"read-tree" => '--prefix=provision/ -u elzar/master'
18
+ gsub_file 'provision/Vagrantfile', /config\.vm\.host_name(\s+)= .*$/,
19
+ "config.vm.host_name\\1= '#{name.gsub('_','-')}.local'"
20
+ end
21
+
22
+ def create_authorized_key_data_bag
23
+ if (@authorized_keys = fetch_keys).empty?
24
+ abort "No ssh keys were found! Check ssh-add -L and your keys_git_url config."
25
+ end
26
+ @authorized_keys.map! {|key| "\"#{key}\""}
27
+ template('authorized_keys.json.erb', 'provision/data_bags/deploy/authorized_keys.json', {:force => true})
28
+ end
29
+
30
+ def create_dna_json
31
+ path = File.expand_path('provision/dna.json', destination_root)
32
+ json = JSON.parse File.binread(path)
33
+ json['rails_app']['name'] = name
34
+ # This generator may not receive a working directory;
35
+ # and we pull data by shelling out to RVM about the ruby
36
+ # version. This sets the directory explicitly beforehand.
37
+ Dir.chdir(destination_root)
38
+ RelevanceRails::ChefDNA.gene_splice(json,database)
39
+ create_file('provision/dna.json', JSON.generate(json), {:force => true})
40
+ end
41
+
42
+ def commit_changes
43
+ git :add => 'provision/data_bags/deploy/authorized_keys.json'
44
+ git :add => 'provision/Vagrantfile'
45
+ git :add => 'provision/dna.json'
46
+ git :commit => '-m "Merge Elzar as our provision subdirectory"'
47
+ end
48
+
49
+ private
50
+
51
+ def fetch_keys
52
+ local_keys = `ssh-add -L`.split("\n")
53
+ local_keys = [] unless $?.success?
54
+ (local_keys + RelevanceRails::PublicKeyFetcher.public_keys).uniq
55
+ end
56
+ end
@@ -0,0 +1,6 @@
1
+ {
2
+ "id":"authorized_keys",
3
+ "keys": [
4
+ <%= authorized_keys.join(",\n") %>
5
+ ]
6
+ }
@@ -6,37 +6,22 @@ class RelevanceFileGenerator < Rails::Generators::NamedBase
6
6
 
7
7
  source_root File.expand_path("../templates", __FILE__)
8
8
 
9
+ argument :database, :type => :string, :default => 'mysql'
10
+
9
11
  def copy_gemfile
10
- copy_file "Gemfile", "Gemfile"
12
+ template "Gemfile.erb", "Gemfile"
11
13
  end
12
14
 
13
15
  def create_readme_markdown
14
- create_file "README.markdown", <<-README
15
- # #{name}
16
-
17
- ## Getting Started
18
-
19
- gem install bundler
20
- # TODO other setup commands here
21
- README
16
+ template "README.markdown.erb", "README.markdown"
22
17
  end
23
18
 
24
19
  def create_application_layout
25
- create_file 'app/views/layouts/application.html.haml', <<-LAYOUT
26
- !!!
27
- %html
28
- %head
29
- %title #{name}
30
- = stylesheet_link_tag :application
31
- = javascript_include_tag :application
32
- = csrf_meta_tag
33
- %body
34
- = yield
35
- LAYOUT
20
+ template 'application.html.haml.erb', 'app/views/layouts/application.html.haml'
36
21
  end
37
22
 
38
23
  def create_rvmrc
39
- create_file ".rvmrc", "rvm use ree-1.8.7-2012.02@#{name}"
24
+ create_file ".rvmrc", "rvm use #{RelevanceRails.rvm_version}@#{name}"
40
25
  end
41
26
 
42
27
  def create_rspec
@@ -52,64 +37,17 @@ gem install bundler
52
37
  end
53
38
 
54
39
  def create_deploy
55
- create_file 'config/deploy.rb', <<-CAP_CONFIG
56
- require 'bundler/capistrano'
57
-
58
- set :application, "#{name}"
59
- set :repository, "."
60
- set :deploy_via, :copy
61
-
62
- set :scm, :git
63
-
64
- set :deploy_to, "/var/www/apps/\#{application}"
65
- default_run_options[:pty] = true
66
- set :ssh_options, { :paranoid => false, :forward_agent => true }
67
-
68
- set :copy_exclude, '.git/*'
69
-
70
- set :stages, %w(vagrant)
71
- set :default_stage, 'vagrant'
72
-
73
- after "deploy:setup", "deploy:copy_shared_db_config"
74
- after "deploy:create_symlink", "deploy:symlink_shared_db_config"
75
-
76
- Dir['config/deploy/recipes/*.rb'].sort.each { |f| eval(File.read(f)) }
77
- CAP_CONFIG
40
+ template 'deploy.rb.erb', 'config/deploy.rb'
78
41
  end
79
42
 
80
43
  def create_database_example_yml
81
- create_file 'config/database.example.yml', <<-DATABASE_CONFIG
82
- development:
83
- adapter: mysql2
84
- encoding: utf8
85
- database: #{name}_development
86
-
87
- # Warning: The database defined as "test" will be erased and
88
- # re-generated from your development database when you run "rake".
89
- # Do not set this db to the same as development or production.
90
- test:
91
- adapter: mysql2
92
- encoding: utf8
93
- database: #{name}_test
94
-
95
- production:
96
- adapter: mysql2
97
- encoding: utf8
98
- database: #{name}_production
99
- DATABASE_CONFIG
100
- end
101
-
102
- def create_authorized_key_data_bag
103
- authorized_keys = (`ssh-add -L`.split("\n") + RelevanceRails::PublicKeyFetcher.public_keys).uniq
104
- authorized_keys.map! {|key| "\"#{key}\""}
105
- create_file 'authorized_keys.json', <<-AUTHORIZED_KEYS
106
- {
107
- "id":"authorized_keys",
108
- "keys": [
109
- #{authorized_keys.join(",\n")}
110
- ]
111
- }
112
- AUTHORIZED_KEYS
44
+ if database == 'mysql'
45
+ template 'database.example.yml.mysql.erb', 'config/database.example.yml'
46
+ elsif database == 'postgresql'
47
+ template 'database.example.yml.postgresql.erb', 'config/database.example.yml'
48
+ else
49
+ create_file 'database.example.yml', "Don't know how to make a template for database: #{database}"
50
+ end
113
51
  end
114
52
 
115
53
  def copy_deploy_recipes