gem_of 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: c50cb7ac955ec40f5ffa86ce19a3955aa88bc16f125565df68a2d3c892360b13
4
+ data.tar.gz: 8ba2454ec1cb3d326daf0cfc90614ebee730dafe8d606ce440c9c1cc10b229a4
5
+ SHA512:
6
+ metadata.gz: 2534b4fb0769aa54e7b2c93edafc2085424570260ff4a4b163c326cce5ef963c001f8a70957b08c0cf0449b8ce6c59eb1a30bcd1af20f899247fc4cb43b4635e
7
+ data.tar.gz: 5d5f54a74993363cb1da4704af68f4b74312adc24a96d97a5a04023a94c03beb6ac1852a5be4e316b2d77e29edd98a3dfdc2a7deefc4e9ebd569d1bfa3b978ae
data/README.md ADDED
@@ -0,0 +1,58 @@
1
+ # gem_of
2
+ Gem testing gems, rake tasks
3
+
4
+ Gemfiles are typically used solely for gems in development and testing. Are you tired of copypastaing the same Gems and rake tasks around to various projects, only to have to update them all later?
5
+
6
+ use the gem_of gems!
7
+
8
+ we bring you:
9
+
10
+ rake, rototiller, rspec, rubocop, simplecov, yardstick, markdown, flay, flog, roodi, rubycritic, and coveralls for all your dev and unit testing needs.
11
+
12
+ we bring you: beaker for your system testing needs, AND we ensure the bundle will install consistently across ruby versions by pinning old dependencies that don't seem to like following semver rules.
13
+
14
+ later we'll supply a bunch of canned rake tasks to bring this all together from the CLI or CI (see our Rakefile)
15
+
16
+ ## currently installed gems
17
+
18
+ * [rake](https://github.com/ruby/rake): "A make-like build utility for Ruby."
19
+ * [rototiller](https://github.com/puppetlabs/rototiller): "A Rake helper library for command-oriented tasks."
20
+ * [rspec](http://rspec.info/): "Behaviour Driven Development for Ruby."
21
+ * [rubocop](https://github.com/bbatsov/rubocop): "A Ruby static code analyzer, based on the community Ruby style guide."
22
+ * [simplecov](https://github.com/colszowka/simplecov): "Code coverage for Ruby 1.9+ with a powerful configuration library and automatic merging of coverage across test suites."
23
+ * [yardstick](https://github.com/dkubb/yardstick): "A tool for verifying YARD documentation coverage."
24
+ * [markdown](https://en.wikipedia.org/wiki/Markdown): "A lightweight markup language with plain text formatting syntax."
25
+ * [flay](https://github.com/seattlerb/flay): "Flay analyzes code for structural similarities."
26
+ * [flog](https://github.com/seattlerb/flog): "Flog reports the most tortured code in an easy to read pain report."
27
+ * [roodi](https://github.com/roodi/roodi): "Ruby Object Oriented Design Inferometer"
28
+ * [rubycritic](https://github.com/whitesmith/rubycritic): "A Ruby code quality reporter."
29
+ * [coveralls](https://docs.coveralls.io/): "Coveralls is a web service to help you track your code coverage over time, and ensure that all your new code is fully covered."
30
+
31
+ ## locally install this gem
32
+ you can't put this in your Gemfile, because we need to use it to form your Gemfile
33
+ ```
34
+ gem install --local gem_of
35
+ ```
36
+ or:
37
+ ```
38
+ clone git@github.com:puppetlabs/gem_of.git
39
+ cd gem_of
40
+ bundle install
41
+ bundle exec rake gem:build
42
+ bundle exec rake gem:install:local
43
+ ```
44
+
45
+ ## In your Gemfile
46
+ ```
47
+ require 'gem_of'
48
+
49
+ eval(GemOf::Gems.new, binding)
50
+ ```
51
+
52
+ ## In your Rakefile
53
+ gem_of distributes itself into your Gemfile, so if it's installed locally, as above, then the bundle for your other project will have it, and the rake tasks:
54
+ ```
55
+ require "gem_of/rake_tasks"
56
+
57
+ GemOf::RakeTasks.new
58
+ ```
data/lib/gem_of.rb ADDED
@@ -0,0 +1,112 @@
1
+ require "rubygems" # for Gem Versioning methods
2
+
3
+ # Namespace for Gem methods
4
+ module GemOf
5
+ # produce a list of gems for use in a gems Gemfile
6
+ # @return [String] a string of Gemfile dependencies for a Gemfile to eval
7
+ # @example eval this in your Gemfile in its binding
8
+ # eval(GemOf.gems, binding)
9
+ # @api public
10
+ class Gems
11
+ def initialize
12
+ set_gem_versions
13
+
14
+ @gem_code = <<-HEREDOC
15
+ source "https://rubygems.org"
16
+ # place all development, system_test, etc dependencies here
17
+
18
+ # lint/unit tests
19
+ gem "rake"
20
+ gem "gem_of" # ensure downstream projects get gem_of for rake tasks
21
+ gem "rototiller", "~> 1.0"
22
+ gem "rspec", "~> 3.4.0"
23
+ gem "rubocop", "~> 0.49.1" # used in tests. pinned
24
+ gem "simplecov", "~> 0.14.0" # used in tests
25
+ gem "yardstick", "~> 0.9.0" # used in tests
26
+ gem "markdown", "~> 0"
27
+ gem "flay", "~> 2.10.0" # used in tests
28
+ gem "flog", "~> 4.6.0" # used in tests
29
+ gem "roodi", "~> 5.0.0" # used in tests
30
+ gem "rubycritic"
31
+ gem "coveralls", require: false # used in tests
32
+
33
+ group :system_tests do
34
+ gem "beaker", GemOf.location_of(ENV["BEAKER_VERSION"] ||
35
+ "#{@beaker_version}")
36
+ gem "beaker-hostgenerator"
37
+ gem "beaker-abs", GemOf.location_for(ENV["BEAKER_ABS_VERSION"] ||
38
+ "~> 0.2")
39
+ gem "nokogiri" ,"#{@nokogiri_version}"
40
+ gem "public_suffix" ,"#{@public_suffix_version}"
41
+ #gem "activesupport" ,"#{@activesupport_version}"
42
+ end
43
+
44
+ local_gemfile = "Gemfile.local"
45
+ if File.exists? local_gemfile
46
+ eval(File.read(local_gemfile), binding)
47
+ end
48
+
49
+ user_gemfile = File.join(Dir.home,".Gemfile")
50
+ if File.exists? user_gemfile
51
+ eval(File.read(user_gemfile), binding)
52
+ end
53
+ HEREDOC
54
+ end
55
+
56
+ # output the gem_code of this class as a string
57
+ # implements both #to_str and #to_s for implicit conversions
58
+ # @return [String] of our gem_code
59
+ # @api public
60
+ def to_str
61
+ @gem_code
62
+ end
63
+ alias to_s to_str
64
+
65
+ private
66
+
67
+ # rubocop:disable Metrics/MethodLength
68
+ # Set instance params for the various gem versions we need based upon ruby
69
+ # should really only be used in above, will change, over time
70
+ # @api private
71
+ def set_gem_versions
72
+ # restrict gems to enable ruby versions
73
+
74
+ @public_suffix_version = "~> 1" # any
75
+ @activesupport_version = "~> 1" # any
76
+ # nokogiri comes along for the ride but needs some restriction too
77
+ if Gem::Version.new(RUBY_VERSION).between?(Gem::Version.new("2.1.6"),
78
+ Gem::Version.new("2.2.4"))
79
+ @beaker_version = "< 3.9.0"
80
+ @nokogiri_version = "< 1.7.0"
81
+ elsif Gem::Version.new(RUBY_VERSION).between?(Gem::Version.new("2.0.0"),
82
+ Gem::Version.new("2.1.5"))
83
+ @beaker_version = "< 3.1.0"
84
+ @nokogiri_version = "< 1.7.0"
85
+ else
86
+ @beaker_version = "~> 3.0"
87
+ @nokogiri_version = "~> 1" # any
88
+ end
89
+ end
90
+ end
91
+
92
+ # string for use as parameter to the #gem method
93
+ # @return [String] string for use as parameter to the #gem method
94
+ # forms file or git urls, typically from user env_vars
95
+ # @param place [String] location string from an env_var
96
+ # @param fake_version [String] uh... a git sha?
97
+ # @api public
98
+ # @example
99
+ # gem "beaker", GemOf.location_of(ENV["BEAKER_VERSION"] || "~> 1")
100
+ def location_of(place, fake_version = nil)
101
+ if place =~ /^(git:[^#]*)#(.*)/
102
+ [fake_version, { git: Regexp.last_match[1],
103
+ branch: Regexp.last_match[2] }].compact
104
+ elsif place =~ %r{^file:\/\/(.*)}
105
+ [">= 0", { path: File.expand_path(Regexp.last_match[1]) }]
106
+ else
107
+ [place]
108
+ end
109
+ end
110
+ alias location_for location_of # reverse compat
111
+ module_function :location_for, :location_of
112
+ end
@@ -0,0 +1,226 @@
1
+ require "fileutils"
2
+ require "rototiller"
3
+ require "yard"
4
+ require "rubocop/rake_task"
5
+ require "flog_task"
6
+ require "flay_task"
7
+ require "roodi_task"
8
+ require "rubycritic/rake_task"
9
+
10
+ module GemOf
11
+ # a bunch of instances of other rake tasks
12
+ # @example create an instance of me in your rakefile
13
+ # GemOf::RakeTasks.new
14
+ # @api public
15
+ class RakeTasks
16
+ include Rake::DSL
17
+ # instance a bunch of our component rake tasks
18
+ # @api public
19
+ def initialize
20
+ task :default do
21
+ sh %(rake -T)
22
+ end
23
+ GemTasks.new
24
+ YardStickTasks.new
25
+ DocsTasks.new
26
+ LintTasks.new
27
+ TestTasks.new
28
+ end
29
+ end
30
+
31
+ # a class to hold the bundler provided "gem" tasks
32
+ # bund of gem build, clean, install, release tasks
33
+ class GemTasks
34
+ # instance bundler gemtasks in namespace :gem
35
+ # @api public
36
+ # @example GemTasks.new
37
+ include Rake::DSL if defined? Rake::DSL
38
+ def initialize
39
+ namespace :gem do
40
+ require "bundler/gem_tasks"
41
+ end
42
+ end
43
+ end
44
+
45
+ # a class to hold the yardstick provided yarddoc tasks
46
+ class YardStickTasks
47
+ include Rake::DSL if defined? Rake::DSL
48
+ # rubocop:disable Metrics/MethodLength
49
+ # instance yardstick tasks in namespace :docs
50
+ # @api public
51
+ # @example YardStackTasks.new
52
+ def initialize
53
+ namespace :docs do
54
+ desc "Measure YARD coverage. see yardstick/report.txt for output"
55
+ require "yardstick/rake/measurement"
56
+ Yardstick::Rake::Measurement.new(:measure) do |measurement|
57
+ measurement.output = "yardstick/report.txt"
58
+ end
59
+
60
+ desc "Verify YARD coverage"
61
+ require "yardstick/rake/verify"
62
+ config = { "require_exact_threshold" => false }
63
+ Yardstick::Rake::Verify.new(:verify, config) do |verify|
64
+ verify.threshold = 80
65
+ end
66
+ end
67
+ end
68
+ end
69
+
70
+ # various yarddoc docs tasks
71
+ # arch, clean, measure, undoc, verify, yard
72
+ class DocsTasks
73
+ include Rake::DSL if defined? Rake::DSL
74
+ # location of the yarddocs produced
75
+ YARD_DIR = "doc".freeze
76
+ # location of the human user docs (markdown, etc)
77
+ DOCS_DIR = "docs".freeze
78
+
79
+ # instance yardoc tasks in namespace :docs
80
+ # @api public
81
+ # @example DocsTasks.new
82
+ def initialize
83
+ namespace :docs do
84
+ # docs:yard task
85
+ YARD::Rake::YardocTask.new
86
+
87
+ desc "Clean/remove the generated YARD Documentation cache"
88
+ task :clean do
89
+ sh "rm -rf #{YARD_DIR}"
90
+ end
91
+
92
+ desc "Tell me about YARD undocumented objects"
93
+ YARD::Rake::YardocTask.new(:undoc) do |t|
94
+ t.stats_options = ["--list-undoc"]
95
+ end
96
+
97
+ desc "Generate static project architecture graph. (Calls docs:yard)"
98
+ # this calls `yard graph` so we can't use the yardoc tasks like above
99
+ # We could create a YARD:CLI:Graph object.
100
+ # But we have to send the output to the graphviz processor, etc.
101
+ task arch: [:yard] do
102
+ arch_diagram
103
+ end
104
+ end
105
+ end
106
+
107
+ private
108
+
109
+ # @private
110
+ def arch_diagram
111
+ original_dir = Dir.pwd
112
+ # this won't work all the time, and when it doesn't,
113
+ # it still says we created a class diagram
114
+ # FIXME: use Rake.application.original_dir
115
+ # Dir.chdir(File.expand_path(File.dirname(__FILE__)))
116
+ graph_processor = "dot"
117
+ if exe_exists?(graph_processor)
118
+ FileUtils.mkdir_p(DOCS_DIR)
119
+ if system("yard graph --full | #{graph_processor} -Tpng " \
120
+ "-o #{DOCS_DIR}/arch_graph.png")
121
+ puts "we made you a class diagram: #{DOCS_DIR}/arch_graph.png"
122
+ end
123
+ else
124
+ puts "ERROR: you don't have dot/graphviz; punting"
125
+ end
126
+ Dir.chdir(original_dir)
127
+ end
128
+
129
+ # Cross-platform exe_exists?
130
+ # @private
131
+ def exe_exists?(name)
132
+ exts = ENV["PATHEXT"] ? ENV["PATHEXT"].split(";") : [""]
133
+ ENV["PATH"].split(File::PATH_SEPARATOR).each do |path|
134
+ exts.each do |ext|
135
+ exe = File.join(path, "#{name}#{ext}")
136
+ return true if File.executable?(exe) && !File.directory?(exe)
137
+ end
138
+ end
139
+ false
140
+ end
141
+ end
142
+
143
+ # various lint-oriented tasks
144
+ class LintTasks
145
+ include Rake::DSL if defined? Rake::DSL
146
+ # instance lint takss in namespace :lint
147
+ # @api public
148
+ # @example LintTasks.new
149
+ def initialize
150
+ namespace :lint do
151
+ desc "check number of lines of code changed. No long PRs"
152
+ task "diff_length" do
153
+ diff_length? exit diff_length: exit
154
+ end
155
+
156
+ # this will produce 'test:rubocop','test:rubocop:auto_correct' tasks
157
+ RuboCop::RakeTask.new do |task|
158
+ task.options = ["--debug"]
159
+ end
160
+
161
+ # this will produce the 'test:flog' task
162
+ allowed_complexity = 585 # <cough!>
163
+ FlogTask.new :flog, allowed_complexity, %w[lib]
164
+ # this will produce the 'test:flay' task
165
+ allowed_repitition = 0
166
+ FlayTask.new :flay, allowed_repitition, %w[lib]
167
+ # this will produce the 'test:roodi' task
168
+ RoodiTask.new
169
+ # this will produce the 'test:rubycritic' task
170
+ RubyCritic::RakeTask.new do |task|
171
+ task.paths = FileList["lib/**/*.rb"]
172
+ end
173
+ end
174
+ end
175
+
176
+ private
177
+
178
+ # @api private
179
+ def diff_length
180
+ max_length = 150
181
+ target_branch = ENV["DISTELLI_RELBRANCH"] || "master"
182
+ diff_cmd = "git diff --numstat #{target_branch}"
183
+ sum_cmd = "awk '{s+=$1} END {print s}'"
184
+ diff_len = `#{diff_cmd} | #{sum_cmd}`.to_i
185
+ if diff_len < max_length
186
+ puts "diff length (#{diff_len}) is less than #{max_length} LoC"
187
+ return
188
+ else
189
+ puts "diff length (#{diff_len}) is more than #{max_length} LoC"
190
+ return diff_len
191
+ end
192
+ end
193
+ end
194
+
195
+ # unit testing tasks
196
+ class TestTasks
197
+ include Rake::DSL if defined? Rake::DSL
198
+ # instance unit tasks in namespace :test
199
+ # @api public
200
+ # @example TestTasks.new
201
+ def initialize
202
+ namespace :test do
203
+ begin
204
+ # this will produce the 'test:spec' task
205
+ require "rspec/core/rake_task"
206
+ desc "Run unit tests"
207
+ RSpec::Core::RakeTask.new do |t|
208
+ t.rspec_opts = ["--color"]
209
+ t.pattern = ENV["SPEC_PATTERN"]
210
+ end
211
+ # if rspec isn't available, we can still use this Rakefile
212
+ # rubocop:disable Lint/HandleExceptions
213
+ rescue LoadError
214
+ end
215
+
216
+ task spec: [:check_spec]
217
+
218
+ desc "" # empty description so it doesn't show up in rake -T
219
+ rototiller_task :check_spec do |t|
220
+ t.add_env(name: "SPEC_PATTERN", default: "spec/",
221
+ message: "The pattern RSpec will use to find tests")
222
+ end
223
+ end
224
+ end
225
+ end
226
+ end
data/lib/version.rb ADDED
@@ -0,0 +1,7 @@
1
+ module GemOf
2
+ # namespace for the future version of this library
3
+ module Version
4
+ # the version string
5
+ STRING = "0.1.0".freeze
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,50 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gem_of
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Puppet, Inc.
8
+ - Eric Thompson
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2018-05-18 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Puppet common tools and setup, for testing, building and documenting
15
+ ruby projects
16
+ email:
17
+ - qa@puppet.com
18
+ executables: []
19
+ extensions: []
20
+ extra_rdoc_files: []
21
+ files:
22
+ - README.md
23
+ - lib/gem_of.rb
24
+ - lib/gem_of/rake_tasks.rb
25
+ - lib/version.rb
26
+ homepage: https://github.com/puppetlabs/gem_of
27
+ licenses:
28
+ - Apache-2.0
29
+ metadata: {}
30
+ post_install_message:
31
+ rdoc_options: []
32
+ require_paths:
33
+ - lib
34
+ required_ruby_version: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ">="
37
+ - !ruby/object:Gem::Version
38
+ version: 2.0.0
39
+ required_rubygems_version: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ requirements: []
45
+ rubyforge_project:
46
+ rubygems_version: 2.7.6
47
+ signing_key:
48
+ specification_version: 4
49
+ summary: Puppet Gem testing Gems, RakeTasks
50
+ test_files: []