devtools 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.
Files changed (55) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +37 -0
  3. data/.rspec +5 -0
  4. data/.rubocop.yml +5 -0
  5. data/.ruby-gemset +1 -0
  6. data/.travis.yml +15 -0
  7. data/Gemfile +5 -0
  8. data/LICENSE +20 -0
  9. data/README.md +47 -0
  10. data/Rakefile +5 -0
  11. data/TODO +0 -0
  12. data/bin/devtools +18 -0
  13. data/circle.yml +7 -0
  14. data/config/flay.yml +3 -0
  15. data/config/flog.yml +2 -0
  16. data/config/mutant.yml +2 -0
  17. data/config/reek.yml +107 -0
  18. data/config/rubocop.yml +117 -0
  19. data/config/yardstick.yml +2 -0
  20. data/default/config/devtools.yml +2 -0
  21. data/default/config/flay.yml +3 -0
  22. data/default/config/flog.yml +2 -0
  23. data/default/config/mutant.yml +3 -0
  24. data/default/config/reek.yml +103 -0
  25. data/default/config/rubocop.yml +91 -0
  26. data/default/config/yardstick.yml +2 -0
  27. data/devtools.gemspec +33 -0
  28. data/lib/devtools.rb +143 -0
  29. data/lib/devtools/config.rb +158 -0
  30. data/lib/devtools/platform.rb +118 -0
  31. data/lib/devtools/project.rb +157 -0
  32. data/lib/devtools/project/initializer.rb +21 -0
  33. data/lib/devtools/project/initializer/rake.rb +19 -0
  34. data/lib/devtools/project/initializer/rspec.rb +105 -0
  35. data/lib/devtools/site.rb +41 -0
  36. data/lib/devtools/site/initializer.rb +57 -0
  37. data/lib/devtools/spec_helper.rb +5 -0
  38. data/shared/spec/shared/abstract_type_behavior.rb +18 -0
  39. data/shared/spec/shared/command_method_behavior.rb +7 -0
  40. data/shared/spec/shared/each_method_behaviour.rb +15 -0
  41. data/shared/spec/shared/hash_method_behavior.rb +9 -0
  42. data/shared/spec/shared/idempotent_method_behavior.rb +12 -0
  43. data/shared/spec/support/ice_nine_config.rb +14 -0
  44. data/spec/spec_helper.rb +31 -0
  45. data/tasks/metrics/ci.rake +18 -0
  46. data/tasks/metrics/coverage.rake +13 -0
  47. data/tasks/metrics/flay.rake +48 -0
  48. data/tasks/metrics/flog.rake +40 -0
  49. data/tasks/metrics/mutant.rake +50 -0
  50. data/tasks/metrics/reek.rake +7 -0
  51. data/tasks/metrics/rubocop.rake +15 -0
  52. data/tasks/metrics/yardstick.rake +26 -0
  53. data/tasks/spec.rake +36 -0
  54. data/tasks/yard.rake +11 -0
  55. metadata +284 -0
