mvz-dnote 1.7.2 → 1.10.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
- SHA1:
3
- metadata.gz: eac8890fe30005d8b91d2435f22b6b147eb824e3
4
- data.tar.gz: 3095d7ed25f4a5bcf188c8d678a01567b8588934
2
+ SHA256:
3
+ metadata.gz: 8f69fc38b3682fab8db2aa937fcde974c166e74e0a72c7ce3fef709f9660fde7
4
+ data.tar.gz: f26dac2be30677f1ce05be309e4b41f178988dd926512fe534168fe4a5e44702
5
5
  SHA512:
6
- metadata.gz: 9d4b828d589ed5157db324540356362017e3be0f6cace8cedc548be8a5673da817d2e0daa91f8cf8cbd167ac03ecda97641a34e06177ae7d58316a7a19130d75
7
- data.tar.gz: a7e26ab03120551110e03e5a81154b7aa6064c6e70ae10d70a4b64eb03cf1b925ab6e41250f370fad735bd7227361683292bc29118ac578e46e681f62573a09a
6
+ metadata.gz: df50e819949330f599cdd53ecba7ef7751f4908336e7c26d9be747ea33f3144e465c993e5318bc653aaee70ba8259b70d73c1f0dc0313eb5de2f6cf1bbbc665e
7
+ data.tar.gz: 69256f599091253c91a76f36681960160cf08c0e6a6eb8bfdf811750ee1a9bc9b681d69212998f220853581c93e846249a215b433a3f3349c92a99e4d15165ad
data/HISTORY.rdoc CHANGED
@@ -1,5 +1,23 @@
1
1
  = RELEASE HISTORY
2
2
 
3
+ == 1.10.0 / 2022-04-10
4
+
5
+ * Add support for Ruby 3.1
6
+ * Drop support for Ruby 2.5
7
+ * Loosen development dependencies
8
+
9
+ == 1.9.0 / 2021-09-17
10
+
11
+ * Drop support for Ruby 2.3 and 2.4
12
+ * Officially support Ruby 2.7 and 3.0
13
+ * Update development dependencies
14
+ * Improve code quality
15
+
16
+ == 1.8.0 / 2018-12-29
17
+
18
+ * Officially support CRuby 2.5 and 2.6
19
+ * Drop support for CRuby 2.1 and 2.2
20
+
3
21
  == 1.7.2 / 2017-03-05
4
22
 
5
23
  * Support CRuby 2.4
