shipit-engine 0.8.9 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/shipit_bs.js.coffee +2 -0
  3. data/app/assets/javascripts/task.js.coffee +14 -5
  4. data/app/assets/javascripts/task/search_bar.js.coffee +52 -0
  5. data/app/assets/javascripts/task/stream.js.coffee +9 -2
  6. data/app/assets/javascripts/task/tty.js.coffee +75 -28
  7. data/app/assets/stylesheets/_base/_forms.scss +5 -0
  8. data/app/assets/stylesheets/_pages/_commits.scss +1 -1
  9. data/app/assets/stylesheets/_pages/_deploy.scss +56 -24
  10. data/app/assets/stylesheets/_pages/_settings.scss +5 -0
  11. data/app/assets/stylesheets/_structure/_layout.scss +1 -0
  12. data/app/assets/stylesheets/_structure/_main.scss +4 -0
  13. data/app/assets/stylesheets/shipit.scss +2 -0
  14. data/app/assets/stylesheets/shipit_bs.scss +22 -0
  15. data/app/controllers/shipit/deploys_controller.rb +5 -1
  16. data/app/controllers/shipit/shipit_controller.rb +10 -3
  17. data/app/controllers/shipit/stacks_controller.rb +12 -3
  18. data/app/controllers/shipit/tasks_controller.rb +4 -0
  19. data/app/helpers/shipit/shipit_helper.rb +18 -0
  20. data/app/helpers/shipit/stacks_helper.rb +1 -1
  21. data/app/jobs/shipit/cache_deploy_spec_job.rb +2 -0
  22. data/app/jobs/shipit/fetch_deployed_revision_job.rb +1 -0
  23. data/app/jobs/shipit/git_mirror_update_job.rb +2 -0
  24. data/app/jobs/shipit/perform_task_job.rb +1 -0
  25. data/app/models/shipit/commit.rb +2 -2
  26. data/app/models/shipit/deploy.rb +1 -1
  27. data/app/models/shipit/deploy_spec/bundler_discovery.rb +1 -1
  28. data/app/models/shipit/duration.rb +28 -0
  29. data/app/models/shipit/stack.rb +33 -11
  30. data/app/models/shipit/task.rb +26 -3
  31. data/app/serializers/shipit/task_serializer.rb +14 -1
  32. data/app/views/bootstrap/shipit/missing_settings.html.erb +97 -0
  33. data/app/views/bootstrap/shipit/stacks/new.html.erb +44 -0
  34. data/app/views/layouts/shipit.html.erb +1 -1
  35. data/app/views/layouts/shipit_bootstrap.html.erb +44 -0
  36. data/app/views/shipit/commits/_commit.html.erb +3 -2
  37. data/app/views/shipit/deploys/_deploy.html.erb +11 -2
  38. data/app/views/shipit/deploys/show.html.erb +1 -1
  39. data/app/views/shipit/stacks/new.html.erb +12 -12
  40. data/app/views/shipit/stacks/settings.html.erb +5 -0
  41. data/app/views/shipit/stacks/show.html.erb +1 -1
  42. data/app/views/shipit/tasks/_task.html.erb +10 -2
  43. data/app/views/shipit/tasks/_task_output.html.erb +11 -1
  44. data/app/views/shipit/tasks/show.html.erb +1 -1
  45. data/config/routes.rb +1 -0
  46. data/db/migrate/20160324155046_add_started_at_and_ended_at_on_tasks.rb +25 -0
  47. data/lib/shipit.rb +13 -0
  48. data/lib/shipit/command.rb +13 -9
  49. data/lib/shipit/engine.rb +8 -0
  50. data/lib/shipit/template_renderer_extension.rb +16 -0
  51. data/lib/shipit/version.rb +1 -1
  52. data/test/controllers/deploys_controller_test.rb +11 -0
  53. data/test/controllers/stacks_controller_test.rb +5 -0
  54. data/test/controllers/tasks_controller_test.rb +6 -0
  55. data/test/dummy/config/secrets.example.yml +4 -0
  56. data/test/dummy/config/secrets.yml +2 -0
  57. data/test/dummy/data/stacks/byroot/junk/production/deploys/83/bar.txt +2 -0
  58. data/test/dummy/data/stacks/byroot/junk/production/deploys/83/dkfdsf +0 -0
  59. data/test/dummy/data/stacks/byroot/junk/production/deploys/83/dskjfsd +0 -0
  60. data/test/dummy/data/stacks/byroot/junk/production/deploys/83/dslkjfjsdf +0 -0
  61. data/test/dummy/data/stacks/byroot/junk/production/deploys/83/plopfizz +0 -0
  62. data/test/dummy/data/stacks/byroot/junk/production/deploys/83/sd +0 -0
  63. data/test/dummy/data/stacks/byroot/junk/production/deploys/83/sdkfjsdf +1 -0
  64. data/test/dummy/data/stacks/byroot/junk/production/deploys/83/sdlfjsdfdsfj +0 -0
  65. data/test/dummy/data/stacks/byroot/junk/production/deploys/83/sdlkfjsdlkfjsdlkfjdsfsdfksdfjsldkfjsdlkfjsdf +0 -0
  66. data/test/dummy/data/stacks/byroot/junk/production/deploys/83/shipit.yml +32 -0
  67. data/test/dummy/data/stacks/byroot/junk/production/deploys/83/toto.txt +2 -0
  68. data/test/dummy/data/stacks/byroot/junk/production/git/bar.txt +1 -0
  69. data/test/dummy/data/stacks/byroot/junk/production/git/shipit.yml +6 -1
  70. data/test/dummy/data/stacks/byroot/test/production/git/README.md +1 -0
  71. data/test/dummy/db/development.sqlite3 +0 -0
  72. data/test/dummy/db/schema.rb +3 -1
  73. data/test/dummy/db/seeds.rb +6 -0
  74. data/test/dummy/db/test.sqlite3 +0 -0
  75. data/test/dummy/db/test.sqlite3-journal +0 -0
  76. data/test/fixtures/shipit/tasks.yml +11 -0
  77. data/test/models/commits_test.rb +1 -1
  78. data/test/models/deploys_test.rb +40 -0
  79. data/test/models/duration_test.rb +13 -0
  80. data/test/models/stacks_test.rb +3 -4
  81. data/test/unit/command_test.rb +14 -0
  82. data/vendor/assets/javascripts/clusterize.js +327 -0
  83. data/vendor/assets/javascripts/mousetrap-global-bind.js +43 -0
  84. data/vendor/assets/javascripts/mousetrap.js +1021 -0
  85. data/vendor/assets/javascripts/string_includes.js +14 -0
  86. data/vendor/assets/stylesheets/clusterize.css +27 -0
  87. metadata +100 -3
  88. data/app/assets/javascripts/task/sticky_element.js.coffee +0 -16
