na 1.0.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.
Files changed (66) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +8 -0
  3. data/Gemfile +2 -0
  4. data/Gemfile.lock +35 -0
  5. data/README.rdoc +6 -0
  6. data/Rakefile +31 -0
  7. data/bin/na +285 -0
  8. data/html/App.html +105 -0
  9. data/html/NA/Action.html +299 -0
  10. data/html/NA/Color.html +373 -0
  11. data/html/NA.html +100 -0
  12. data/html/README_rdoc.html +328 -0
  13. data/html/String.html +368 -0
  14. data/html/created.rid +9 -0
  15. data/html/css/fonts.css +167 -0
  16. data/html/css/rdoc.css +639 -0
  17. data/html/fonts/Lato-Light.ttf +0 -0
  18. data/html/fonts/Lato-LightItalic.ttf +0 -0
  19. data/html/fonts/Lato-Regular.ttf +0 -0
  20. data/html/fonts/Lato-RegularItalic.ttf +0 -0
  21. data/html/fonts/SourceCodePro-Bold.ttf +0 -0
  22. data/html/fonts/SourceCodePro-Regular.ttf +0 -0
  23. data/html/images/add.png +0 -0
  24. data/html/images/arrow_up.png +0 -0
  25. data/html/images/brick.png +0 -0
  26. data/html/images/brick_link.png +0 -0
  27. data/html/images/bug.png +0 -0
  28. data/html/images/bullet_black.png +0 -0
  29. data/html/images/bullet_toggle_minus.png +0 -0
  30. data/html/images/bullet_toggle_plus.png +0 -0
  31. data/html/images/date.png +0 -0
  32. data/html/images/delete.png +0 -0
  33. data/html/images/find.png +0 -0
  34. data/html/images/loadingAnimation.gif +0 -0
  35. data/html/images/macFFBgHack.png +0 -0
  36. data/html/images/package.png +0 -0
  37. data/html/images/page_green.png +0 -0
  38. data/html/images/page_white_text.png +0 -0
  39. data/html/images/page_white_width.png +0 -0
  40. data/html/images/plugin.png +0 -0
  41. data/html/images/ruby.png +0 -0
  42. data/html/images/tag_blue.png +0 -0
  43. data/html/images/tag_green.png +0 -0
  44. data/html/images/transparent.png +0 -0
  45. data/html/images/wrench.png +0 -0
  46. data/html/images/wrench_orange.png +0 -0
  47. data/html/images/zoom.png +0 -0
  48. data/html/index.html +297 -0
  49. data/html/js/darkfish.js +84 -0
  50. data/html/js/navigation.js +105 -0
  51. data/html/js/navigation.js.gz +0 -0
  52. data/html/js/search.js +110 -0
  53. data/html/js/search_index.js +1 -0
  54. data/html/js/search_index.js.gz +0 -0
  55. data/html/js/searcher.js +229 -0
  56. data/html/js/searcher.js.gz +0 -0
  57. data/html/table_of_contents.html +237 -0
  58. data/lib/na/action.rb +65 -0
  59. data/lib/na/colors.rb +335 -0
  60. data/lib/na/next_action.rb +181 -0
  61. data/lib/na/string.rb +42 -0
  62. data/lib/na/version.rb +3 -0
  63. data/lib/na.rb +11 -0
  64. data/na.gemspec +26 -0
  65. data/na.rdoc +167 -0
  66. metadata +211 -0
