poise-boiler 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,24 @@
1
+ #
2
+ # Copyright 2015, Noah Kantrowitz
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+
18
+ module PoiseBoiler
19
+ # Base class for poise-boiler errors.
20
+ #
21
+ # @since 1.0.0
22
+ class Error < Exception
23
+ end
24
+ end
@@ -0,0 +1,26 @@
1
+ #
2
+ # Copyright 2015, Noah Kantrowitz
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+
18
+ module PoiseBoiler
19
+ # Module for helper classes of various forms.
20
+ #
21
+ # @since 1.0.0
22
+ module Helpers
23
+ autoload :Rake, 'poise_boiler/helpers/rake'
24
+ autoload :SpecHelper, 'poise_boiler/helpers/spec_helper'
25
+ end
26
+ end
@@ -0,0 +1,43 @@
1
+ #
2
+ # Copyright 2015, Noah Kantrowitz
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require 'halite/helper_base'
18
+
19
+
20
+ module PoiseBoiler
21
+ module Helpers
22
+ # Helper for a Rakefile to install common tasks for the Poise workflow.
23
+ #
24
+ # @since 1.0.0
25
+ # @see Badges
26
+ # @see Core
27
+ # @see Travis
28
+ class Rake < Halite::HelperBase
29
+ autoload :Badges, 'poise_boiler/helpers/rake/badges'
30
+ autoload :Core, 'poise_boiler/helpers/rake/core'
31
+ autoload :Travis, 'poise_boiler/helpers/rake/travis'
32
+
33
+ # Install all rake tasks.
34
+ #
35
+ # @return [void]
36
+ def install(*args)
37
+ Core.install(*args)
38
+ Badges.install(*args)
39
+ Travis.install(*args)
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,124 @@
1
+ #
2
+ # Copyright 2015, Noah Kantrowitz
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require 'addressable/uri'
18
+ require 'halite/gem'
19
+ require 'halite/helper_base'
20
+ require 'mixlib/shellout'
21
+
22
+
23
+ module PoiseBoiler
24
+ module Helpers
25
+ class Rake
26
+ # Helper for a Rakefile to add a `badges` command. This command will print
27
+ # out README badges suitable for use on GitHub.
28
+ #
29
+ # @since 1.0.0
30
+ # @example Installing tasks
31
+ # require 'poise_boiler/helpers/rake/badges'
32
+ # PoiseBoiler::Helpers::Rake::Badges.install
33
+ # @example Creating badges
34
+ # $ rake badges >> README.md
35
+ class Badges < Halite::HelperBase
36
+ # Install the `badges` rake task.
37
+ #
38
+ # @return [void]
39
+ def install
40
+ # Delayed so that Rake doesn't need to be loaded to run this file.
41
+ extend ::Rake::DSL
42
+
43
+ desc "Generate README badges for #{gemspec.name}"
44
+ task 'badges' do
45
+ shell.say(generate_badges)
46
+ end
47
+ end
48
+
49
+ private
50
+
51
+ # Generate badges as a string.
52
+ #
53
+ # @return [String]
54
+ def generate_badges
55
+ # Example badges
56
+ # [![Build Status](https://img.shields.io/travis/poise/poise.svg)](https://travis-ci.org/poise/poise)
57
+ # [![Gem Version](https://img.shields.io/gem/v/poise.svg)](https://rubygems.org/gems/poise)
58
+ # [![Cookbook Version](https://img.shields.io/cookbook/v/poise.svg)](https://supermarket.chef.io/cookbooks/poise)
59
+ # [![Code Climate](https://img.shields.io/codeclimate/github/poise/poise.svg)](https://codeclimate.com/github/poise/poise)
60
+ # [![Coverage](https://img.shields.io/codecov/c/github/poise/poise.svg)](https://codecov.io/github/poise/poise)
61
+ # [![Gemnasium](https://img.shields.io/gemnasium/poise/poise.svg)](https://gemnasium.com/poise/poise)
62
+ # [![License](https://img.shields.io/badge/license-Apache_2-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0)
63
+ ''.tap do |badges|
64
+ github = options[:github] || detect_github
65
+ badges << badge('Build Status', "travis/#{github}", "https://travis-ci.org/#{github}") if github
66
+ badges << badge('Gem Version', "gem/v/#{gemspec.name}", "https://rubygems.org/gems/#{gemspec.name}")
67
+ badges << badge('Cookbook Version', "cookbook/v/#{cookbook.cookbook_name}", "https://supermarket.chef.io/cookbooks/#{cookbook.cookbook_name}") if cookbook.is_halite_cookbook?
68
+ badges << badge('Code Climate', "codeclimate/github/#{github}", "https://codeclimate.com/github/#{github}") if github
69
+ badges << badge('Coverage', "codecov/c/github/#{github}", "https://codecov.io/github/#{github}") if github
70
+ badges << badge('Gemnasium', "gemnasium/#{github}", "https://gemnasium.com/#{github}") if github
71
+ badges << badge('License', 'badge/license-Apache_2-blue', 'https://www.apache.org/licenses/LICENSE-2.0')
72
+ end
73
+ end
74
+
75
+ # Create a single badge string.
76
+ #
77
+ # @param alt [String] Alt text for the badge.
78
+ # @param img [String] Image URI. If just a relative path is givenm it
79
+ # will be a Shields.io image.
80
+ # @param href [String] URI to link to.
81
+ # @return [String]
82
+ def badge(alt, img, href)
83
+ # Default scheme and hostname because I can.
84
+ img = "https://img.shields.io/#{img}.svg" unless Addressable::URI.parse(img).host
85
+ "[![#{alt}](#{img})](#{href})\n"
86
+ end
87
+
88
+ # Find the GitHub user/org and repository name for this repository.
89
+ # Based on travis.rb https://github.com/travis-ci/travis.rb/blob/23ea1d2f34231a50a475b4ee8d19fa15b1d6b0e3/lib/travis/cli/repo_command.rb#L65
90
+ # Copyright (c) 2014-2015 Travis CI GmbH <support@travis-ci.com>
91
+ #
92
+ # @return [String, nil]
93
+ def detect_github
94
+ git_head = git_shell_out(%w{name-rev --name-only HEAD})
95
+ return nil unless git_head
96
+ git_remote = git_shell_out(%W{config --get branch.#{git_head}.remote})
97
+ git_remote = 'origin' if !git_remote || git_remote.empty? # Default value
98
+ git_info = git_shell_out(%w{ls-remote --get-url}+[git_remote])
99
+ git_regex = %r{/?(.*/.+?)(\.git)?$}
100
+ if md = Addressable::URI.parse(git_info).path.match(git_regex)
101
+ md[1]
102
+ else
103
+ # Unable to auto-detect
104
+ nil
105
+ end
106
+ end
107
+
108
+ # Run a git command and return the output.
109
+ #
110
+ # @param cmd [Array<String>] Command arguments to pass to git.
111
+ # @return [String, nil]
112
+ def git_shell_out(cmd)
113
+ cmd = Mixlib::ShellOut.new(['git']+cmd, cwd: base)
114
+ cmd.run_command
115
+ if cmd.error?
116
+ nil
117
+ else
118
+ cmd.stdout.strip
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,71 @@
1
+ #
2
+ # Copyright 2015, Noah Kantrowitz
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require 'halite/helper_base'
18
+
19
+
20
+ module PoiseBoiler
21
+ module Helpers
22
+ class Rake
23
+ # Helper for a Rakefile to install some standard tasks used by most
24
+ # Poise/Halite-style gems.
25
+ #
26
+ # @since 1.0.0
27
+ # @example Installing tasks
28
+ # require 'poise_boiler/helpers/rake/core'
29
+ # PoiseBoiler::Helpers::Rake::Core.install
30
+ # @example Running tests
31
+ # $ rake test
32
+ class Core < Halite::HelperBase
33
+ # Install the rake tasks.
34
+ #
35
+ # @return [void]
36
+ def install
37
+ # Delayed so that Rake doesn't need to be loaded to run this file.
38
+ extend ::Rake::DSL
39
+
40
+ # Set the default task.
41
+ task default: %i{test}
42
+
43
+ # Create the spec task.
44
+ require 'rspec/core/rake_task'
45
+ RSpec::Core::RakeTask.new(:spec, :tag) do |t, args|
46
+ t.rspec_opts = [].tap do |a|
47
+ a << '--color'
48
+ a << "--format #{ENV['CI'] ? 'documentation' : 'Fuubar'}"
49
+ a << '--backtrace' if ENV['DEBUG']
50
+ a << "--seed #{ENV['SEED']}" if ENV['SEED']
51
+ a << "--tag #{args[:tag]}" if args[:tag]
52
+ a << "--default-path test"
53
+ a << '-I test/spec'
54
+ end.join(' ')
55
+ end
56
+
57
+ # Create the test task (which Halite will extend).
58
+ task test: %i{spec}
59
+
60
+ # Install gem tasks (build, upload, etc).
61
+ require 'bundler/gem_helper'
62
+ Bundler::GemHelper.install_tasks(options[:bundler] || {})
63
+
64
+ # Install the Halite tasks.
65
+ require 'halite/rake_helper'
66
+ Halite::RakeHelper.install(options)
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,132 @@
1
+ #
2
+ # Copyright 2015, Noah Kantrowitz
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require 'halite/helper_base'
18
+
19
+
20
+ module PoiseBoiler
21
+ module Helpers
22
+ class Rake
23
+ # Helper for a Rakefile to install a task for testing on CI.
24
+ #
25
+ # @since 1.0.0
26
+ # @example Installing tasks
27
+ # require 'poise_boiler/helpers/rake/travis'
28
+ # PoiseBoiler::Helpers::Rake::Travis.install
29
+ # @example Running CI suite
30
+ # $ rake travis
31
+ class Travis < Halite::HelperBase
32
+ # Install the rake tasks.
33
+ #
34
+ # @return [void]
35
+ def install
36
+ # Delayed so that Rake doesn't need to be loaded to run this file.
37
+ extend ::Rake::DSL
38
+
39
+ file 'test/docker/docker.key' do
40
+ sh 'openssl rsa -in test/docker/docker.pem -passin env:KITCHEN_DOCKER_PASS -out test/docker/docker.key'
41
+ end
42
+
43
+ file './docker' do
44
+ sh 'wget https://get.docker.io/builds/Linux/x86_64/docker-latest -O docker'
45
+ File.chmod(0755, './docker')
46
+ end
47
+
48
+ desc 'Run Test-Kitchen integration tests.'
49
+ task 'travis:integration' => %w{test/docker/docker.key ./docker} do
50
+ sh './bin/kitchen test -d always'
51
+ end
52
+
53
+ desc 'Run CI tests'
54
+ task 'travis' do
55
+ run_subtask('spec')
56
+ run_subtask('chef:foodcritic')
57
+ run_subtask('travis:integration') if integration_tests?
58
+ end
59
+ end
60
+
61
+ private
62
+
63
+ # Should we run integration tests?
64
+ #
65
+ # @return [Boolean]
66
+ def integration_tests?
67
+ ENV['TRAVIS_SECURE_ENV_VARS'] && !ENV['TRAVIS_SECURE_ENV_VARS'].empty? && !ENV['BUNDLE_GEMFILE'].to_s.include?('master')
68
+ end
69
+
70
+ # Convert a Time object to nanoseconds since the epoch.
71
+ #
72
+ # @param t [Time] Time object to convert.
73
+ # @return [Integer]
74
+ def time_nanoseconds(t)
75
+ (t.tv_sec * 1000000000) + t.nsec
76
+ end
77
+
78
+ # Wrap a block in Travis-CI timer tags. These are read by the web UI
79
+ # to nicely format timing information.
80
+ #
81
+ # @param block [Proc] Block to time.
82
+ # @return [void]
83
+ def travis_timer(&block)
84
+ begin
85
+ start_time = time_nanoseconds(Time.now)
86
+ timer_id = '%08x' % Random.rand(0xFFFFFFFF)
87
+ shell.say("travis_time:start:#{timer_id}")
88
+ block.call
89
+ ensure
90
+ end_time = time_nanoseconds(Time.now)
91
+ shell.say("travis_time:end:#{timer_id}:start=#{start_time},finish=#{end_time},duration=#{end_time - start_time}")
92
+ end
93
+ end
94
+
95
+ # Wrap a block in Travis-CI fold tags. These are read bu the web UI to
96
+ # allow hiding sections of output.
97
+ #
98
+ # @param name [String] Name of the fold block.
99
+ # @param block [Proc] Block to fold.
100
+ # @return [void]
101
+ def travis_fold(name, &block)
102
+ begin
103
+ shell.say("travis_fold:start:#{name}")
104
+ block.call
105
+ ensure
106
+ shell.say("travis_fold:end:#{name}")
107
+ end
108
+ end
109
+
110
+ # Decorate a Rake subtask for Travis.
111
+ #
112
+ # @param name [String] Task to run.
113
+ # @return [void]
114
+ def run_subtask(name)
115
+ travis_timer do
116
+ begin
117
+ shell.say("Running task #{name}")
118
+ task(name).invoke
119
+ shell.say("Task #{name} succeeded.", :green)
120
+ rescue StandardError => ex
121
+ shell.say("Task #{name} failed with #{ex}:", :red)
122
+ travis_fold "#{name}.backtrace" do
123
+ shell.say(ex.backtrace.map{|line| ' '+line }.join("\n"), :red)
124
+ end
125
+ end
126
+ end
127
+ end
128
+
129
+ end
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,79 @@
1
+ #
2
+ # Copyright 2015, Noah Kantrowitz
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require 'halite/helper_base'
18
+
19
+
20
+ module PoiseBoiler
21
+ module Helpers
22
+ # Helper for a spec_helper.rb to configure things for the Poise workflow.
23
+ # This configures rspec, rspec-its, simplecov (with codeclimate and codecov
24
+ # if possible), and the Halite spec helper.
25
+ #
26
+ # @since 1.0.0
27
+ class SpecHelper < Halite::HelperBase
28
+ def install
29
+ require 'rspec'
30
+ require 'rspec/its'
31
+ require 'simplecov'
32
+
33
+ # Check for coverage stuffs
34
+ formatters = []
35
+ if ENV['CODECLIMATE_REPO_TOKEN']
36
+ require 'codeclimate-test-reporter'
37
+ formatters << CodeClimate::TestReporter::Formatter
38
+ end
39
+
40
+ if ENV['CODECOV_TOKEN'] || ENV['TRAVIS']
41
+ require 'codecov'
42
+ formatters << SimpleCov::Formatter::Codecov
43
+ end
44
+
45
+ unless formatters.empty?
46
+ SimpleCov.formatters = formatters
47
+ end
48
+
49
+ SimpleCov.start do
50
+ # Don't get coverage on the test cases themselves.
51
+ add_filter '/spec/'
52
+ add_filter '/test/'
53
+ # Codecov doesn't automatically ignore vendored files.
54
+ add_filter '/vendor/'
55
+ end
56
+
57
+ RSpec.configure do |config|
58
+ # Basic configuraiton
59
+ config.run_all_when_everything_filtered = true
60
+ config.filter_run(:focus)
61
+
62
+ # Run specs in random order to surface order dependencies. If you find an
63
+ # order dependency and want to debug it, you can fix the order by providing
64
+ # the seed, which is printed after each run.
65
+ # --seed 1234
66
+ config.order = 'random'
67
+
68
+ unless options['no_halite']
69
+ require 'halite/spec_helper'
70
+ config.include Halite::SpecHelper(gem_name ? gemspec : nil)
71
+ # Hide the spec helper from RSpec traces by default.
72
+ config.backtrace_exclusion_patterns << %r{/halite/spec_helper}
73
+ end
74
+ end
75
+ end # /def install
76
+
77
+ end
78
+ end
79
+ end