@@ -0,0 +1,97 @@
1
+ <% content_for :page_title do %>
2
+ Shipit
3
+ <% end %>
4
+
5
+ <div class="jumbotron bg-warning">
6
+ <div class="container">
7
+ <h1 class="display-4">Oops! You're not ready to ship just yet.</h1>
8
+ <p class="lead">
9
+ Shipit is missing some of the information it needs to work properly.
10
+ Once you've added the configuration, make sure you restart the Rails server.
11
+ </p>
12
+ </div>
13
+ </div>
14
+
15
+ <div class="container">
16
+ <section>
17
+ <header>
18
+ <h2>GitHub application</h2>
19
+ </header>
20
+
21
+ <% if Shipit.github_oauth_id.blank? || Shipit.github_oauth_secret.blank? %>
22
+ <p><%= missing_github_oauth_message %></p>
23
+ <% end %>
24
+ <p id="github_oauth_id">
25
+ ID:
26
+ <% if Shipit.github_oauth_id.present? %>
27
+ Success!
28
+ <% else %>
29
+ <span class="missing">
30
+ <%= missing_github_oauth_id_message %>
31
+ </span>
32
+ <% end %>
33
+ </p>
34
+
35
+ <p id="github_oauth_secret">
36
+ Secret:
37
+ <% if Shipit.github_oauth_secret.present? %>
38
+ Success!
39
+ <% else %>
40
+ <span class="missing">
41
+ <%= missing_github_oauth_secret_message %>
42
+ </span>
43
+ <% end %>
44
+ </p>
45
+ </section>
46
+
47
+ <section>
48
+ <header>
49
+ <h2>GitHub API</h2>
50
+ </header>
51
+
52
+ <p id="github_api">
53
+ Token:
54
+ <% if Shipit.github_api_credentials.present? %>
55
+ Success!
56
+ <% else %>
57
+ <span class="missing">
58
+ <%= missing_github_api_credentials_message %>
59
+ </span>
60
+ <% end %>
61
+ </p>
62
+ </section>
63
+
64
+ <section>
65
+ <header>
66
+ <h2>Redis</h2>
67
+ </header>
68
+
69
+ <p id="redis_url">
70
+ Redis:
71
+ <% if Shipit.redis_url.present? %>
72
+ Success!
73
+ <% else %>
74
+ <span class="missing">
75
+ <%= missing_redis_url_message %>
76
+ </span>
77
+ <% end %>
78
+ </p>
79
+ </section>
80
+
81
+ <section>
82
+ <header>
83
+ <h2>Host</h2>
84
+ </header>
85
+
86
+ <p id="host">
87
+ Host:
88
+ <% if Shipit.host.present? %>
89
+ Success!
90
+ <% else %>
91
+ <span class="missing">
92
+ <%= missing_host_message %>
93
+ </span>
94
+ <% end %>
95
+ </p>
96
+ </section>
97
+ </div>
@@ -0,0 +1,44 @@
1
+ <% content_for :page_title do %>
2
+ Create a stack
3
+ <% end %>
4
+
5
+ <div class='container'>
6
+ <section>
7
+ <header>
8
+ <h1>Create a stack</h1>
9
+ </header>
10
+ <%= form_for @stack do |f| %>
11
+ <fieldset class='form-group'>
12
+ <%= label_tag :stack_repo_owner, 'Repo' %>
13
+ <div class='input-group'>
14
+ <div class='input-group-addon'><%= Shipit.github_url %>/</div>
15
+ <%= f.text_field :repo_owner, placeholder: 'e.g. Shopify', required: true, class: 'form-control' %>
16
+ <div class='input-group-addon'>/</div>
17
+ <%= f.text_field :repo_name, placeholder: 'e.g. shipit-engine', required: true, pattern: "^[a-zA-Z0-9\-_\.]+$", class: 'form-control' %>
18
+ </div>
19
+ </fieldset>
20
+ <fieldset class='form-group'>
21
+ <%= f.label :branch %>
22
+ <%= f.text_field :branch, placeholder: 'master', class: 'form-control' %>
23
+ </fieldset>
24
+ <fieldset class='form-group'>
25
+ <%= f.label :environment %>
26
+ <%= f.text_field :environment, placeholder: 'production', class: 'form-control' %>
27
+ </fieldset>
28
+ <fieldset class='form-group'>
29
+ <%= f.label :deploy_url %>
30
+ <%= f.text_field :deploy_url, placeholder: 'https://', class: 'form-control' %>
31
+ <small class='text-muted'>Where is this stack deployed to?</small>
32
+ </fieldset>
33
+ <fieldset class='form-group checkbox'>
34
+ <%= label_tag :stack_ignore_ci do %>
35
+ <%= f.check_box :ignore_ci, class: 'checkbox' %>
36
+ Allow deploys regardless of CI status
37
+ <% end %>
38
+ </fieldset>
39
+ <fieldset>
40
+ <%= f.submit class: 'btn btn-primary' %>
41
+ </fieldset>
42
+ <% end %>
43
+ </section>
44
+ </div>
@@ -48,7 +48,7 @@
48
48
  </div>
