devtools 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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