codeland-starter 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +22 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +6 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +56 -0
  8. data/Rakefile +13 -0
  9. data/bin/codeland-starter +5 -0
  10. data/codeland-starter.gemspec +33 -0
  11. data/lib/codeland/starter.rb +50 -0
  12. data/lib/codeland/starter/cli.rb +33 -0
  13. data/lib/codeland/starter/codeland-starter.yml +5 -0
  14. data/lib/codeland/starter/configuration.rb +37 -0
  15. data/lib/codeland/starter/integrations/heroku.rb +87 -0
  16. data/lib/codeland/starter/version.rb +5 -0
  17. data/spec/fixtures/heroku_app.json +30 -0
  18. data/spec/spec_helper.rb +111 -0
  19. data/spec/starter/configuration_spec.rb +64 -0
  20. data/spec/starter/integrations/heroku_spec.rb +177 -0
  21. data/spec/starter/starter_spec.rb +62 -0
  22. data/template/codeland.rb +276 -0
  23. data/template/files/Procfile +1 -0
  24. data/template/files/app/assets/javascripts/flash.js.coffee.erb +11 -0
  25. data/template/files/app/assets/stylesheets/application.scss +18 -0
  26. data/template/files/app/assets/stylesheets/atoms/.keep +0 -0
  27. data/template/files/app/assets/stylesheets/base/_base.scss +0 -0
  28. data/template/files/app/assets/stylesheets/base/_typography.scss +0 -0
  29. data/template/files/app/assets/stylesheets/base/_utility.scss +0 -0
  30. data/template/files/app/assets/stylesheets/base/_variables-colors.scss +3 -0
  31. data/template/files/app/assets/stylesheets/base/_variables.scss +0 -0
  32. data/template/files/app/assets/stylesheets/molecules/_flash.scss +21 -0
  33. data/template/files/app/assets/stylesheets/organisms/_footer.scss +0 -0
  34. data/template/files/app/assets/stylesheets/organisms/_header.scss +0 -0
  35. data/template/files/app/views/layouts/_flash.html.slim +6 -0
  36. data/template/files/app/views/layouts/application.html.slim.erb +19 -0
  37. data/template/files/app/views/partials/_footer.html.slim +0 -0
  38. data/template/files/app/views/partials/_header.html.slim +0 -0
  39. metadata +244 -0