49
49
  </header>
50
50
 
51
- <div class="main" data-layout-content>
51
+ <div class="main <%= content_for(:main_classes) %>" data-layout-content>
52
52
  <%= yield %>
53
53
  </div>
54
54
  </body>
@@ -0,0 +1,44 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en" data-controller="<%= controller_name %>" data-action="<%= action_name %>">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
6
+ <meta http-equiv="x-ua-compatible" content="ie=edge">
7
+ <title><%= [Shipit.app_name, @stack.try!(:repo_name)].compact.join(' - ') %></title>
8
+
9
+ <%= favicon_link_tag %>
10
+ <%= stylesheet_link_tag :shipit_bs, media: 'all' %>
11
+ <%= javascript_include_tag :shipit_bs %>
12
+
13
+ <%= csrf_meta_tags %>
14
+ </head>
15
+ <body>
16
+ <% flash.each do |name, msg| %>
17
+ <%= content_tag :div, msg, class: ["flash-#{name}", :flash] %>
18
+ <% end %>
19
+
20
+ <nav class="navbar navbar-fixed-top navbar-light bg-faded">
21
+ <%= link_to "Shipit", root_path, class: "navbar-brand" %>
22
+
23
+ <ul class="nav navbar-nav">
24
+ <li class="nav-item active">
25
+ <%= link_to "#", class: "nav-link" do %>
26
+ <%= yield :page_title %>
27
+ <% end %>
28
+ </li>
29
+ </ul>
30
+
31
+ <div class="pull-xs-right">
32
+ <%= link_to "Shipit v#{Shipit::VERSION}", "https://github.com/Shopify/shipit-engine/tree/v#{Shipit::VERSION}" %>
33
+ </div>
34
+
35
+ <div class="container pull-xs-right">
36
+ <%= yield :primary_navigation %>
37
+ </div>
38
+ </nav>
39
+
40
+ <div class="main">
41
+ <%= yield %>
42
+ </div>
43
+ </body>
44
+ </html>
@@ -5,13 +5,14 @@
5
5
  <span class="commit-title"><%= render_commit_message_with_link commit %></span>
