develry 0.0.2

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/.ruby-gemset +1 -0
  5. data/.travis.yml +30 -0
  6. data/Gemfile +7 -0
  7. data/Guardfile +32 -0
  8. data/LICENSE +20 -0
  9. data/README.md +71 -0
  10. data/Rakefile +5 -0
  11. data/TODO +0 -0
  12. data/bin/develry +18 -0
  13. data/config/flay.yml +3 -0
  14. data/config/flog.yml +2 -0
  15. data/config/mutant.yml +2 -0
  16. data/config/reek.yml +106 -0
  17. data/config/rubocop.yml +66 -0
  18. data/config/yardstick.yml +2 -0
  19. data/default/config/develry.yml +4 -0
  20. data/default/config/flay.yml +3 -0
  21. data/default/config/flog.yml +2 -0
  22. data/default/config/mutant.yml +3 -0
  23. data/default/config/reek.yml +103 -0
  24. data/default/config/rubocop.yml +58 -0
  25. data/default/config/yardstick.yml +2 -0
  26. data/develry.gemspec +53 -0
  27. data/lib/develry.rb +164 -0
  28. data/lib/develry/config.rb +167 -0
  29. data/lib/develry/platform.rb +118 -0
  30. data/lib/develry/project.rb +144 -0
  31. data/lib/develry/project/initializer.rb +21 -0
  32. data/lib/develry/project/initializer/rake.rb +19 -0
  33. data/lib/develry/project/initializer/rspec.rb +104 -0
  34. data/lib/develry/site.rb +64 -0
  35. data/lib/develry/site/initializer.rb +73 -0
  36. data/lib/develry/spec_helper.rb +5 -0
  37. data/shared/Gemfile +55 -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 +17 -0
  42. data/shared/spec/shared/idempotent_method_behavior.rb +9 -0
  43. data/shared/spec/support/ice_nine_config.rb +14 -0
  44. data/spec/spec_helper.rb +33 -0
  45. data/tasks/metrics/ci.rake +18 -0
  46. data/tasks/metrics/coverage.rake +13 -0
  47. data/tasks/metrics/flay.rake +66 -0
  48. data/tasks/metrics/flog.rake +59 -0
  49. data/tasks/metrics/mutant.rake +44 -0
  50. data/tasks/metrics/reek.rake +27 -0
  51. data/tasks/metrics/rubocop.rake +18 -0
  52. data/tasks/metrics/yardstick.rake +42 -0
  53. data/tasks/spec.rake +28 -0
  54. data/tasks/yard.rake +11 -0
  55. metadata +452 -0
