eastrails 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +0 -0
- data/LICENSE +20 -0
- data/README.md +44 -0
- data/ROADMAP.md +0 -0
- data/bin/eastrails +4 -0
- data/lib/eastrails.rb +12 -0
- data/lib/eastrails/commands/add.rb +31 -0
- data/lib/eastrails/commands/base.rb +18 -0
- data/lib/eastrails/commands/init.rb +63 -0
- data/lib/eastrails/components.rb +18 -0
- data/lib/eastrails/components/base.rb +77 -0
- data/lib/eastrails/components/cancan.rb +12 -0
- data/lib/eastrails/components/capistrano.rb +15 -0
- data/lib/eastrails/components/cucumber.rb +14 -0
- data/lib/eastrails/components/devise.rb +47 -0
- data/lib/eastrails/components/exception_notifier.rb +17 -0
- data/lib/eastrails/components/haml.rb +15 -0
- data/lib/eastrails/components/heroku.rb +29 -0
- data/lib/eastrails/components/jasmine.rb +22 -0
- data/lib/eastrails/components/new_relic.rb +15 -0
- data/lib/eastrails/components/rspec.rb +24 -0
- data/lib/eastrails/components/twitter_bootstrap.rb +16 -0
- data/lib/eastrails/components/vcr.rb +21 -0
- data/lib/eastrails/executor.rb +38 -0
- data/lib/eastrails/generator.rb +13 -0
- data/lib/eastrails/parameters.rb +37 -0
- data/lib/eastrails/scanner/base.rb +17 -0
- data/lib/eastrails/scanner/security.rb +13 -0
- data/lib/eastrails/thor_ext.rb +36 -0
- data/lib/eastrails/version.rb +3 -0
- data/lib/resources/capistrano/deploy.rb +38 -0
- data/lib/resources/default/controllers/welcome_controller.rb +4 -0
- data/lib/resources/default/stylesheets/application-theme-default.css.scss +11 -0
- data/lib/resources/default/stylesheets/application-theme-kickstarter.css.scss +51 -0
- data/lib/resources/default/views/layouts/_messages.html.erb +8 -0
- data/lib/resources/default/views/layouts/_navigation.html.erb +1 -0
- data/lib/resources/default/views/layouts/application.html.erb +35 -0
- data/lib/resources/default/views/welcome/index.html.erb +1 -0
- data/lib/resources/devise/registrations/edit.html.erb +27 -0
- data/lib/resources/devise/registrations/new.html.erb +18 -0
- data/lib/resources/devise/sessions/new.html.erb +16 -0
- data/lib/resources/devise/shared/_links.html.erb +25 -0
- data/lib/resources/navigation/devise.html.erb +20 -0
- data/lib/resources/vcr/features/samples/internet.feature +6 -0
- data/lib/resources/vcr/features/step_definitions/internet_steps.rb +10 -0
- data/lib/resources/vcr/features/support/vcr_cucumber.rb +12 -0
- data/lib/resources/vcr/spec/samples/sample_spec.rb +10 -0
- data/lib/resources/vcr/spec/support/vcr_rspec.rb +13 -0
- metadata +238 -0
@@ -0,0 +1,22 @@
|
|
1
|
+
module Eastrails
|
2
|
+
module Components
|
3
|
+
class Jasmine < Base
|
4
|
+
include Eastrails::ThorExt
|
5
|
+
|
6
|
+
def add
|
7
|
+
gem 'jasmine', :group => [:development, :test]
|
8
|
+
system 'bundle install'
|
9
|
+
system "rails g jasmine:install"
|
10
|
+
if yes_wizard?("Do you want to generate jasmine sample specs?")
|
11
|
+
system "rails g jasmine:examples"
|
12
|
+
end
|
13
|
+
puts "==============================="
|
14
|
+
puts "Usage: "
|
15
|
+
puts "- Start jasmine server: rake jasmine"
|
16
|
+
puts "- Point your browser to http://localhost:8888"
|
17
|
+
puts "More information at: https://github.com/pivotal/jasmine-gem"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Eastrails
|
2
|
+
module Components
|
3
|
+
class NewRelic < Base
|
4
|
+
def add
|
5
|
+
gem 'newrelic_rpm'
|
6
|
+
puts "============================"
|
7
|
+
puts "You should do followings manually:"
|
8
|
+
puts "- Create an account at http://newrelic.com/. There you can sign up for a free Lite account or one of our paid subscriptions."
|
9
|
+
puts "- Go to app setting page, download newrelic.yml"
|
10
|
+
puts "- Place this file into your app's config directory, replacing the existing one."
|
11
|
+
puts "- Restart your application. In a few minutes, your application will send data to New Relic. Then go to New Relic to monitor your applications in production."
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Eastrails
|
2
|
+
module Components
|
3
|
+
class Rspec < Base
|
4
|
+
def add
|
5
|
+
gem 'rspec-rails', '>= 2.11.4', :group => [:development, :test]
|
6
|
+
gem 'database_cleaner', :group => :test
|
7
|
+
system 'bundle install'
|
8
|
+
system 'rails g rspec:install -f'
|
9
|
+
inject_into_file 'spec/spec_helper.rb', :after => "RSpec.configure do |config|\n" do <<-RUBY
|
10
|
+
config.before(:suite) do
|
11
|
+
DatabaseCleaner.strategy = :truncation
|
12
|
+
end
|
13
|
+
config.before(:each) do
|
14
|
+
DatabaseCleaner.start
|
15
|
+
end
|
16
|
+
config.after(:each) do
|
17
|
+
DatabaseCleaner.clean
|
18
|
+
end
|
19
|
+
RUBY
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Eastrails
|
2
|
+
module Components
|
3
|
+
class TwitterBootstrap < Base
|
4
|
+
def add
|
5
|
+
gem 'anjlab-bootstrap-rails', '>= 2.2', :require => 'bootstrap-rails'
|
6
|
+
run "bundle"
|
7
|
+
inject_into_file "app/assets/stylesheets/application.css", :before => /\s\*= require_tree/ do
|
8
|
+
" *= require twitter/bootstrap\n"
|
9
|
+
end
|
10
|
+
append_to_file "app/assets/javascripts/application.js" do
|
11
|
+
"//= require twitter/bootstrap"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Eastrails
|
2
|
+
module Components
|
3
|
+
class Vcr < Base
|
4
|
+
def add
|
5
|
+
do_if_installed("cucumber", "rspec") do
|
6
|
+
gem "vcr", require: false, group: :test
|
7
|
+
gem "webmock", require: false, group: :test
|
8
|
+
|
9
|
+
system 'bundle install'
|
10
|
+
do_if_installed("rspec") do
|
11
|
+
directory "vcr/spec", "spec"
|
12
|
+
end
|
13
|
+
|
14
|
+
do_if_installed("cucumber") do
|
15
|
+
directory "vcr/features", "features"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Eastrails
|
2
|
+
class Executor
|
3
|
+
include Thor::Actions
|
4
|
+
|
5
|
+
def initialize(args)
|
6
|
+
self.args = args
|
7
|
+
self.destination_root = File.expand_path(".")
|
8
|
+
self.behavior = :invoke
|
9
|
+
end
|
10
|
+
|
11
|
+
def execute
|
12
|
+
parameter = Eastrails::Parameters.new(args)
|
13
|
+
case parameter.command
|
14
|
+
when "init"
|
15
|
+
Eastrails::Commands::Init.new(parameter).execute
|
16
|
+
when "add"
|
17
|
+
Eastrails::Commands::Add.new(parameter).execute
|
18
|
+
when "check"
|
19
|
+
scan_security_holes
|
20
|
+
else
|
21
|
+
puts "Invalid commands"
|
22
|
+
puts "Usage: "
|
23
|
+
puts <<-RUBY
|
24
|
+
eastrails init <app_name> <comma_separated_components_names>
|
25
|
+
eastrails add <component_name>
|
26
|
+
eastrails check
|
27
|
+
RUBY
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def scan_security_holes
|
32
|
+
Eastrails::Scanner::Security.new.execute
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
attr_accessor :args
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
module Eastrails
|
3
|
+
class Generator < ::Rails::Generators::Base
|
4
|
+
include Thor::Actions
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
self.options = {}
|
8
|
+
self.behavior = :invoke
|
9
|
+
self.destination_root = File.expand_path(".")
|
10
|
+
self.class.source_root File.expand_path("../../resources", __FILE__)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Eastrails
|
2
|
+
class Parameters
|
3
|
+
attr_accessor :args
|
4
|
+
attr_accessor :options
|
5
|
+
attr_accessor :non_options
|
6
|
+
|
7
|
+
def initialize(args = [])
|
8
|
+
self.args = args.dup
|
9
|
+
self.non_options = args.select { |arg| !arg.start_with?("-") }
|
10
|
+
parse_options
|
11
|
+
end
|
12
|
+
|
13
|
+
def parse_options
|
14
|
+
self.options = {}
|
15
|
+
parser = OptionParser.new do |opts|
|
16
|
+
opts.on('-v', '--verbose', 'Print debugging details') do
|
17
|
+
options[:verbose] = true
|
18
|
+
end
|
19
|
+
|
20
|
+
opts.on('-b', '--bundle', 'Run bundle after complete') do
|
21
|
+
options[:bundle] = true
|
22
|
+
end
|
23
|
+
|
24
|
+
opts.on('-d', '--database', "Specify the database adapter as of eastrails new")
|
25
|
+
end
|
26
|
+
parser.parse!(args)
|
27
|
+
end
|
28
|
+
|
29
|
+
def command
|
30
|
+
non_options[0] || "help"
|
31
|
+
end
|
32
|
+
|
33
|
+
def component
|
34
|
+
non_options[1]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Eastrails
|
2
|
+
module Scanner
|
3
|
+
class Security < Base
|
4
|
+
def execute
|
5
|
+
self.destination_root = File.expand_path(".")
|
6
|
+
system "brakeman -o tmp/scanner.html"
|
7
|
+
system "open 'tmp/scanner.html'"
|
8
|
+
puts "You should also check http://weblog.rubyonrails.org/ for security holes"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Eastrails
|
2
|
+
module ThorExt
|
3
|
+
def say_custom(tag, text); say "\033[1m\033[36m" + tag.to_s.rjust(10) + "\033[0m" + " #{text}" end
|
4
|
+
def say_recipe(name); say "\033[1m\033[36m" + "recipe".rjust(10) + "\033[0m" + " Running #{name} recipe..." end
|
5
|
+
def say_wizard(text); say_custom(@current_recipe || 'eastrails', text) end
|
6
|
+
|
7
|
+
def ask_wizard(question)
|
8
|
+
ask "\033[1m\033[30m\033[46m" + (@current_recipe || "prompt").rjust(10) + "\033[1m\033[36m" + " #{question}\033[0m"
|
9
|
+
end
|
10
|
+
|
11
|
+
def yes_wizard?(question)
|
12
|
+
answer = ask_wizard(question + " \033[33m(y/n)\033[0m")
|
13
|
+
case answer.downcase
|
14
|
+
when "yes", "y"
|
15
|
+
true
|
16
|
+
when "no", "n"
|
17
|
+
false
|
18
|
+
else
|
19
|
+
yes_wizard?(question)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def no_wizard?(question); !yes_wizard?(question) end
|
24
|
+
|
25
|
+
def multiple_choice(question, choices)
|
26
|
+
say_custom('question', question)
|
27
|
+
values = {}
|
28
|
+
choices.each_with_index do |choice,i|
|
29
|
+
values[(i + 1).to_s] = choice[1]
|
30
|
+
say_custom( (i + 1).to_s + ')', choice[0] )
|
31
|
+
end
|
32
|
+
answer = ask_wizard("Enter your selection:") while !values.keys.include?(answer)
|
33
|
+
values[answer]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require "bundler/capistrano"
|
2
|
+
|
3
|
+
set :application, "<application_name>"
|
4
|
+
set :repository, "<git_repo_url>"
|
5
|
+
|
6
|
+
set :deploy_to, "/opt/#{application}"
|
7
|
+
set :keep_releases, 10
|
8
|
+
|
9
|
+
server "<server_domain>", :app, :web, :db, :primary => true
|
10
|
+
|
11
|
+
set :scm, 'git'
|
12
|
+
set :git_enable_submodules, 1 # if you have vendored rails
|
13
|
+
set :branch, 'master'
|
14
|
+
set :git_shallow_clone, 1
|
15
|
+
set :scm_verbose, true
|
16
|
+
set :use_sudo, false
|
17
|
+
set :rails_env, "production"
|
18
|
+
|
19
|
+
set :user, "<username>"
|
20
|
+
|
21
|
+
ssh_options[:forward_agent] = true
|
22
|
+
# if you're still using the script/reaper helper you will need
|
23
|
+
# these http://github.com/rails/irs_process_scripts
|
24
|
+
|
25
|
+
# for passenger
|
26
|
+
namespace :deploy do
|
27
|
+
task :start do ; end
|
28
|
+
task :stop do ; end
|
29
|
+
task :restart, :roles => :app, :except => { :no_release => true } do
|
30
|
+
run "touch #{File.join(current_path,'tmp','restart.txt')}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
after 'deploy:update_code', 'deploy:migrate'
|
35
|
+
before "deploy", "deploy:setup"
|
36
|
+
|
37
|
+
after "deploy:restart", "deploy:cleanup"
|
38
|
+
|
@@ -0,0 +1,11 @@
|
|
1
|
+
.content {
|
2
|
+
background-color: #eee;
|
3
|
+
padding: 20px;
|
4
|
+
margin: 50px -20px 0 -20px;
|
5
|
+
-webkit-border-radius: 0 0 6px 6px;
|
6
|
+
-moz-border-radius: 0 0 6px 6px;
|
7
|
+
border-radius: 0 0 6px 6px;
|
8
|
+
-webkit-box-shadow: 0 1px 2px rgba(0,0,0,.15);
|
9
|
+
-moz-box-shadow: 0 1px 2px rgba(0,0,0,.15);
|
10
|
+
box-shadow: 0 1px 2px rgba(0,0,0,.15);
|
11
|
+
}
|
@@ -0,0 +1,51 @@
|
|
1
|
+
.navbar-inner {
|
2
|
+
background-color: #E6E6E6;
|
3
|
+
background-image: -moz-linear-gradient(top, #E6E6E6, #E6E6E6);
|
4
|
+
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#E6E6E6), to(#E6E6E6));
|
5
|
+
background-image: -webkit-linear-gradient(top, #E6E6E6, #E6E6E6);
|
6
|
+
background-image: -o-linear-gradient(top, #E5E6E6, #E6E6E6);
|
7
|
+
background-image: linear-gradient(to bottom, #E6E6E6, #E6E6E6);
|
8
|
+
}
|
9
|
+
|
10
|
+
.content {
|
11
|
+
background-color: #EDEAE3;
|
12
|
+
padding: 20px;
|
13
|
+
margin: 50px -20px 0 -20px;
|
14
|
+
-webkit-border-radius: 0 0 6px 6px;
|
15
|
+
-moz-border-radius: 0 0 6px 6px;
|
16
|
+
border-radius: 0 0 6px 6px;
|
17
|
+
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15);
|
18
|
+
-moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15);
|
19
|
+
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15);
|
20
|
+
}
|
21
|
+
|
22
|
+
$primary_color: #86C543;
|
23
|
+
|
24
|
+
a {
|
25
|
+
color: $primary_color;
|
26
|
+
}
|
27
|
+
|
28
|
+
a:hover {
|
29
|
+
color: lighten($primary_color, 10%);
|
30
|
+
text-decoration: underline;
|
31
|
+
}
|
32
|
+
|
33
|
+
.btn-primary {
|
34
|
+
color: white;
|
35
|
+
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
|
36
|
+
background-color: darken($primary_color, 10%);
|
37
|
+
background-image: -moz-linear-gradient(top, $primary_color, darken($primary_color, 20%));
|
38
|
+
background-image: -webkit-gradient(linear, 0 0, 0 100%, from($primary_color), to(darken($primary_color, 50%)));
|
39
|
+
background-image: -webkit-linear-gradient(top, $primary_color, darken($primary_color, 20%));
|
40
|
+
background-image: -o-linear-gradient(top, $primary_color, darken($primary_color, 20%));
|
41
|
+
background-image: linear-gradient(to bottom, $primary_color, darken($primary_color, 20%));
|
42
|
+
background-repeat: repeat-x;
|
43
|
+
border-color: darken($primary_color, 20%) darken($primary_color, 20%) darken($primary_color, 30%);
|
44
|
+
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) fadein(rgba(0, 0, 0, 0.1), 15%);
|
45
|
+
}
|
46
|
+
|
47
|
+
|
48
|
+
.btn-primary:hover, .btn-primary:active, .btn-primary.active, .btn-primary.disabled, .btn-primary[disabled] {
|
49
|
+
color: white;
|
50
|
+
background-color: darken($primary_color, 20%);
|
51
|
+
}
|
@@ -0,0 +1,8 @@
|
|
1
|
+
<% flash.each do |name, msg| %>
|
2
|
+
<% if msg.is_a?(String) %>
|
3
|
+
<div class="alert alert-<%= name == :notice ? "success" : "error" %>">
|
4
|
+
<a class="close" data-dismiss="alert">×</a>
|
5
|
+
<%= content_tag :div, msg, :id => "flash_#{name}" %>
|
6
|
+
</div>
|
7
|
+
<% end %>
|
8
|
+
<% end %>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= link_to "App_Name", root_path, :class => 'brand' %>
|
@@ -0,0 +1,35 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
5
|
+
<title><%= content_for?(:title) ? yield(:title) : "App_Name" %></title>
|
6
|
+
<meta name="description" content="<%= content_for?(:description) ? yield(:description) : "App_Name" %>">
|
7
|
+
<%= stylesheet_link_tag "application", :media => "all" %>
|
8
|
+
<%= javascript_include_tag "application" %>
|
9
|
+
<%= csrf_meta_tags %>
|
10
|
+
<%= yield(:head) %>
|
11
|
+
</head>
|
12
|
+
<body class="<%= controller_name %> <%= action_name %>">
|
13
|
+
<header class="navbar navbar-fixed-top">
|
14
|
+
<nav class="navbar-inner">
|
15
|
+
<div class="container">
|
16
|
+
<%= render 'layouts/navigation' %>
|
17
|
+
</div>
|
18
|
+
</nav>
|
19
|
+
</header>
|
20
|
+
<div id="main" role="main">
|
21
|
+
<div class="container">
|
22
|
+
<div class="content">
|
23
|
+
<div class="row">
|
24
|
+
<div class="span12">
|
25
|
+
<%= render 'layouts/messages' %>
|
26
|
+
<%= yield %>
|
27
|
+
</div>
|
28
|
+
</div>
|
29
|
+
<footer>
|
30
|
+
</footer>
|
31
|
+
</div>
|
32
|
+
</div> <!--! end of .container -->
|
33
|
+
</div> <!--! end of #main -->
|
34
|
+
</body>
|
35
|
+
</html>
|
@@ -0,0 +1 @@
|
|
1
|
+
Hello from Main App
|
@@ -0,0 +1,27 @@
|
|
1
|
+
<h2>Edit <%= resource_name.to_s.humanize %></h2>
|
2
|
+
|
3
|
+
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :method => :put }) do |f| %>
|
4
|
+
<%= devise_error_messages! %>
|
5
|
+
<p><%= f.label :name %>
|
6
|
+
<%= f.text_field :name %></p>
|
7
|
+
|
8
|
+
<div class="control-group"><%= f.label :email %>
|
9
|
+
<%= f.email_field :email %></div>
|
10
|
+
|
11
|
+
<div class="control-group"><%= f.label :password %> <i>(leave blank if you don't want to change it)</i>
|
12
|
+
<%= f.password_field :password, :autocomplete => "off" %></div>
|
13
|
+
|
14
|
+
<div class="control-group"><%= f.label :password_confirmation %>
|
15
|
+
<%= f.password_field :password_confirmation %></div>
|
16
|
+
|
17
|
+
<div class="control-group"><%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i>
|
18
|
+
<%= f.password_field :current_password %></div>
|
19
|
+
|
20
|
+
<div class="control-group"><%= f.submit "Update", :class => "btn btn-primary" %></div>
|
21
|
+
<% end %>
|
22
|
+
|
23
|
+
<h3>Cancel my account</h3>
|
24
|
+
|
25
|
+
<p>Unhappy? <%= link_to "Cancel my account", registration_path(resource_name), :data => { :confirm => "Are you sure?" }, :method => :delete %>.</p>
|
26
|
+
|
27
|
+
<%= link_to "Back", :back %>
|