6
6
  <p class="commit-meta">
7
7
  <span class="sha"><%= render_commit_id_link(commit) %></span>
8
- <%= timeago_tag(commit.committed_at, force: true) %>
9
- <span class="utc-timecode">at <%= commit.committed_at.strftime('%H:%M:%S') %> UTC</span>
10
8
  <% if commit.additions? && commit.deletions? %>
11
9
  <span class="code-additions">+<%= commit.additions %></span>
12
10
  <span class="code-deletions">-<%= commit.deletions %></span>
13
11
  <% end %>
14
12
  </p>
13
+ <p class="commit-meta">
14
+ <%= timeago_tag(commit.committed_at, force: true) %>
15
+ </p>
15
16
  </div>
16
17
  <div class="commit-actions">
17
18
  <%= deploy_button(commit) %>
@@ -13,12 +13,21 @@
13
13
  </a>
14
14
  </span>
15
15
  <p class="commit-meta">
16
+ <%= deploy.rollback? ? 'rolled back' : 'deployed' %>
16
17
  <span class="sha"><%= link_to_github_deploy(deploy) %></span>
17
- <%= deploy.rollback? ? 'rolled back' : 'deployed' %> <%= timeago_tag(deploy.created_at, force: true) %>
18
- <span class="utc-timecode">at <%= deploy.created_at.strftime('%H:%M:%S') %> UTC</span>
19
18
  <span class="code-additions">+<%= deploy.additions %></span>
20
19
  <span class="code-deletions">-<%= deploy.deletions %></span>
21
20
  </p>
21
+ <p class="commit-meta">
22
+ <% if read_only %>
23
+ <span class="utc-timecode">on <%= deploy.created_at.strftime('%Y-%m-%d %H:%M:%S') %> UTC</span>
24
+ <% else %>
25
+ <%= timeago_tag(deploy.created_at, force: true) %>
26
+ <% end %>
27
+ <% if deploy.duration? %>
28
+ in <%= deploy.duration %>
29
+ <% end %>
30
+ </p>
22
31
  </div>
23
32
  <% unless read_only %>
24
33
  <div class="commit-actions">
@@ -5,7 +5,7 @@
5
5
  deploying
6
6
  <% end %>
7
7
  <span class="short-sha"><%= render_commit_id_link(@deploy.until_commit) %></span>
8
- <%= timeago_tag(@deploy.created_at, force: true) %> at <%= @deploy.created_at %>
8
+ <%= timeago_tag(@deploy.created_at, force: true) %>
9
9
  <% end %>
10
10
 
11
11
  <%= render partial: 'shipit/tasks/task_output', locals: {task: @deploy} %>
@@ -6,7 +6,7 @@
6
6
  <section>
7
7
  <div class="setting-section">
8
8
  <%= form_for @stack do |f| %>
9
- <p>
9
+ <div class="field-wrapper">
10
10
  <%= label_tag "Repo" %>
11
11
  <br>
12
12
  <%= Shipit.github_url %>
