pdd 0.17.9 → 0.18

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
  SHA1:
3
- metadata.gz: 13b8f74b0fadd780f0b33023410df1b44cc83f8f
4
- data.tar.gz: 9ec0aa1148ee8bbeee5b75d9fe678dc3269c74b8
3
+ metadata.gz: 99bde0870af357f7eba5e562cf4e80367fd5022a
4
+ data.tar.gz: 0fc0b88a2e83a2eccb98ed6a5089b469a6d549b7
5
5
  SHA512:
6
- metadata.gz: 1f9fa206b2bf86935642f2660393049b53be4432804d34b0dfe0b9ab75cbc0421fe61b9ad698cb4113bf43bfea83b85f894161ede93229bd0837a64a68d92607
7
- data.tar.gz: 93f4bdb7f8f793e66be89d256af0307734d04cf782aad05f9e446866117f4c23407359f68a11d36ca3d0c07d0cae4dd4c72823af1853f7274f1ac2169f32b8b2
6
+ metadata.gz: 69b16a076410aec375c78acb4bb01332718edc630541b50c64da84bb92151d9205dddbbce3fe97ef708122fed0d5b832ecf07e1fcef3eb7b6ae61be0f351e146
7
+ data.tar.gz: 1685a80e5bf84944218a5211b41f905a7bdccbd8112bf877515518dd79b6ef8f28275f2b6519e86ae52d04428b4a9199369f51b2e8f4d736dedb7ea5b9990982
data/.rubocop.yml CHANGED
@@ -1,6 +1,16 @@
1
+ AllCops:
2
+ Exclude:
3
+ - 'bin/**/*'
4
+ - 'assets/**/*'
5
+ DisplayCopNames: true
6
+
1
7
  MethodLength:
2
8
  Max: 30
3
9
  Style/ClassLength:
4
10
  Max: 150
5
11
  Metrics/AbcSize:
6
12
  Max: 37
13
+ Style/MultilineBlockChain:
14
+ Enabled: false
15
+ Metrics/BlockLength:
16
+ Max: 50
data/.rultor.yml CHANGED
@@ -5,6 +5,7 @@ install: |
5
5
  sudo apt-get update
6
6
  sudo apt-get install -y --fix-missing libmagic1 libmagic-dev
7
7
  sudo gem install pdd
8
+ sudo gem install xcop
8
9
  release:
9
10
  script: |-
10
11
  env
data/.simplecov CHANGED
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
- #
3
1
  # Copyright (c) 2014-2017 Yegor Bugayenko
4
2
  #
5
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -20,8 +18,6 @@
20
18
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
19
  # SOFTWARE.
22
20
 
23
- require 'coveralls'
24
-
25
21
  if Gem.win_platform? then
26
22
  SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
27
23
  SimpleCov::Formatter::HTMLFormatter
@@ -31,10 +27,9 @@ if Gem.win_platform? then
31
27
  add_filter "/features/"
32
28
  end
33
29
  else
34
- SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
35
- SimpleCov::Formatter::HTMLFormatter,
36
- Coveralls::SimpleCov::Formatter
37
- ]
30
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new(
31
+ SimpleCov::Formatter::HTMLFormatter
32
+ )
38
33
  SimpleCov.start do
39
34
  add_filter "/test/"
40
35
  add_filter "/features/"
data/Gemfile CHANGED
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
- #
3
1
  # Copyright (c) 2014-2017 Yegor Bugayenko
4
2
  #
5
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  <img src="https://avatars2.githubusercontent.com/u/24456188" width="64px" height="64px"/>
2
2
 