@@ -0,0 +1,111 @@
1
+ require 'bundler/setup'
2
+ Bundler.setup
3
+
4
+ require 'simplecov'
5
+ require 'simplecov-console'
6
+ formaters = [
7
+ SimpleCov::Formatter::HTMLFormatter,
8
+ SimpleCov::Formatter::Console
9
+ ]
10
+ if ENV['CI']
11
+ require 'codeclimate-test-reporter'
12
+ formaters << CodeClimate::TestReporter::Formatter
13
+ end
14
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[*formaters]
15
+ SimpleCov.start
16
+
17
+ require 'webmock/rspec'
18
+ WebMock.disable_net_connect!(:allow => 'codeclimate.com') if ENV['CI']
19
+ require 'codeland/starter'
20
+
21
+ # This file was generated by the `rspec --init` command. Conventionally, all
22
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
23
+ # The generated `.rspec` file contains `--require spec_helper` which will cause this
24
+ # file to always be loaded, without a need to explicitly require it in any files.
25
+ #
26
+ # Given that it is always loaded, you are encouraged to keep this file as
27
+ # light-weight as possible. Requiring heavyweight dependencies from this file
28
+ # will add to the boot time of your test suite on EVERY test run, even for an
29
+ # individual file that may not need all of that loaded. Instead, consider making
30
+ # a separate helper file that requires the additional dependencies and performs
31
+ # the additional setup, and require it from the spec files that actually need it.
32
+ #
33
+ # The `.rspec` file also contains a few flags that are not defaults but that
34
+ # users commonly want.
35
+ #
36
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
37
+ RSpec.configure do |config|
38
+ # rspec-expectations config goes here. You can use an alternate
39
+ # assertion/expectation library such as wrong or the stdlib/minitest
40
+ # assertions if you prefer.
41
+ config.expect_with :rspec do |expectations|
42
+ # This option will default to `true` in RSpec 4. It makes the `description`
43
+ # and `failure_message` of custom matchers include text for helper methods
44
+ # defined using `chain`, e.g.:
45
+ # be_bigger_than(2).and_smaller_than(4).description
46
+ # # => "be bigger than 2 and smaller than 4"
47
+ # ...rather than:
48
+ # # => "be bigger than 2"
49
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
50
+ end
51
+
52
+ # rspec-mocks config goes here. You can use an alternate test double
53
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
54
+ config.mock_with :rspec do |mocks|
55
+ # Prevents you from mocking or stubbing a method that does not exist on
56
+ # a real object. This is generally recommended, and will default to
57
+ # `true` in RSpec 4.
58
+ mocks.verify_partial_doubles = true
59
+ end
60
+
61
+ # The settings below are suggested to provide a good initial experience
62
+ # with RSpec, but feel free to customize to your heart's content.
63
+ =begin
64
+ # These two settings work together to allow you to limit a spec run
65
+ # to individual examples or groups you care about by tagging them with
66
+ # `:focus` metadata. When nothing is tagged with `:focus`, all examples
67
+ # get run.
68
+ config.filter_run :focus
69
+ config.run_all_when_everything_filtered = true
70
+
71
+ # Limits the available syntax to the non-monkey patched syntax that is recommended.
72
+ # For more details, see:
73
+ # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
74
+ # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
75
+ # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
76
+ config.disable_monkey_patching!
77
+
78
+ # This setting enables warnings. It's recommended, but in some cases may
79
+ # be too noisy due to issues in dependencies.
80
+ config.warnings = true
81
+
82
+ # Many RSpec users commonly either run the entire suite or an individual
83
+ # file, and it's useful to allow more verbose output when running an
84
+ # individual spec file.
85
+ if config.files_to_run.one?
86
+ # Use the documentation formatter for detailed output,
87
+ # unless a formatter has already been configured
88
+ # (e.g. via a command-line flag).
89
+ config.default_formatter = 'doc'
90
+ end
91
+
92
+ # Print the 10 slowest examples and example groups at the
93
+ # end of the spec run, to help surface which specs are running
94
+ # particularly slow.
95
+ config.profile_examples = 10
96
+ =end
97
+
98
+ # Run specs in random order to surface order dependencies. If you find an
99
+ # order dependency and want to debug it, you can fix the order by providing
100
+ # the seed, which is printed after each run.
101
+ # --seed 1234
102
+ config.order = :random
103
+
104
+ =begin
105
+ # Seed global randomization in this process using the `--seed` CLI option.
106
+ # Setting this allows you to use `--seed` to deterministically reproduce
107
+ # test failures related to randomization by passing the same `--seed` value
108
+ # as the one that triggered the failure.
109
+ Kernel.srand config.seed
110
+ =end
111
+ end
@@ -0,0 +1,64 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Codeland::Starter::Configuration do
4
+ let!(:installed_yaml) { File.join(File.dirname(__FILE__), '..', '..', 'lib', 'codeland', 'starter', 'codeland-starter.yml') }
5
+
6
+ describe '::DEFAULT_FILENAME' do
7
+ it { expect(described_class::DEFAULT_FILENAME).to eq('codeland-starter.yml') }
8
+ end
9
+
10
+ describe 'initialize' do
11
+ context '@yaml' do
12
+ let!(:other_yaml) { 'otherfile.yml' }
13
+
14
+ context 'installed' do
15
+ context 'argument file exists' do
16
+ subject { described_class.new(other_yaml) }
17
+
18
+ before do
19
+ expect(File).to receive(:exists?).with(other_yaml).and_return(true)
20
+ expect(File).to receive(:open).with(other_yaml).and_return(other_yaml)
21
+ expect(YAML).to receive(:load_file).with(other_yaml).and_return(other_yaml)
22
+ end
23
+
24
+ it { expect(subject.yaml).to eq(other_yaml) }
25
+ end
26
+
27
+ context 'argument dont exists' do
28
+ let!(:default_yaml) { File.join(Dir.home, described_class::DEFAULT_FILENAME) }
29
+
30
+ before do
31
+ expect(File).to receive(:exists?).with(other_yaml).and_return(false)
32
+ expect(File).to receive(:exists?).with(default_yaml).and_return(true)
33
+ expect(File).to receive(:open).with(default_yaml).and_return(default_yaml)
34
+ expect(YAML).to receive(:load_file).with(default_yaml).and_return(default_yaml)
35
+ end
36
+
37
+ subject { described_class.new(other_yaml) }
38
+
39
+ it { expect(subject.yaml).to eq(subject.default_yaml_file) }
40
+ end
41
+ end
42
+
43
+ context 'not installed' do
44
+ before { expect(File).to receive(:exists?).exactly(2).times.and_return(false) }
45
+
46
+ it { expect{ described_class.new(installed_yaml) }.to raise_error(Codeland::Starter::MissingYAML) }
47
+ end
48
+ end
49
+ end
50
+
51
+ describe '#default_yaml_file' do
52
+ subject { described_class.new(file).default_yaml_file }
53
+
54
+ let!(:file) { File.open(File.join(File.dirname(__FILE__), '..', '..', 'lib', 'codeland', 'starter', 'codeland-starter.yml')) }
55
+
56
+ it { is_expected.to eq(File.join(Dir.home, described_class::DEFAULT_FILENAME)) }
57
+ end
58
+
59
+ describe '#integrations' do
60
+ subject { described_class.new(installed_yaml).integrations }
61
+
62
+ it { is_expected.to be_a(Array) }
63
+ end
64
+ end
@@ -0,0 +1,177 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Codeland::Starter::Integrations::Heroku do
4
+ def stub_heroku(content = nil, status = 201, app_name = name)
5
+ stub_request(:post, 'https://api.heroku.com/apps')
6
+ .with(
7
+ :body => { :name => name, :region => 'us', :stack => 'cedar' },
8
+ :headers => {
9
+ 'Accept' => 'application/vnd.heroku+json; version=3',
10
+ 'Authorization' => "Bearer #{heroku_token}",
11
+ 'Content-Type' => 'application/json',
12
+ 'Host' => 'api.heroku.com:443',
13
+ 'User-Agent' => "excon/#{Excon::VERSION}"
14
+ }
15
+ ).to_return(:status => status, :body => content)
16
+ end
17
+
18
+ def stub_heroku_error(error, app_name = name)
19
+ stub_request(:post, 'https://api.heroku.com/apps')
20
+ .with(
21
+ :body => { :name => app_name, :region => 'us', :stack => 'cedar' },
22
+ :headers => {
23
+ 'Accept' => 'application/vnd.heroku+json; version=3',
24
+ 'Authorization' => "Bearer #{heroku_token}",
25
+ 'Content-Type' => 'application/json',
26
+ 'Host' => 'api.heroku.com:443',
27
+ 'User-Agent' => "excon/#{Excon::VERSION}"
28
+ }
29
+ ).to_raise(error)
30
+ end
31
+
32
+ let!(:heroku_token) { 'HEROKU_OAUTH_TOKEN' }
33
+
34
+ let!(:heroku_file) do
35
+ File.open(File.dirname(__FILE__) + '/../../fixtures/heroku_app.json', 'rb')
36
+ end
37
+
38
+ let!(:installed_yaml) { File.join(File.dirname(__FILE__), '..', '..', '..', 'lib', 'codeland', 'starter', 'codeland-starter.yml') }
39
+
40
+
41
+ describe '#initialize' do
42
+ let!(:name) { 'MyAppName' }
43
+
44
+ context 'api' do
45
+ context 'with heroku key in YAML' do
46
+ before { expect(Codeland::Starter::Configuration).to receive(:[]).with('heroku').exactly(2).times.and_return({'oauth_token' => heroku_token}) }
47
+
48
+ it 'sets @api' do
49
+ expected_kind = PlatformAPI::Client
50
+ expect(subject.instance_variable_get(:@api)).to be_a(expected_kind)
51
+ end
52
+ end
53
+
54
+ context 'without heroku key in YAML' do
55
+ before do
56
+ expect(Codeland::Starter::Configuration).to receive(:[]).with('heroku').once.and_return(nil)
57
+ expect(Codeland::Starter).to receive(:config).and_return(Codeland::Starter::Configuration.new(installed_yaml))
58
+ end
59
+
60
+ it 'raises missing yaml' do
61
+ expect{ described_class.new }.to raise_error(Codeland::Starter::MissingYAML)
62
+ end
63
+ end
64
+ end
65
+ end
66
+
67
+ describe '#create' do
68
+ before do
69
+ expect(Codeland::Starter).to receive(:name).and_return(name)
70
+ end
71
+
72
+ subject { described_class.new.create }
73
+
74
+ context 'wrong oauth token' do
75
+ let!(:name) { 'MyAppName' }
76
+ before { stub_heroku_error(Excon::Errors::Unauthorized) }
77
+ before { expect(Codeland::Starter).to receive(:config).and_return(Codeland::Starter::Configuration.new(installed_yaml)) }
78
+ before { expect(Codeland::Starter::Configuration).to receive(:[]).with('heroku').exactly(2).times.and_return({'oauth_token' => heroku_token}) }
79
+ before { allow_any_instance_of(described_class).to receive(:add_git_remote).and_return(nil) }
80
+
81
+ it 'raises MissingYAML' do
82
+ expect{ subject }.to raise_error(Codeland::Starter::MissingYAML)
83
+ end
84
+ end
85
+
86
+ context 'app with name taken' do
87
+ subject { described_class.new }
88
+ let!(:name) { 'codeland' }
89
+ before do
90
+ expect(Codeland::Starter::Configuration).to receive(:[]).with('heroku').exactly(2).times.and_return({'oauth_token' => heroku_token})
91
+ error = Excon::Errors::UnprocessableEntity.new("UnprocessableEntity")
92
+ stub_heroku_error(error, name)
93
+ stub_heroku(heroku_file, 201, nil)
94
+ is_expected.to receive(:create_app).with(name).once.and_raise(error)
95
+ is_expected.to receive(:create_app).with(no_args).once
96
+ allow_any_instance_of(described_class).to receive(:add_git_remote).and_return(nil)
97
+ end
98
+
99
+ it 'calls create with empty name' do
100
+ subject.create
101
+ end
102
+ end
103
+
104
+ context 'app with new unique name' do
105
+ before { expect(Codeland::Starter::Configuration).to receive(:[]).with('heroku').exactly(2).times.and_return({'oauth_token' => heroku_token}) }
106
+ before { stub_heroku(heroku_file) }
107
+
108
+ subject { described_class.new }
109
+
110
+ let!(:name) { 'new-app-for-codeland' }
111
+
112
+ context 'returned json have some keys' do
113
+ before { subject.create }
114
+ before { allow_any_instance_of(described_class).to receive(:add_git_remote).and_return(nil) }
115
+
116
+ %w(git_url id name web_url).each do |key|
117
+ it "includes #{key} key" do
118
+ expect(JSON.parse(subject.app)).to have_key('id')
119
+ end
120
+ end
121
+ end
122
+
123
+ context 'git remote' do
124
+ before do
125
+ expected = "git remote add heroku git_url"
126
+ expect(subject).to receive(:system).with(expected).once
127
+ end
128
+
129
+ it 'calls git remote add heroku' do
130
+ subject.create
131
+ end
132
+ end
133
+ end
134
+ end
135
+
136
+ describe '#output' do
137
+ before { expect(Codeland::Starter).to receive(:config).exactly(4).times.and_return(Codeland::Starter::Configuration.new(installed_yaml)) }
138
+
139
+ context 'default' do
140
+ it { expect(subject.output).to be_nil }
141
+ end
142
+
143
+ context 'successfull' do
144
+ it 'prints a message' do
145
+ expect(subject).to receive(:success?).and_return(true)
146
+ expect(STDOUT).to receive(:puts)
147
+ subject.output
148
+ end
149
+ end
150
+ end
151
+
152
+ describe '#perform' do
153
+ before { expect(Codeland::Starter).to receive(:config).exactly(4).times.and_return(Codeland::Starter::Configuration.new(installed_yaml)) }
154
+
155
+ context '#create' do
156
+ before do
157
+ expect_any_instance_of(Codeland::Starter::Integrations::Heroku).to receive(:create).once
158
+ expect_any_instance_of(Codeland::Starter::Integrations::Heroku).to receive(:output).once.and_return(nil)
159
+ end
160
+
161
+ it 'calls #create' do
162
+ subject.perform
163
+ end
164
+ end
165
+
166
+ context '#output' do
167
+ before do
168
+ expect_any_instance_of(Codeland::Starter::Integrations::Heroku).to receive(:create).once.and_return(nil)
169
+ expect_any_instance_of(Codeland::Starter::Integrations::Heroku).to receive(:output).once
170
+ end
171
+
172
+ it 'calls #output' do
173
+ subject.perform
174
+ end
175
+ end
176
+ end
177
+ end
@@ -0,0 +1,62 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Codeland::Starter do
4
+ describe '.create_project' do
5
+ before do
6
+ allow(Codeland::Starter).to receive(:create_rails_project).and_return(true)
7
+ end
8
+ let!(:name) { 'app-name' }
9
+ let!(:installed_yaml) { File.join(File.dirname(__FILE__), '..', '..', 'lib', 'codeland', 'starter', 'codeland-starter.yml') }
10
+
11
+ context 'name' do
12
+ before { expect_any_instance_of(Codeland::Starter::Configuration).to receive(:integrations).exactly(2).times.and_return([]) }
13
+
14
+ it 'sets @name' do
15
+ subject.create_project(name, installed_yaml)
16
+ expect(subject.name).to eq(name)
17
+ end
18
+ end
19
+
20
+ context 'integrations' do
21
+ context 'with correct yaml' do
22
+ context 'empty integrations on yaml' do
23
+ before { expect_any_instance_of(Codeland::Starter::Configuration).to receive(:integrations).and_return([]) }
24
+
25
+ end
26
+ context 'with integrations' do
27
+ after { subject.create_project(name, installed_yaml) }
28
+
29
+ context 'defined integrations' do
30
+ let!(:integration) { 'heroku' }
31
+ let!(:integration_class) { Codeland::Starter::Integrations::Heroku }
32
+ before do
33
+ expect_any_instance_of(Codeland::Starter::Configuration).to receive(:integrations).exactly(2).times.and_return([integration])
34
+ end
35
+
36
+ it 'calls integration#perform' do
37
+ expect_any_instance_of(integration_class).to receive(:perform).and_return(nil)
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ context 'not existing yaml' do
44
+ end
45
+ end
46
+ end
47
+
48
+ describe '.create_rails_project' do
49
+ subject { described_class }
50
+ let!(:app_name) { 'my-cool-app' }
51
+ before do
52
+ is_expected.to receive(:name).and_return(app_name).at_least(1).times
53
+ expected = "rails new #{app_name} --database=postgresql --template=#{File.join(described_class::ROOT_PATH, 'template', 'codeland.rb')} --skip-bundle --skip-test-unit"
54
+ expect(described_class).to receive(:system).with(expected).once.and_return(nil)
55
+ expect(Dir).to receive(:chdir).with(app_name).once.and_return(nil)
56
+ end
57
+
58
+ it 'calls rails new app_name with correct options' do
59
+ subject.create_rails_project
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,276 @@
1
+ def source_paths
2
+ [
3
+ File.join(File.expand_path(File.dirname(__FILE__)), 'files')
4
+ ] + Array(super)
5
+ end
6
+
7
+ def rails_4?
8
+ Rails.gem_version >= Gem::Version.new('4.2')
9
+ end
10
+
11
+ run 'bundle install --quiet'
12
+ git :init
13
+ git :add => '.'
14
+ git :commit => %Q{ -m 'Initial commit' --quiet }
15
+
16
+ # Ruby and Rails check
17
+ if Gem::Version.new(RUBY_VERSION) > Gem::Version.new('2.0')
18
+ if yes?("You are using #{RUBY_VERSION}. Is the version of the project?")
19
+ insert_into_file 'Gemfile', "ruby '#{RUBY_VERSION}'\n", :after => "source 'https://rubygems.org'\n\n"
20
+ end
21
+ else
22
+ puts '******* WARNING *******'
23
+ puts "Your Ruby version #{RUBY_VERSION} is too old"
24
+ puts 'Please upgrade to ruby 2.2 or more'
25
+ end
26
+
27
+ gem_group :development, :test do
28
+ unless rails_4?
29
+ gem 'pry-rails', '~> 0.3.2'
30
+ end
31
+ gem 'machinist', '~> 2.0'
32
+ gem 'rspec-rails', '~> 3.2.0'
33
+ gem 'awesome_print', '~> 1.6.1', :require => false
34
+ gem 'spring-commands-rspec', '~> 1.0.4'
35
+ gem 'thin', '~> 1.6.3'
36
+ end
37
+
38
+ gem_group :test do
39
+ gem 'simplecov', '~> 0.9.2', :require => false
40
+ gem 'database_cleaner', '~> 1.4.1'
41
+ gem 'shoulda-matchers', '~> 2.8.0', :require => false
42
+ gem 'capybara'
43
+ gem 'selenium-webdriver'
44
+ end
45
+ run 'bundle install --quiet'
46
+ run 'bundle exec spring binstub rspec'
47
+ generate :'machinist:install'
48
+ generate :'rspec:install'
49
+ inside 'spec' do
50
+ insert_into_file 'rails_helper.rb', "\nrequire 'shoulda-matchers'", :after => "require 'rspec/rails'"
51
+ insert_into_file 'rails_helper.rb', "\nrequire 'capybara/rspec'", :after => "require 'rspec/rails'"
52
+ insert_into_file 'rails_helper.rb', "\nrequire 'capybara/rails'", :after => "require 'rspec/rails'"
53
+ insert_into_file 'rails_helper.rb', "\nrequire Rails.root.join('spec', 'support', 'blueprints.rb')
54
+
55
+ Capybara.javascript_driver = :selenium
56
+ Capybara.server_port = 52662
57
+ Capybara.exact = true\n", :after => "require 'shoulda-matchers'"
58
+ insert_into_file 'rails_helper.rb', "require 'simplecov'
59
+ SimpleCov.start('rails')\n", :before => "require 'spec_helper'"
60
+
61
+ insert_into_file 'rails_helper.rb', "\nconfig.before(:suite) do
62
+ DatabaseCleaner.strategy = :transaction
63
+ DatabaseCleaner.clean_with(:truncation)
64
+ end
65
+
66
+ config.before(:each) do
67
+ DatabaseCleaner.start
68
+ end
69
+
70
+ config.after(:each) do
71
+ DatabaseCleaner.clean
72
+ end", :after => 'config.infer_spec_type_from_file_location!'
73
+ end
74
+ append_to_file '.gitignore', "coverage/\n"
75
+ append_to_file '.gitignore', "public/uploads/\n"
76
+ git :add => '.'
77
+ git :commit => %Q{ -m 'Development & test setup (specs and utilities)' --quiet }
78
+
79
+ application <<-CONFIG
80
+ config.generators do |g|
81
+ g.javascripts false
82
+ g.stylesheets false
83
+ g.helper false
84
+ g.template_engine :slim
85
+ g.test_framework :rspec,
86
+ view_specs: false,
87
+ helper_specs: false
88
+ g.fixtures_replacement :machinist
89
+ end
90
+ CONFIG
91
+ git :add => '.'
92
+ git :commit => %Q{ -m 'Configure generators' --quiet }
93
+
94
+ gem 'initjs', '~> 2.1.2'
95
+ run 'bundle install --quiet'
96
+ generate :'initjs:install'
97
+ inside 'app' do
98
+ inside 'assets' do
99
+ inside 'javascripts' do
100
+ gsub_file 'application.js', 'require_tree .', "require_tree ./#{@app_name.underscore}"
101
+ create_file 'lib/.keep'
102
+ insert_into_file 'application.js', "//= require_tree ./lib\n", :after => "//= require turbolinks\n"
103
+ end
104
+ end
105
+ end
106
+ git :add => '.'
107
+ git :commit => %Q{ -m 'Install Initjs' --quiet }
108
+
109
+ gem 'rails-i18n', '~> 4.0.4'
110
+ run 'bundle install --quiet'
111
+
112
+ if yes?('Config for pt-BR?')
113
+ application %Q{config.i18n.enforce_available_locales = false}
114
+ application %Q{config.i18n.available_locales = %i(pt-BR en)}
115
+ application %Q{config.i18n.default_locale = :'pt-BR'}
116
+ application %Q{config.i18n.locale = :'pt-BR'}
117
+ application %Q{config.time_zone = 'Brasilia'}
118
+ end
119
+ git :add => '.'
120
+ git :commit => %Q{ -m 'Install Rails-i18n' --quiet }
121
+
122
+ gem 'slim-rails', '~> 3.0.1'
123
+ run 'bundle install --quiet'
124
+ application %Q(config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }), :env => 'development'
125
+ application 'Slim::Engine.set_options pretty: true', :env => 'development'
126
+ git :add => '.'
127
+ git :commit => %Q{ -m 'Install Slim-rails' --quiet }
128
+
129
+ if yes?('Install Devise?')
130
+ gem 'devise', '~> 3.4.1'
131
+ gem 'devise-i18n'
132
+ run 'bundle install --quiet'
133
+ generate :'devise:install'
134
+ git :add => '.'
135
+ git :commit => %Q{ -m 'Install Devise' --quiet }
136
+ end
137
+
138
+ if yes?('Install ActiveAdmin?')
139
+ gem 'activeadmin', :github => 'gregbell/active_admin'
140
+ run 'bundle install --quiet'
141
+ generate :'active_admin:install'
142
+ git :add => '.'
143
+ git :commit => %Q{ -m 'Install Activeadmin' --quiet }
144
+ end
145
+
146
+ if yes?('Install Simpleform?')
147
+ gem 'simple_form', '~> 3.1.0'
148
+ run 'bundle install --quiet'
149
+ generate :'simple_form:install', '--bootstrap'
150
+
151
+ git :add => '.'
152
+ git :commit => %Q{ -m 'Install Simpleform' --quiet }
153
+ end
154
+
155
+ if yes?('Install Pundit?')
156
+ gem 'pundit', '~> 0.3.0'
157
+ run 'bundle install --quiet'
158
+ generate :'pundit:install'
159
+ inside 'app' do
160
+ inside 'controllers' do
161
+ insert_into_file 'application_controller.rb', " include Pundit\n", :after => "class ApplicationController < ActionController::Base\n"
162
+ insert_into_file 'application_controller.rb', '
163
+ rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized
164
+
165
+ private
166
+
167
+ def user_not_authorized
168
+ flash[:error] = "Você não tem permissão para fazer isso."
169
+ redirect_to(request.referrer || root_path)
170
+ end
171
+ ', :after => "protect_from_forgery with: :exception\n"
172
+ end
173
+ end
174
+ git :add => '.'
175
+ git :commit => %Q{ -m 'Install Pundit' --quiet }
176
+ end
177
+
178
+ # Front-end stuffs
179
+
180
+ gem 'autoprefixer-rails'
181
+ gem 'bootstrap-sass', '~> 3.3.3'
182
+ gem 'font-awesome-rails'
183
+ run 'bundle install --quiet'
184
+
185
+ inside 'app' do
186
+ inside 'assets' do
187
+ inside 'stylesheets' do
188
+ directory 'base'
189
+ directory 'organisms'
190
+ directory 'molecules'
191
+ directory 'atoms'
192
+ remove_file 'application.css'
193
+ copy_file 'application.scss'
194
+ end
195
+ end
196
+
197
+ inside 'views' do
198
+ directory 'partials'
199
+ end
200
+ end
201
+
202
+ if yes?('Install NProgress?')
203
+ gem 'nprogress-rails'
204
+ run 'bundle install --quiet'
205
+ inside 'app' do
206
+ inside 'assets' do
207
+ inside 'javascripts' do
208
+ insert_into_file 'application.js', "//= require nprogress\n", :after => "//= require turbolinks\n"
209
+ insert_into_file 'application.js', "//= require nprogress-turbolinks\n", :after => "//= require nprogress\n"
210
+ end
211
+
212
+ inside 'stylesheets' do
213
+ append_to_file 'application.scss', <<NPROGRESS
214
+
215
+ // ==== NProgress
216
+ // $nprogress-color : ;
217
+ // $nprogress-height: ;
218
+ @import "nprogress";
219
+ NPROGRESS
220
+ end
221
+ end
222
+ end
223
+ end
224
+
225
+ git :add => '.'
226
+ git :commit => %Q{ -m 'Setup front-end files' --quiet }
227
+
228
+ inside 'app' do
229
+ inside 'assets' do
230
+ inside 'javascripts' do
231
+ template 'flash.js.coffee.erb', "#{app_name.underscore}/flash.js.coffee"
232
+ gsub_file "#{app_name.underscore}/#{app_name.underscore}.js.coffee", ' modules: -> []', <<MODULE
233
+ modules: ->
234
+ [
235
+ #{app_const_base}.Flash
236
+ ]
237
+ MODULE
238
+ end
239
+ end
240
+ inside 'views' do
241
+ inside 'layouts' do
242
+ copy_file '_flash.html.slim'
243
+ template 'application.html.slim.erb', 'application.html.slim'
244
+ remove_file 'application.html.erb'
245
+ end
246
+ end
247
+ end
248
+
249
+ git :add => '.'
250
+ git :commit => %Q{ -m 'Setup default flash messages' --quiet }
251
+
252
+ gem_group :production do
253
+ gem 'rails_12factor', '~> 0.0.3'
254
+ gem 'passenger', '~> 5.0'
255
+ end
256
+ run 'bundle install --quiet'
257
+ copy_file 'Procfile'
258
+ git :add => '.'
259
+ git :commit => %Q{ -m 'Heroku setup' --quiet }
260
+
261
+ append_to_file '.gitignore', "config/database.yml\n"
262
+ inside 'config' do
263
+ git :mv => %Q{ database.yml database.yml.sample }
264
+ end
265
+ git :commit => %Q{ -a -m 'Ignore database.yml in favor of a example' --quiet }
266
+
267
+ inside 'bin' do
268
+ uncomment_lines 'setup', /(Copying|end$|config\/database)/
269
+ insert_into_file 'setup', " system \"vi config/database.yml\"\n", :after => "config/database.yml\"\n"
270
+ end
271
+
272
+ git :commit => %Q{ -a -m 'Change bin/setup to copy database.yml' --quiet }
273
+
274
+ puts '=' * 60
275
+ puts 'Project created. Run `bin/setup` to complete the installation.'
276
+ puts '=' * 60