@@ -0,0 +1,3 @@
1
+ ---
2
+ threshold: 0
3
+ total_score: 0
@@ -0,0 +1,2 @@
1
+ ---
2
+ threshold: 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,58 @@
1
+ AllCops:
2
+ Includes:
3
+ - '**/*.rake'
4
+ - 'Gemfile'
5
+ - 'Gemfile.develry'
6
+ Excludes:
7
+ - '**/vendor/**'
8
+ - '**/benchmarks/**'
9
+
10
+ # Avoid parameter lists longer than five parameters.
11
+ ParameterLists:
12
+ Max: 3
13
+ CountKeywordArgs: true
14
+
15
+ # Avoid more than `Max` levels of nesting.
16
+ BlockNesting:
17
+ Max: 3
18
+
19
+ # Align with the style guide.
20
+ CollectionMethods:
21
+ PreferredMethods:
22
+ collect: 'map'
23
+ inject: 'reduce'
24
+ find: 'detect'
25
+ find_all: 'select'
26
+
27
+ # Do not force public/protected/private keyword to be indented at the same
28
+ # level as the def keyword. My personal preference is to outdent these keywords
29
+ # because I think when scanning code it makes it easier to identify the
30
+ # sections of code and visually separate them. When the keyword is at the same
31
+ # level I think it sort of blends in with the def keywords and makes it harder
32
+ # to scan the code and see where the sections are.
33
+ AccessControl:
34
+ Enabled: false
35
+
36
+ # Limit line length
37
+ LineLength:
38
+ Max: 79
39
+
40
+ # Disable documentation checking until a class needs to be documented once
41
+ Documentation:
42
+ Enabled: false
43
+
44
+ # Do not favor modifier if/unless usage when you have a single-line body
45
+ IfUnlessModifier:
46
+ Enabled: false
47
+
48
+ # Allow case equality operator (in limited use within the specs)
49
+ CaseEquality:
50
+ Enabled: false
51
+
52
+ # Constants do not always have to use SCREAMING_SNAKE_CASE
53
+ ConstantName:
54
+ Enabled: false
55
+
56
+ # Not all trivial readers/writers can be defined with attr_* methods
57
+ TrivialAccessors:
58
+ Enabled: false
@@ -0,0 +1,2 @@
1
+ ---
2
+ threshold: 100
@@ -0,0 +1,53 @@
1
+ # encoding: utf-8
2
+
3
+ Gem::Specification.new do |gem|
4
+ gem.name = 'develry'
5
+ gem.version = '0.0.2'
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/develry'
11
+ gem.license = 'MIT'
12
+
13
+ gem.require_paths = %w[lib]
14
+ gem.files = `git ls-files`.split($/)
15
+ gem.executables = %w[develry]
16
+ gem.test_files = `git ls-files -- spec`.split($/)
17
+ gem.extra_rdoc_files = %w[README.md TODO]
18
+
19
+ gem.add_dependency 'rake', '~> 10.1.0'
20
+ gem.add_dependency 'rspec', '~> 2.14.1'
21
+ gem.add_dependency 'yard', '~> 0.8.7'
22
+ gem.add_dependency 'kramdown', '~> 1.2.0'
23
+
24
+ # guard
25
+ gem.add_dependency 'guard', '~> 1.8.1'
26
+ gem.add_dependency 'guard-bundler', '~> 1.0.0'
27
+ gem.add_dependency 'guard-rspec', '~> 3.0.2'
28
+ gem.add_dependency 'guard-rubocop', '~> 0.2.0'
29
+ gem.add_dependency 'guard-mutant', '~> 0.0.1'
30
+
31
+ # file system change event handling
32
+ gem.add_dependency 'listen', '~> 1.3.0'
33
+ gem.add_dependency 'rb-fchange', '~> 0.0.6'
34
+ gem.add_dependency 'rb-fsevent', '~> 0.9.3'
35
+ gem.add_dependency 'rb-inotify', '~> 0.9.0'
36
+
37
+ # notification handling
38
+ gem.add_dependency 'libnotify', '~> 0.8.0'
39
+ gem.add_dependency 'rb-notifu', '~> 0.0.4'
40
+ gem.add_dependency 'terminal-notifier-guard', '~> 1.5.3'
41
+
42
+ # metrics
43
+ gem.add_dependency 'coveralls', '~> 0.6.7'
44
+ gem.add_dependency 'flay', '~> 2.4.0'
45
+ gem.add_dependency 'flog', '~> 4.1.1'
46
+ gem.add_dependency 'reek', '~> 1.3.2'
47
+ gem.add_dependency 'rubocop', '~> 0.13.0'
48
+ gem.add_dependency 'simplecov', '~> 0.7.1'
49
+ gem.add_dependency 'yardstick', '~> 0.9.7'
50
+
51
+ gem.add_dependency 'mutant', '~> 0.3.0.rc3'
52
+ gem.add_dependency 'yard-spellcheck', '~> 0.1.5'
53
+ end
@@ -0,0 +1,164 @@
1
+ # encoding: utf-8
2
+
3
+ require 'pathname'
4
+ require 'rake'
5
+ require 'timeout'
6
+ require 'yaml'
7
+ require 'fileutils'
8
+
9
+ require 'develry/platform'
10
+ require 'develry/site'
11
+ require 'develry/site/initializer'
12
+ require 'develry/project'
13
+ require 'develry/config'
14
+ require 'develry/project/initializer'
15
+ require 'develry/project/initializer/rake'
16
+ require 'develry/project/initializer/rspec'
17
+
18
+ # Provides access to metric tools
19
+ module Develry
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
+ SHARED_GEMFILE_PATH = SHARED_PATH.join('Gemfile').freeze
28
+ DEFAULT_CONFIG_PATH = ROOT.join('default/config').freeze
29
+ RAKE_FILES_GLOB = ROOT.join('tasks/**/*.rake').to_s.freeze
30
+ LIB_DIRECTORY_NAME = 'lib'.freeze
31
+ SPEC_DIRECTORY_NAME = 'spec'.freeze
32
+ RB_FILE_PATTERN = '**/*.rb'.freeze
33
+ RAKE_FILE_NAME = 'Rakefile'.freeze
34
+ DEFAULT_GEMFILE_NAME = 'Gemfile'.freeze
35
+ GEMFILE_NAME = 'Gemfile.develry'.freeze
36
+ EVAL_GEMFILE = "eval_gemfile '#{GEMFILE_NAME}'".freeze
37
+ BUNDLE_UPDATE = 'bundle update'.freeze
38
+ REQUIRE = "require 'develry'".freeze
39
+ INIT_RAKE_TASKS = 'Develry.init_rake_tasks'.freeze
40
+ SHARED_SPEC_PATTERN = '{shared,support}/**/*.rb'.freeze
41
+ UNIT_TEST_PATH_REGEXP = %r{\bspec/unit/}.freeze
42
+ DEFAULT_CONFIG_DIR_NAME = 'config'.freeze
43
+ ANNOTATION_WRAPPER = "\n# Added by develry\n%s".freeze
44
+
45
+ # Provides develry for a project
46
+ SITE = Site.new(Project.new(PROJECT_ROOT))
47
+
48
+ # Initialize project and load tasks
49
+ #
50
+ # Should *only* be called from your $application_root/Rakefile
51
+ #
52
+ # @return [self]
53
+ #
54
+ # @api public
55
+ def self.init_rake_tasks
56
+ Project::Initializer::Rake.call
57
+ self
58
+ end
59
+
60
+ # Initialize project and load shared specs
61
+ #
62
+ # Expects to be called from $application_root/spec/spec_helper.rb
63
+ #
64
+ # @return [self]
65
+ #
66
+ # @api public
67
+ def self.init_spec_helper
68
+ SITE.init_spec_helper
69
+ self
70
+ end
71
+
72
+ # Initialize develry using default config
73
+ #
74
+ # @return [undefined]
75
+ #
76
+ # @api public
77
+ def self.init
78
+ SITE.init
79
+ self
80
+ end
81
+
82
+ # Sync Gemfile.develry
83
+ #
84
+ # @return [undefined]
85
+ #
86
+ # @api public
87
+ def self.sync
88
+ SITE.sync
89
+ end
90
+
91
+ # Sync Gemfile.develry and run bundle update
92
+ #
93
+ # @return [undefined]
94
+ #
95
+ # @api public
96
+ def self.update
97
+ SITE.update
98
+ end
99
+
100
+ # Return project
101
+ #
102
+ # @return [Project]
103
+ #
104
+ # @api private
105
+ def self.project
106
+ SITE.project
107
+ end
108
+
109
+ # Require shared examples
110
+ #
111
+ # @param [Pathname] dir
112
+ # the directory containing the files to require
113
+ #
114
+ # @param [String] pattern
115
+ # the file pattern to match inside directory
116
+ #
117
+ # @return [self]
118
+ #
119
+ # @api private
120
+ def self.require_files(dir, pattern)
121
+ Dir[dir.join(pattern)].each { |file| require file }
122
+ self
123
+ end
124
+
125
+ # Notify or abort depending on the branch
126
+ #
127
+ # @param [String] msg
128
+ #
129
+ # @return [undefined]
130
+ #
131
+ # @api private
132
+ def self.notify(msg)
133
+ fail_on_current_branch? ? abort(msg) : puts(msg)
134
+ end
135
+
136
+ # Test if the build should fail because of metrics on this branch
137
+ #
138
+ # @return [Boolean]
139
+ #
140
+ # @api private
141
+ def self.fail_on_current_branch?
142
+ fail_on_branch.include?(current_branch)
143
+ end
144
+
145
+ # Return the branches the build should fail on because of metrics
146
+ #
147
+ # @return [Array[String]]
148
+ #
149
+ # @api private
150
+ def self.fail_on_branch
151
+ project.devtools.fail_on_branch
152
+ end
153
+
154
+ # Return current git branch
155
+ #
156
+ # @return [String]
157
+ #
158
+ # @api private
159
+ def self.current_branch
160
+ `git rev-parse --abbrev-ref HEAD`.rstrip
161
+ end
162
+ private_class_method :current_branch
163
+
164
+ end # module Develry
@@ -0,0 +1,167 @@
1
+ # encoding: utf-8
2
+
3
+ module Develry
4
+
5
+ MASTER_BRANCH = 'master'.freeze
6
+
7
+ # Abstract base class of tool configuration
8
+ class Config
9
+ # Represent no configuration
10
+ DEFAULT_CONFIG = {}.freeze
11
+
12
+ # Declare an attribute
13
+ #
14
+ # @param [Symbol] name
15
+ #
16
+ # @yieldreturn [Object]
17
+ # the default value to use
18
+ #
19
+ # @api private
20
+ #
21
+ # @return [self]
22
+ #
23
+ def self.attribute(name, *default)
24
+ define_method(name) do
25
+ raw.fetch(name.to_s, *default)
26
+ end
27
+ end
28
+ private_class_method :attribute
29
+
30
+ # Return project
31
+ #
32
+ # @return [Project]
33
+ #
34
+ # @api private
35
+ #
36
+ attr_reader :project
37
+
38
+ # Initialize object
39
+ #
40
+ # @return [Project]
41
+ #
42
+ # @api private
43
+ #
44
+ def initialize(project)
45
+ @project = project
46
+ end
47
+
48
+ # Return config path
49
+ #
50
+ # @return [String]
51
+ #
52
+ # @api private
53
+ #
54
+ def config_file
55
+ @config_file ||= project.config_dir.join(self.class::FILE).freeze
56
+ end
57
+
58
+ # Test if the task is enabled
59
+ #
60
+ # If there is no config file, and no sensible defaults, then the rake task
61
+ # should become disabled.
62
+ #
63
+ # @return [Boolean]
64
+ #
65
+ # @api private
66
+ #
67
+ def enabled?
68
+ ! raw.equal?(DEFAULT_CONFIG)
69
+ end
70
+
71
+ private
72
+
73
+ # Return raw data
74
+ #
75
+ # @return [Hash]
76
+ #
77
+ # @api private
78
+ #
79
+ def raw
80
+ @raw ||= yaml_config || DEFAULT_CONFIG
81
+ end
82
+
83
+ # Return the raw config data from a yaml file
84
+ #
85
+ # @return [Hash]
86
+ # returned if the yaml file is found
87
+ # @return [nil]
88
+ # returned if the yaml file is not found
89
+ #
90
+ # @api private
91
+ #
92
+ def yaml_config
93
+ config_file = self.config_file
94
+ YAML.load_file(config_file).freeze if config_file.file?
95
+ end
96
+
97
+ # Rubocop configuration
98
+ class Rubocop < self
99
+ FILE = 'rubocop.yml'.freeze
100
+ end
101
+
102
+ # Reek configuration
103
+ class Reek < self
104
+ FILE = 'reek.yml'.freeze
105
+ end
106
+
107
+ # Flay configuration
108
+ class Flay < self
109
+ FILE = 'flay.yml'.freeze
110
+
111
+ attribute :total_score
112
+ attribute :threshold
113
+ end
114
+
115
+ # Yardstick configuration
116
+ class Yardstick < self
117
+ FILE = 'yardstick.yml'.freeze
118
+ OPTIONS = %w[
119
+ threshold
120
+ rules
121
+ verbose
122
+ path
123
+ require_exact_threshold
124
+ ].freeze
125
+
126
+ # Options hash that Yardstick understands
127
+ #
128
+ # @return [Hash]
129
+ #
130
+ # @api private
131
+ def options
132
+ OPTIONS.each_with_object({}) { |name, hash|
133
+ hash[name] = raw.fetch(name, nil)
134
+ }
135
+ end
136
+ end
137
+
138
+ # Flog configuration
139
+ class Flog < self
140
+ FILE = 'flog.yml'.freeze
141
+
142
+ attribute :total_score
143
+ attribute :threshold
144
+ end
145
+
146
+ # Mutant configuration
147
+ class Mutant < self
148
+ FILE = 'mutant.yml'.freeze
149
+ DEFAULT_NAME = ''.freeze
150
+ DEFAULT_STRATEGY = '--rspec'.freeze
151
+
152
+ attribute :name, DEFAULT_NAME
153
+ attribute :namespace
154
+ attribute :strategy, DEFAULT_STRATEGY
155
+ end
156
+
157
+ # Develry configuration
158
+ class Develry < self
159
+ FILE = 'develry.yml'.freeze
160
+ DEFAULT_UNIT_TEST_TIMEOUT = 0.1 # 100ms
161
+ DEFAULT_BRANCHES_TO_FAIL_ON = [MASTER_BRANCH]
162
+
163
+ attribute :unit_test_timeout, DEFAULT_UNIT_TEST_TIMEOUT
164
+ attribute :fail_on_branch, DEFAULT_BRANCHES_TO_FAIL_ON
165
+ end
166
+ end
167
+ end