3
- [![Made By Teamed.io](http://img.teamed.io/btn.svg)](http://www.teamed.io)
3
+ [![Managed by Zerocracy](http://www.zerocracy.com/badge.svg)](http://www.zerocracy.com)
4
4
  [![DevOps By Rultor.com](http://www.rultor.com/b/yegor256/pdd)](http://www.rultor.com/p/yegor256/pdd)
5
5
  [![We recommend RubyMine](http://img.teamed.io/rubymine-recommend.svg)](https://www.jetbrains.com/ruby/)
6
6
 
@@ -99,9 +99,44 @@ Here is a list of rules available now:
99
99
 
100
100
  * `min-words:5` blocks puzzles with descriptions shorter than five words.
101
101
 
102
- * `max-duplicates:1` blocks more than one duplicate of any puzzle
103
- (this rule is used by default).
102
+ * `max-duplicates:1` blocks more than one duplicate of any puzzle.
103
+ This rule is used by default and you can't configure it at the moment,
104
+ it must always be set to `1`.
104
105
 
105
106
  You can put all command line options into `.pdd` file. The options from the
106
107
  file will be used first. Command line options may be added on top of them.
107
108
  See, how it is done in [yegor256/0pdd](https://github.com/yegor256/0pdd/blob/master/.pdd).
109
+
110
+ ## How to contribute?
111
+
112
+ Just submit a pull request. Make sure `rake` passes.
113
+
114
+ This is how you run it locally to test how it works:
115
+
116
+ ```bash
117
+ $ ./bin/pdd --help
118
+ ```
119
+
120
+ ## License
121
+
122
+ (The MIT License)
123
+
124
+ Copyright (c) 2016-2017 Yegor Bugayenko
125
+
126
+ Permission is hereby granted, free of charge, to any person obtaining a copy
127
+ of this software and associated documentation files (the 'Software'), to deal
128
+ in the Software without restriction, including without limitation the rights
129
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
130
+ copies of the Software, and to permit persons to whom the Software is
131
+ furnished to do so, subject to the following conditions:
132
+
133
+ The above copyright notice and this permission notice shall be included in all
134
+ copies or substantial portions of the Software.
135
+
136
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
137
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
138
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
139
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
140
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
141
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
142
+ SOFTWARE.
data/Rakefile CHANGED
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
- #
3
1
  # Copyright (c) 2014-2017 Yegor Bugayenko
4
2
  #
5
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -33,7 +31,7 @@ def version
33
31
  Gem::Specification.load(Dir['*.gemspec'].first).version
34
32
  end
35
33
 
36
- task default: [:clean, :test, :features, :rubocop, :copyright]
34
+ task default: %i[clean test features rubocop xcop copyright]
37
35
 
38
36
  require 'rake/testtask'
39
37
  desc 'Run all unit tests'
@@ -60,8 +58,17 @@ RuboCop::RakeTask.new(:rubocop) do |task|
60
58
  task.requires << 'rubocop-rspec'
61
59
  end
62
60
 
61
+ require 'xcop/rake_task'
62
+ desc 'Validate all XML/XSL/XSD/HTML files for formatting'
63
+ Xcop::RakeTask.new :xcop do |task|
64
+ task.license = 'LICENSE.txt'
65
+ task.includes = ['**/*.xml', '**/*.xsl', '**/*.xsd', '**/*.html']
66
+ task.excludes = ['target/**/*', 'coverage/**/*']
67
+ end
68
+
63
69
  require 'cucumber/rake/task'
64
- Cucumber::Rake::Task.new(:features) do
70
+ Cucumber::Rake::Task.new(:features) do |t|
71
+ t.cucumber_opts = 'features --format progress'
65
72
  Rake::Cleaner.cleanup_files(['coverage'])
66
73
  end
67
74
  Cucumber::Rake::Task.new(:'features:html') do |t|
data/assets/puzzles.xsd CHANGED
@@ -1,25 +1,27 @@
1
1
  <?xml version="1.0"?>
2
2
  <!--
3
- * Copyright (c) 2014-2017 Yegor Bugayenko
4
- *
5
- * Permission is hereby granted, free of charge, to any person obtaining a copy
6
- * of this software and associated documentation files (the 'Software'), to deal
7
- * in the Software without restriction, including without limitation the rights
8
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- * copies of the Software, and to permit persons to whom the Software is
10
- * furnished to do so, subject to the following conditions:
11
- *
12
- * The above copyright notice and this permission notice shall be included in all
13
- * copies or substantial portions of the Software.
14
- *
15
- * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
18
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- * SOFTWARE.
22
- -->
3
+ (The MIT License)
4
+
5
+ Copyright (c) 2014-2017 Yegor Bugayenko
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ of this software and associated documentation files (the 'Software'), to deal
9
+ in the Software without restriction, including without limitation the rights
10
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ copies of the Software, and to permit persons to whom the Software is
12
+ furnished to do so, subject to the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be included in all
15
+ copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ SOFTWARE.
24
+ -->
23
25
  <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
24
26
  <xs:complexType name="puzzle">
25
27
  <xs:all>
@@ -92,14 +94,14 @@
92
94
  <xs:element name="puzzles">
93
95
  <xs:complexType>
94
96
  <xs:sequence>
95
- <xs:element name="puzzle" type="puzzle" minOccurs="0" maxOccurs="unbounded" />
97
+ <xs:element name="puzzle" type="puzzle" minOccurs="0" maxOccurs="unbounded"/>
96
98
  </xs:sequence>
97
99
  <xs:attribute name="version" use="required" type="xs:string"/>
98
100
  <xs:attribute name="date" use="required" type="xs:dateTime"/>
99
101
  </xs:complexType>
100
102
  <xs:unique name="puzzleBody">
101
- <xs:selector xpath="./puzzle" />
102
- <xs:field xpath="body" />
103
+ <xs:selector xpath="./puzzle"/>
104
+ <xs:field xpath="body"/>
103
105
  </xs:unique>
104
106
  </xs:element>
105
107
  </xs:schema>
data/assets/puzzles.xsl CHANGED
@@ -1,27 +1,28 @@
1
1
  <?xml version="1.0"?>
2
2
  <!--
3
- * Copyright (c) 2014-2017 Yegor Bugayenko
4
- *
5
- * Permission is hereby granted, free of charge, to any person obtaining a copy
6
- * of this software and associated documentation files (the 'Software'), to deal
7
- * in the Software without restriction, including without limitation the rights
8
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- * copies of the Software, and to permit persons to whom the Software is
10
- * furnished to do so, subject to the following conditions:
11
- *
12
- * The above copyright notice and this permission notice shall be included in all
13
- * copies or substantial portions of the Software.
14
- *
15
- * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
18
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- * SOFTWARE.
22
- -->
23
- <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
24
- version="1.0" xmlns="http://www.w3.org/1999/xhtml">
3
+ (The MIT License)
4
+
5
+ Copyright (c) 2014-2017 Yegor Bugayenko
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ of this software and associated documentation files (the 'Software'), to deal
9
+ in the Software without restriction, including without limitation the rights
10
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ copies of the Software, and to permit persons to whom the Software is
12
+ furnished to do so, subject to the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be included in all
15
+ copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ SOFTWARE.
24
+ -->
25
+ <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml" version="1.0">
25
26
  <xsl:template match="/">
26
27
  <xsl:text disable-output-escaping="yes">&lt;!DOCTYPE html&gt;</xsl:text>
27
28
  <html lang="en">
@@ -30,7 +31,9 @@
30
31
  <meta name="description" content="PDD puzzles"/>
31
32
  <meta name="keywords" content="puzzle driven development"/>
32
33
  <meta name="author" content="teamed.io"/>
33
- <title><xsl:text>PDD Summary Report</xsl:text></title>
34
+ <title>
35
+ <xsl:text>PDD Summary Report</xsl:text>
36
+ </title>
34
37
  <style type="text/css">
35
38
  body {
36
39
  background-color: #e6e1ce;
@@ -67,11 +70,21 @@
67
70
  </colgroup>
68
71
  <thead>
69
72
  <tr>
70
- <th><xsl:text>id</xsl:text></th>
71
- <th><xsl:text>ticket</xsl:text></th>
72
- <th><xsl:text>body</xsl:text></th>
73
- <th><xsl:text>estimate</xsl:text></th>
74
- <th><xsl:text>role</xsl:text></th>
73
+ <th>
74
+ <xsl:text>id</xsl:text>
75
+ </th>
76
+ <th>
77
+ <xsl:text>ticket</xsl:text>
78
+ </th>
79
+ <th>
80
+ <xsl:text>body</xsl:text>
81
+ </th>
82
+ <th>
83
+ <xsl:text>estimate</xsl:text>
84
+ </th>
85
+ <th>
86
+ <xsl:text>role</xsl:text>
87
+ </th>
75
88
  </tr>
76
89
  </thead>
77
90
  <tbody>
@@ -84,8 +97,12 @@
84
97
  </xsl:template>
85
98
  <xsl:template match="puzzle">
86
99
  <tr>
87
- <td><xsl:value-of select="id"/></td>
88
- <td><xsl:value-of select="ticket"/></td>
100
+ <td>
101
+ <xsl:value-of select="id"/>
102
+ </td>
103
+ <td>
104
+ <xsl:value-of select="ticket"/>
105
+ </td>
89
106
  <td>
90
107
  <code>
91
108
  <xsl:value-of select="file"/>
@@ -95,8 +112,12 @@
95
112
  <br/>
96
113
  <xsl:value-of select="body"/>
97
114
  </td>
98
- <td><xsl:value-of select="estimate"/></td>
99
- <td><xsl:value-of select="role"/></td>
115
+ <td>
116
+ <xsl:value-of select="estimate"/>
117
+ </td>
118
+ <td>
119
+ <xsl:value-of select="role"/>
120
+ </td>
100
121
  </tr>
101
122
  </xsl:template>
102
123
  </xsl:stylesheet>
data/bin/pdd CHANGED
@@ -1,6 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
- # encoding: utf-8
3
- #
4
2
  # Copyright (c) 2014-2017 Yegor Bugayenko
5
3
  #
6
4
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -25,51 +23,80 @@ STDOUT.sync = true
25
23
 
26
24
  require 'slop'
27
25
  require 'nokogiri'
26
+ require 'rainbow'
28
27
  require_relative '../lib/pdd'
29
28
  require_relative '../lib/pdd/version'
30
29
 
31
- args = []
32
- args += File.read('.pdd').split(/\s+/).map(&:strip) if File.exist?('.pdd')
33
- args += ARGV
34
-
35
- opts = Slop.parse(args, strict: true, help: true) do |o|
36
- o.banner = "Usage (#{PDD::VERSION}): pdd [options]"
37
- o.bool '-h', '--help', 'Show these instructions'
38
- o.bool '-v', '--verbose', 'Enable verbose mode'
39
- o.bool '-q', '--quiet', 'Enable quiet mode'
40
- o.bool '--version', 'Show current version'
41
- o.string '-s', '--source', 'Source directory to parse'
42
- o.string '-f', '--file', 'File to save XML into'
43
- o.array '-e', '--exclude', 'Glob pattern to exclude'
44
- o.string '-t', '--format', 'Format to use (xml|html)'
45
- o.array '-r', '--rule', 'Rule to apply', delimiter: ';'
46
- end
30
+ begin
31
+ args = []
32
+ if File.exist?('.pdd')
33
+ cfg = File.new('.pdd')
34
+ body = File.read(cfg)
35
+ extra = body.split(/\s+/).map(&:strip)
36
+ args += extra
37
+ puts "Found #{body.split(/\n/).length} lines in #{File.absolute_path(cfg)}"
38
+ end
39
+ args += ARGV
47
40
 
48
- raise '-f is mandatory when using -v' if opts.verbose? && !opts.file?
41
+ begin
42
+ opts = Slop.parse(args, strict: true, help: true) do |o|
43
+ o.banner = "Usage (#{PDD::VERSION}): pdd [options]"
44
+ o.bool '-h', '--help', 'Show these instructions'
45
+ o.bool '-v', '--verbose', 'Enable verbose mode (a lot of logging)'
46
+ o.bool '-q', '--quiet', 'Enable quiet mode (almost no logging)'
47
+ o.bool '-i', '--version', 'Show current version' do
48
+ puts PDD::VERSION
49
+ exit
50
+ end
51
+ o.string '-s', '--source', 'Source directory to parse ("." by default)'
52
+ o.string '-f', '--file', 'File to save XML into'
53
+ o.array '-e', '--exclude', 'Glob pattern to exclude, e.g. "**/*.jpg"'
54
+ o.string '-t', '--format', 'Format of the report (xml|html)'
55
+ o.array(
56
+ '-r', '--rule', 'Rule to apply (can be used many times)',
57
+ delimiter: ';'
58
+ )
59
+ end
60
+ rescue Slop::Error => ex
61
+ raise StandardError, "#{ex.message}, try --help"
62
+ end
49
63
 
50
- if opts.help?
51
- puts opts
52
- exit
53
- end
64
+ if opts.help?
65
+ puts opts
66
+ puts "This is our README to learn more: \
67
+ https://github.com/yegor256/pdd/blob/master/README.md"
68
+ exit
69
+ end
54
70
 
55
- if opts.version?
56
- puts PDD::VERSION
57
- exit
58
- end
71
+ if opts.verbose? && !opts.file?
72
+ raise '-f is mandatory when using -v, try --help for more information'
73
+ end
59
74
 
60
- Encoding.default_external = Encoding::UTF_8
61
- Encoding.default_internal = Encoding::UTF_8
62
- file = opts.file? ? File.new(opts[:file], 'w') : STDOUT
63
- output = PDD::Base.new(opts).xml
64
- if opts[:format]
65
- if opts[:format] == 'html'
66
- xslt = File.join(
67
- File.dirname(File.dirname(__FILE__)),
68
- 'assets', 'puzzles.xsl'
69
- )
70
- output = Nokogiri::XSLT(File.read(xslt)).transform(Nokogiri::XML(output))
71
- elsif opts[:format] != 'xml'
72
- raise 'invalid format, use html or xml'
75
+ Encoding.default_external = Encoding::UTF_8
76
+ Encoding.default_internal = Encoding::UTF_8
77
+ file = opts.file? ? File.new(opts[:file], 'w') : STDOUT
78
+ output = PDD::Base.new(opts).xml
79
+ if opts[:format]
80
+ if opts[:format] == 'html'
81
+ xslt = File.join(
82
+ File.dirname(File.dirname(__FILE__)),
83
+ 'assets', 'puzzles.xsl'
84
+ )
85
+ output = Nokogiri::XSLT(File.read(xslt)).transform(Nokogiri::XML(output))
86
+ elsif opts[:format] != 'xml'
87
+ raise 'Invalid format, use html or xml'
88
+ end
73
89
  end
90
+ file << output
91
+ rescue SystemExit => ex
92
+ puts ex.message unless ex.success?
93
+ exit(ex.status)
94
+ rescue StandardError => ex
95
+ puts "#{Rainbow('ERROR').red}: #{ex.message}"
96
+ puts "If you can't understand the cause of this issue or you don't know \
97
+ how to fix it, please submit a GitHub issue, we will try to help you: \
98
+ https://github.com/yegor256/pdd/issues. This tool is still in its beta \
99
+ version and we will appreciate your feedback. Here is where you can find \
100
+ more documentation: https://github.com/yegor256/pdd/blob/master/README.md."
101
+ exit(-1)
74
102
  end
75
- file << output
@@ -21,7 +21,7 @@ Feature: Catches Broken Puzzles
21
21
  }
22
22
  """
23
23
  When I run pdd it fails with "Space expected"
24
- When I run pdd it fails with "in line #6"
24
+ When I run pdd it fails with "puzzle at line #6"
25
25
 
26
26
  Scenario: Throwing exception on another broken puzzle
27
27
  Given I have a "Sample.java" file with content:
@@ -36,7 +36,7 @@ Feature: Catches Broken Puzzles
36
36
  }
37
37
  }
38
38
  """
39
- When I run pdd it fails with "Too many spaces"
39
+ When I run pdd it fails with "Too many leading spaces"
40
40
 
41
41
  Scenario: Throwing exception on yet another broken puzzle
42
42
  Given I have a "Sample.java" file with content:
data/features/cli.feature CHANGED
@@ -26,7 +26,7 @@ Feature: Command Line Processing
26
26
  """
27
27
  When I run bin/pdd with "-v -s . -f out.xml"
28
28
  Then Exit code is zero
29
- And Stdout contains "reading ."
29
+ And Stdout contains "Reading ."
30
30
  And XML file "out.xml" matches "/puzzles[count(puzzle)=1]"
31
31
 
32
32
  Scenario: Using basic rules
@@ -18,5 +18,5 @@ Feature: HTML output
18
18
  """
19
19
  When I run bin/pdd with "-v -s . -f out.html --format=html"
20
20
  Then Exit code is zero
21
- And Stdout contains "reading ."
21
+ And Stdout contains "Reading ."
22
22
  And XML file "out.html" matches "/html/body"
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
- #
3
1
  # Copyright (c) 2014-2017 Yegor Bugayenko
4
2
  #
5
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -31,8 +29,9 @@ Before do
31
29
  @dir = Dir.mktmpdir('test')
32
30
  FileUtils.mkdir_p(@dir) unless File.exist?(@dir)
33
31
  Dir.chdir(@dir)
34
- @opts = Slop.parse ['-v', '-s', @dir] do |o|
32
+ @opts = Slop.parse ['-q', '-s', @dir] do |o|
35
33
  o.bool '-v', '--verbose'
34
+ o.bool '-q', '--quiet'
36
35
  o.string '-s', '--source'
37
36
  end
38
37
  end
@@ -95,11 +94,11 @@ Then(/^XML file "([^"]+)" matches "([^"]+)"$/) do |file, xpath|
95
94
  end
96
95
 
97
96
  Then(/^Exit code is zero$/) do
98
- raise "Non-zero exit code #{@exitstatus}" unless @exitstatus == 0
97
+ raise "Non-zero exit code #{@exitstatus}" unless @exitstatus.zero?
99
98
  end
100
99
 
101
100
  Then(/^Exit code is not zero$/) do
102
- raise 'Zero exit code' if @exitstatus == 0
101
+ raise 'Zero exit code' if @exitstatus.zero?
103
102
  end
104
103
 
105
104
  When(/^I run bash with$/) do |text|
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
- #
3
1
  # Copyright (c) 2014-2017 Yegor Bugayenko
4
2
  #
5
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -23,5 +23,5 @@ Feature: Unicode
23
23
  \xFF test again
24
24
  """
25
25
  When I run bin/pdd with "--exclude=test.txt -v -f=/dev/null"
26
- Then Stdout contains "excluding test.txt"
26
+ Then Stdout contains "Excluding test.txt"
27
27
  Then Exit code is zero
@@ -16,6 +16,6 @@ Feature: Using .pdd config file
16
16
  """
17
17
  When I run bin/pdd with ""
18
18
  Then Exit code is zero
19
- And Stdout contains "reading ."
19
+ And Stdout contains "Reading ."
20
20
  And XML file "out.xml" matches "/puzzles[count(puzzle)=1]"
21
21
 
data/lib/pdd.rb CHANGED
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
- #
3
1
  # Copyright (c) 2014-2017 Yegor Bugayenko
4
2
  #
5
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -23,6 +21,7 @@
23
21
  require 'nokogiri'
24
22
  require 'logger'
25
23
  require 'time'
24
+ require 'rainbow'
26
25
  require_relative 'pdd/sources'
27
26
  require_relative 'pdd/version'
28
27
  require_relative 'pdd/rule/estimates'
@@ -53,10 +52,14 @@ module PDD
53
52
 
54
53
  # Get logger.
55
54
  def self.log
56
- unless @logger
55
+ unless defined?(@logger)
57
56
  @logger = Logger.new(STDOUT)
58
57
  @logger.formatter = proc { |severity, _, _, msg|
59
- "#{severity}: #{msg.dump}\n"
58
+ if severity == 'ERROR'
59
+ "#{Rainbow(severity).red}: #{msg}\n"
60
+ else
61
+ "#{msg}\n"
62
+ end
60
63
  }
61
64
  @logger.level = Logger::ERROR
62
65
  end
@@ -75,19 +78,21 @@ module PDD
75
78
  @opts = opts
76
79
  PDD.log.level = Logger::INFO if @opts[:verbose]
77
80
  PDD.log.level = Logger::ERROR if @opts[:quiet]
78
- PDD.log.info "my version is #{PDD::VERSION}"
81
+ PDD.log.info "My version is #{PDD::VERSION}"
79
82
  PDD.log.info "Ruby version is #{RUBY_VERSION} at #{RUBY_PLATFORM}"
80
83
  end
81
84
 
82
85
  # Generate XML.
83
86
  def xml
84
87
  dir = @opts[:source] ? @opts[:source] : Dir.pwd
85
- PDD.log.info "reading #{dir}"
88
+ PDD.log.info "Reading #{dir}"
86
89
  sources = Sources.new(dir)
87
- @opts[:exclude].each do |p|
88
- sources = sources.exclude(p)
89
- PDD.log.info "excluding #{p}"
90
- end unless @opts[:exclude].nil?
90
+ unless @opts[:exclude].nil?
91
+ @opts[:exclude].each do |p|
92
+ sources = sources.exclude(p)
93
+ PDD.log.info "Excluding #{p}"
94
+ end
95
+ end
91
96
  sanitize(
92
97
  rules(
93
98
  Nokogiri::XML::Builder.new do |xml|
@@ -95,7 +100,7 @@ module PDD
95
100
  xml.puzzles(attrs) do
96
101
  sources.fetch.each do |source|
97
102
  source.puzzles.each do |puzzle|
98
- PDD.log.info "puzzle #{puzzle.props[:id]} " \
103
+ PDD.log.info "Puzzle #{puzzle.props[:id]} " \
99
104
  "#{puzzle.props[:estimate]}/#{puzzle.props[:role]}" \
100
105
  " at #{puzzle.props[:file]}"
101
106
  render puzzle, xml
@@ -145,13 +150,13 @@ module PDD
145
150
  list.push('max-duplicates:1').map do |r|
146
151
  name, value = r.split(':')
147
152
  rule = RULES[name]
148
- raise "rule '#{name}' doesn't exist" if rule.nil?
153
+ raise "Rule '#{name}' doesn't exist" if rule.nil?
149
154
  rule.new(doc, value).errors.each do |e|
150
155
  PDD.log.error e
151
156
  total += 1
152
157
  end
153
158
  end
154
- raise PDD::Error, "#{total} errors, see log above" unless total == 0
159
+ raise PDD::Error, "#{total} errors, see log above" unless total.zero?
155
160
  xml
156
161
  end
157
162
 
data/lib/pdd/puzzle.rb CHANGED
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
- #
3
1
  # Copyright (c) 2014-2017 Yegor Bugayenko
4
2
  #
5
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
- #
3
1
  # Copyright (c) 2014-2017 Yegor Bugayenko
4
2
  #
5
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
- #
3
1
  # Copyright (c) 2014-2017 Yegor Bugayenko
4
2
  #
5
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -34,7 +32,7 @@ module PDD
34
32
 
35
33
  def errors
36
34
  @xml.xpath("//puzzle[number(estimate) < #{@min}]").map do |p|
37
- "puzzle #{p.xpath('file/text()')}:#{p.xpath('lines/text()')}"\
35
+ "Puzzle #{p.xpath('file/text()')}:#{p.xpath('lines/text()')}"\
38
36
  " has an estimate of #{p.xpath('estimate/text()')} minutes,"\
39
37
  " which is lower than #{@min} minutes"
40
38
  end
@@ -52,7 +50,7 @@ module PDD
52
50
 
53
51
  def errors
54
52
  @xml.xpath("//puzzle[number(estimate) > #{@min}]").map do |p|
55
- "puzzle #{p.xpath('file/text()')}:#{p.xpath('lines/text()')}"\
53
+ "Puzzle #{p.xpath('file/text()')}:#{p.xpath('lines/text()')}"\
56
54
  " has an estimate of #{p.xpath('estimate/text()')} minutes,"\
57
55
  " which is bigger than #{@min} minutes"
58
56
  end
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
- #
3
1
  # Copyright (c) 2014-2017 Yegor Bugayenko
4
2
  #
5
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
data/lib/pdd/rule/text.rb CHANGED
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
- #
3
1
  # Copyright (c) 2014-2017 Yegor Bugayenko
4
2
  #
5
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -36,7 +34,7 @@ module PDD
36
34
  @xml.xpath('//puzzle').map do |p|
37
35
  words = p.xpath('body/text()').to_s.split.size
38
36
  next nil if words >= @min
39
- "puzzle #{p.xpath('file/text()')}:#{p.xpath('lines/text()')}"\
37
+ "Puzzle #{p.xpath('file/text()')}:#{p.xpath('lines/text()')}"\
40
38
  " has a very short description of just #{words} words while"\
41
39
  " a minimum of #{@min} is required"
42
40
  end.compact
data/lib/pdd/source.rb CHANGED
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
- #
3
1
  # Copyright (c) 2014-2017 Yegor Bugayenko
4
2
  #
5
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -22,7 +20,6 @@
22
20
 
23
21
  require 'digest/md5'
24
22
  require 'shellwords'
25
- require_relative '../pdd'
26
23
  require_relative '../pdd/puzzle'
27
24
 
28
25
  module PDD
@@ -38,7 +35,7 @@ module PDD
38
35
 
39
36
  # Fetch all puzzles.
40
37
  def puzzles
41
- PDD.log.info "reading #{@path}..."
38
+ PDD.log.info "Reading #{@path}..."
42
39
  re = %r{(.*(?:^|\s))@todo\s+#([\w\-\.:/]+)\s+(.+)}
43
40
  puzzles = []
44
41
  lines = File.readlines(@file)
@@ -47,10 +44,8 @@ module PDD
47
44
  re.match(line) do |match|
48
45
  puzzles << puzzle(lines.drop(idx + 1), match, idx)
49
46
  end
50
- rescue Error => ex
51
- raise Error, ["in line ##{idx + 1}", ex]
52
- rescue ArgumentError => ex
53
- raise Error, ["in line ##{idx + 1}", ex]
47
+ rescue Error, ArgumentError => ex
48
+ raise Error, "puzzle at line ##{idx + 1}; #{ex.message}"
54
49
  end
55
50
  end
56
51
  lines.each_with_index do |line, idx|
@@ -66,7 +61,7 @@ explains: https://github.com/yegor256/pdd#how-to-format"
66
61
 
67
62
  # Fetch puzzle
68
63
  def puzzle(lines, match, idx)
69
- tail = tail(lines, match[1])
64
+ tail = tail(lines, match[1], idx)
70
65
  body = (match[3] + ' ' + tail.join(' ')).gsub(/\s+/, ' ').strip
71
66
  marker = marker(match[2])
72
67
  Puzzle.new(
@@ -102,35 +97,52 @@ against the rules explained here: https://github.com/yegor256/pdd#how-to-format"
102
97
  end
103
98
 
104
99
  # Fetch puzzle tail (all lines after the first one)
105
- def tail(lines, prefix)
100
+ def tail(lines, prefix, start)
106
101
  lines
107
102
  .take_while { |t| t.start_with?(prefix) }
108
103
  .map { |t| t[prefix.length, t.length] }
109
104
  .take_while { |t| t =~ /^[ a-zA-Z0-9]/ }
110
- .each { |t| raise Error, 'Space expected' unless t.start_with?(' ') }
111
- .each { |t| raise Error, 'Too many spaces' if t =~ /^\s{2,}/ }
105
+ .each_with_index do |t, i|
106
+ next if t.start_with?(' ')
107
+ raise Error, "Space expected at #{start + i + 2}:#{prefix.length}; \
108
+ make sure all lines in the puzzle body have a single leading space."
109
+ end
110
+ .each_with_index do |t, i|
111
+ next if t !~ /^\s{2,}/
112
+ raise Error, "Too many leading spaces \
113
+ at #{start + i + 2}:#{prefix.length}; \
114
+ make sure all lines that include the puzzle body start \
115
+ at position ##{prefix.length + 1}."
116
+ end
112
117
  .map { |t| t[1, t.length] }
113
118
  end
114
119
 
115
120
  # Git information at the line
116
121
  def git(pos)
117
- cmd = "cd #{Shellwords.escape(File.dirname(@file))} && \
118
- git blame -L #{pos},#{pos} --porcelain \
119
- #{Shellwords.escape(File.basename(@file))}"
120
- Hash[
121
- `#{cmd}`.split("\n").map do |line|
122
- if line =~ /^author /
123
- [:author, line.sub(/^author /, '')]
124
- elsif line =~ /^author-mail /
125
- [:email, line.sub(/^author-mail <(.+)>$/, '\1')]
126
- elsif line =~ /^author-time /
127
- [
128
- :time,
129
- Time.at(line.sub(/^author-time ([0-9]+)$/, '\1').to_i).utc.iso8601
130
- ]
131
- end
132
- end.compact
133
- ]
122
+ dir = Shellwords.escape(File.dirname(@file))
123
+ name = Shellwords.escape(File.basename(@file))
124
+ git = "cd #{dir} && git"
125
+ if `#{git} rev-parse --is-inside-work-tree 2>/dev/null`.strip == 'true'
126
+ cmd = "#{git} blame -L #{pos},#{pos} --porcelain #{name}"
127
+ Hash[
128
+ `#{cmd}`.split("\n").map do |line|
129
+ if line =~ /^author /
130
+ [:author, line.sub(/^author /, '')]
131
+ elsif line =~ /^author-mail /
132
+ [:email, line.sub(/^author-mail <(.+)>$/, '\1')]
133
+ elsif line =~ /^author-time /
134
+ [
135
+ :time,
136
+ Time.at(
137
+ line.sub(/^author-time ([0-9]+)$/, '\1').to_i
138
+ ).utc.iso8601
139
+ ]
140
+ end
141
+ end.compact
142
+ ]
143
+ else
144
+ {}
145
+ end
134
146
  end
135
147
  end
136
148
 
@@ -148,7 +160,7 @@ git blame -L #{pos},#{pos} --porcelain \
148
160
  def puzzles
149
161
  @source.puzzles
150
162
  rescue Error => ex
151
- raise Error, ["in #{@file}", ex]
163
+ raise Error, "#{@file}; #{ex.message}"
152
164
  end
153
165
  end
154
166
  end
data/lib/pdd/sources.rb CHANGED
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
- #
3
1
  # Copyright (c) 2014-2017 Yegor Bugayenko
4
2
  #
5
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -22,7 +20,6 @@
22
20
 
23
21
  require 'shellwords'
24
22
  require 'English'
25
- require_relative '../pdd'
26
23
  require_relative 'source'
27
24
 
28
25
  module PDD
data/lib/pdd/version.rb CHANGED
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
- #
3
1
  # Copyright (c) 2014-2017 Yegor Bugayenko
4
2
  #
5
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -25,5 +23,5 @@
25
23
  # Copyright:: Copyright (c) 2014-2017 Yegor Bugayenko
26
24
  # License:: MIT
27
25
  module PDD
28
- VERSION = '0.17.9'.freeze
26
+ VERSION = '0.18'.freeze
29
27
  end
data/pdd.gemspec CHANGED
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
- #
3
1
  # Copyright (c) 2014-2017 Yegor Bugayenko
4
2
  #
5
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -20,6 +18,8 @@
20
18
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
19
  # SOFTWARE.
22
20
 
21
+ require 'English'
22
+
23
23
  lib = File.expand_path('../lib', __FILE__)
24
24
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
25
25
  require_relative 'lib/pdd/version'
@@ -35,7 +35,7 @@ Gem::Specification.new do |s|
35
35
  s.version = PDD::VERSION
36
36
  s.license = 'MIT'
37
37
  s.summary = 'Puzzle Driven Development collector'
38
- s.description = 'Collects PDD puzzles from source code base'
38
+ s.description = 'Collects PDD puzzles from a source code base'
39
39
  s.authors = ['Yegor Bugayenko']
40
40
  s.email = 'yegor256@gmail.com'
41
41
  s.homepage = 'http://github.com/yegor256/pdd'
@@ -44,14 +44,16 @@ Gem::Specification.new do |s|
44
44
  s.test_files = s.files.grep(%r{^(test|spec|features)/})
45
45
  s.rdoc_options = ['--charset=UTF-8']
46
46
  s.extra_rdoc_files = ['README.md', 'LICENSE.txt']
47
- s.add_runtime_dependency 'nokogiri', '~>1.7.2'
48
- s.add_runtime_dependency 'slop', '~>4.4.1'
47
+ s.add_runtime_dependency 'nokogiri', '~>1.7'
48
+ s.add_runtime_dependency 'slop', '~>4.4'
49
+ s.add_runtime_dependency 'rainbow', '~>2.2'
49
50
  s.add_development_dependency 'rake', '12.0.0'
50
51
  s.add_development_dependency 'codecov', '0.1.10'
51
52
  s.add_development_dependency 'rdoc', '4.2.0'
52
53
  s.add_development_dependency 'cucumber', '1.3.17'
53
54
  s.add_development_dependency 'minitest', '5.5.0'
54
- s.add_development_dependency 'rubocop', '0.41.2'
55
- s.add_development_dependency 'rubocop-rspec', '1.5.1'
55
+ s.add_development_dependency 'rubocop', '0.48.1'
56
+ s.add_development_dependency 'rubocop-rspec', '1.15.1'
56
57
  s.add_development_dependency 'rspec-rails', '3.1.0'
58
+ s.add_development_dependency 'xcop', '~>0.5'
57
59
  end
data/test/test__helper.rb CHANGED
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
- #
3
1
  # Copyright (c) 2014-2017 Yegor Bugayenko
4
2
  #
5
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
- #
3
1
  # Copyright (c) 2014-2017 Yegor Bugayenko
4
2
  #
5
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
- #
3
1
  # Copyright (c) 2014-2017 Yegor Bugayenko
4
2
  #
5
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
data/test/test_pdd.rb CHANGED
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
- #
3
1
  # Copyright (c) 2014-2017 Yegor Bugayenko
4
2
  #
5
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -33,7 +31,7 @@ require_relative '../lib/pdd'
33
31
  class TestPDD < Minitest::Test
34
32
  def test_basic
35
33
  Dir.mktmpdir 'test' do |dir|
36
- opts = opts(['-v', '-s', dir, '-e', '**/*.png', '-r', 'max-estimate:15'])
34
+ opts = opts(['-q', '-s', dir, '-e', '**/*.png', '-r', 'max-estimate:15'])
37
35
  File.write(File.join(dir, 'a.txt'), '@todo #55 hello!')
38
36
  matches(
39
37
  Nokogiri::XML(PDD::Base.new(opts).xml),
@@ -50,7 +48,7 @@ class TestPDD < Minitest::Test
50
48
 
51
49
  def test_rules_failure
52
50
  Dir.mktmpdir 'test' do |dir|
53
- opts = opts(['-v', '-s', dir, '-e', '**/*.png', '-r', 'min-estimate:30'])
51
+ opts = opts(['-q', '-s', dir, '-e', '**/*.png', '-r', 'min-estimate:30'])
54
52
  File.write(File.join(dir, 'a.txt'), '@todo #90 hello!')
55
53
  assert_raises PDD::Error do
56
54
  PDD::Base.new(opts).xml
@@ -61,21 +59,21 @@ class TestPDD < Minitest::Test
61
59
  def test_git_repo
62
60
  skip if Gem.win_platform?
63
61
  Dir.mktmpdir 'test' do |dir|
64
- opts = opts(['-v', '-s', dir])
62
+ opts = opts(['-q', '-s', dir])
65
63
  raise unless system("
66
64
  set -e
67
65
  cd '#{dir}'
68
- git init .
66
+ git init --quiet .
69
67
  git config user.email test@teamed.io
70
68
  git config user.name 'Mr. Tester'
71
69
  mkdir 'a long dir name'
72
70
  cd 'a long dir name'
73
71
  mkdir 'a kid'
74
72
  cd 'a kid'
75
- echo '@todo #1 this is the puzzle' > '.это файл.txt'
73
+ echo '@todo #1 this is some puzzle' > '.это файл.txt'
76
74
  cd ../..
77
75
  git add -f .
78
- git commit -am 'first version'
76
+ git commit --quiet -am 'first version'
79
77
  ")
80
78
  matches(
81
79
  Nokogiri::XML(PDD::Base.new(opts).xml),
@@ -96,6 +94,7 @@ class TestPDD < Minitest::Test
96
94
  def opts(args)
97
95
  Slop.parse args do |o|
98
96
  o.bool '-v', '--verbose'
97
+ o.bool '-q', '--quiet'
99
98
  o.string '-s', '--source'
100
99
  o.array '-e', '--exclude'
101
100
  o.array '-r', '--rule'
data/test/test_roles.rb CHANGED
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
- #
3
1
  # Copyright (c) 2014-2017 Yegor Bugayenko
4
2
  #
5
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
data/test/test_source.rb CHANGED
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
- #
3
1
  # Copyright (c) 2014-2017 Yegor Bugayenko
4
2
  #
5
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -22,6 +20,7 @@
22
20
 
23
21
  require 'minitest/autorun'
24
22
  require 'tmpdir'
23
+ require_relative '../lib/pdd'
25
24
  require_relative '../lib/pdd/sources'
26
25
 
27
26
  # Source test.
@@ -49,6 +48,9 @@ class TestSource < Minitest::Test
49
48
  assert_equal '2-3', puzzle.props[:lines]
50
49
  assert_equal 'hello, how are you doing?', puzzle.props[:body]
51
50
  assert_equal '44', puzzle.props[:ticket]
51
+ assert puzzle.props[:author].nil?
52
+ assert puzzle.props[:email].nil?
53
+ assert puzzle.props[:time].nil?
52
54
  end
53
55
  end
54
56
 
@@ -119,13 +121,12 @@ class TestSource < Minitest::Test
119
121
  raise unless system("
120
122
  set -e
121
123
  cd '#{dir}'
122
- git init .
124
+ git init --quiet .
123
125
  git config user.email test@teamed.io
124
126
  git config user.name test
125
127
  echo '@todo #1 this is the puzzle' > a.txt
126
128
  git add a.txt
127
- git commit -am 'first version'
128
- git blame a.txt
129
+ git commit --quiet -am 'first version'
129
130
  ")
130
131
  list = PDD::Source.new(File.join(dir, 'a.txt'), '').puzzles
131
132
  assert_equal 1, list.size
data/test/test_sources.rb CHANGED
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
- #
3
1
  # Copyright (c) 2014-2017 Yegor Bugayenko
4
2
  #
5
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
data/test/test_text.rb CHANGED
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
- #
3
1
  # Copyright (c) 2014-2017 Yegor Bugayenko
4
2
  #
5
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
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.17.9
4
+ version: '0.18'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yegor Bugayenko
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-06-07 00:00:00.000000000 Z
11
+ date: 2017-10-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -16,28 +16,42 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 1.7.2
19
+ version: '1.7'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 1.7.2
26
+ version: '1.7'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: slop
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 4.4.1
33
+ version: '4.4'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 4.4.1
40
+ version: '4.4'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rainbow
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '2.2'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '2.2'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: rake
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -114,28 +128,28 @@ dependencies:
114
128
  requirements:
115
129
  - - '='
116
130
  - !ruby/object:Gem::Version
117
- version: 0.41.2
131
+ version: 0.48.1
118
132
  type: :development
119
133
  prerelease: false
120
134
  version_requirements: !ruby/object:Gem::Requirement
121
135
  requirements:
122
136
  - - '='
123
137
  - !ruby/object:Gem::Version
124
- version: 0.41.2
138
+ version: 0.48.1
125
139
  - !ruby/object:Gem::Dependency
126
140
  name: rubocop-rspec
127
141
  requirement: !ruby/object:Gem::Requirement
128
142
  requirements:
129
143
  - - '='
130
144
  - !ruby/object:Gem::Version
131
- version: 1.5.1
145
+ version: 1.15.1
132
146
  type: :development
133
147
  prerelease: false
134
148
  version_requirements: !ruby/object:Gem::Requirement
135
149
  requirements:
136
150
  - - '='
137
151
  - !ruby/object:Gem::Version
138
- version: 1.5.1
152
+ version: 1.15.1
139
153
  - !ruby/object:Gem::Dependency
140
154
  name: rspec-rails
141
155
  requirement: !ruby/object:Gem::Requirement
@@ -150,7 +164,21 @@ dependencies:
150
164
  - - '='
151
165
  - !ruby/object:Gem::Version
152
166
  version: 3.1.0
153
- description: Collects PDD puzzles from source code base
167
+ - !ruby/object:Gem::Dependency
168
+ name: xcop
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - "~>"
172
+ - !ruby/object:Gem::Version
173
+ version: '0.5'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - "~>"
179
+ - !ruby/object:Gem::Version
180
+ version: '0.5'
181
+ description: Collects PDD puzzles from a source code base
154
182
  email: yegor256@gmail.com
155
183
  executables:
156
184
  - pdd