pdd 0.21.2 → 0.22.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c76649118dbe4b4884f07d453b611ca05da5845e753357fcb98cd0e6e8324b64
4
- data.tar.gz: 4b85d7b84b62f8d695d2e8b95a92bc03cb87d5e6acbef283723ac353a43c42cd
3
+ metadata.gz: 1c97d7f2451c60abeae2fa0374b8578c852b6c2e42a78568c5fff8c7b5c3acc1
4
+ data.tar.gz: 5353eec5dea5875dc31a7655e694fc41c3585ff176f849db8122b777ee38a25a
5
5
  SHA512:
6
- metadata.gz: 1a54147d056c4593c20142e9c45497308bc57c0ec34a63e84fc0f025e1722ed406102f9383196cec51a084baffe17d2de4174060c93173328605089410a48dff
7
- data.tar.gz: 4270c5b9ec6e8b63ca371b2c6c5905b13394d5078943f1c66b8c8ec9ccc30ae25026efd375f3fd2d5bd8c2a1fd29080c86755935d5c91bc6d47baceda89e6edd
6
+ metadata.gz: ecded4d1f191fb5ab36eb237add8d46ca48430371a8c6ab9758a159ebfc796ac276a7327c4f9b33a3186ebd104c95e0255af12def22ccbcfaf0e3239decb67d7
7
+ data.tar.gz: 0fe7422e26da6f53561a3e51c597cb779f39f39828b9af55f8b2cd0fc8b1b359c919a0b82f3d39f26d487f5ac31a50020494f5fc1048cedf7b64545096847b22
@@ -6,7 +6,7 @@ on:
6
6
  - master
7
7
  jobs:
8
8
  codecov:
9
- runs-on: ubuntu-latest
9
+ runs-on: ubuntu-20.04
10
10
  steps:
11
11
  - uses: actions/checkout@v2
12
12
  - uses: actions/setup-ruby@v1
@@ -0,0 +1,15 @@
1
+ ---
2
+ name: pdd
3
+ "on":
4
+ push:
5
+ branches:
6
+ - master
7
+ pull_request:
8
+ branches:
9
+ - master
10
+ jobs:
11
+ pdd:
12
+ runs-on: ubuntu-20.04
13
+ steps:
14
+ - uses: actions/checkout@v2
15
+ - uses: g4s8/pdd-action@master
@@ -12,7 +12,7 @@ jobs:
12
12
  name: test
13
13
  strategy:
14
14
  matrix:
15
- os: [ubuntu-latest]
15
+ os: [ubuntu-20.04]
16
16
  ruby: [2.7]
17
17
  runs-on: ${{ matrix.os }}
18
18
  steps:
@@ -0,0 +1,15 @@
1
+ ---
2
+ name: xcop
3
+ "on":
4
+ push:
5
+ branches:
6
+ - master
7
+ pull_request:
8
+ branches:
9
+ - master
10
+ jobs:
11
+ xcop:
12
+ runs-on: ubuntu-20.04
13
+ steps:
14
+ - uses: actions/checkout@v2
15
+ - uses: g4s8/xcop-action@master
data/.pdd CHANGED
@@ -9,6 +9,7 @@
9
9
  --exclude features/cli.feature
10
10
  --exclude features/parsing.feature
11
11
  --exclude features/catches_broken_puzzles.feature
12
+ --exclude features/remove.feature
12
13
  --exclude features/uses_config.feature
13
14
  --exclude features/html_output.feature
14
15
  --exclude features/avoiding_duplicates.feature
data/.rubocop.yml CHANGED
@@ -3,12 +3,20 @@ AllCops:
3
3
  - "assets/**/*"
4
4
  DisplayCopNames: true
5
5
  TargetRubyVersion: 2.3
6
+ NewCops: enable
7
+ SuggestExtensions: false
6
8
 
9
+ Layout/EmptyLineAfterGuardClause:
10
+ Enabled: false
11
+ Metrics/CyclomaticComplexity:
12
+ Max: 10
13
+ Metrics/PerceivedComplexity:
14
+ Max: 15
7
15
  Layout/EndOfLine:
8
16
  EnforcedStyle: lf
9
17
  Metrics/ClassLength:
10
18
  Max: 360
11
- Metrics/LineLength:
19
+ Layout/LineLength:
12
20
  Max: 90
13
21
  Metrics/MethodLength:
14
22
  Max: 35
data/.rultor.yml CHANGED
@@ -19,7 +19,3 @@ release:
19
19
  merge:
20
20
  script: |-
21
21
  LC_ALL=US-ASCII bundle exec rake
