railblazer 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ *~
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) Stack Builders inc.
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,75 @@
1
+ # Railblazer - spend less time setting up apps locally and on CI servers
2
+
3
+ Railblazer helps you to spend less time setting up Rails apps by providing three scripts:
4
+
5
+ 1. `app_adapter`: given a Gemfile, detects whether the application runs on mysql, mysql2, or postgres
6
+ 2. `build`: build script that can be used by Jenkins
7
+ 3. `db_config`: outputs a database.yml when given an adapter and app name.
8
+
9
+ In other words, Railblazer tries to take the work out of setting up things like builds on CI servers, assuming you're using RVM and bundler in your applications.
10
+
11
+ # Installation
12
+
13
+ You can install railblazer via the gem, but since gems that you install are limited to a particular gemset or Ruby version (assuming you're running rvm), you can just clone this repository. In order to
14
+ run the scripts in this package, just add the `bin` directory in this repository to your path.
15
+
16
+ # app_adapter
17
+
18
+ `app_adapter` detects the database adapter used in a Rails application when given a Gemfile path
19
+ as an argument:
20
+
21
+ ```
22
+ app_adapter ~/Code/project/Gemfile
23
+ ```
24
+
25
+ This will return a string like `mysql2` without a trailing newline (for easier inclusion in other scripts). The program will raise an error if exactly one adapter is not found. It currently only
26
+ works with applications that use the mysql, mysql2, or postgres (pg) adapters.
27
+
28
+ # build
29
+
30
+ `build` is a shell script that can be used by Jenkins. It assumes that for your build you don't want to run migrations, and that instead we should just drop the test db, re-create it, and load the schema.rb file.
31
+
32
+ It also does the following, which we find useful in our CI builds:
33
+
34
+ 1. Load the RVM environment
35
+ 2. Run bundle (excluding the production environment)
36
+ 3. Run the tests with xvfb-run, autodetecting an available buffer (for simultaneous builds that need to open windows, for things like Selenium)
37
+ 4. Auto-generate a database.yml (requires `app_adapter` to be in the `$PATH`)
38
+
39
+ The script uses variables like ${WORKSPACE} and ${JOB_NAME}, which are passed by default to scripts
40
+ invoked from Jenkins.
41
+
42
+ Example usage:
43
+
44
+ ```
45
+ build
46
+ ```
47
+
48
+ # db_config
49
+
50
+ `db_config` automatically generates a database.yml file when given an adapter and application name. This is generated from a template for mysql, mysql2, and postgres included with this gem. If you want, you can also override the default templates by including templates in a directory named `~/.blaze/templates`.
51
+
52
+ Example usage:
53
+
54
+ ```
55
+ db_config mysql2 myapp
56
+ ```
57
+
58
+ # Summary
59
+
60
+ Railblazer helps with configuration of database connections in Rails apps, and provides scripts which can help with configuraiton of Rails apps for CI server builds.
61
+
62
+ Instead of relying on the database.sample.yml files included in many Rails apps, I find that it's often easier to just copy a working database.yml from another project on my computer. These settings reflect things like the correct host and username / password configuration for my local workstation. I think that we can move towards slightly less configuration work for new Rails apps on workstations that are already in use by developers by building up frameworks that:
63
+
64
+ 1. use local templates for database configuration and
65
+ 2. auto-detect the database adapter from the Rails application configuration.
66
+
67
+ Railblazer provides a first pass at automating this type of configuration, and provides a script showing how this is useful in the context of auto-configuring apps for Jenkins CI server.
68
+
69
+ # Author
70
+
71
+ Justin Leitgeb <justin@stackbuilders.com>
72
+
73
+ # License
74
+
75
+ See the LICENSE file included with the program.
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+
4
+ require 'rake/testtask'
5
+
6
+ Rake::TestTask.new do |t|
7
+ t.libs << "spec"
8
+ t.test_files = FileList['spec/**/*_spec.rb']
9
+ end
10
+
11
+ task :default => :test
data/bin/app_adapter ADDED
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Detects the database adapter used in a Rails application from a Gemfile.
4
+ # If more than one adapter is found, an exception will be raised, since the
5
+ # ultimate purpose of this script is to help generate a database.yml. Our
6
+ # assumption is that something weird is going on if there is more than one
7
+ # adapter gem listed in the Gemfile, so we throw up our hands.
8
+
9
+ # *Note that this evaluates the Gemfile as a ruby script, so it's possible
10
+ # for someone to do something nasty in this file*
11
+
12
+ require "#{File.dirname(__FILE__)}/../lib/railblazer"
13
+
14
+ if ARGV.empty?
15
+ puts "Usage is app_adapter GEMFILE_PATH"
16
+ exit 1
17
+ end
18
+
19
+ gemfile = Railblazer::MinimalGemfile.new(File.new(ARGV[0]))
20
+ print Railblazer::AdapterDetection.new(gemfile).run
data/bin/build ADDED
@@ -0,0 +1,16 @@
1
+ #!/bin/bash
2
+
3
+ # A script for running a build for CI using RVM.
4
+
5
+ PATH=$PATH:$HOME/.rvm/bin:/usr/bin:`dirname $0`
6
+
7
+ [[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm"
8
+
9
+ export RAILS_ENV=test
10
+
11
+ db_config `app_adapter ${WORKSPACE}/Gemfile` ${JOB_NAME} > ${WORKSPACE}/config/database.yml && \
12
+ cd ${WORKSPACE} && \
13
+ bundle --without production && \
14
+ bundle exec rake db:drop db:create db:schema:load && \
15
+ xvfb-run -a rspec spec
16
+
data/bin/db_config ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Generates a database.yml from a template. Templates in
4
+ # ~/.blaze/templates override those in the application.
5
+ # Templates are included for mysql, mysql2, and pg.
6
+
7
+ require "#{File.dirname(__FILE__)}/../lib/railblazer"
8
+
9
+ if ARGV.empty?
10
+ puts "Usage is db_config db_adapter app_name"
11
+ exit 1
12
+ end
13
+
14
+ raise ArgumentError, "App name must be specified as second parameter" if ARGV[1].nil?
15
+
16
+ puts Railblazer::ConfigGenerator.new(ARGV[0], ARGV[1])
17
+
@@ -0,0 +1,30 @@
1
+ module Railblazer
2
+ class AdapterDetection
3
+ ADAPTERS = {
4
+ 'mysql' => 'mysql',
5
+ 'mysql2' => 'mysql2',
6
+ 'pg' => 'postgresql'
7
+ }.freeze
8
+
9
+ attr_reader :gems
10
+
11
+ def initialize minimal_gemfile
12
+ @gems = minimal_gemfile.gems
13
+ end
14
+
15
+ def run
16
+ ADAPTERS[adapter_gem]
17
+ end
18
+
19
+ private
20
+
21
+ def adapter_gem
22
+ adapter_gems = gems & ADAPTERS.keys.to_set
23
+
24
+ raise "More than one adapter gem found in Gemfile! #{gems.to_a.join(', ')}" if adapter_gems.count > 1
25
+ raise "Unable to detect any database adapters in database.yml" if adapter_gems.empty?
26
+
27
+ adapter_gems.first
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,32 @@
1
+ require 'erb'
2
+ require 'etc'
3
+
4
+ module Railblazer
5
+ class ConfigGenerator
6
+
7
+ HOME_TEMPLATE_PATH = "#{Etc.getpwuid.dir}/.blaze/templates"
8
+
9
+ attr_reader :db_adapter, :app_name
10
+ def initialize db_adapter, app_name
11
+ @db_adapter = db_adapter
12
+ @app_name = app_name
13
+ end
14
+
15
+ def to_s
16
+ ERB.new(template).result(binding)
17
+ end
18
+
19
+ private
20
+ def template
21
+ selected_template = File.join(template_path, "#{db_adapter}.yml.erb")
22
+ raise "Template file not found for #{db_adapter}" unless File.exist?(selected_template)
23
+ template = File.read(selected_template)
24
+ end
25
+
26
+ def template_path
27
+ File.directory?(HOME_TEMPLATE_PATH) ?
28
+ HOME_TEMPLATE_PATH :
29
+ File.join(File.dirname(__FILE__), '../../templates')
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,22 @@
1
+ require 'set'
2
+
3
+ module Railblazer
4
+ class MinimalGemfile
5
+ attr_reader :gems
6
+
7
+ def initialize gemfile
8
+ @gems = Set.new
9
+ instance_eval gemfile.read
10
+ end
11
+
12
+ def gem name, *args
13
+ @gems << name
14
+ end
15
+
16
+ def group *args, &block
17
+ yield
18
+ end
19
+
20
+ def method_missing name, *args ; end
21
+ end
22
+ end
@@ -0,0 +1,3 @@
1
+ module Railblazer
2
+ VERSION = "0.0.1"
3
+ end
data/lib/railblazer.rb ADDED
@@ -0,0 +1,5 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__)))
2
+
3
+ require 'railblazer/adapter_detection'
4
+ require 'railblazer/minimal_gemfile'
5
+ require 'railblazer/config_generator'
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/railblazer/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Justin S. Leitgeb"]
6
+ gem.email = ["justin@stackbuilders.com"]
7
+ gem.summary = %q{Tools to automate builds for Stack Builders CI server}
8
+ gem.description = <<-EOS
9
+ Contains tools to automate the build for the Stack Builders CI server.
10
+ Includes
11
+ EOS
12
+
13
+ gem.homepage = "http://github.com/stackbuilders"
14
+
15
+ gem.files = `git ls-files`.split($\)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.name = "railblazer"
19
+ gem.require_paths = ["lib"]
20
+ gem.version = Railblazer::VERSION
21
+ end
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+ describe Railblazer::AdapterDetection do
4
+ describe "#detect" do
5
+ FauxGemfile = Struct.new(:gems)
6
+
7
+ it "should detect mysql" do
8
+ gemfile = FauxGemfile.new(%w[mysql othergem].to_set)
9
+ Railblazer::AdapterDetection.new(gemfile).run.must_equal 'mysql'
10
+ end
11
+
12
+ it "should detect postgres" do
13
+ gemfile = FauxGemfile.new(%w[othergem pg].to_set)
14
+ Railblazer::AdapterDetection.new(gemfile).run.must_equal 'postgresql'
15
+ end
16
+
17
+ it "should raise an exception when more than one db gem is detected" do
18
+ gemfile = FauxGemfile.new(%w[mysql2 pg].to_set)
19
+
20
+ assert_raises RuntimeError do
21
+ Railblazer::AdapterDetection.new(gemfile).run
22
+ end
23
+ end
24
+
25
+ it "should raise an exception when there was no db gem detected" do
26
+ gemfile = FauxGemfile.new(%w[thor rails].to_set)
27
+
28
+ assert_raises RuntimeError do
29
+ Railblazer::AdapterDetection.new(gemfile).run
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ describe Railblazer::ConfigGenerator do
4
+ describe "#to_s" do
5
+ it "should generate a valid configuration for mysql2" do
6
+ desired = <<EOS
7
+ test:
8
+ adapter: mysql2
9
+ database: fooapp_test
10
+ username: root
11
+ host: 127.0.0.1
12
+ EOS
13
+ Railblazer::ConfigGenerator.new('mysql2', 'fooapp').to_s.must_equal desired
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+ require 'set'
3
+ require 'stringio'
4
+
5
+ describe Railblazer::MinimalGemfile do
6
+ describe "#gems" do
7
+ it "should read a flat list of gems" do
8
+ mysql_gemfile = <<-EOF
9
+ gem 'mysql'
10
+ gem 'othergem'
11
+ EOF
12
+
13
+ Railblazer::MinimalGemfile.new(StringIO.new(mysql_gemfile)).gems.must_equal %w[mysql othergem].to_set
14
+ end
15
+
16
+ it "should detect gems inside of group blocks" do
17
+ mysql_gemfile = <<-EOF
18
+ gem 'mysql'
19
+ group 'development' do
20
+ gem 'othergem'
21
+ end
22
+ EOF
23
+
24
+ Railblazer::MinimalGemfile.new(StringIO.new(mysql_gemfile)).gems.must_equal %w[mysql othergem].to_set
25
+ end
26
+
27
+ it "should ignore other methods in the Gemfile" do
28
+ mysql_gemfile = <<-EOF
29
+ gem 'mysql'
30
+ funky_method
31
+
32
+ group 'development' do
33
+ gem 'othergem'
34
+ end
35
+ EOF
36
+
37
+ Railblazer::MinimalGemfile.new(StringIO.new(mysql_gemfile)).gems.must_equal %w[mysql othergem].to_set
38
+ end
39
+ end
40
+ end
41
+
@@ -0,0 +1,2 @@
1
+ require 'minitest/autorun'
2
+ require "#{File.dirname(__FILE__)}/../lib/railblazer"
@@ -0,0 +1,5 @@
1
+ test:
2
+ adapter: mysql
3
+ database: <%= app_name %>_test
4
+ username: root
5
+ host: 127.0.0.1
@@ -0,0 +1,5 @@
1
+ test:
2
+ adapter: mysql2
3
+ database: <%= app_name %>_test
4
+ username: root
5
+ host: 127.0.0.1
@@ -0,0 +1,4 @@
1
+ test:
2
+ adapter: postgresql
3
+ min_messages: WARNING
4
+ database: <%= app_name %>_test
metadata ADDED
@@ -0,0 +1,73 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: railblazer
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Justin S. Leitgeb
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-04-08 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: ! " Contains tools to automate the build for the Stack Builders CI
15
+ server.\n Includes\n"
16
+ email:
17
+ - justin@stackbuilders.com
18
+ executables:
19
+ - app_adapter
20
+ - build
21
+ - db_config
22
+ extensions: []
23
+ extra_rdoc_files: []
24
+ files:
25
+ - .gitignore
26
+ - LICENSE
27
+ - README.md
28
+ - Rakefile
29
+ - bin/app_adapter
30
+ - bin/build
31
+ - bin/db_config
32
+ - lib/railblazer.rb
33
+ - lib/railblazer/adapter_detection.rb
34
+ - lib/railblazer/config_generator.rb
35
+ - lib/railblazer/minimal_gemfile.rb
36
+ - lib/railblazer/version.rb
37
+ - railblazer.gemspec
38
+ - spec/railblazer/adapter_spec.rb
39
+ - spec/railblazer/config_generator_spec.rb
40
+ - spec/railblazer/minimal_gemfile_spec.rb
41
+ - spec/spec_helper.rb
42
+ - templates/mysql.yml.erb
43
+ - templates/mysql2.yml.erb
44
+ - templates/postgresql.yml.erb
45
+ homepage: http://github.com/stackbuilders
46
+ licenses: []
47
+ post_install_message:
48
+ rdoc_options: []
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ! '>='
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ! '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ requirements: []
64
+ rubyforge_project:
65
+ rubygems_version: 1.8.21
66
+ signing_key:
67
+ specification_version: 3
68
+ summary: Tools to automate builds for Stack Builders CI server
69
+ test_files:
70
+ - spec/railblazer/adapter_spec.rb
71
+ - spec/railblazer/config_generator_spec.rb
72
+ - spec/railblazer/minimal_gemfile_spec.rb
73
+ - spec/spec_helper.rb