data/README.md ADDED
@@ -0,0 +1,116 @@
1
+ # DNote
2
+
3
+ * [Homepage](http://rubyworks.github.com/dnote)
4
+ * [Mailing List](http://googlegroups.com/group/rubyworks-mailinglist)
5
+ * [Source Code](http://github.com/rubyworks/dnote)
6
+
7
+ [![Gem Version](https://badge.fury.io/rb/mvz-dnote.svg)](https://badge.fury.io/rb/mvz-dnote)
8
+ [![Maintainability](https://api.codeclimate.com/v1/badges/608621bbad5de3a98e3b/maintainability)](https://codeclimate.com/github/mvz/dnote/maintainability)
9
+
10
+ ## DESCRIPTION
11
+
12
+ Extract development notes from source code and generate some nice
13
+ output formats for them.
14
+
15
+
16
+ ## SYNOPSIS
17
+
18
+ ### Note Structure
19
+
20
+ DNote scans for the common note patterns used by developers of many languages in the form of an
21
+ all-caps labels followed by a colon. To be more specific, for DNote to recognize a note,
22
+ it needs to follow this simple set of rules:
23
+
24
+ 1. Notes start with an all-caps label punctuated with a colon, followed by the note's text.
25
+
26
+ # LABEL: description ...
27
+
28
+ 2. Any note that requires more than one line must remain flush to the left
29
+ margin (the margin is set by the first line). This is done because RDoc will mistake
30
+ the note for a `pre` block if it is indented.
31
+
32
+ # LABEL: description ...
33
+ # continue ...
34
+
35
+ 3. An alternative to the previous limitation is to indent the whole note, making it
36
+ a `<pre>` block when rendered by RDoc. Then the text layout is free-form.
37
+
38
+ # This is a description of something...
39
+ #
40
+ # LABEL: description ...
41
+ # continue ...
42
+
43
+ That's all there is to it, if I can convince the developers of RDoc to recognize labels,
44
+ we may eventually be able to relax the flush rule too, which would be very nice.
45
+
46
+ There is also a command-line option, `--no-colon`, which deactives the need for
47
+ a colon after the note label. However this often produces false positives, so its use is
48
+ discouraged.
49
+
50
+ ### Generating Notes
51
+
52
+ As you can see the commandline interface is pretty straight-forward.
53
+
54
+ USAGE:
55
+
56
+ dnote [OPTIONS] path1 [path2 ...]
57
+
58
+ OUTPUT FORMAT: (choose one)
59
+ -f, --format NAME select a format [text]
60
+ -c, --custom FILE use a custom ERB template
61
+ --file shortcut for text/file format
62
+ --list shortcut for text/list format
63
+
64
+ OTHER OPTIONS:
65
+ -l, --label LABEL labels to collect
66
+ --[no-]colon match labels with/without colon suffix
67
+ -m, --marker MARK alternative remark marker
68
+ -u --url TEMPLATE url template for line entries (for HTML)
69
+ -x, --exclude PATH exclude file or directory
70
+ -i, --ignore NAME ignore based on any part of the pathname
71
+ -t, --title TITLE title to use in header
72
+ -o, --output PATH name of file or directory
73
+ -n, --dryrun do not actually write to disk
74
+ --debug debug mode
75
+
76
+ COMMAND OPTIONS:
77
+ -T, --templates list available format templates
78
+ -h, --help show this help information
79
+
80
+ The default path is `**/*.rb` and the default format is `-f text`.
81
+ Here is an example of DNote's current notes in RDoc format:
82
+
83
+ = Development Notes
84
+
85
+ == TODO
86
+
87
+ === file://lib/dnote/notes.rb
88
+
89
+ * TODO: Add ability to read header notes. They often
90
+ have a outline format, rather then the single line. (19)
91
+ * TODO: Need good CSS file. (22)
92
+ * TODO: Need XSL? (24)
93
+
94
+ === file://plug/syckle/services/dnote.rb
95
+
96
+ * TODO: Should this service be part of the +site+ cycle? (18)
97
+
98
+ (4 TODOs)
99
+
100
+
101
+ ## INSTALLATION
102
+
103
+ The usual rubygems command will do the trick.
104
+
105
+ $ gem install mvz-dnote
106
+
107
+
108
+ ## COPYRIGHT
109
+
110
+ Copyright (c) 2006 Thomas Sawyer, Rubyworks
111
+
112
+ Copyright (c) 2017-2018 Matijs van Zuijlen
113
+
114
+ DNote is distributable in accordance with the terms of the *FreeBSD* license.
115
+
116
+ See COPYING.rdoc for details.
data/bin/dnote CHANGED
@@ -1,4 +1,13 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
2
4
  require "dnote"
3
- DNote::Session.main(*ARGV)
4
5
 
6
+ begin
7
+ DNote::Session.main(*ARGV)
8
+ rescue StandardError => e
9
+ raise e if $DEBUG
10
+
11
+ puts e
12
+ exit 1
13
+ end
@@ -1,92 +1,36 @@
1
- module Enumerable
2
-
3
- # Taken from Ruby Facets.
4
- def group_by #:yield:
5
- #h = k = e = nil
6
- r = Hash.new
7
- each{ |e| (r[yield(e)] ||= []) << e }
8
- r
9
- end unless method_defined?(:group_by)
10
-
11
- end
1
+ # frozen_string_literal: true
12
2
 
13
3
  module DNote
14
-
15
4
  # Extensions for String class.
16
5
  # These methods are taken directly from Ruby Facets.
17
6
  #
18
7
  module StringExt
19
-
20
- # Provides a margin controlled string.
21
- #
22
- # x = %Q{
23
- # | This
24
- # | is
25
- # | margin controlled!
26
- # }.margin
27
- #
28
- #
29
- # NOTE: This may still need a bit of tweaking.
30
- #
31
- # CREDIT: Trans
32
-
33
- def margin(n=0)
34
- #d = /\A.*\n\s*(.)/.match( self )[1]
35
- #d = /\A\s*(.)/.match( self)[1] unless d
36
- d = ((/\A.*\n\s*(.)/.match(self)) ||
37
- (/\A\s*(.)/.match(self)))[1]
38
- return '' unless d
39
- if n == 0
40
- gsub(/\n\s*\Z/,'').gsub(/^\s*[#{d}]/, '')
41
- else
42
- gsub(/\n\s*\Z/,'').gsub(/^\s*[#{d}]/, ' ' * n)
43
- end
44
- end
45
-
46
- # Preserves relative tabbing.
47
- # The first non-empty line ends up with n spaces before nonspace.
48
- #
49
- # CREDIT: Gavin Sinclair
50
-
51
- def tabto(n)
52
- if self =~ /^( *)\S/
53
- indent(n - $1.length)
54
- else
55
- self
56
- end
57
- end
58
-
59
- # Indent left or right by n spaces.
8
+ # Indent left or right by num spaces.
60
9
  # (This used to be called #tab and aliased as #indent.)
61
10
  #
62
11
  # CREDIT: Gavin Sinclair
63
12
  # CREDIT: Trans
64
13
 
65
- def indent(n)
66
- if n >= 0
67
- gsub(/^/, ' ' * n)
14
+ def indent(num)
15
+ if num >= 0
16
+ gsub(/^/, " " * num)
68
17
  else
69
- gsub(/^ {0,#{-n}}/, "")
18
+ gsub(/^ {0,#{-num}}/, "")
70
19
  end
71
20
  end
72
21
 
73
- #
74
- #
75
- def tabset(n)
22
+ def tabset(num)
76
23
  i = lines.map do |line|
77
24
  line.strip.empty? ? nil : line.index(/\S/)
78
25
  end
79
26
  x = i.compact.min
80
- t = n - x.to_i
27
+ t = num - x.to_i
81
28
  t = 0 if t < 0
82
29
  indent(t)
83
30
  end
84
-
85
31
  end
86
-
87
- class ::String #:nodoc:
88
- include DNote::StringExt
89
- end
90
-
91
32
  end
92
33
 
34
+ String.class_eval do
35
+ include DNote::StringExt
36
+ end
data/lib/dnote/format.rb CHANGED
@@ -1,5 +1,6 @@
1
- module DNote
1
+ # frozen_string_literal: true
2
2
 
3
+ module DNote
3
4
  # = Notes Formatter
4
5
  #
5
6
  #--
@@ -8,55 +9,35 @@ module DNote
8
9
  # TODO: Need XSL?
9
10
  #++
10
11
  class Format
11
-
12
- require 'fileutils'
13
- require 'erb'
14
- require 'rexml/text'
15
- require 'dnote/core_ext'
16
-
17
- #DEFAULT_OUTPUT_DIR = "log/dnote"
18
-
19
- EXTENSIONS = { 'text'=>'txt', 'soap'=>'xml', 'xoxo'=>'xml' }
20
-
21
- #
22
- attr :notes
23
-
24
- #
25
- attr_accessor :format
26
-
27
- #
28
- attr_accessor :subtype
29
-
30
- #
31
- attr_accessor :output
32
-
33
- #
34
- attr_accessor :template
35
-
36
- #
37
- attr_accessor :title
38
-
39
- #
40
- attr_accessor :dryrun
41
-
42
- #
43
- def initialize(notes, options={})
44
- @notes = notes
45
- @format = 'text'
46
- @subtype = 'label'
47
- @title = "Developer's Notes"
48
- @dryrun = false
49
- options.each{ |k,v| __send__("#{k}=", v) if v }
50
- yield(self) if block_given?
12
+ require "fileutils"
13
+ require "erb"
14
+ require "rexml/text"
15
+ require "dnote/core_ext"
16
+
17
+ EXTENSIONS = {"text" => "txt", "soap" => "xml", "xoxo" => "xml"}.freeze
18
+
19
+ attr_reader :notes, :format, :output, :template, :title, :dryrun
20
+
21
+ def initialize(notes,
22
+ format: "text",
23
+ title: "Developer's Notes",
24
+ template: nil,
25
+ output: nil,
26
+ dryrun: false)
27
+ @notes = notes
28
+ @format = format
29
+ @title = title
30
+ @dryrun = dryrun
31
+ @template = template
32
+ @output = output
51
33
  end
52
34
 
53
- #
54
35
  def render
55
36
  if notes.empty?
56
- $stderr << "No #{notes.labels.join(', ')} notes.\n"
37
+ $stderr << "No #{notes.labels.join(", ")} notes.\n"
57
38
  else
58
39
  case format
59
- when 'custom'
40
+ when "custom"
60
41
  render_custom
61
42
  else
62
43
  render_template
@@ -64,48 +45,43 @@ module DNote
64
45
  end
65
46
  end
66
47
 
48
+ private
49
+
67
50
  # C U S T O M
68
51
 
69
- #
70
52
  def render_custom
71
- #raise ArgumentError unless File.exist?(template)
72
53
  result = erb(template)
73
- publish(result)
54
+ publish(result)
74
55
  end
75
56
 
76
57
  # T E M P L A T E
77
58
 
78
- #
79
59
  def render_template
80
- template = File.join(File.dirname(__FILE__), 'templates', "#{format}.erb")
60
+ template = File.join(File.dirname(__FILE__), "templates", "#{format}.erb")
81
61
  raise "No such format - #{format}" unless File.exist?(template)
62
+
82
63
  result = erb(template)
83
- publish(result)
64
+ publish(result)
84
65
  end
85
66
 
86
- private
87
-
88
- #
89
67
  def erb(file)
90
- scope = ErbScope.new(:notes=>notes, :title=>title)
68
+ scope = ErbScope.new(notes: notes, title: title)
91
69
  scope.render(file)
92
70
  end
93
71
 
94
- #
95
- def publish(result, fname=nil)
72
+ def publish(result, fname = nil)
96
73
  if output
97
74
  write(result, fname)
98
75
  else
99
76
  puts(result)
100
77
  end
101
- $stderr << "(" + notes.counts.map{|l,n| "#{n} #{l}s"}.join(', ') + ")\n"
78
+ $stderr << "(#{notes.counts.map { |l, n| "#{n} #{l}s" }.join(", ")})\n"
102
79
  end
103
80
 
104
- #
105
- def write(result, fname=nil)
106
- if output.to_s[-1,1] == '/' || File.directory?(output)
107
- fmt = format.split('/').first
108
- ext = EXTENSIONS[fmt] || fmt
81
+ def write(result, fname = nil)
82
+ if output.to_s[-1, 1] == "/" || File.directory?(output)
83
+ fmt = format.split("/").first
84
+ ext = EXTENSIONS[fmt] || fmt
109
85
  file = File.join(output, fname || "notes.#{ext}")
110
86
  else
111
87
  file = output
@@ -116,25 +92,22 @@ module DNote
116
92
  else
117
93
  dir = File.dirname(file)
118
94
  fu.mkdir(dir) unless File.exist?(dir)
119
- File.open(file, 'w'){ |f| f << result }
95
+ File.open(file, "w") { |f| f << result }
120
96
  end
121
- return file
97
+ file
122
98
  end
123
99
 
124
- #
125
100
  def dryrun?
126
101
  @dryrun
127
102
  end
128
103
 
129
- #
130
104
  def debug?
131
105
  $DEBUG
132
106
  end
133
107
 
134
- #
135
108
  def fu
136
- @fu ||= (
137
- if dryrun? and debug?
109
+ @fu ||=
110
+ if dryrun? && debug?
138
111
  FileUtils::DryRun
139
112
  elsif dryrun?
140
113
  FileUtils::Noop
@@ -143,31 +116,34 @@ module DNote
143
116
  else
144
117
  FileUtils
145
118
  end
146
- )
147
119
  end
148
120
 
149
- #
150
- class ErbScope
151
- #
152
- def initialize(data={})
121
+ # Evaluation scope for ERB templates
122
+ class ErbScope
123
+ def initialize(data = {})
153
124
  @data = data
154
125
  end
155
- #
126
+
156
127
  def render(file)
157
- erb = ERB.new(File.read(file), nil, '<>')
128
+ contents = File.read(file)
129
+ erb = ERB.new(contents, trim_mode: "<>")
158
130
  erb.result(binding)
159
131
  end
160
- #
132
+
161
133
  def h(string)
162
134
  REXML::Text.normalize(string)
163
135
  end
164
- #
165
- def method_missing(s, *a)
166
- @data[s.to_sym]
136
+
137
+ def method_missing(method, *_args)
138
+ sym = method.to_sym
139
+ return @data.fetch(sym) if @data.key? sym
140
+
141
+ super
142
+ end
143
+
144
+ def respond_to_missing?(method)
145
+ @data.key?(method.to_sym) || super
167
146
  end
168
147
  end
169
-
170
148
  end
171
-
172
149
  end
173
-
data/lib/dnote/note.rb CHANGED
@@ -1,45 +1,41 @@
1
- module DNote
1
+ # frozen_string_literal: true
2
2
 
3
+ module DNote
3
4
  # The Note class encapsulates a single note made in a source file.
4
5
  #
5
6
  # Each note instance holds a reference, +notes+, to the set of notes
6
7
  # being generated for a given session. This allows the note to access
7
8
  # general options applicable to all notes.
8
9
  class Note
9
-
10
- # Number of lines to provide in source context.
11
- #CONTEXT_DEPTH = 5
12
-
13
10
  # Set of notes to which this note belongs.
14
- attr :notes
11
+ attr_reader :notes
15
12
 
16
13
  # The file in which the note is made.
17
- attr :file
14
+ attr_reader :file
18
15
 
19
16
  # The type of note.
20
- attr :label
17
+ attr_reader :label
21
18
 
22
19
  # The line number of the note.
23
- attr :line
20
+ attr_reader :line
24
21
 
25
22
  # The verbatim text of the note.
26
- attr :text
23
+ attr_reader :text
27
24
 
28
25
  # Remark marker used in parsing the note.
29
- attr :mark
26
+ attr_reader :mark
30
27
 
31
28
  # Contextual lines of code.
32
- attr :capture
29
+ attr_reader :capture
33
30
 
34
31
  # Initialize new Note instance.
35
32
  def initialize(notes, file, label, line, text, mark)
36
- @notes = notes
37
-
38
- @file = file
39
- @label = label
40
- @line = line
41
- @text = text.rstrip
42
- @mark = mark
33
+ @notes = notes
34
+ @file = file
35
+ @label = label
36
+ @line = line
37
+ @text = text.rstrip
38
+ @mark = mark
43
39
  @capture = []
44
40
  end
45
41
 
@@ -55,13 +51,14 @@ module DNote
55
51
 
56
52
  # Remove newlines from note text.
57
53
  def textline
58
- text.gsub("\n", " ")
54
+ text.tr("\n", " ")
59
55
  end
60
56
 
61
57
  # Sort by file name and line number.
62
58
  def <=>(other)
63
59
  s = file <=> other.file
64
60
  return s unless s == 0
61
+
65
62
  line <=> other.line
66
63
  end
67
64
 
@@ -71,12 +68,12 @@ module DNote
71
68
  # TODO: Add +code+? Problem is that xml needs code in CDATA.
72
69
  #++
73
70
  def to_h
74
- { 'label'=>label, 'text'=>textline, 'file'=>file, 'line'=>line }
71
+ {"label" => label, "text" => textline, "file" => file, "line" => line}
75
72
  end
76
73
 
77
74
  # Convert to Hash, leaving the note text verbatim.
78
75
  def to_h_raw
79
- { 'label'=>label, 'text'=>text, 'file'=>file, 'line'=>line, 'code'=>code }
76
+ {"label" => label, "text" => text, "file" => file, "line" => line, "code" => code}
80
77
  end
81
78
 
82
79
  # Convert to JSON.
@@ -91,15 +88,16 @@ module DNote
91
88
 
92
89
  # Return line URL based on URL template. If no template was set, then
93
90
  # returns the file.
91
+ #
92
+ # FIXME: Move out of Note so we can drop the reference to notes
94
93
  def url
95
94
  if notes.url
96
- notes.url % [file, line]
95
+ format(notes.url, file, line)
97
96
  else
98
97
  file
99
98
  end
100
99
  end
101
100
 
102
- #
103
101
  def code
104
102
  unindent(capture).join
105
103
  end
@@ -109,42 +107,20 @@ module DNote
109
107
  !capture.empty?
110
108
  end
111
109
 
112
- =begin
113
- # This isn't being used currently b/c the URL solution as deeemd better,
114
- # but the code is here for custom templates.
115
- def capture
116
- @context ||= (
117
- lines = file_cache(file) #.lines.to_a
118
- count = line()
119
- count +=1 while /^\s*#{mark}/ =~ lines[count]
120
- lines[count, context_depth]
121
- )
122
- end
123
-
124
- # Read in +file+, parse into lines and cache.
125
- def file_cache(file)
126
- @@file_cache ||= {}
127
- @@file_cache[file] ||= File.read(file).lines.to_a
128
- end
129
- =end
130
-
131
110
  private
132
111
 
133
112
  # Remove blank space from lines.
134
113
  def unindent(lines)
135
114
  dents = []
136
115
  lines.each do |line|
137
- if md = /^([\ ]*)/.match(line)
138
- size = md[1].size
116
+ if (md = /^(\ *)/.match(line))
139
117
  dents << md[1]
140
118
  end
141
119
  end
142
- dent = dents.min{ |a,b| a.size <=> b.size }
120
+ dent = dents.min_by(&:size)
143
121
  lines.map do |line|
144
- line.sub(dent, '')
122
+ line.sub(dent, "")
145
123
  end
146
124
  end
147
-
148
125
  end
149
-
150
126
  end