@@ -0,0 +1,3 @@
1
+ ---
2
+ name: your_lib
3
+ namespace: YourLib
@@ -0,0 +1,103 @@
1
+ ---
2
+ Attribute:
3
+ enabled: true
4
+ exclude: []
5
+ BooleanParameter:
6
+ enabled: true
7
+ exclude: []
8
+ ClassVariable:
9
+ enabled: true
10
+ exclude: []
11
+ ControlParameter:
12
+ enabled: true
13
+ exclude: []
14
+ DataClump:
15
+ enabled: true
16
+ exclude: []
17
+ max_copies: 2
18
+ min_clump_size: 2
19
+ DuplicateMethodCall:
20
+ enabled: true
21
+ exclude: []
22
+ max_calls: 1
23
+ allow_calls: []
24
+ FeatureEnvy:
25
+ enabled: true
26
+ exclude: []
27
+ IrresponsibleModule:
28
+ enabled: true
29
+ exclude: []
30
+ LongParameterList:
31
+ enabled: true
32
+ exclude: []
33
+ max_params: 2
34
+ overrides:
35
+ initialize:
36
+ max_params: 3
37
+ LongYieldList:
38
+ enabled: true
39
+ exclude: []
40
+ max_params: 2
41
+ NestedIterators:
42
+ enabled: true
43
+ exclude: []
44
+ max_allowed_nesting: 1
45
+ ignore_iterators: []
46
+ NilCheck:
47
+ enabled: true
48
+ exclude: []
49
+ RepeatedConditional:
50
+ enabled: true
51
+ exclude: []
52
+ max_ifs: 1
53
+ TooManyInstanceVariables:
54
+ enabled: true
55
+ exclude: []
56
+ max_instance_variables: 3
57
+ TooManyMethods:
58
+ enabled: true
59
+ exclude: []
60
+ max_methods: 10
61
+ TooManyStatements:
62
+ enabled: true
63
+ exclude:
64
+ - each
65
+ max_statements: 2
66
+ UncommunicativeMethodName:
67
+ enabled: true
68
+ exclude: []
69
+ reject:
70
+ - !ruby/regexp /^[a-z]$/
71
+ - !ruby/regexp /[0-9]$/
72
+ - !ruby/regexp /[A-Z]/
73
+ accept: []
74
+ UncommunicativeModuleName:
75
+ enabled: true
76
+ exclude: []
77
+ reject:
78
+ - !ruby/regexp /^.$/
79
+ - !ruby/regexp /[0-9]$/
80
+ accept: []
81
+ UncommunicativeParameterName:
82
+ enabled: true
83
+ exclude: []
84
+ reject:
85
+ - !ruby/regexp /^.$/
86
+ - !ruby/regexp /[0-9]$/
87
+ - !ruby/regexp /[A-Z]/
88
+ accept: []
89
+ UncommunicativeVariableName:
90
+ enabled: true
91
+ exclude: []
92
+ reject:
93
+ - !ruby/regexp /^.$/
94
+ - !ruby/regexp /[0-9]$/
95
+ - !ruby/regexp /[A-Z]/
96
+ accept: []
97
+ UnusedParameters:
98
+ enabled: true
99
+ exclude: []
100
+ UtilityFunction:
101
+ enabled: true
102
+ exclude: []
103
+ max_helper_calls: 0
@@ -0,0 +1,91 @@
1
+ AllCops:
2
+ Includes:
3
+ - '**/*.rake'
4
+ - 'Gemfile'
5
+ Excludes:
6
+ - '**/vendor/**'
7
+ - '**/benchmarks/**'
8
+
9
+ # Avoid parameter lists longer than five parameters.
10
+ ParameterLists:
11
+ Max: 3
12
+ CountKeywordArgs: true
13
+
14
+ # Limit method length
15
+ MethodLength:
16
+ CountComments: false
17
+ Max: 10
18
+
19
+ # Avoid more than `Max` levels of nesting.
20
+ BlockNesting:
21
+ Max: 3
22
+
23
+ # Align with the style guide.
24
+ CollectionMethods:
25
+ PreferredMethods:
26
+ collect: 'map'
27
+ inject: 'reduce'
28
+ find: 'detect'
29
+ find_all: 'select'
30
+
31
+ # Do not force public/protected/private keyword to be indented at the same
32
+ # level as the def keyword. My personal preference is to outdent these keywords
33
+ # because I think when scanning code it makes it easier to identify the
34
+ # sections of code and visually separate them. When the keyword is at the same
35
+ # level I think it sort of blends in with the def keywords and makes it harder
36
+ # to scan the code and see where the sections are.
37
+ AccessModifierIndentation:
38
+ Enabled: false
39
+
40
+ # Limit line length
41
+ LineLength:
42
+ Max: 79
43
+
44
+ # Disable documentation checking until a class needs to be documented once
45
+ Documentation:
46
+ Enabled: false
47
+
48
+ # Do not always use &&/|| instead of and/or.
49
+ AndOr:
50
+ Enabled: false
51
+
52
+ # Do not favor modifier if/unless usage when you have a single-line body
53
+ IfUnlessModifier:
54
+ Enabled: false
55
+
56
+ # Allow case equality operator (in limited use within the specs)
57
+ CaseEquality:
58
+ Enabled: false
59
+
60
+ # Constants do not always have to use SCREAMING_SNAKE_CASE
61
+ ConstantName:
62
+ Enabled: false
63
+
64
+ # Not all trivial readers/writers can be defined with attr_* methods
65
+ TrivialAccessors:
66
+ Enabled: false
67
+
68
+ # Do not prefer do/end over {} for multiline blocks
69
+ Blocks:
70
+ Enabled: false
71
+
72
+ # Allow empty lines around body
73
+ EmptyLinesAroundBody:
74
+ Enabled: false
75
+
76
+ # Prefer String#% over Kernel#sprintf
77
+ FormatString:
78
+ Enabled: false
79
+
80
+ # Use square brackets for literal Array objects
81
+ PercentLiteralDelimiters:
82
+ PreferredDelimiters:
83
+ '%': ()
84
+ '%i': '[]'
85
+ '%q': ()
86
+ '%Q': ()
87
+ '%r': '{}'
88
+ '%s': ()
89
+ '%w': '[]'
90
+ '%W': '[]'
91
+ '%x': ()
@@ -0,0 +1,2 @@
1
+ ---
2
+ threshold: 100
@@ -0,0 +1,33 @@
1
+ # encoding: utf-8
2
+
3
+ Gem::Specification.new do |gem|
4
+ gem.name = 'devtools'
5
+ gem.version = '0.1.0'
6
+ gem.authors = [ 'Markus Schirp' ]
7
+ gem.email = [ 'mbj@schirp-dso.com' ]
8
+ gem.description = 'A metagem for ROM-style development'
9
+ gem.summary = gem.description
10
+ gem.homepage = 'https://github.com/rom-rb/devtools'
11
+ gem.license = 'MIT'
12
+
13
+ gem.require_paths = %w[lib]
14
+ gem.files = `git ls-files`.split($/)
15
+ gem.executables = %w[devtools]
16
+ gem.test_files = `git ls-files -- spec`.split($/)
17
+ gem.extra_rdoc_files = %w[README.md TODO]
18
+ gem.required_ruby_version = '>= 2.1'
19
+
20
+ gem.add_dependency 'rspec', '~> 3.3.0'
21
+ gem.add_dependency 'rspec-core', '~> 3.3.0'
22
+ gem.add_dependency 'rspec-its', '~> 1.2.0'
23
+ gem.add_dependency 'rake', '~> 10.4.2'
24
+ gem.add_dependency 'yard', '~> 0.8.7.6'
25
+ gem.add_dependency 'flay', '~> 2.6.1'
26
+ gem.add_dependency 'flog', '~> 4.3.2'
27
+ gem.add_dependency 'reek', '~> 3.3.1'
28
+ gem.add_dependency 'rubocop', '~> 0.33.0'
29
+ gem.add_dependency 'simplecov', '~> 0.10.0'
30
+ gem.add_dependency 'yardstick', '~> 0.9.9'
31
+ gem.add_dependency 'mutant', '~> 0.8.3'
32
+ gem.add_dependency 'mutant-rspec', '~> 0.8.2'
33
+ end
@@ -0,0 +1,143 @@
1
+ # encoding: utf-8
2
+
3
+ require 'pathname'
4
+ require 'rake'
5
+ require 'timeout'
6
+ require 'yaml'
7
+ require 'fileutils'
8
+
9
+ require 'devtools/platform'
10
+ require 'devtools/site'
11
+ require 'devtools/site/initializer'
12
+ require 'devtools/project'
13
+ require 'devtools/config'
14
+ require 'devtools/project/initializer'
15
+ require 'devtools/project/initializer/rake'
16
+ require 'devtools/project/initializer/rspec'
17
+
18
+ # Provides access to metric tools
19
+ module Devtools
20
+
21
+ extend Platform
22
+
23
+ ROOT = Pathname.new(__FILE__).parent.parent.freeze
24
+ PROJECT_ROOT = Pathname.pwd.freeze
25
+ SHARED_PATH = ROOT.join('shared').freeze
26
+ SHARED_SPEC_PATH = SHARED_PATH.join('spec').freeze
27
+ DEFAULT_CONFIG_PATH = ROOT.join('default/config').freeze
28
+ RAKE_FILES_GLOB = ROOT.join('tasks/**/*.rake').to_s.freeze
29
+ LIB_DIRECTORY_NAME = 'lib'.freeze
30
+ SPEC_DIRECTORY_NAME = 'spec'.freeze
31
+ RB_FILE_PATTERN = '**/*.rb'.freeze
32
+ RAKE_FILE_NAME = 'Rakefile'.freeze
33
+ REQUIRE = "require 'devtools'".freeze
34
+ INIT_RAKE_TASKS = 'Devtools.init_rake_tasks'.freeze
35
+ SHARED_SPEC_PATTERN = '{shared,support}/**/*.rb'.freeze
36
+ UNIT_TEST_PATH_REGEXP = %r{\bspec/unit/}.freeze
37
+ DEFAULT_CONFIG_DIR_NAME = 'config'.freeze
38
+ ANNOTATION_WRAPPER = "\n# Added by devtools\n%s\n".freeze
39
+
40
+ # Provides devtools for a project
41
+ SITE = Site.new(Project.new(PROJECT_ROOT))
42
+
43
+ # React to metric violation
44
+ #
45
+ # @param [String] msg
46
+ #
47
+ # @return [undefined]
48
+ #
49
+ # @api private
50
+ def self.notify_metric_violation(msg)
51
+ abort(msg)
52
+ end
53
+
54
+ # Initialize project and load tasks
55
+ #
56
+ # Should *only* be called from your $application_root/Rakefile
57
+ #
58
+ # @return [self]
59
+ #
60
+ # @api public
61
+ def self.init_rake_tasks
62
+ Project::Initializer::Rake.call
63
+ self
64
+ end
65
+
66
+ # Initialize project and load shared specs
67
+ #
68
+ # Expects to be called from $application_root/spec/spec_helper.rb
69
+ #
70
+ # @return [self]
71
+ #
72
+ # @api public
73
+ def self.init_spec_helper
74
+ SITE.init_spec_helper
75
+ self
76
+ end
77
+
78
+ # Initialize devtools using default config
79
+ #
80
+ # @return [undefined]
81
+ #
82
+ # @api public
83
+ def self.init
84
+ SITE.init
85
+ self
86
+ end
87
+
88
+ # Return project
89
+ #
90
+ # @return [Project]
91
+ #
92
+ # @api private
93
+ def self.project
94
+ SITE.project
95
+ end
96
+
97
+ # Require shared examples
98
+ #
99
+ # @param [Pathname] dir
100
+ # the directory containing the files to require
101
+ #
102
+ # @param [String] pattern
103
+ # the file pattern to match inside directory
104
+ #
105
+ # @return [self]
106
+ #
107
+ # @api private
108
+ def self.require_files(dir, pattern)
109
+ Dir[dir.join(pattern)].each { |file| require file }
110
+ self
111
+ end
112
+
113
+ # Detect ci
114
+ #
115
+ # @return [Boolean]
116
+ #
117
+ # @api private
118
+ #
119
+ def self.ci?
120
+ ENV.key?('CI')
121
+ end
122
+
123
+ # Detect circle ci
124
+ #
125
+ # @return [Boolean]
126
+ #
127
+ # @api private
128
+ #
129
+ def self.circle_ci?
130
+ ENV.key?('CIRCLECI')
131
+ end
132
+
133
+ # Detect travis ci
134
+ #
135
+ # @return [Boolean]
136
+ #
137
+ # @api private
138
+ #
139
+ def self.travis?
140
+ ENV.key?('TRAVIS')
141
+ end
142
+
143
+ end # module Devtools
@@ -0,0 +1,158 @@
1
+ # encoding: utf-8
2
+
3
+ module Devtools
4
+
5
+ # Abstract base class of tool configuration
6
+ class Config
7
+ # Represent no configuration
8
+ DEFAULT_CONFIG = {}.freeze
9
+
10
+ # Declare an attribute
11
+ #
12
+ # @param [Symbol] name
13
+ #
14
+ # @yieldreturn [Object]
15
+ # the default value to use
16
+ #
17
+ # @api private
18
+ #
19
+ # @return [self]
20
+ #
21
+ def self.attribute(name, *default)
22
+ define_method(name) do
23
+ raw.fetch(name.to_s, *default)
24
+ end
25
+ end
26
+ private_class_method :attribute
27
+
28
+ # Return project
29
+ #
30
+ # @return [Project]
31
+ #
32
+ # @api private
33
+ #
34
+ attr_reader :project
35
+
36
+ # Initialize object
37
+ #
38
+ # @return [Project]
39
+ #
40
+ # @api private
41
+ #
42
+ def initialize(project)
43
+ @project = project
44
+ end
45
+
46
+ # Return config path
47
+ #
48
+ # @return [String]
49
+ #
50
+ # @api private
51
+ #
52
+ def config_file
53
+ @config_file ||= project.config_dir.join(self.class::FILE).freeze
54
+ end
55
+
56
+ private
57
+
58
+ # Return raw data
59
+ #
60
+ # @return [Hash]
61
+ #
62
+ # @api private
63
+ #
64
+ def raw
65
+ @raw ||= yaml_config || DEFAULT_CONFIG
66
+ end
67
+
68
+ # Return the raw config data from a yaml file
69
+ #
70
+ # @return [Hash]
71
+ # returned if the yaml file is found
72
+ # @return [nil]
73
+ # returned if the yaml file is not found
74
+ #
75
+ # @api private
76
+ #
77
+ def yaml_config
78
+ config_file = self.config_file
79
+ YAML.load_file(config_file).freeze if config_file.file?
80
+ end
81
+
82
+ # Rubocop configuration
83
+ class Rubocop < self
84
+ FILE = 'rubocop.yml'.freeze
85
+ end
86
+
87
+ # Reek configuration
88
+ class Reek < self
89
+ FILE = 'reek.yml'.freeze
90
+ end
91
+
92
+ # Flay configuration
93
+ class Flay < self
94
+ FILE = 'flay.yml'.freeze
95
+ DEFAULT_LIB_DIRS = %w[lib].freeze
96
+
97
+ attribute :total_score
98
+ attribute :threshold
99
+ attribute :lib_dirs, DEFAULT_LIB_DIRS
100
+ end
101
+
102
+ # Yardstick configuration
103
+ class Yardstick < self
104
+ FILE = 'yardstick.yml'.freeze
105
+ OPTIONS = %w[
106
+ threshold
107
+ rules
108
+ verbose
109
+ path
110
+ require_exact_threshold
111
+ ].freeze
112
+
113
+ # Options hash that Yardstick understands
114
+ #
115
+ # @return [Hash]
116
+ #
117
+ # @api private
118
+ def options
119
+ OPTIONS.each_with_object({}) do |name, hash|
120
+ hash[name] = raw.fetch(name, nil)
121
+ end
122
+ end
123
+ end
124
+
125
+ # Flog configuration
126
+ class Flog < self
127
+ FILE = 'flog.yml'.freeze
128
+ DEFAULT_LIB_DIRS = %w[lib].freeze
129
+
130
+ attribute :total_score
131
+ attribute :threshold
132
+ attribute :lib_dirs, DEFAULT_LIB_DIRS
133
+ end
134
+
135
+ # Mutant configuration
136
+ class Mutant < self
137
+ FILE = 'mutant.yml'.freeze
138
+ DEFAULT_NAME = ''.freeze
139
+ DEFAULT_STRATEGY = 'rspec'.freeze
140
+
141
+ attribute :name, DEFAULT_NAME
142
+ attribute :strategy, DEFAULT_STRATEGY
143
+ attribute :zombify, false
144
+ attribute :since, nil
145
+ attribute :ignore_subjects, []
146
+ attribute :expect_coverage, 1
147
+ attribute :namespace
148
+ end
149
+
150
+ # Devtools configuration
151
+ class Devtools < self
152
+ FILE = 'devtools.yml'.freeze
153
+ DEFAULT_UNIT_TEST_TIMEOUT = 0.1 # 100ms
154
+
155
+ attribute :unit_test_timeout, DEFAULT_UNIT_TEST_TIMEOUT
156
+ end
157
+ end
158
+ end