@@ -14,25 +14,25 @@
14
14
  <%= f.text_field :repo_owner, placeholder: 'e.g. Shopify', required: true, class: "repo" %>
15
15
  /
16
16
  <%= f.text_field :repo_name, required: true, pattern: "^[a-zA-Z0-9\-_\.]+$", class: "repo" %>
17
- </p>
18
- <p>
17
+ </div>
18
+ <div class="field-wrapper">
19
19
  <%= f.label :branch %>
20
20
  <%= f.text_field :branch, placeholder: 'master' %>
21
- </p>
22
- <p>
21
+ </div>
22
+ <div class="field-wrapper">
23
23
  <%= f.label :environment %>
24
24
  <%= f.text_field :environment, placeholder: 'production' %>
25
- </p>
26
- <p>
25
+ </div>
26
+ <div class="field-wrapper">
27
27
  <%= f.label :deploy_url %>
28
+ <span class="form-hint"><small>Where is this stack deployed to?</small></span>
28
29
  <%= f.text_field :deploy_url, placeholder: 'https://' %>
29
- <span class="form-hint">Where is this stack deployed to?</span>
30
- </p>
31
- <p>
30
+ </div>
31
+ <div class="field-wrapper">
32
32
  <%= f.check_box :ignore_ci %>
33
33
  <%= f.label :ignore_ci, "Allow deploys regardless of CI status" %>
34
- </p>
35
- <p><%= f.submit class: 'btn' %></p>
34
+ </div>
35
+ <div class="field-wrapper"><%= f.submit class: 'btn' %></div>
36
36
  <% end %>
37
37
  </div>
38
38
  </section>
@@ -8,6 +8,11 @@
8
8
 
9
9
  <div class="setting-section">
10
10
  <%= form_for @stack do |f| %>
11
+ <div class="field-wrapper">
12
+ <%= f.label :environment %>
13
+ <%= f.text_field :environment, placeholder: 'production' %>
14
+ </div>
15
+
11
16
  <div class="field-wrapper">
12
17
  <%= f.label :deploy_url, 'Deploy URL (Where is this stack deployed to?)' %>
13
18
  <%= f.text_field :deploy_url, placeholder: 'https://' %>
@@ -42,7 +42,7 @@
42
42
  Deploys are locked by <%= @stack.lock_author.name %>
43
43
  </h2>
44
44
  <p class="banner__text">
45
- <%= auto_link @stack.lock_reason %>
45
+ <%= auto_link emojify(@stack.lock_reason) %>
46
46
  </p>
47
47
  </div>
48
48
  </div>
@@ -1,3 +1,5 @@
1
+ <%- read_only ||= false -%>
2
+
1
3
  <li class="task" id="task-<%= task.id %>" data-status="<%= task.status %>">
2
4
  <%= render 'shipit/commits/commit_author', commit: task %>
3
5
  <a href="<%= stack_task_path(@stack, task) %>" class="status status--<%= task.status %>" data-tooltip="<%= task.status.capitalize %>">
@@ -12,8 +14,14 @@
12
14
  </a>
13
15
  </span>
14
16
  <p class="commit-meta">
15
- ran a command <%= timeago_tag(task.created_at, force: true) %>
16
- <span class="utc-timecode">at <%= task.created_at.strftime('%H:%M:%S') %> UTC</span>
17
+ ran a command
18
+ </p>
19
+ <p class="commit-meta">
20
+ <% if read_only %>
21
+ <span class="utc-timecode">on <%= task.created_at.strftime('%Y-%m-%d %H:%M:%S') %> UTC</span>
22
+ <% else %>
23
+ <%= timeago_tag(task.created_at, force: true) %>
24
+ <% end %>
17
25
  </p>
18
26
  </div>
19
27
  </li>
@@ -1,3 +1,5 @@
1
+ <% content_for :main_classes do %>no-footer<% end %>
2
+
1
3
  <%= javascript_include_tag 'task' %>
2
4
  <%= include_plugins(@stack) %>
3
5
  <%= render partial: 'shipit/stacks/header', locals: { stack: @stack } %>
@@ -9,6 +11,7 @@
9
11
  <div class="deploy-main" data-task="<%= {repo: @stack.github_repo_name, description: task_description(task)}.to_json %>">
10
12
  <span class="deploy-tasks"></span>
