pdd 0.20.6 → 0.21.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 +4 -4
- data/.github/workflows/codecov.yml +20 -0
- data/.github/workflows/rake.yml +24 -0
- data/.gitignore +5 -5
- data/.overcommit.yml +96 -0
- data/.pdd +3 -0
- data/.rubocop.yml +3 -4
- data/.rultor.yml +8 -15
- data/.simplecov +6 -6
- data/Gemfile +1 -1
- data/LICENSE.txt +1 -1
- data/README.md +67 -37
- data/Rakefile +7 -1
- data/assets/puzzles.xsd +1 -1
- data/assets/puzzles.xsl +1 -1
- data/bin/pdd +31 -18
- data/features/catches_broken_puzzles.feature +3 -36
- data/features/cli.feature +1 -1
- data/features/html_output.feature +1 -1
- data/features/parsing.feature +31 -1
- data/features/rake.feature +14 -12
- data/features/step_definitions/steps.rb +7 -10
- data/features/support/env.rb +1 -1
- data/features/uses_config.feature +1 -1
- data/lib/pdd/puzzle.rb +1 -1
- data/lib/pdd/rake_task.rb +11 -12
- data/lib/pdd/rule/duplicates.rb +2 -1
- data/lib/pdd/rule/estimates.rb +1 -1
- data/lib/pdd/rule/roles.rb +2 -1
- data/lib/pdd/rule/text.rb +2 -1
- data/lib/pdd/source.rb +86 -75
- data/lib/pdd/sources.rb +42 -21
- data/lib/pdd/version.rb +3 -3
- data/lib/pdd.rb +20 -13
- data/pdd.gemspec +8 -5
- data/test/test__helper.rb +15 -2
- data/test/test_duplicates.rb +2 -2
- data/test/test_estimates.rb +2 -2
- data/test/test_pdd.rb +4 -2
- data/test/test_rake_task.rb +7 -4
- data/test/test_roles.rb +2 -2
- data/test/test_source.rb +168 -51
- data/test/test_source_todo.rb +38 -29
- data/test/test_sources.rb +18 -3
- data/test/test_text.rb +2 -2
- data/utils/glob.rb +65 -0
- metadata +37 -7
- data/.travis.yml +0 -13
- data/appveyor.yml +0 -21
data/lib/pdd/sources.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2014-
|
1
|
+
# Copyright (c) 2014-2022 Yegor Bugayenko
|
2
2
|
#
|
3
3
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
4
|
# of this software and associated documentation files (the 'Software'), to deal
|
@@ -18,58 +18,79 @@
|
|
18
18
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
19
19
|
# SOFTWARE.
|
20
20
|
|
21
|
-
require '
|
21
|
+
require 'rainbow'
|
22
22
|
require 'English'
|
23
|
+
require 'filemagic'
|
23
24
|
require_relative 'source'
|
25
|
+
require_relative '../../utils/glob'
|
24
26
|
|
25
27
|
module PDD
|
26
28
|
# Code base abstraction
|
27
29
|
class Sources
|
28
30
|
# Ctor.
|
29
31
|
# +dir+:: Directory with source code files
|
30
|
-
def initialize(dir
|
32
|
+
def initialize(dir)
|
31
33
|
@dir = File.absolute_path(dir)
|
32
|
-
@exclude =
|
34
|
+
@exclude = ['.git/**/*']
|
35
|
+
@include = []
|
33
36
|
end
|
34
37
|
|
35
38
|
# Fetch all sources.
|
36
39
|
def fetch
|
40
|
+
exclude_paths = @exclude.map do |ptn|
|
41
|
+
Glob.new(File.join(@dir, ptn)).to_regexp
|
42
|
+
end
|
37
43
|
files = Dir.glob(
|
38
44
|
File.join(@dir, '**/*'), File::FNM_DOTMATCH
|
39
|
-
).reject
|
40
|
-
|
41
|
-
@exclude.each do |ptn|
|
42
|
-
Dir.glob(File.join(@dir, ptn), File::FNM_DOTMATCH) do |f|
|
43
|
-
files.delete_if { |i| i == f }
|
44
|
-
excluded += 1
|
45
|
-
end
|
45
|
+
).reject do |f|
|
46
|
+
File.directory?(f) || exclude_paths.any? { |ptn| f.match(ptn) }
|
46
47
|
end
|
47
|
-
|
48
|
+
files += Dir.glob(
|
49
|
+
@include.map { |ptn| File.join(@dir, ptn) }
|
50
|
+
).reject { |f| File.directory?(f) }
|
51
|
+
files = files.uniq # remove duplicates
|
48
52
|
files.reject { |f| binary?(f) }.map do |file|
|
49
53
|
path = file[@dir.length + 1, file.length]
|
50
54
|
VerboseSource.new(path, Source.new(file, path))
|
51
55
|
end
|
52
56
|
end
|
53
57
|
|
54
|
-
def exclude(
|
55
|
-
|
58
|
+
def exclude(paths)
|
59
|
+
paths = paths.nil? ? [] : paths
|
60
|
+
paths = paths.is_a?(Array) ? paths : [paths]
|
61
|
+
@exclude.push(*paths)
|
62
|
+
paths&.each do |path|
|
63
|
+
PDD.log.info "#{Rainbow('Excluding').orange} #{path}"
|
64
|
+
end
|
65
|
+
self
|
66
|
+
end
|
67
|
+
|
68
|
+
def include(paths)
|
69
|
+
paths = paths.nil? ? [] : paths
|
70
|
+
paths = paths.is_a?(Array) ? paths : [paths]
|
71
|
+
@include.push(*paths)
|
72
|
+
paths&.each do |path|
|
73
|
+
PDD.log.info "#{Rainbow('Including').blue} #{path}"
|
74
|
+
end
|
75
|
+
self
|
56
76
|
end
|
57
77
|
|
58
78
|
private
|
59
79
|
|
60
|
-
# @todo #98:30min Change the implementation of this method
|
61
|
-
# to also work in Windows machines. Investigate the possibility
|
62
|
-
# of use a gem for this. After that, remove the skip of the test
|
63
|
-
# `test_ignores_binary_files` in `test_sources.rb`.
|
64
80
|
def binary?(file)
|
65
|
-
|
66
|
-
`grep -qI '.' #{Shellwords.escape(file)}`
|
67
|
-
if $CHILD_STATUS.success?
|
81
|
+
if text_file?(file)
|
68
82
|
false
|
69
83
|
else
|
70
84
|
PDD.log.info "#{file} is a binary file (#{File.size(file)} bytes)"
|
71
85
|
true
|
72
86
|
end
|
73
87
|
end
|
88
|
+
|
89
|
+
def text_file?(file)
|
90
|
+
fm = FileMagic.new(FileMagic::MAGIC_MIME)
|
91
|
+
fm.file(file) =~ %r{^text/}
|
92
|
+
ensure
|
93
|
+
fm.close
|
94
|
+
end
|
74
95
|
end
|
75
96
|
end
|
data/lib/pdd/version.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2014-
|
1
|
+
# Copyright (c) 2014-2022 Yegor Bugayenko
|
2
2
|
#
|
3
3
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
4
|
# of this software and associated documentation files (the 'Software'), to deal
|
@@ -20,8 +20,8 @@
|
|
20
20
|
|
21
21
|
# PDD main module.
|
22
22
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
23
|
-
# Copyright:: Copyright (c) 2014-
|
23
|
+
# Copyright:: Copyright (c) 2014-2022 Yegor Bugayenko
|
24
24
|
# License:: MIT
|
25
25
|
module PDD
|
26
|
-
VERSION = '0.
|
26
|
+
VERSION = '0.21.0'.freeze
|
27
27
|
end
|
data/lib/pdd.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2014-
|
1
|
+
# Copyright (c) 2014-2022 Yegor Bugayenko
|
2
2
|
#
|
3
3
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
4
|
# of this software and associated documentation files (the 'Software'), to deal
|
@@ -30,7 +30,7 @@ require_relative 'pdd/rule/roles'
|
|
30
30
|
|
31
31
|
# PDD main module.
|
32
32
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
33
|
-
# Copyright:: Copyright (c) 2014-
|
33
|
+
# Copyright:: Copyright (c) 2014-2022 Yegor Bugayenko
|
34
34
|
# License:: MIT
|
35
35
|
module PDD
|
36
36
|
# If it breaks.
|
@@ -52,21 +52,25 @@ module PDD
|
|
52
52
|
# Get logger.
|
53
53
|
def self.log
|
54
54
|
unless defined?(@logger)
|
55
|
-
@logger = Logger.new(
|
55
|
+
@logger = Logger.new($stdout)
|
56
56
|
@logger.formatter = proc { |severity, _, _, msg|
|
57
|
-
|
57
|
+
case severity
|
58
|
+
when 'ERROR'
|
58
59
|
"#{Rainbow(severity).red}: #{msg}\n"
|
60
|
+
when 'WARN'
|
61
|
+
"#{Rainbow(severity).orange}: #{msg}\n"
|
59
62
|
else
|
60
63
|
"#{msg}\n"
|
61
64
|
end
|
62
65
|
}
|
63
|
-
@logger.level = Logger::
|
66
|
+
@logger.level = Logger::WARN
|
64
67
|
end
|
65
68
|
@logger
|
66
69
|
end
|
67
70
|
|
68
71
|
class << self
|
69
72
|
attr_writer :logger
|
73
|
+
attr_accessor :opts
|
70
74
|
end
|
71
75
|
|
72
76
|
# Code base abstraction
|
@@ -75,6 +79,7 @@ module PDD
|
|
75
79
|
# +opts+:: Options
|
76
80
|
def initialize(opts)
|
77
81
|
@opts = opts
|
82
|
+
PDD.opts = opts
|
78
83
|
PDD.log.level = Logger::INFO if @opts[:verbose]
|
79
84
|
PDD.log.level = Logger::ERROR if @opts[:quiet]
|
80
85
|
PDD.log.info "My version is #{PDD::VERSION}"
|
@@ -83,17 +88,15 @@ module PDD
|
|
83
88
|
|
84
89
|
# Generate XML.
|
85
90
|
def xml
|
86
|
-
dir = @opts[:source]
|
87
|
-
PDD.log.info "Reading #{dir}"
|
91
|
+
dir = @opts[:source] || Dir.pwd
|
92
|
+
PDD.log.info "Reading from root dir #{dir}"
|
88
93
|
require_relative 'pdd/sources'
|
89
|
-
sources = Sources.new(dir)
|
90
|
-
@opts[:exclude]
|
91
|
-
|
92
|
-
PDD.log.info "Excluding #{p}"
|
93
|
-
end
|
94
|
+
sources = Sources.new(File.expand_path(dir))
|
95
|
+
sources.exclude((@opts[:exclude] || []) + (@opts['skip-gitignore'] || []))
|
96
|
+
sources.include(@opts[:include])
|
94
97
|
sanitize(
|
95
98
|
rules(
|
96
|
-
Nokogiri::XML::Builder.new do |xml|
|
99
|
+
Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml|
|
97
100
|
xml << "<?xml-stylesheet type='text/xsl' href='#{xsl}'?>"
|
98
101
|
xml.puzzles(attrs) do
|
99
102
|
sources.fetch.each do |source|
|
@@ -145,16 +148,19 @@ module PDD
|
|
145
148
|
unless list.select { |r| r.start_with?('max-duplicates:') }.empty?
|
146
149
|
raise PDD::Error, 'You can\'t modify max-duplicates, it\'s always 1'
|
147
150
|
end
|
151
|
+
|
148
152
|
list.push('max-duplicates:1').map do |r|
|
149
153
|
name, value = r.split(':')
|
150
154
|
rule = RULES[name]
|
151
155
|
raise "Rule '#{name}' doesn't exist" if rule.nil?
|
156
|
+
|
152
157
|
rule.new(doc, value).errors.each do |e|
|
153
158
|
PDD.log.error e
|
154
159
|
total += 1
|
155
160
|
end
|
156
161
|
end
|
157
162
|
raise PDD::Error, "#{total} errors, see log above" unless total.zero?
|
163
|
+
|
158
164
|
xml
|
159
165
|
end
|
160
166
|
|
@@ -166,6 +172,7 @@ module PDD
|
|
166
172
|
errors.each { |e| PDD.log.error e }
|
167
173
|
PDD.log.error(xml) unless errors.empty?
|
168
174
|
raise SchemaError, errors.join('; ') unless errors.empty?
|
175
|
+
|
169
176
|
xml
|
170
177
|
end
|
171
178
|
end
|
data/pdd.gemspec
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2014-
|
1
|
+
# Copyright (c) 2014-2022 Yegor Bugayenko
|
2
2
|
#
|
3
3
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
4
|
# of this software and associated documentation files (the 'Software'), to deal
|
@@ -20,17 +20,18 @@
|
|
20
20
|
|
21
21
|
require 'English'
|
22
22
|
|
23
|
-
lib = File.expand_path('
|
23
|
+
lib = File.expand_path('lib', __dir__)
|
24
24
|
$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
28
|
s.specification_version = 2 if s.respond_to? :specification_version=
|
29
29
|
if s.respond_to? :required_rubygems_version=
|
30
|
-
s.required_rubygems_version =
|
30
|
+
s.required_rubygems_version =
|
31
|
+
Gem::Requirement.new('>= 0')
|
31
32
|
end
|
32
33
|
s.rubygems_version = '2.3'
|
33
|
-
s.required_ruby_version = '
|
34
|
+
s.required_ruby_version = '~> 2.3'
|
34
35
|
s.name = 'pdd'
|
35
36
|
s.version = PDD::VERSION
|
36
37
|
s.license = 'MIT'
|
@@ -38,7 +39,7 @@ Gem::Specification.new do |s|
|
|
38
39
|
s.description = 'Collects PDD puzzles from a source code base'
|
39
40
|
s.authors = ['Yegor Bugayenko']
|
40
41
|
s.email = 'yegor256@gmail.com'
|
41
|
-
s.homepage = 'http://github.com/
|
42
|
+
s.homepage = 'http://github.com/cqfn/pdd'
|
42
43
|
s.files = `git ls-files`.split($RS)
|
43
44
|
s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
44
45
|
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
@@ -46,6 +47,7 @@ Gem::Specification.new do |s|
|
|
46
47
|
s.extra_rdoc_files = ['README.md', 'LICENSE.txt']
|
47
48
|
s.add_runtime_dependency 'nokogiri', '~> 1.10'
|
48
49
|
s.add_runtime_dependency 'rainbow', '~> 3.0'
|
50
|
+
s.add_runtime_dependency 'ruby-filemagic', '~> 0.7.2'
|
49
51
|
s.add_runtime_dependency 'slop', '~> 4.6'
|
50
52
|
s.add_development_dependency 'aruba', '~> 0.14.1'
|
51
53
|
s.add_development_dependency 'codecov', '0.2.12'
|
@@ -56,5 +58,6 @@ Gem::Specification.new do |s|
|
|
56
58
|
s.add_development_dependency 'rspec-rails', '3.1.0'
|
57
59
|
s.add_development_dependency 'rubocop', '0.52.1'
|
58
60
|
s.add_development_dependency 'rubocop-rspec', '1.15.1'
|
61
|
+
s.add_development_dependency 'slop', '4.9.1'
|
59
62
|
s.add_development_dependency 'xcop', '0.5.8'
|
60
63
|
end
|
data/test/test__helper.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2014-
|
1
|
+
# Copyright (c) 2014-2022 Yegor Bugayenko
|
2
2
|
#
|
3
3
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
4
|
# of this software and associated documentation files (the 'Software'), to deal
|
@@ -18,7 +18,7 @@
|
|
18
18
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
19
19
|
# SOFTWARE.
|
20
20
|
|
21
|
-
|
21
|
+
$stdout.sync = true
|
22
22
|
|
23
23
|
require 'simplecov'
|
24
24
|
SimpleCov.start
|
@@ -29,3 +29,16 @@ end
|
|
29
29
|
|
30
30
|
require 'minitest/autorun'
|
31
31
|
require_relative '../lib/pdd'
|
32
|
+
|
33
|
+
def stub_source_find_github_user(file, path = '')
|
34
|
+
source = PDD::Source.new(file, path)
|
35
|
+
verbose_source = PDD::VerboseSource.new(file, source)
|
36
|
+
fake = proc do |info = {}|
|
37
|
+
email, author = info.values_at(:email, :author)
|
38
|
+
{ 'login' => 'yegor256' } if email == 'yegor256@gmail.com' ||
|
39
|
+
author == 'Yegor Bugayenko'
|
40
|
+
end
|
41
|
+
source.stub :find_github_user, fake do
|
42
|
+
yield verbose_source
|
43
|
+
end
|
44
|
+
end
|
data/test/test_duplicates.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2014-
|
1
|
+
# Copyright (c) 2014-2022 Yegor Bugayenko
|
2
2
|
#
|
3
3
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
4
|
# of this software and associated documentation files (the 'Software'), to deal
|
@@ -24,7 +24,7 @@ require_relative '../lib/pdd/rule/duplicates'
|
|
24
24
|
|
25
25
|
# PDD::Rule::MaxDuplicates class test.
|
26
26
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
27
|
-
# Copyright:: Copyright (c) 2014-
|
27
|
+
# Copyright:: Copyright (c) 2014-2022 Yegor Bugayenko
|
28
28
|
# License:: MIT
|
29
29
|
class TestMaxDuplicates < Minitest::Test
|
30
30
|
def test_max_duplicates
|
data/test/test_estimates.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2014-
|
1
|
+
# Copyright (c) 2014-2022 Yegor Bugayenko
|
2
2
|
#
|
3
3
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
4
|
# of this software and associated documentation files (the 'Software'), to deal
|
@@ -24,7 +24,7 @@ require_relative '../lib/pdd/rule/estimates'
|
|
24
24
|
|
25
25
|
# PDD::Rule::Estimate module tests.
|
26
26
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
27
|
-
# Copyright:: Copyright (c) 2014-
|
27
|
+
# Copyright:: Copyright (c) 2014-2022 Yegor Bugayenko
|
28
28
|
# License:: MIT
|
29
29
|
class TestEstimates < Minitest::Test
|
30
30
|
def test_min
|
data/test/test_pdd.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2014-
|
1
|
+
# Copyright (c) 2014-2022 Yegor Bugayenko
|
2
2
|
#
|
3
3
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
4
|
# of this software and associated documentation files (the 'Software'), to deal
|
@@ -26,7 +26,7 @@ require_relative '../lib/pdd'
|
|
26
26
|
|
27
27
|
# PDD main module test.
|
28
28
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
29
|
-
# Copyright:: Copyright (c) 2014-
|
29
|
+
# Copyright:: Copyright (c) 2014-2022 Yegor Bugayenko
|
30
30
|
# License:: MIT
|
31
31
|
class TestPDD < Minitest::Test
|
32
32
|
def test_basic
|
@@ -75,6 +75,7 @@ class TestPDD < Minitest::Test
|
|
75
75
|
git add -f .
|
76
76
|
git commit --quiet -am 'first version'
|
77
77
|
")
|
78
|
+
|
78
79
|
matches(
|
79
80
|
Nokogiri::XML(PDD::Base.new(opts).xml),
|
80
81
|
[
|
@@ -95,6 +96,7 @@ class TestPDD < Minitest::Test
|
|
95
96
|
Slop.parse args do |o|
|
96
97
|
o.bool '-v', '--verbose'
|
97
98
|
o.bool '-q', '--quiet'
|
99
|
+
o.bool '--skip-errors'
|
98
100
|
o.string '-s', '--source'
|
99
101
|
o.array '-e', '--exclude'
|
100
102
|
o.array '-r', '--rule'
|
data/test/test_rake_task.rb
CHANGED
@@ -5,11 +5,14 @@ require_relative '../lib/pdd/rake_task'
|
|
5
5
|
|
6
6
|
# Test for RakeTask
|
7
7
|
class TestRakeTask < Minitest::Test
|
8
|
-
def
|
9
|
-
|
10
|
-
|
8
|
+
def test_basic
|
9
|
+
Dir.mktmpdir 'test' do |dir|
|
10
|
+
file = File.join(dir, 'a.txt')
|
11
|
+
File.write(file, "\x40todo #55 hello!")
|
12
|
+
PDD::RakeTask.new(:pdd1) do |task|
|
13
|
+
task.quiet = true
|
14
|
+
end
|
11
15
|
Rake::Task['pdd1'].invoke
|
12
16
|
end
|
13
|
-
assert_equal('NOT IMPLEMENTED', error.message)
|
14
17
|
end
|
15
18
|
end
|
data/test/test_roles.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2014-
|
1
|
+
# Copyright (c) 2014-2022 Yegor Bugayenko
|
2
2
|
#
|
3
3
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
4
|
# of this software and associated documentation files (the 'Software'), to deal
|
@@ -24,7 +24,7 @@ require_relative '../lib/pdd/rule/roles'
|
|
24
24
|
|
25
25
|
# PDD::Rule::Role module tests.
|
26
26
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
27
|
-
# Copyright:: Copyright (c) 2014-
|
27
|
+
# Copyright:: Copyright (c) 2014-2022 Yegor Bugayenko
|
28
28
|
# License:: MIT
|
29
29
|
class TestRoles < Minitest::Test
|
30
30
|
def test_incorrect_role
|