data/lib/na/colors.rb ADDED
@@ -0,0 +1,335 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Cribbed from <https://github.com/flori/term-ansicolor>
4
+ module NA
5
+ # Terminal output color functions.
6
+ module Color
7
+ # Regexp to match excape sequences
8
+ ESCAPE_REGEX = /(?<=\[)(?:(?:(?:[349]|10)[0-9]|[0-9])?;?)+(?=m)/.freeze
9
+
10
+ # All available color names. Available as methods and string extensions.
11
+ #
12
+ # @example Use a color as a method. Color reset will be added to end of string.
13
+ # Color.yellow('This text is yellow') => "\e[33mThis text is yellow\e[0m"
14
+ #
15
+ # @example Use a color as a string extension. Color reset added automatically.
16
+ # 'This text is green'.green => "\e[1;32mThis text is green\e[0m"
17
+ #
18
+ # @example Send a text string as a color
19
+ # Color.send('red') => "\e[31m"
20
+ ATTRIBUTES = [
21
+ [:clear, 0], # String#clear is already used to empty string in Ruby 1.9
22
+ [:reset, 0], # synonym for :clear
23
+ [:bold, 1],
24
+ [:dark, 2],
25
+ [:italic, 3], # not widely implemented
26
+ [:underline, 4],
27
+ [:underscore, 4], # synonym for :underline
28
+ [:blink, 5],
29
+ [:rapid_blink, 6], # not widely implemented
30
+ [:negative, 7], # no reverse because of String#reverse
31
+ [:concealed, 8],
32
+ [:strikethrough, 9], # not widely implemented
33
+ [:strike, 9], # not widely implemented
34
+ [:black, 30],
35
+ [:red, 31],
36
+ [:green, 32],
37
+ [:yellow, 33],
38
+ [:blue, 34],
39
+ [:magenta, 35],
40
+ [:purple, 35],
41
+ [:cyan, 36],
42
+ [:white, 37],
43
+ [:bgblack, 40],
44
+ [:bgred, 41],
45
+ [:bggreen, 42],
46
+ [:bgyellow, 43],
47
+ [:bgblue, 44],
48
+ [:bgmagenta, 45],
49
+ [:bgpurple, 45],
50
+ [:bgcyan, 46],
51
+ [:bgwhite, 47],
52
+ [:boldblack, 90],
53
+ [:boldred, 91],
54
+ [:boldgreen, 92],
55
+ [:boldyellow, 93],
56
+ [:boldblue, 94],
57
+ [:boldmagenta, 95],
58
+ [:boldpurple, 95],
59
+ [:boldcyan, 96],
60
+ [:boldwhite, 97],
61
+ [:boldbgblack, 100],
62
+ [:boldbgred, 101],
63
+ [:boldbggreen, 102],
64
+ [:boldbgyellow, 103],
65
+ [:boldbgblue, 104],
66
+ [:boldbgmagenta, 105],
67
+ [:boldbgpurple, 105],
68
+ [:boldbgcyan, 106],
69
+ [:boldbgwhite, 107],
70
+ [:softpurple, '0;35;40'],
71
+ [:hotpants, '7;34;40'],
72
+ [:knightrider, '7;30;40'],
73
+ [:flamingo, '7;31;47'],
74
+ [:yeller, '1;37;43'],
75
+ [:whiteboard, '1;30;47'],
76
+ [:chalkboard, '1;37;40'],
77
+ [:led, '0;32;40'],
78
+ [:redacted, '0;30;40'],
79
+ [:alert, '1;31;43'],
80
+ [:error, '1;37;41'],
81
+ [:default, '0;39']
82
+ ].map(&:freeze).freeze
83
+
84
+ # Array of attribute keys only
85
+ ATTRIBUTE_NAMES = ATTRIBUTES.transpose.first
86
+
87
+ # Returns true if NA::Color supports the +feature+.
88
+ #
89
+ # The feature :clear, that is mixing the clear color attribute into String,
90
+ # is only supported on ruby implementations, that do *not* already
91
+ # implement the String#clear method. It's better to use the reset color
92
+ # attribute instead.
93
+ def support?(feature)
94
+ case feature
95
+ when :clear
96
+ !String.instance_methods(false).map(&:to_sym).include?(:clear)
97
+ end
98
+ end
99
+
100
+ # Template coloring
101
+ class ::String
102
+ ##
103
+ ## Extract the longest valid %color name from a string.
104
+ ##
105
+ ## Allows %colors to bleed into other text and still
106
+ ## be recognized, e.g. %greensomething still finds
107
+ ## %green.
108
+ ##
109
+ ## @return [String] a valid color name
110
+ ##
111
+ def validate_color
112
+ valid_color = nil
113
+ compiled = ''
114
+ normalize_color.split('').each do |char|
115
+ compiled += char
116
+ valid_color = compiled if Color.attributes.include?(compiled.to_sym) || compiled =~ /^([fb]g?)?#([a-f0-9]{6})$/i
117
+ end
118
+
119
+ valid_color
120
+ end
121
+
122
+ ##
123
+ ## Normalize a color name, removing underscores,
124
+ ## replacing "bright" with "bold", and converting
125
+ ## bgbold to boldbg
126
+ ##
127
+ ## @return [String] Normalized color name
128
+ ##
129
+ def normalize_color
130
+ gsub(/_/, '').sub(/bright/i, 'bold').sub(/bgbold/, 'boldbg')
131
+ end
132
+
133
+ # Get the calculated ANSI color at the end of the
134
+ # string
135
+ #
136
+ # @return ANSI escape sequence to match color
137
+ #
138
+ def last_color_code
139
+ m = scan(ESCAPE_REGEX)
140
+
141
+ em = ['0']
142
+ fg = nil
143
+ bg = nil
144
+ rgbf = nil
145
+ rgbb = nil
146
+
147
+ m.each do |c|
148
+ case c
149
+ when '0'
150
+ em = ['0']
151
+ fg, bg, rgbf, rgbb = nil
152
+ when /^[34]8/
153
+ case c
154
+ when /^3/
155
+ fg = nil
156
+ rgbf = c
157
+ when /^4/
158
+ bg = nil
159
+ rgbb = c
160
+ end
161
+ else
162
+ c.split(/;/).each do |i|
163
+ x = i.to_i
164
+ if x <= 9
165
+ em << x
166
+ elsif x >= 30 && x <= 39
167
+ rgbf = nil
168
+ fg = x
169
+ elsif x >= 40 && x <= 49
170
+ rgbb = nil
171
+ bg = x
172
+ elsif x >= 90 && x <= 97
173
+ rgbf = nil
174
+ fg = x
175
+ elsif x >= 100 && x <= 107
176
+ rgbb = nil
177
+ bg = x
178
+ end
179
+ end
180
+ end
181
+ end
182
+
183
+ escape = "\e[#{em.join(';')}m"
184
+ escape += "\e[#{rgbb}m" if rgbb
185
+ escape += "\e[#{rgbf}m" if rgbf
186
+ escape + "\e[#{[fg, bg].delete_if(&:nil?).join(';')}m"
187
+ end
188
+ end
189
+
190
+ class << self
191
+ # Returns true if the coloring function of this module
192
+ # is switched on, false otherwise.
193
+ def coloring?
194
+ @coloring
195
+ end
196
+
197
+ attr_writer :coloring
198
+
199
+ ##
200
+ ## Enables colored output
201
+ ##
202
+ ## @example Turn color on or off based on TTY
203
+ ## NA::Color.coloring = STDOUT.isatty
204
+ def coloring
205
+ @coloring ||= true
206
+ end
207
+
208
+ ##
209
+ ## Convert a template string to a colored string.
210
+ ## Colors are specified with single letters inside
211
+ ## curly braces. Uppercase changes background color.
212
+ ##
213
+ ## w: white, k: black, g: green, l: blue, y: yellow, c: cyan,
214
+ ## m: magenta, r: red, b: bold, u: underline, i: italic,
215
+ ## x: reset (remove background, color, emphasis)
216
+ ##
217
+ ## @example Convert a templated string
218
+ ## Color.template('{Rwb}Warning:{x} {w}you look a little {g}ill{x}')
219
+ ##
220
+ ## @param input [String, Array] The template
221
+ ## string. If this is an array, the
222
+ ## elements will be joined with a
223
+ ## space.
224
+ ##
225
+ ## @return [String] Colorized string
226
+ ##
227
+ def template(input)
228
+ input = input.join(' ') if input.is_a? Array
229
+ fmt = input.gsub(/%/, '%%')
230
+ fmt = fmt.gsub(/(?<!\\u)\{(\w+)\}/i) do
231
+ Regexp.last_match(1).split('').map { |c| "%<#{c}>s" }.join('')
232
+ end
233
+
234
+ colors = { w: white, k: black, g: green, l: blue,
235
+ y: yellow, c: cyan, m: magenta, r: red,
236
+ W: bgwhite, K: bgblack, G: bggreen, L: bgblue,
237
+ Y: bgyellow, C: bgcyan, M: bgmagenta, R: bgred,
238
+ d: dark, b: bold, u: underline, i: italic, x: reset }
239
+
240
+ format(fmt, colors)
241
+ end
242
+ end
243
+
244
+ ATTRIBUTES.each do |c, v|
245
+ new_method = <<-EOSCRIPT
246
+ # Color string as #{c}
247
+ def #{c}(string = nil)
248
+ result = ''
249
+ result << "\e[#{v}m" if NA::Color.coloring?
250
+ if block_given?
251
+ result << yield
252
+ elsif string.respond_to?(:to_str)
253
+ result << string.to_str
254
+ elsif respond_to?(:to_str)
255
+ result << to_str
256
+ else
257
+ return result #only switch on
258
+ end
259
+ result << "\e[0m" if NA::Color.coloring?
260
+ result
261
+ end
262
+ EOSCRIPT
263
+
264
+ module_eval(new_method)
265
+
266
+ next unless c =~ /bold/
267
+
268
+ # Accept brightwhite in addition to boldwhite
269
+ new_method = <<-EOSCRIPT
270
+ # color string as #{c}
271
+ def #{c.to_s.sub(/bold/, 'bright')}(string = nil)
272
+ result = ''
273
+ result << "\e[#{v}m" if NA::Color.coloring?
274
+ if block_given?
275
+ result << yield
276
+ elsif string.respond_to?(:to_str)
277
+ result << string.to_str
278
+ elsif respond_to?(:to_str)
279
+ result << to_str
280
+ else
281
+ return result #only switch on
282
+ end
283
+ result << "\e[0m" if NA::Color.coloring?
284
+ result
285
+ end
286
+ EOSCRIPT
287
+
288
+ module_eval(new_method)
289
+ end
290
+
291
+ ##
292
+ ## Generate escape codes for hex colors
293
+ ##
294
+ ## @param hex [String] The hexadecimal color code
295
+ ##
296
+ ## @return [String] ANSI escape string
297
+ ##
298
+ def rgb(hex)
299
+ is_bg = hex.match(/^bg?#/) ? true : false
300
+ hex_string = hex.sub(/^([fb]g?)?#/, '')
301
+
302
+ parts = hex_string.match(/(?<r>..)(?<g>..)(?<b>..)/)
303
+ t = []
304
+ %w[r g b].each do |e|
305
+ t << parts[e].hex
306
+ end
307
+ color =
308
+ "\e[#{is_bg ? '48' : '38'};2;#{t.join(';')}m"
309
+ end
310
+
311
+ # Regular expression that is used to scan for ANSI-sequences while
312
+ # uncoloring strings.
313
+ COLORED_REGEXP = /\e\[(?:(?:[349]|10)[0-7]|[0-9])?m/.freeze
314
+
315
+ # Returns an uncolored version of the string, that is all
316
+ # ANSI-sequences are stripped from the string.
317
+ def uncolor(string = nil) # :yields:
318
+ if block_given?
319
+ yield.to_str.gsub(COLORED_REGEXP, '')
320
+ elsif string.respond_to?(:to_str)
321
+ string.to_str.gsub(COLORED_REGEXP, '')
322
+ elsif respond_to?(:to_str)
323
+ to_str.gsub(COLORED_REGEXP, '')
324
+ else
325
+ ''
326
+ end
327
+ end
328
+
329
+ # Returns an array of all NA::Color attributes as symbols.
330
+ def attributes
331
+ ATTRIBUTE_NAMES
332
+ end
333
+ extend self
334
+ end
335
+ end
@@ -0,0 +1,181 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Next Action methods
4
+ module NA
5
+ class << self
6
+ def create_todo(target, basename)
7
+ File.open(target, 'w') do |f|
8
+ content = <<~ENDCONTENT
9
+ Inbox: @inbox
10
+ #{basename}:
11
+ \tNew Features:
12
+ \tIdeas:
13
+ \tBugs:
14
+ Archive:
15
+ Search Definitions:
16
+ \tTop Priority @search(@priority = 5 and not @done)
17
+ \tHigh Priority @search(@priority > 3 and not @done)
18
+ \tMaybe @search(@maybe)
19
+ \tNext @search(@na and not @done and not project = \"Archive\")
20
+ ENDCONTENT
21
+ f.puts(content)
22
+ end
23
+ puts NA::Color.template("{y}Created {bw}#{target}{x}")
24
+ end
25
+
26
+ def find_files(depth: 1, extension: 'taskpaper')
27
+ `find . -name "*.#{extension}" -maxdepth #{depth}`.strip.split("\n")
28
+ end
29
+
30
+ def select_file(files)
31
+ if TTY::Which.exist?('gum')
32
+ args = [
33
+ '--cursor.foreground="151"',
34
+ '--item.foreground=""'
35
+ ]
36
+ `echo #{Shellwords.escape(files.join("\n"))}|#{TTY::Which.which('gum')} choose #{args.join(' ')}`.strip
37
+ elsif TTY::Which.exist?('fzf')
38
+ res = choose_from(files, prompt: 'Use which file?')
39
+ unless res
40
+ puts 'No file selected, cancelled'
41
+ Process.exit 1
42
+ end
43
+
44
+ res.strip
45
+ else
46
+ reader = TTY::Reader.new
47
+ puts
48
+ files.each.with_index do |f, i|
49
+ puts NA::Color.template(format("{bw}%<idx> 2d{xw}) {y}%<file>s{x}\n", idx: i + 1, file: f))
50
+ end
51
+ res = reader.read_line(NA::Color.template('{bw}Use which file? {x}')).strip.to_i
52
+ files[res - 1]
53
+ end
54
+ end
55
+
56
+ def add_action(file, action, note = nil)
57
+ content = IO.read(file)
58
+ unless content =~ /^[ \t]*Inbox:/i
59
+ content = "Inbox: @inbox\n#{content}"
60
+ end
61
+
62
+ content.sub!(/^([ \t]*)Inbox:(.*?)$/) do
63
+ m = Regexp.last_match
64
+ note = note.nil? ? '' : "\n#{m[1]}\t\t#{note.join('').strip}"
65
+ "#{m[1]}Inbox:#{m[2]}\n#{m[1]}\t- #{action}#{note}"
66
+ end
67
+
68
+ File.open(file, 'w') { |f| f.puts content }
69
+
70
+ puts NA::Color.template("{by}Task added to {bw}#{file}{x}")
71
+ end
72
+
73
+ def output_actions(actions, depth, extension)
74
+ template = if NA.find_files(depth: depth, extension: extension).count > 1
75
+ if depth > 1
76
+ '%filename%parent%action'
77
+ else
78
+ '%project%parent%action'
79
+ end
80
+ else
81
+ '%parent%action'
82
+ end
83
+ puts actions.map { |action| action.pretty(template: { output: template }) }
84
+ end
85
+
86
+ def parse_actions(depth: 1, extension: 'taskpaper', na_tag: 'na', tag: nil, search: nil)
87
+ actions = []
88
+ required = []
89
+ optional = []
90
+
91
+ tag&.each do |t|
92
+ new_rx = " @#{t[:tag]}"
93
+ new_rx = "#{new_rx}\\(#{t[:value]}\\)" if t[:value]
94
+
95
+ optional.push(new_rx)
96
+ required.push(new_rx) if t[:required]
97
+ end
98
+
99
+ unless search.nil?
100
+ if search.is_a?(String)
101
+ optional.push(search)
102
+ required.push(search)
103
+ else
104
+ search.each do |t|
105
+ new_rx = t[:token].to_s
106
+
107
+ optional.push(new_rx)
108
+ required.push(new_rx) if t[:required]
109
+ end
110
+ end
111
+ end
112
+
113
+ na_tag = "@#{na_tag.sub(/^@/, '')}"
114
+
115
+ files = find_files(depth: depth, extension: extension)
116
+ files.each do |file|
117
+ content = IO.read(file)
118
+ indent_level = 0
119
+ parent = []
120
+ content.split("\n").each do |line|
121
+ new_action = nil
122
+ if line =~ /([ \t]*)([^\-]+.*?):/
123
+ proj = Regexp.last_match(2)
124
+ indent = line.indent_level
125
+
126
+ if indent.zero?
127
+ parent = [proj]
128
+ elsif indent <= indent_level
129
+ parent.slice!(indent_level, parent.count - indent_level)
130
+ parent.push(proj)
131
+ elsif indent > indent_level
132
+ parent.push(proj)
133
+ indent_level = indent
134
+ end
135
+ elsif line =~ /^[ \t]*- / && line !~ / @done/
136
+ unless optional.empty? && required.empty?
137
+ next unless line.matches(any: optional, all: required)
138
+
139
+ end
140
+
141
+ action = line.sub(/^[ \t]*- /, '').sub(/ #{na_tag}/, '')
142
+ new_action = NA::Action.new(file, File.basename(file, ".#{extension}"), parent.dup, action)
143
+ actions.push(new_action)
144
+ end
145
+ end
146
+ end
147
+ actions
148
+ end
149
+
150
+ ##
151
+ ## Generate a menu of options and allow user selection
152
+ ##
153
+ ## @return [String] The selected option
154
+ ##
155
+ ## @param options [Array] The options from which to choose
156
+ ## @param prompt [String] The prompt
157
+ ## @param multiple [Boolean] If true, allow multiple selections
158
+ ## @param sorted [Boolean] If true, sort selections alphanumerically
159
+ ## @param fzf_args [Array] Additional fzf arguments
160
+ ##
161
+ def choose_from(options, prompt: 'Make a selection: ', multiple: false, sorted: true, fzf_args: [])
162
+ return nil unless $stdout.isatty
163
+
164
+ # fzf_args << '-1' # User is expecting a menu, and even if only one it seves as confirmation
165
+ default_args = []
166
+ default_args << %(--prompt="#{prompt}")
167
+ default_args << "--height=#{options.count + 2}"
168
+ default_args << '--info=inline'
169
+ default_args << '--multi' if multiple
170
+ header = "esc: cancel,#{multiple ? ' tab: multi-select, ctrl-a: select all,' : ''} return: confirm"
171
+ default_args << %(--header="#{header}")
172
+ default_args.concat(fzf_args)
173
+ options.sort! if sorted
174
+
175
+ res = `echo #{Shellwords.escape(options.join("\n"))}|#{TTY::Which.which('fzf')} #{default_args.join(' ')}`
176
+ return false if res.strip.size.zero?
177
+
178
+ res
179
+ end
180
+ end
181
+ end
data/lib/na/string.rb ADDED
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ::String
4
+ def indent_level
5
+ prefix = match(/(^[ \t]+)/)
6
+ return 0 if prefix.nil?
7
+
8
+ prefix[1].gsub(/ /, "\t").scan(/\t/).count
9
+ end
10
+
11
+ ##
12
+ ## Colorize @tags with ANSI escapes
13
+ ##
14
+ ## @param color [String] color (see #Color)
15
+ ##
16
+ ## @return [String] string with @tags highlighted
17
+ ##
18
+ def highlight_tags(color: '{m}', value: '{y}', parens: '{m}', last_color: '{g}')
19
+ tag_color = NA::Color.template(color)
20
+ paren_color = NA::Color.template(parens)
21
+ value_color = NA::Color.template(value)
22
+ gsub(/(\s|m)(@[^ ("']+)(?:(\()(.*?)(\)))?/, "\\1#{tag_color}\\2#{paren_color}\\3#{value_color}\\4#{paren_color}\\5#{last_color}")
23
+ end
24
+
25
+ def matches(any: [], all: [])
26
+ matches_any(any) && matches_all(all)
27
+ end
28
+
29
+ def matches_any(regexes)
30
+ regexes.each do |rx|
31
+ return true if match(Regexp.new(rx, Regexp::IGNORECASE))
32
+ end
33
+ false
34
+ end
35
+
36
+ def matches_all(regexes)
37
+ regexes.each do |rx|
38
+ return false unless match(Regexp.new(rx, Regexp::IGNORECASE))
39
+ end
40
+ true
41
+ end
42
+ end
data/lib/na/version.rb ADDED
@@ -0,0 +1,3 @@
1
+ module Na
2
+ VERSION = '1.0.0'
3
+ end
data/lib/na.rb ADDED
@@ -0,0 +1,11 @@
1
+ require 'na/version.rb'
2
+
3
+ # Add requires for other files you add to your project here, so
4
+ # you just need to require this one file in your bin file
5
+ require 'shellwords'
6
+ require 'tty-reader'
7
+ require 'tty-which'
8
+ require 'na/colors.rb'
9
+ require 'na/string.rb'
10
+ require 'na/action.rb'
11
+ require 'na/next_action.rb'
data/na.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # Ensure we require the local version and not one we might have installed already
2
+ require File.join([File.dirname(__FILE__),'lib','na','version.rb'])
3
+ spec = Gem::Specification.new do |s|
4
+ s.name = 'na'
5
+ s.version = Na::VERSION
6
+ s.author = 'Brett Terpstra'
7
+ s.email = 'me@brettterpstra.com'
8
+ s.homepage = 'https://brettterpstra.com'
9
+ s.platform = Gem::Platform::RUBY
10
+ s.summary = 'A command line tool for adding and listing project todos'
11
+ s.license = 'MIT'
12
+ s.files = Dir.chdir(File.expand_path('..', __FILE__)) do
13
+ `git ls-files -z`.split("\x0").reject { |f| f.strip =~ %r{^((test|spec|features)/|\.git|buildnotes|.*\.taskpaper)} }
14
+ end
15
+ s.require_paths << 'lib'
16
+ s.extra_rdoc_files = ['README.rdoc','na.rdoc']
17
+ s.rdoc_options << '--title' << 'na' << '--main' << 'README.rdoc' << '-ri'
18
+ s.bindir = 'bin'
19
+ s.executables << 'na'
20
+ s.add_development_dependency('rake','~> 0.9.2')
21
+ s.add_development_dependency('rdoc', '~> 4.3')
22
+ s.add_development_dependency('minitest', '~> 5.14')
23
+ s.add_runtime_dependency('gli','~> 2.21.0')
24
+ s.add_runtime_dependency('tty-reader', '~> 0.9', '>= 0.9.0')
25
+ s.add_runtime_dependency('tty-which', '~> 0.5', '>= 0.5.0')
26
+ end