22
- deploy:
23
- script: |-
24
- echo "There is nothing to deploy"
25
- exit -1
data/README.md CHANGED
@@ -4,15 +4,16 @@
4
4
  [![DevOps By Rultor.com](http://www.rultor.com/b/cqfn/pdd)](http://www.rultor.com/p/cqfn/pdd)
5
5
  [![We recommend RubyMine](https://www.elegantobjects.org/rubymine.svg)](https://www.jetbrains.com/ruby/)
6
6
 
7
+ [![rake](https://github.com/cqfn/pdd/actions/workflows/rake.yml/badge.svg)](https://github.com/cqfn/pdd/actions/workflows/rake.yml)
7
8
  [![PDD status](http://www.0pdd.com/svg?name=cqfn/pdd)](http://www.0pdd.com/p?name=cqfn/pdd)
8
9
  [![codecov](https://codecov.io/gh/cqfn/pdd/branch/master/graph/badge.svg)](https://codecov.io/gh/cqfn/pdd)
9
10
  ![Lines of code](https://img.shields.io/tokei/lines/github/cqfn/pdd)
10
11
  [![Hits-of-Code](https://hitsofcode.com/github/cqfn/pdd)](https://hitsofcode.com/view/github/cqfn/pdd)
11
12
  [![License](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/cqfn/pdd/blob/master/LICENSE.txt)
12
-
13
13
  [![Gem Version](https://badge.fury.io/rb/pdd.svg)](http://badge.fury.io/rb/pdd)
14
14
  [![Maintainability](https://api.codeclimate.com/v1/badges/c8e46256fdd8ddc817e5/maintainability)](https://codeclimate.com/github/cqfn/pdd/maintainability)
15
15
  [![Yard Docs](http://img.shields.io/badge/yard-docs-blue.svg)](http://rubydoc.info/github/cqfn/pdd/master/frames)
16
+ [![Codacy Badge](https://app.codacy.com/project/badge/Grade/1792d42f96fb45448e8d495ebc4348aa)](https://www.codacy.com/gh/cqfn/pdd/dashboard?utm_source=github.com&utm_medium=referral&utm_content=cqfn/pdd&utm_campaign=Badge_Grade)
16
17
 
17
18
  Read this article about
18
19
  [_Puzzle Driven Development_](http://www.yegor256.com/2009/03/04/pdd.html).
@@ -235,3 +236,9 @@ This is how you run the tool locally to test how it works:
235
236
  ```bash
236
237
  $ ./bin/pdd --help
237
238
  ```
239
+
240
+ To run a single unit test:
241
+
242
+ ```bash
243
+ $ bundle exec ruby test/test_many.rb
244
+ ```
data/bin/pdd CHANGED
@@ -50,6 +50,7 @@ begin
50
50
  o.bool '-h', '--help', 'Show these instructions'
51
51
  o.bool '-v', '--verbose', 'Enable verbose mode (a lot of logging)'
52
52
  o.bool '-q', '--quiet', 'Enable quiet mode (almost no logging)'
53
+ o.bool '--remove', 'Remove all found puzzles from the source code'
53
54
  o.bool '--skip-gitignore', 'Don\'t look into .gitignore for excludes'
54
55
  o.bool '--skip-errors', 'Suppress error as warning and skip badly
55
56
  formatted puzzles'
@@ -89,31 +90,52 @@ https://github.com/cqfn/pdd/blob/master/README.md"
89
90
  body = File.read(cfg)
90
91
  extra = body.split(/\s+/).map(&:strip)
91
92
  opts['skip-gitignore'] = extra
92
- puts "Found #{body.split(/\n/).length} lines in #{File.absolute_path(cfg)}"
93
+ PDD.log.info "Found #{body.split(/\n/).length} lines in #{File.absolute_path(cfg)}"
93
94
  end
94
95
 
95
96
  Encoding.default_external = Encoding::UTF_8
96
97
  Encoding.default_internal = Encoding::UTF_8
97
98
  file = opts.file? ? File.new(opts[:file], 'w') : $stdout
98
- output = PDD::Base.new(opts).xml
99
+ xml = PDD::Base.new(opts).xml
100
+ output = xml
99
101
  if opts[:format]
100
102
  if opts[:format] == 'html'
101
103
  xslt = File.join(
102
104
  File.dirname(File.dirname(__FILE__)),
103
105
  'assets', 'puzzles.xsl'
104
106
  )
105
- output = Nokogiri::XSLT(File.read(xslt)).transform(Nokogiri::XML(output))
107
+ output = Nokogiri::XSLT(File.read(xslt)).transform(Nokogiri::XML(xml))
106
108
  elsif opts[:format] != 'xml'
107
109
  raise 'Invalid format, use html or xml'
108
110
  end
109
111
  end
110
112
  file << output
113
+ if opts.remove?
114
+ home = opts[:source] || Dir.pwd
115
+ PDD.log.info "Removing puzzles from #{home}..."
116
+ files = {}
117
+ Nokogiri::XML(xml).xpath('/puzzles/puzzle').each do |p|
118
+ file = p.xpath('file/text()').to_s
119
+ files[file] = [] if files[file].nil?
120
+ files[file] << p.xpath('lines/text()').to_s.split('-').map(&:to_i)
121
+ end
122
+ files.each do |src, all|
123
+ f = File.join(home, src)
124
+ File.write(
125
+ f,
126
+ File.readlines(f).reject.each_with_index do |_t, i|
127
+ all.any? { |pair| i + 1 >= pair[0] && i + 1 <= pair[1] }
128
+ end.join
129
+ )
130
+ PDD.log.info "#{all.count} puzzles removed from #{src}"
131
+ end
132
+ end
111
133
  rescue SystemExit => e
112
134
  puts e.message unless e.success?
113
135
  PDD.log.info "Exit code is #{e.status}"
114
136
  exit(e.status)
115
137
  rescue PDD::Error => e
116
- puts "#{Rainbow('ERROR').red}: #{e.message}
138
+ PDD.log.error "#{Rainbow('ERROR').red}: #{e.message}
117
139
  If you can't understand the cause of this issue or you don't know \
118
140
  how to fix it, please submit a GitHub issue, we will try to help you: \
119
141
  https://github.com/cqfn/pdd/issues. This tool is still in its beta \
@@ -122,7 +144,7 @@ more documentation: https://github.com/cqfn/pdd/blob/master/README.md."
122
144
  PDD.log.info 'Exit code is 1'
123
145
  exit(1)
124
146
  rescue StandardError => e
125
- puts "#{Rainbow('ERROR').red} (#{e.class.name}): #{e.message}"
147
+ PDD.log.error "#{Rainbow('ERROR').red} (#{e.class.name}): #{e.message}"
126
148
  PDD.log.info 'Exit code is 255'
127
149
  exit(255)
128
150
  end
@@ -0,0 +1,15 @@
1
+ Feature: Removing Puzzles
2
+ As a source code writer I want to be able to
3
+ remove PDD puzzles from source code
4
+
5
+ Scenario: Removing puzzles from code
6
+ Given I have a "a/test.txt" file with content:
7
+ """
8
+ Hello,
9
+ # @todo #42 Bye!
10
+ # Bye!
11
+ The End.
12
+ """
13
+ When I run bin/pdd with "-v --remove -f /dev/null"
14
+ Then Exit code is zero
15
+ And Stdout contains "1 puzzles removed from a/test.txt"
@@ -27,7 +27,7 @@ require_relative '../../lib/pdd'
27
27
  Before do
28
28
  @cwd = Dir.pwd
29
29
  @dir = Dir.mktmpdir('test')
30
- FileUtils.mkdir_p(@dir) unless File.exist?(@dir)
30
+ FileUtils.mkdir_p(@dir)
31
31
  Dir.chdir(@dir)
32
32
  @opts = Slop.parse ['-q', '-s', @dir] do |o|
33
33
  o.bool '-v', '--verbose'
@@ -38,7 +38,7 @@ end
38
38
 
39
39
  After do
40
40
  Dir.chdir(@cwd)
41
- FileUtils.rm_rf(@dir) if File.exist?(@dir)
41
+ FileUtils.rm_rf(@dir)
42
42
  end
43
43
 
44
44
  Given(/skip/) do
@@ -79,6 +79,7 @@ When(%r{^I run bin/pdd with "([^"]*)"$}) do |arg|
79
79
  end
80
80
 
81
81
  Then(/^Stdout contains "([^"]*)"$/) do |txt|
82
+ raise 'STDOUT is empty!' if @stdout.empty?
82
83
  raise "STDOUT doesn't contain '#{txt}':\n#{@stdout}" unless @stdout.include?(txt)
83
84
  end
84
85
 
data/lib/pdd/rake_task.rb CHANGED
@@ -13,6 +13,7 @@ module PDD
13
13
  attr_accessor :name, :fail_on_error, :includes, :license, :quiet
14
14
 
15
15
  def initialize(*args, &task_block)
16
+ super()
16
17
  @name = args.shift || :pdd
17
18
  @includes = []
18
19
  @excludes = []
@@ -32,9 +32,9 @@ module PDD
32
32
 
33
33
  def errors
34
34
  @xml.xpath("//puzzle[number(estimate) < #{@min}]").map do |p|
35
- "Puzzle #{p.xpath('file/text()')}:#{p.xpath('lines/text()')}"\
36
- " has an estimate of #{p.xpath('estimate/text()')} minutes,"\
37
- " which is lower than #{@min} minutes"
35
+ "Puzzle #{p.xpath('file/text()')}:#{p.xpath('lines/text()')} " \
36
+ "has an estimate of #{p.xpath('estimate/text()')} minutes, " \
37
+ "which is lower than #{@min} minutes"
38
38
  end
39
39
  end
40
40
  end
@@ -50,9 +50,9 @@ module PDD
50
50
 
51
51
  def errors
52
52
  @xml.xpath("//puzzle[number(estimate) > #{@min}]").map do |p|
53
- "Puzzle #{p.xpath('file/text()')}:#{p.xpath('lines/text()')}"\
54
- " has an estimate of #{p.xpath('estimate/text()')} minutes,"\
55
- " which is bigger than #{@min} minutes"
53
+ "Puzzle #{p.xpath('file/text()')}:#{p.xpath('lines/text()')} " \
54
+ "has an estimate of #{p.xpath('estimate/text()')} minutes, " \
55
+ "which is bigger than #{@min} minutes"
56
56
  end
57
57
  end
58
58
  end
@@ -37,11 +37,11 @@ module PDD
37
37
 
38
38
  "puzzle #{p.xpath('file/text()')}:#{p.xpath('lines/text()')}" +
39
39
  if role.empty?
40
- " doesn't define any role"\
41
- ", while one of these roles is required: #{@roles}"
40
+ " doesn't define any role" \
41
+ ", while one of these roles is required: #{@roles}"
42
42
  else
43
- " defines role #{role}"\
44
- ", while only these roles are allowed: #{@roles}"
43
+ " defines role #{role}" \
44
+ ", while only these roles are allowed: #{@roles}"
45
45
  end
46
46
  end.compact
47
47
  end
data/lib/pdd/rule/text.rb CHANGED
@@ -35,9 +35,9 @@ module PDD
35
35
  words = p.xpath('body/text()').to_s.split.size
36
36
  next nil if words >= @min
37
37
 
38
- "Puzzle #{p.xpath('file/text()')}:#{p.xpath('lines/text()')}"\
39
- " has a very short description of just #{words} words while"\
40
- " a minimum of #{@min} is required"
38
+ "Puzzle #{p.xpath('file/text()')}:#{p.xpath('lines/text()')} " \
39
+ "has a very short description of just #{words} words while " \
40
+ "a minimum of #{@min} is required"
41
41
  end.compact
42
42
  end
43
43
  end
data/lib/pdd/source.rb CHANGED
@@ -37,27 +37,27 @@ module PDD
37
37
  @path = path
38
38
  end
39
39
 
40
- def match_markers(l)
41
- if l.downcase.include? 'todo'
42
- /[^\s]\x40todo/.match(l) do |_|
40
+ def match_markers(line)
41
+ if line.downcase.include? 'todo'
42
+ /[^\s]\x40todo/.match(line) do |_|
43
43
  raise Error, get_no_leading_space_error("\x40todo")
44
44
  end
45
- /\x40todo(?!\s+#)/.match(l) do |_|
45
+ /\x40todo(?!\s+#)/.match(line) do |_|
46
46
  raise Error, get_no_puzzle_marker_error("\x40todo")
47
47
  end
48
- /\x40todo\s+#\s/.match(l) do |_|
48
+ /\x40todo\s+#\s/.match(line) do |_|
49
49
  raise Error, get_space_after_hash_error("\x40todo")
50
50
  end
51
- /[^\s]TODO:?/.match(l) do |_|
51
+ /[^\s]TODO:?/.match(line) do |_|
52
52
  raise Error, get_no_leading_space_error('TODO')
53
53
  end
54
- /TODO(?!:?\s+#)/.match(l) do |_|
54
+ /TODO(?!:?\s+#)/.match(line) do |_|
55
55
  raise Error, get_no_puzzle_marker_error('TODO')
56
56
  end
57
- /TODO:?\s+#\s/.match(l) do |_|
57
+ /TODO:?\s+#\s/.match(line) do |_|
58
58
  raise Error, get_space_after_hash_error('TODO')
59
59
  end
60
- a = [%r{(.*(?:^|\s))(?:\x40todo|TODO:|TODO)\s+#([\w\-.:/]+)\s+(.+)}.match(l)]
60
+ a = [%r{(.*(?:^|\s))(?:\x40todo|TODO:|TODO)\s+#([\w\-.:/]+)\s+(.+)}.match(line)]
61
61
  a.compact
62
62
  else
63
63
  []
@@ -74,10 +74,9 @@ module PDD
74
74
  match_markers(line).each do |m|
75
75
  puzzles << puzzle(lines.drop(idx + 1), m, idx)
76
76
  end
77
- rescue Error, ArgumentError => ex
78
- message = "#{@path}:#{idx + 1} #{ex.message}"
77
+ rescue Error, ArgumentError => e
78
+ message = "#{e.class} at #{@path}:#{idx + 1}: #{e.message}"
79
79
  raise Error, message unless PDD.opts && PDD.opts['skip-errors']
80
- PDD.log.warn message
81
80
  end
82
81
  end
83
82
  puzzles
@@ -147,22 +146,18 @@ against the rules explained here: https://github.com/cqfn/pdd#how-to-format"
147
146
  #
148
147
  # Fetch puzzle tail (all lines after the first one)
149
148
  def tail(lines, prefix, start)
150
- prefix = prefix.rstrip
151
149
  prefix = " #{' ' * start}" if prefix.empty? # fallback to space indentation
152
- line = lines[0][prefix.length + 1, lines[0].length] if lines[0]
150
+ line = lines[0][prefix.length, lines[0].length] if lines[0]
153
151
  is_indented = line&.start_with?(' ')
154
152
  lines
155
- .take_while { |t| match_markers(t).none? && t.start_with?(prefix) }
156
153
  .take_while do |t|
157
- !is_indented || t[prefix.length + 1, t.length].start_with?(' ')
154
+ start = t.length > prefix.length ? prefix : prefix.rstrip
155
+ match_markers(t).none? && t.start_with?(start)
158
156
  end
159
157
  .take_while do |t|
160
- # account for carriage return in line endings
161
- t_len = t.length - 1
162
- t_len <= prefix.length || t_len > prefix.length + 2
158
+ !is_indented || t[prefix.length, t.length].start_with?(' ')
163
159
  end
164
- .map { |t| t[prefix.length, t.length] }
165
- .map { |t| t.start_with?(' ') ? t[1, t.length] : t }
160
+ .map { |t| t[prefix.length, t.length]&.lstrip }
166
161
  end
167
162
  # rubocop:enable Metrics/CyclomaticComplexity
168
163
 
@@ -177,23 +172,22 @@ against the rules explained here: https://github.com/cqfn/pdd#how-to-format"
177
172
  git = "cd #{dir} && git"
178
173
  if `#{git} rev-parse --is-inside-work-tree 2>/dev/null`.strip == 'true'
179
174
  cmd = "#{git} blame -L #{pos},#{pos} --porcelain #{name}"
180
- add_github_login(Hash[
181
- `#{cmd}`.split("\n").map do |line|
182
- case line
183
- when /^author /
184
- [:author, line.sub(/^author /, '')]
185
- when /^author-mail [^@]+@[^.]+\..+/
186
- [:email, line.sub(/^author-mail <(.+)>$/, '\1')]
187
- when /^author-time /
188
- [
189
- :time,
190
- Time.at(
191
- line.sub(/^author-time ([0-9]+)$/, '\1').to_i
192
- ).utc.iso8601
193
- ]
194
- end
195
- end.compact
196
- ])
175
+ login = `#{cmd}`.split("\n").map do |line|
176
+ case line
177
+ when /^author /
178
+ [:author, line.sub(/^author /, '')]
179
+ when /^author-mail [^@]+@[^.]+\..+/
180
+ [:email, line.sub(/^author-mail <(.+)>$/, '\1')]
181
+ when /^author-time /
182
+ [
183
+ :time,
184
+ Time.at(
185
+ line.sub(/^author-time ([0-9]+)$/, '\1').to_i
186
+ ).utc.iso8601
187
+ ]
188
+ end
189
+ end.compact.to_h
190
+ add_github_login(login)
197
191
  else
198
192
  {}
199
193
  end
data/lib/pdd/sources.rb CHANGED
@@ -56,8 +56,8 @@ module PDD
56
56
  end
57
57
 
58
58
  def exclude(paths)
59
- paths = paths.nil? ? [] : paths
60
- paths = paths.is_a?(Array) ? paths : [paths]
59
+ paths = [] if paths.nil?
60
+ paths = [paths] unless paths.is_a?(Array)
61
61
  @exclude.push(*paths)
62
62
  paths&.each do |path|
63
63
  PDD.log.info "#{Rainbow('Excluding').orange} #{path}"
@@ -66,8 +66,8 @@ module PDD
66
66
  end
67
67
 
68
68
  def include(paths)
69
- paths = paths.nil? ? [] : paths
70
- paths = paths.is_a?(Array) ? paths : [paths]
69
+ paths = [] if paths.nil?
70
+ paths = [paths] unless paths.is_a?(Array)
71
71
  @include.push(*paths)
72
72
  paths&.each do |path|
73
73
  PDD.log.info "#{Rainbow('Including').blue} #{path}"
data/lib/pdd/version.rb CHANGED
@@ -23,5 +23,5 @@
23
23
  # Copyright:: Copyright (c) 2014-2022 Yegor Bugayenko
24
24
  # License:: MIT
25
25
  module PDD
26
- VERSION = '0.21.2'.freeze
26
+ VERSION = '0.22.0'.freeze
27
27
  end
data/lib/pdd.rb CHANGED
@@ -102,8 +102,8 @@ module PDD
102
102
  sources.fetch.each do |source|
103
103
  source.puzzles.each do |puzzle|
104
104
  PDD.log.info "Puzzle #{puzzle.props[:id]} " \
105
- "#{puzzle.props[:estimate]}/#{puzzle.props[:role]}" \
106
- " at #{puzzle.props[:file]}"
105
+ "#{puzzle.props[:estimate]}/#{puzzle.props[:role]} " \
106
+ "at #{puzzle.props[:file]}"
107
107
  render puzzle, xml
108
108
  end
109
109
  end
data/pdd.gemspec CHANGED
@@ -25,12 +25,10 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
25
25
  require_relative 'lib/pdd/version'
26
26
 
27
27
  Gem::Specification.new do |s|
28
- s.specification_version = 2 if s.respond_to? :specification_version=
29
28
  if s.respond_to? :required_rubygems_version=
30
29
  s.required_rubygems_version =
31
30
  Gem::Requirement.new('>= 0')
32
31
  end
33
- s.rubygems_version = '2.3'
34
32
  s.required_ruby_version = '~> 2.3'
35
33
  s.name = 'pdd'
36
34
  s.version = PDD::VERSION
@@ -42,7 +40,6 @@ Gem::Specification.new do |s|
42
40
  s.homepage = 'http://github.com/cqfn/pdd'
43
41
  s.files = `git ls-files`.split($RS)
44
42
  s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
45
- s.test_files = s.files.grep(%r{^(test|spec|features)/})
46
43
  s.rdoc_options = ['--charset=UTF-8']
47
44
  s.extra_rdoc_files = ['README.md', 'LICENSE.txt']
48
45
  s.add_runtime_dependency 'nokogiri', '~> 1.10'
@@ -50,14 +47,15 @@ Gem::Specification.new do |s|
50
47
  s.add_runtime_dependency 'ruby-filemagic', '~> 0.7.2'
51
48
  s.add_runtime_dependency 'slop', '~> 4.6'
52
49
  s.add_development_dependency 'aruba', '~> 0.14.1'
53
- s.add_development_dependency 'codecov', '0.2.12'
54
- s.add_development_dependency 'cucumber', '3.1.0'
55
- s.add_development_dependency 'minitest', '5.5.0'
56
- s.add_development_dependency 'rake', '12.0.0'
57
- s.add_development_dependency 'rdoc', '4.2.0'
58
- s.add_development_dependency 'rspec-rails', '3.1.0'
59
- s.add_development_dependency 'rubocop', '0.52.1'
60
- s.add_development_dependency 'rubocop-rspec', '1.15.1'
61
- s.add_development_dependency 'slop', '4.9.1'
62
- s.add_development_dependency 'xcop', '0.5.8'
50
+ s.add_development_dependency 'codecov', '0.6.0'
51
+ s.add_development_dependency 'cucumber', '8.0.0'
52
+ s.add_development_dependency 'minitest', '5.16.2'
53
+ s.add_development_dependency 'rake', '13.0.6'
54
+ s.add_development_dependency 'rdoc', '6.4.0'
55
+ s.add_development_dependency 'rspec-rails', '5.1.2'
56
+ s.add_development_dependency 'rubocop', '1.32.0'
57
+ s.add_development_dependency 'rubocop-rspec', '2.12.1'
58
+ s.add_development_dependency 'slop', '4.9.2'
59
+ s.add_development_dependency 'xcop', '0.7.1'
60
+ s.metadata['rubygems_mfa_required'] = 'true'
63
61
  end
data/test/test_many.rb ADDED
@@ -0,0 +1,42 @@
1
+ # Copyright (c) 2014-2022 Yegor Bugayenko
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the 'Software'), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all
11
+ # copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ # SOFTWARE.
20
+
21
+ require 'minitest/autorun'
22
+ require 'tmpdir'
23
+ require_relative '../lib/pdd'
24
+ require_relative '../lib/pdd/sources'
25
+
26
+ # Test many puzzles to make sure their IDs are correct.
27
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
28
+ # Copyright:: Copyright (c) 2014-2022 Yegor Bugayenko
29
+ # License:: MIT
30
+ class TestMany < Minitest::Test
31
+ def test_parsing
32
+ Dir['./test_assets/puzzles/**'].each do |p|
33
+ name = File.basename(p)
34
+ list = PDD::Source.new("./test_assets/puzzles/#{name}", 'hey').puzzles
35
+ assert_equal 1, list.size
36
+ puzzle = list.first
37
+ puts "#{name}: \"#{puzzle.props[:body]}\""
38
+ next if name.start_with?('_')
39
+ assert_equal name, puzzle.props[:id]
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,3 @@
1
+ /**
2
+ * @todo #1:30min How are you?
3
+ */
@@ -0,0 +1,8 @@
1
+ //
2
+ //
3
+ // @todo #132 Just a few lines
4
+ // before another comment
5
+ // @comment This is not a puzzle,
6
+ // but another bloc of text
7
+ //
8
+ //
@@ -0,0 +1,9 @@
1
+ /**
2
+ *
3
+ *
4
+ * @todo #1425:30min Continue replacing usage of MatcherAssert.assertThat with
5
+ * Assertion from cactoos-matchers. Keep PR short and limit the changes to
6
+ * single package. Update this puzzle for the next package.
7
+ * After all packages are done, add MatcherAssert to forbidden-apis.txt
8
+ *
9
+ */
@@ -0,0 +1,7 @@
1
+ #
2
+ # @todo #42 This is a very
3
+ # long puzzle of many lines and not always
4
+ # well formatted...
5
+ #
6
+ #
7
+ #
@@ -0,0 +1,9 @@
1
+
2
+ // @todo #44 This puzzle
3
+ // consists
4
+ // of
5
+ //
6
+ // two
7
+ // paragraphs
8
+
9
+ // This text doesn't belong to the puzzle
@@ -0,0 +1,9 @@
1
+
2
+ Some text goes before
3
+ In a few lines
4
+
5
+ // @todo #55 This is the puzzle;
6
+ // Indented this way.
7
+
8
+ Another piece of text after
9
+ Again in a few lines
@@ -0,0 +1,6 @@
1
+
2
+ // @todo #71 This puzzle
3
+ // consists
4
+ // of just one paragraph
5
+ //
6
+ // this piece doesn't belong to the puzzle
@@ -0,0 +1,9 @@
1
+ # Text before
2
+
3
+ # @todo #91 This puzzle
4
+ # Looks weird
5
+ # But it has to work
6
+ # Even though
7
+ # It's weird
8
+
9
+ # Here is the text after
@@ -0,0 +1,4 @@
1
+ #
2
+ # @todo #93:30min This puzzle is very simple. It is indented right by more spaces than the other text.
3
+ # This is the other text here,
4
+ # which doesn't belong to the puzzle
data/utils/glob.rb CHANGED
@@ -28,7 +28,7 @@ class Glob
28
28
 
29
29
  # rubocop:disable Metrics/CyclomaticComplexity
30
30
  def to_regexp
31
- chars = @glob_string.gsub(%r{(\*\*\/\*)|(\*\*)}, '*').split('')
31
+ chars = @glob_string.gsub(%r{(\*\*/\*)|(\*\*)}, '*').chars
32
32
  in_curlies = 0, escaping = false
33
33
  chars.map do |char|
34
34
  if escaping
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pdd
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.21.2
4
+ version: 0.22.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yegor Bugayenko
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-07-12 00:00:00.000000000 Z
11
+ date: 2022-09-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -86,140 +86,140 @@ dependencies:
86
86
  requirements:
87
87
  - - '='
88
88
  - !ruby/object:Gem::Version
89
- version: 0.2.12
89
+ version: 0.6.0
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - '='
95
95
  - !ruby/object:Gem::Version
96
- version: 0.2.12
96
+ version: 0.6.0
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: cucumber
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - '='
102
102
  - !ruby/object:Gem::Version
103
- version: 3.1.0
103
+ version: 8.0.0
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - '='
109
109
  - !ruby/object:Gem::Version
110
- version: 3.1.0
110
+ version: 8.0.0
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: minitest
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
115
  - - '='
116
116
  - !ruby/object:Gem::Version
117
- version: 5.5.0
117
+ version: 5.16.2
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - '='
123
123
  - !ruby/object:Gem::Version
124
- version: 5.5.0
124
+ version: 5.16.2
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: rake
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
129
  - - '='
130
130
  - !ruby/object:Gem::Version
131
- version: 12.0.0
131
+ version: 13.0.6
132
132
  type: :development
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
136
  - - '='
137
137
  - !ruby/object:Gem::Version
138
- version: 12.0.0
138
+ version: 13.0.6
139
139
  - !ruby/object:Gem::Dependency
140
140
  name: rdoc
141
141
  requirement: !ruby/object:Gem::Requirement
142
142
  requirements:
143
143
  - - '='
144
144
  - !ruby/object:Gem::Version
145
- version: 4.2.0
145
+ version: 6.4.0
146
146
  type: :development
147
147
  prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
150
  - - '='
151
151
  - !ruby/object:Gem::Version
152
- version: 4.2.0
152
+ version: 6.4.0
153
153
  - !ruby/object:Gem::Dependency
154
154
  name: rspec-rails
155
155
  requirement: !ruby/object:Gem::Requirement
156
156
  requirements:
157
157
  - - '='
158
158
  - !ruby/object:Gem::Version
159
- version: 3.1.0
159
+ version: 5.1.2
160
160
  type: :development
161
161
  prerelease: false
162
162
  version_requirements: !ruby/object:Gem::Requirement
163
163
  requirements:
164
164
  - - '='
165
165
  - !ruby/object:Gem::Version
166
- version: 3.1.0
166
+ version: 5.1.2
167
167
  - !ruby/object:Gem::Dependency
168
168
  name: rubocop
169
169
  requirement: !ruby/object:Gem::Requirement
170
170
  requirements:
171
171
  - - '='
172
172
  - !ruby/object:Gem::Version
173
- version: 0.52.1
173
+ version: 1.32.0
174
174
  type: :development
175
175
  prerelease: false
176
176
  version_requirements: !ruby/object:Gem::Requirement
177
177
  requirements:
178
178
  - - '='
179
179
  - !ruby/object:Gem::Version
180
- version: 0.52.1
180
+ version: 1.32.0
181
181
  - !ruby/object:Gem::Dependency
182
182
  name: rubocop-rspec
183
183
  requirement: !ruby/object:Gem::Requirement
184
184
  requirements:
185
185
  - - '='
186
186
  - !ruby/object:Gem::Version
187
- version: 1.15.1
187
+ version: 2.12.1
188
188
  type: :development
189
189
  prerelease: false
190
190
  version_requirements: !ruby/object:Gem::Requirement
191
191
  requirements:
192
192
  - - '='
193
193
  - !ruby/object:Gem::Version
194
- version: 1.15.1
194
+ version: 2.12.1
195
195
  - !ruby/object:Gem::Dependency
196
196
  name: slop
197
197
  requirement: !ruby/object:Gem::Requirement
198
198
  requirements:
199
199
  - - '='
200
200
  - !ruby/object:Gem::Version
201
- version: 4.9.1
201
+ version: 4.9.2
202
202
  type: :development
203
203
  prerelease: false
204
204
  version_requirements: !ruby/object:Gem::Requirement
205
205
  requirements:
206
206
  - - '='
207
207
  - !ruby/object:Gem::Version
208
- version: 4.9.1
208
+ version: 4.9.2
209
209
  - !ruby/object:Gem::Dependency
210
210
  name: xcop
211
211
  requirement: !ruby/object:Gem::Requirement
212
212
  requirements:
213
213
  - - '='
214
214
  - !ruby/object:Gem::Version
215
- version: 0.5.8
215
+ version: 0.7.1
216
216
  type: :development
217
217
  prerelease: false
218
218
  version_requirements: !ruby/object:Gem::Requirement
219
219
  requirements:
220
220
  - - '='
221
221
  - !ruby/object:Gem::Version
222
- version: 0.5.8
222
+ version: 0.7.1
223
223
  description: Collects PDD puzzles from a source code base
224
224
  email: yegor256@gmail.com
225
225
  executables:
@@ -231,10 +231,10 @@ extra_rdoc_files:
231
231
  files:
232
232
  - ".0pdd.yml"
233
233
  - ".gitattributes"
234
- - ".github/ISSUE_TEMPLATE.md"
235
- - ".github/PULL_REQUEST_TEMPLATE.md"
236
234
  - ".github/workflows/codecov.yml"
235
+ - ".github/workflows/pdd.yml"
237
236
  - ".github/workflows/rake.yml"
237
+ - ".github/workflows/xcop.yml"
238
238
  - ".gitignore"
239
239
  - ".overcommit.yml"
240
240
  - ".pdd"
@@ -258,6 +258,7 @@ files:
258
258
  - features/html_output.feature
259
259
  - features/parsing.feature
260
260
  - features/rake.feature
261
+ - features/remove.feature
261
262
  - features/step_definitions/steps.rb
262
263
  - features/support/env.rb
263
264
  - features/unicode.feature
@@ -276,6 +277,7 @@ files:
276
277
  - test/test__helper.rb
277
278
  - test/test_duplicates.rb
278
279
  - test/test_estimates.rb
280
+ - test/test_many.rb
279
281
  - test/test_pdd.rb
280
282
  - test/test_rake_task.rb
281
283
  - test/test_roles.rb
@@ -288,11 +290,21 @@ files:
288
290
  - test_assets/cambria.woff
289
291
  - test_assets/elegant-objects.png
290
292
  - test_assets/favicon.ico
293
+ - test_assets/puzzles/1-04e35eb3
294
+ - test_assets/puzzles/132-bc1dfafe
295
+ - test_assets/puzzles/1425-59819ae3
296
+ - test_assets/puzzles/42-0d933cc0
297
+ - test_assets/puzzles/44-660e9d6f
298
+ - test_assets/puzzles/55-947a180a
299
+ - test_assets/puzzles/71-8097fa26
300
+ - test_assets/puzzles/91-ecb9aa47
301
+ - test_assets/puzzles/93-641fe341
291
302
  - utils/glob.rb
292
303
  homepage: http://github.com/cqfn/pdd
293
304
  licenses:
294
305
  - MIT
295
- metadata: {}
306
+ metadata:
307
+ rubygems_mfa_required: 'true'
296
308
  post_install_message:
297
309
  rdoc_options:
298
310
  - "--charset=UTF-8"
@@ -311,28 +323,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
311
323
  requirements: []
312
324
  rubygems_version: 3.1.2
313
325
  signing_key:
314
- specification_version: 2
326
+ specification_version: 4
315
327
  summary: Puzzle Driven Development collector
316
- test_files:
317
- - features/applies_rules.feature
318
- - features/avoiding_duplicates.feature
319
- - features/catches_broken_puzzles.feature
320
- - features/cli.feature
321
- - features/gem_package.feature
322
- - features/html_output.feature
323
- - features/parsing.feature
324
- - features/rake.feature
325
- - features/step_definitions/steps.rb
326
- - features/support/env.rb
327
- - features/unicode.feature
328
- - features/uses_config.feature
329
- - test/test__helper.rb
330
- - test/test_duplicates.rb
331
- - test/test_estimates.rb
332
- - test/test_pdd.rb
333
- - test/test_rake_task.rb
334
- - test/test_roles.rb
335
- - test/test_source.rb
336
- - test/test_source_todo.rb
337
- - test/test_sources.rb
338
- - test/test_text.rb
328
+ test_files: []
@@ -1,12 +0,0 @@
1
- Make sure the title of the issue explains the problem you are having. Also, the description of the issue must clearly explain what is broken, not what you want us to implement. Go through this checklist and make sure you answer "YES" to all points:
2
-
3
- - You have all pre-requisites listed in README.md installed
4
- - You are sure that you are not reporting a duplicate (search all issues)
5
- - You say "is broken" or "doesn't work" in the title
6
- - You tell us what you are trying to do
7
- - You explain the results you are getting
8
- - You suggest an alternative result you would like to see
9
-
10
- This article will help you understand what we are looking for: http://www.yegor256.com/2014/11/24/principles-of-bug-tracking.html
11
-
12
- Thank you for your contribution!
@@ -1,11 +0,0 @@
1
- Many thanks for your contribution, we truly appreciate it. We will appreciate it even more, if you make sure that you can say "YES" to each point in this short checklist:
2
-
3
- - You made a small amount of changes (less than 100 lines, less than 10 files)
4
- - You made changes related to only one bug (create separate PRs for separate problems)
5
- - You are ready to defend your changes (there will be a code review)
6
- - You don't touch what you don't understand
7
- - You ran the build locally and it passed
8
-
9
- This article will help you understand what we are looking for: http://www.yegor256.com/2015/02/09/serious-code-reviewer.html
10
-
11
- Thank you for your contribution!