11
13
  <div class="deploy-banner" data-status="<%= task.status %>">
14
+ <div class="deploy-banner-status"></div>
12
15
  <div class="deploy-banner-section stack-link">
13
16
  <%= link_to "Return to #{@stack.repo_name}/#{@stack.environment}", stack_path(@stack) %>
14
17
  </div>
@@ -17,6 +20,7 @@
17
20
  <span class="deploy-status">
18
21
  <%= content_for :task_title %>
19
22
  </span>
23
+ <%= link_to('(view raw output)', { format: :txt }) %>
20
24
  </div>
21
25
 
22
26
  <div class="deploy-banner-section action-buttons">
@@ -34,5 +38,11 @@
34
38
  </div>
35
39
  </div>
36
40
 
37
- <pre class="nowrap" data-status="<%= task.status %>"><code data-next-chunks-url="<%= next_chunks_url(task) %>"><%= task.chunk_output %></code></pre>
41
+ <div class="search-bar hidden">
42
+ <input type="search" class="search-input" />
43
+ </div>
44
+
45
+ <div class="clusterize-scroll task-output-container">
46
+ <pre class="nowrap" data-status="<%= task.status %>"><code class="clusterize-content" data-output="<%= task.chunk_output %>" data-next-chunks-url="<%= next_chunks_url(task) %>"></code></pre>
47
+ </div>
38
48
  </div>
@@ -1,6 +1,6 @@
1
1
  <% content_for :task_title do %>
2
2
  executing <%= @task.definition.id %>
3
- <%= timeago_tag(@task.created_at, force: true) %> at <%= @task.created_at %>
3
+ <%= timeago_tag(@task.created_at, force: true) %>
4
4
  <% end %>
5
5
 
6
6
  <%= render partial: 'shipit/tasks/task_output', locals: {task: @task} %>
data/config/routes.rb CHANGED
@@ -85,4 +85,5 @@ Shipit::Engine.routes.draw do
85
85
  end
86
86
  end
87
87
  end
88
+ get '/stacks/:id' => 'stacks#lookup'
88
89
  end
@@ -0,0 +1,25 @@
1
+ class AddStartedAtAndEndedAtOnTasks < ActiveRecord::Migration
2
+ def up
3
+ add_column :tasks, :started_at, :datetime, null: true
4
+ add_column :tasks, :ended_at, :datetime, null: true
5
+
6
+ say "Migrating #{Shipit::Task.count} tasks:"
7
+ Shipit::Task.find_each.with_index do |task, index|
8
+ unless task.started_at
9
+ task.update_columns(
10
+ started_at: task.created_at,
11
+ ended_at: task.updated_at, # good enough approximation but not perfect
12
+ )
13
+ puts if index % 100 == 0
14
+ print '.'
15
+ end
16
+ end
17
+ puts
18
+ say "Done"
19
+ end
20
+
21
+ def down
22
+ remove_column :tasks, :started_at
23
+ remove_column :tasks, :ended_at
24
+ end
25
+ end
data/lib/shipit.rb CHANGED
@@ -10,9 +10,11 @@ require 'sass-rails'
10
10
  require 'coffee-rails'
11
11
  require 'jquery-rails'
12
12
  require 'rails-timeago'
13
+ require 'lodash-rails'
13
14
  require 'ansi_stream'
14
15
  require 'autoprefixer-rails'
15
16
  require 'rails_autolink'
17
+ require 'gemoji'
16
18
 
17
19
  require 'omniauth-github'
18
20
 
@@ -27,6 +29,9 @@ require 'octokit'
27
29
  require 'faraday-http-cache'
28
30
 
29
31
  require 'shipit/version'
32
+
33
+ require 'shipit/template_renderer_extension'
34
+
30
35
  require 'shipit/paginator'
31
36
  require 'shipit/null_serializer'
32
37
  require 'shipit/csv_serializer'
@@ -171,6 +176,14 @@ module Shipit
171
176
  end
172
177
  end
173
178
 
179
+ def feature_bootstrap?
180
+ secrets.features.try!(:include?, 'bootstrap')
181
+ end
182
+
183
+ def bootstrap_view_path
184
+ @bootstrap_view_path ||= Engine.root.join('app/views/bootstrap')
185
+ end
186
+
174
187
  protected
175
188
 
176
189
  def revision_file