jtag 0.1.18 → 0.1.19
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/bin/jtag +226 -188
- data/lib/jtag/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 71af8eca8dc4710dbb6d924c08a68cc834ab90e15f29d533809bdc1a2e269c6a
|
4
|
+
data.tar.gz: 964a8e7a5bc147edbd6006d2721ec57d89ca11fd77e77b189f5c0bfa8e6691db
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 13c13c4f35e36c9a9015082a370127bcc2e83f0d7682e1821390fc949534b45d0d134cadcbbe057a669582f16039cc7e7cc1a6f05e1d17edeec92f9663d371b0
|
7
|
+
data.tar.gz: 3c0b420b164c1f5fe67e09a6bd4827195c84fe51a8adb6ae153189ec18d75dc649820b3b7c539b780d37d1d311acc2309beeae4f3df59795a57039253ea8f12b
|
data/bin/jtag
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# encoding: utf-8
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "gli"
|
4
|
+
require "jtag"
|
5
|
+
require "fcntl"
|
5
6
|
|
6
7
|
include GLI::App
|
7
8
|
|
8
|
-
program_desc
|
9
|
+
program_desc "Autotagging for Jekyll"
|
9
10
|
|
10
11
|
version Jtag::VERSION
|
11
12
|
|
@@ -20,15 +21,24 @@ def config_files_complete?
|
|
20
21
|
true
|
21
22
|
end
|
22
23
|
|
23
|
-
|
24
|
-
|
25
|
-
|
24
|
+
class ::String
|
25
|
+
def file_list?
|
26
|
+
self.strip.split("\n").each do |line|
|
27
|
+
return false unless File.exist?(line)
|
28
|
+
end
|
29
|
+
true
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
desc "Debug level"
|
34
|
+
default_value "0"
|
35
|
+
arg_name "debug_level"
|
26
36
|
flag %i[d debug], :must_match => /\d+/, :type => Integer, :default_value => 0
|
27
37
|
|
28
|
-
desc
|
38
|
+
desc "Run silently"
|
29
39
|
switch %i[s silent]
|
30
40
|
|
31
|
-
desc
|
41
|
+
desc "Perform case-insensitive matches and searches"
|
32
42
|
switch %i[i case_insensitive]
|
33
43
|
|
34
44
|
desc "Test (dry run, don't update files)"
|
@@ -36,7 +46,7 @@ long_desc "Run all commands and show results on the command line, but don't over
|
|
36
46
|
default_value false
|
37
47
|
switch %i[t test]
|
38
48
|
|
39
|
-
def console_log(msg="", options={})
|
49
|
+
def console_log(msg = "", options = {})
|
40
50
|
err = options[:err] || false
|
41
51
|
options[:log] ||= false
|
42
52
|
|
@@ -57,13 +67,13 @@ def console_log(msg="", options={})
|
|
57
67
|
end
|
58
68
|
end
|
59
69
|
|
60
|
-
desc
|
70
|
+
desc "Update and notify user of configuration files location"
|
61
71
|
command :config do |c|
|
62
|
-
c.desc
|
63
|
-
c.switch [:r,
|
72
|
+
c.desc "Reset all configuration files to default values"
|
73
|
+
c.switch [:r, "reset"]
|
64
74
|
|
65
75
|
c.skips_pre
|
66
|
-
c.action do |global_options,options,args|
|
76
|
+
c.action do |global_options, options, args|
|
67
77
|
if options[:r]
|
68
78
|
print "Are you sure you want to reset all config files? y/N: "
|
69
79
|
response = STDIN.gets.strip
|
@@ -77,24 +87,22 @@ command :config do |c|
|
|
77
87
|
end
|
78
88
|
end
|
79
89
|
|
80
|
-
def write_config(atomic=false)
|
81
|
-
gem_root = Gem.loaded_specs[
|
82
|
-
gem_lib = File.join(gem_root,
|
83
|
-
config_source = File.join(gem_lib,
|
84
|
-
|
85
|
-
|
90
|
+
def write_config(atomic = false)
|
91
|
+
gem_root = Gem.loaded_specs["jtag"].full_gem_path
|
92
|
+
gem_lib = File.join(gem_root, "lib")
|
93
|
+
config_source = File.join(gem_lib, "/jtag/config_files")
|
86
94
|
|
87
95
|
unless File.directory?(@config_target) || atomic
|
88
|
-
FileUtils.cp_r(config_source
|
96
|
+
FileUtils.cp_r(config_source, @config_target)
|
89
97
|
console_log "Configuration files are located in the folder: " + @config_target
|
90
98
|
console_log %Q{Make sure that "tags_location" in config.yml is set to your tags.json url.}
|
91
99
|
console_log "Configuration files written to #{@config_target}"
|
92
100
|
end
|
93
101
|
|
94
102
|
@config_files.each do |file|
|
95
|
-
unless File.exist?(File.join(@config_target,file))
|
96
|
-
source_file = File.join(config_source,file)
|
97
|
-
target_file = File.join(@config_target,file)
|
103
|
+
unless File.exist?(File.join(@config_target, file))
|
104
|
+
source_file = File.join(config_source, file)
|
105
|
+
target_file = File.join(@config_target, file)
|
98
106
|
FileUtils.cp(source_file, target_file)
|
99
107
|
console_log "Config file #{file} added."
|
100
108
|
end
|
@@ -104,66 +112,66 @@ def write_config(atomic=false)
|
|
104
112
|
console_log %Q{Make sure that "tags_location" in the config.yml file is set to your tags json file.}
|
105
113
|
end
|
106
114
|
|
107
|
-
desc
|
108
|
-
long_desc
|
109
|
-
arg_name
|
115
|
+
desc "List tags, optionally filter for keywords/regular expressions (OR)"
|
116
|
+
long_desc "This command can be used to find the exact format for a given tag to keep spaces, underscores, capitalization and pluralization consistent"
|
117
|
+
arg_name "keyword", :multiple
|
110
118
|
command :search do |c|
|
111
|
-
c.desc
|
112
|
-
c.arg_name
|
113
|
-
c.default_value
|
119
|
+
c.desc "Format to use when outputting tags to console: list, json, plist, csv or yaml. Defaults to yaml."
|
120
|
+
c.arg_name "output_format"
|
121
|
+
c.default_value "yaml"
|
114
122
|
c.flag %i[f format], :must_match => /^(csv|list|yaml|json|plist)$/i, :type => String
|
115
123
|
|
116
|
-
c.desc
|
117
|
-
c.arg_name
|
124
|
+
c.desc "Include tag counts"
|
125
|
+
c.arg_name "counts"
|
118
126
|
c.default_value false
|
119
127
|
c.switch %i[c counts]
|
120
128
|
|
121
|
-
c.action do |global_options,options,args|
|
122
|
-
tags = @jt.get_tags({:counts => true})
|
129
|
+
c.action do |global_options, options, args|
|
130
|
+
tags = @jt.get_tags({ :counts => true })
|
123
131
|
if args.length > 0
|
124
132
|
re = args.join("|")
|
125
|
-
tags.delete_if {|tag|
|
126
|
-
if tag && tag[
|
133
|
+
tags.delete_if { |tag|
|
134
|
+
if tag && tag["name"] =~ /(#{re})/i
|
127
135
|
false
|
128
136
|
else
|
129
137
|
true
|
130
138
|
end
|
131
139
|
}
|
132
140
|
if options[:c]
|
133
|
-
tags.map! {|tag| "#{tag[
|
141
|
+
tags.map! { |tag| "#{tag["name"]} (#{tag["count"]})" }
|
134
142
|
else
|
135
|
-
tags.map! {|tag| tag[
|
143
|
+
tags.map! { |tag| tag["name"] }
|
136
144
|
end
|
137
|
-
output_tags(tags,{ :format => options[:format] })
|
145
|
+
output_tags(tags, { :format => options[:format] })
|
138
146
|
else
|
139
|
-
tags.delete_if {|tag| !tag }
|
147
|
+
tags.delete_if { |tag| !tag }
|
140
148
|
if options[:c]
|
141
|
-
tags.map! {|tag| "#{tag[
|
149
|
+
tags.map! { |tag| "#{tag["name"]} (#{tag["count"]})" }
|
142
150
|
else
|
143
|
-
tags.map! {|tag| tag[
|
151
|
+
tags.map! { |tag| tag["name"] }
|
144
152
|
end
|
145
|
-
output_tags(tags,{ :format => options[:format] })
|
153
|
+
output_tags(tags, { :format => options[:format] })
|
146
154
|
end
|
147
155
|
end
|
148
156
|
end
|
149
157
|
|
150
|
-
desc
|
151
|
-
arg_name
|
158
|
+
desc "List posts with tag(s)"
|
159
|
+
arg_name "tags", :multiple
|
152
160
|
command :posts_tagged do |c|
|
153
|
-
c.desc
|
154
|
-
c.arg_name
|
155
|
-
c.default_value
|
161
|
+
c.desc "Boolean operator for multiple tags (AND/OR/NOT)"
|
162
|
+
c.arg_name "bool"
|
163
|
+
c.default_value "OR"
|
156
164
|
c.flag %i[b bool], :must_match => /(AND|OR|NOT)/i, :type => String
|
157
165
|
|
158
|
-
c.desc
|
159
|
-
c.arg_name
|
160
|
-
c.default_value
|
166
|
+
c.desc "Format to use when outputting file list: list, json, plist, csv or yaml. Defaults to list."
|
167
|
+
c.arg_name "output_format"
|
168
|
+
c.default_value "list"
|
161
169
|
c.flag %i[f format], :must_match => /^(csv|list|yaml|json|plist)$/, :type => String
|
162
170
|
|
163
|
-
c.desc
|
171
|
+
c.desc "If output format is list, print without newlines."
|
164
172
|
c.switch [:print0]
|
165
173
|
|
166
|
-
c.action do |global_options,options,args|
|
174
|
+
c.action do |global_options, options, args|
|
167
175
|
bool = options[:bool].upcase
|
168
176
|
files = []
|
169
177
|
tags = []
|
@@ -176,30 +184,33 @@ command :posts_tagged do |c|
|
|
176
184
|
tags.push(arg)
|
177
185
|
end
|
178
186
|
end
|
187
|
+
|
188
|
+
files.concat(@piped_content.split("\n")) if @piped_content
|
189
|
+
|
179
190
|
if files.empty?
|
180
191
|
if @jt.default_post_location && File.exist?(File.dirname(@jt.default_post_location))
|
181
192
|
files = Dir.glob(@jt.default_post_location)
|
182
193
|
end
|
183
194
|
end
|
184
195
|
exit_now! "No valid filename in arguments" if files.empty?
|
185
|
-
files.each {|file|
|
196
|
+
files.each { |file|
|
186
197
|
if File.exist?(file)
|
187
198
|
post_tags = @jt.post_tags(file)
|
188
199
|
|
189
200
|
if bool == "AND"
|
190
201
|
matched = 0
|
191
|
-
tags.each {|tag|
|
202
|
+
tags.each { |tag|
|
192
203
|
matched += 1 if post_tags.include?(tag)
|
193
204
|
}
|
194
205
|
matches.push(file) if matched == tags.length
|
195
206
|
elsif bool == "NOT"
|
196
207
|
matched = false
|
197
|
-
tags.each {|tag|
|
208
|
+
tags.each { |tag|
|
198
209
|
matched = true if post_tags.include?(tag)
|
199
210
|
}
|
200
211
|
matches.push(file) unless matched
|
201
212
|
else
|
202
|
-
tags.each {|tag|
|
213
|
+
tags.each { |tag|
|
203
214
|
if post_tags.include?(tag)
|
204
215
|
matches.push(file) unless matches.include?(file)
|
205
216
|
end
|
@@ -214,23 +225,23 @@ command :posts_tagged do |c|
|
|
214
225
|
if matches.empty?
|
215
226
|
console_log "No matching files found for #{search_string}"
|
216
227
|
else
|
217
|
-
console_log "(#{search_string})", {:err => true}
|
228
|
+
console_log "(#{search_string})", { :err => true }
|
218
229
|
output_tags(matches, { :format => options[:format], :print0 => options[:print0], :grouping => "files" })
|
219
230
|
end
|
220
231
|
end
|
221
232
|
end
|
222
233
|
|
223
|
-
desc
|
224
|
-
arg_name
|
234
|
+
desc "Show tags with fewer than X posts attached to them, optionally removing them from specified posts"
|
235
|
+
arg_name "file_pattern", :multiple
|
225
236
|
command :loners do |c|
|
226
|
-
c.desc
|
227
|
-
c.arg_name
|
228
|
-
c.default_value
|
237
|
+
c.desc "Format to use when outputting tags to console: list, json, plist, csv or yaml. Defaults to yaml."
|
238
|
+
c.arg_name "output_format"
|
239
|
+
c.default_value "yaml"
|
229
240
|
c.flag %i[f format], :must_match => /^(csv|list|yaml|json|plist)$/, :type => String
|
230
241
|
|
231
|
-
c.desc
|
232
|
-
c.arg_name
|
233
|
-
c.default_value
|
242
|
+
c.desc "Upper limit for how many posts a tag can be attached to and still be a loner"
|
243
|
+
c.arg_name "max"
|
244
|
+
c.default_value "2"
|
234
245
|
c.flag %i[m max], :default_value => 2, :must_match => /^\d+$/
|
235
246
|
|
236
247
|
c.desc "Remove tags with fewer than X posts attached"
|
@@ -239,17 +250,17 @@ command :loners do |c|
|
|
239
250
|
c.desc "Display output without attached occurence counts"
|
240
251
|
c.switch [:no_counts], :default_value => false
|
241
252
|
|
242
|
-
c.desc
|
243
|
-
c.arg_name
|
253
|
+
c.desc "Output a file list of tags that can be edited and passed back in for removing"
|
254
|
+
c.arg_name "filename"
|
244
255
|
c.flag %i[e edit], :default_value => false, :type => String
|
245
256
|
|
246
|
-
c.action do |global_options,options,args|
|
257
|
+
c.action do |global_options, options, args|
|
247
258
|
max = options[:m].to_i
|
248
|
-
loner_tags = @jt.get_tags({:counts => true})
|
259
|
+
loner_tags = @jt.get_tags({ :counts => true })
|
249
260
|
loner_tags.delete_if { |tag|
|
250
|
-
tag.class == FalseClass || tag[
|
261
|
+
tag.class == FalseClass || tag["count"] > max
|
251
262
|
}
|
252
|
-
loner_tags.sort_by! {|tag| tag[
|
263
|
+
loner_tags.sort_by! { |tag| tag["count"] }
|
253
264
|
|
254
265
|
exit_now! "No tags matched the criteria" if loner_tags.empty? || loner_tags.nil?
|
255
266
|
|
@@ -261,10 +272,10 @@ command :loners do |c|
|
|
261
272
|
$1.next! + $2
|
262
273
|
end
|
263
274
|
else
|
264
|
-
path.sub!(/(\.[^\.]+?)?$/,'01\1')
|
275
|
+
path.sub!(/(\.[^\.]+?)?$/, '01\1')
|
265
276
|
end
|
266
277
|
end
|
267
|
-
File.open(path,
|
278
|
+
File.open(path, "w+") do |f|
|
268
279
|
f.puts "# Edit this file to remove tags you want to keep,"
|
269
280
|
f.puts "# then run `jtag remove -p '#{path}' [/path/to/posts/*.md]`"
|
270
281
|
f.puts "# to remove any tags left in the file."
|
@@ -273,18 +284,18 @@ command :loners do |c|
|
|
273
284
|
f.puts "# be automatically ignored when reading the list back in."
|
274
285
|
f.puts "#"
|
275
286
|
f.puts "# Lines beginning with a # are comments (ignored), but you probably figured that out."
|
276
|
-
loner_tags.each{ |t|
|
277
|
-
f.printf "% 3d |\t%s\n", t[
|
287
|
+
loner_tags.each { |t|
|
288
|
+
f.printf "% 3d |\t%s\n", t["count"], t["name"]
|
278
289
|
}
|
279
290
|
end
|
280
291
|
|
281
292
|
console_log "A list of results and instructions for use have been written to #{path}."
|
282
|
-
if ENV[
|
293
|
+
if ENV["EDITOR"]
|
283
294
|
console_log
|
284
|
-
print "Would you like to open the file in #{ENV[
|
295
|
+
print "Would you like to open the file in #{ENV["EDITOR"]} now? (y/N) "
|
285
296
|
input = STDIN.gets
|
286
297
|
if input =~ /^y/i
|
287
|
-
system "#{ENV[
|
298
|
+
system "#{ENV["EDITOR"]} '#{path}'"
|
288
299
|
end
|
289
300
|
end
|
290
301
|
elsif options[:r]
|
@@ -293,13 +304,16 @@ command :loners do |c|
|
|
293
304
|
arg = args.pop
|
294
305
|
files.push(arg) if File.exist?(arg)
|
295
306
|
end
|
307
|
+
|
308
|
+
files.concat(@piped_content.split("\n")) if @piped_content
|
309
|
+
|
296
310
|
if files.empty?
|
297
311
|
if @jt.default_post_location && File.exist?(File.dirname(@jt.default_post_location))
|
298
312
|
files = Dir.glob(@jt.default_post_location)
|
299
313
|
end
|
300
314
|
end
|
301
315
|
exit_now! "No valid filename in arguments" if files.empty?
|
302
|
-
files.each {|file|
|
316
|
+
files.each { |file|
|
303
317
|
tags = @jt.post_tags(file)
|
304
318
|
loner_tags.each { |d|
|
305
319
|
tags.delete_if { |tag|
|
@@ -317,69 +331,76 @@ command :loners do |c|
|
|
317
331
|
|
318
332
|
console_log
|
319
333
|
console_log File.basename(file) + ":"
|
320
|
-
output_tags(tags, :format => options[:format], :filename => file
|
334
|
+
output_tags(tags, :format => options[:format], :filename => file)
|
321
335
|
}
|
322
336
|
else
|
323
|
-
output_tags(loner_tags.map{|tag|
|
324
|
-
count = options[:no_counts] ? "" : " (#{tag[
|
325
|
-
"#{tag[
|
337
|
+
output_tags(loner_tags.map { |tag|
|
338
|
+
count = options[:no_counts] ? "" : " (#{tag["count"]})"
|
339
|
+
"#{tag["name"]}#{count}"
|
340
|
+
}, :format => options[:format])
|
326
341
|
end
|
327
342
|
end
|
328
343
|
end
|
329
344
|
|
330
|
-
|
331
|
-
|
332
|
-
arg_name 'file_pattern', :multiple
|
345
|
+
desc "Show the current tags for posts"
|
346
|
+
arg_name "file_pattern", :multiple
|
333
347
|
command :tags do |c|
|
334
|
-
c.desc
|
335
|
-
c.arg_name
|
336
|
-
c.default_value
|
348
|
+
c.desc "Format to use when outputting tags to console: list, json, plist, csv or yaml. Defaults to yaml."
|
349
|
+
c.arg_name "output_format"
|
350
|
+
c.default_value "yaml"
|
337
351
|
c.flag %i[f format], :must_match => /^(csv|list|yaml|json|plist)$/, :type => String
|
338
352
|
|
339
|
-
c.action do |global_options,options,args|
|
353
|
+
c.action do |global_options, options, args|
|
354
|
+
files = []
|
355
|
+
args.length.times do
|
356
|
+
arg = args.pop
|
357
|
+
if File.exist?(arg)
|
358
|
+
files.push(arg)
|
359
|
+
end
|
360
|
+
end
|
361
|
+
|
362
|
+
files.concat(@piped_content.split("\n")) if @piped_content && @piped_content.file_list?
|
363
|
+
|
364
|
+
tags = []
|
365
|
+
files.each do |file|
|
366
|
+
tags.concat(@jt.post_tags(file)) if File.exist?(file)
|
340
367
|
|
341
|
-
|
342
|
-
tags = @jt.post_tags(@piped_content, true)
|
343
|
-
if args.length > 1
|
368
|
+
if args.length > 0
|
344
369
|
console_log
|
345
|
-
console_log
|
346
|
-
end
|
347
|
-
if tags.empty? || tags.nil?
|
348
|
-
console_log "No tags in post", {:err => true}
|
349
|
-
else
|
350
|
-
output_tags(tags,{ :format => options[:format] })
|
370
|
+
console_log "STDIN:"
|
351
371
|
end
|
352
372
|
end
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
console_log "No tags in post", {:err => true}
|
362
|
-
else
|
363
|
-
output_tags(tags,{ :format => options[:format], :filename => file })
|
364
|
-
end
|
365
|
-
else
|
366
|
-
raise "File not found: #{file}"
|
367
|
-
end
|
368
|
-
}
|
373
|
+
|
374
|
+
if tags.empty? || tags.nil?
|
375
|
+
console_log "No tags in post", { :err => true }
|
376
|
+
else
|
377
|
+
tags.sort!
|
378
|
+
tags.uniq!
|
379
|
+
output_tags(tags, { :format => options[:format] })
|
380
|
+
end
|
369
381
|
end
|
370
382
|
end
|
371
383
|
|
372
|
-
|
373
|
-
|
374
|
-
arg_name 'file_pattern', :multiple
|
384
|
+
desc "Sort the existing tags for posts"
|
385
|
+
arg_name "file_pattern", :multiple
|
375
386
|
command :sort do |c|
|
376
|
-
c.desc
|
377
|
-
c.arg_name
|
378
|
-
c.default_value
|
387
|
+
c.desc "Format to use when outputting tags to console: list, json, plist, csv or yaml. Defaults to yaml."
|
388
|
+
c.arg_name "output_format"
|
389
|
+
c.default_value "yaml"
|
379
390
|
c.flag %i[f format], :must_match => /^(csv|list|yaml|json|plist)$/, :type => String
|
380
391
|
|
381
|
-
c.action do |global_options,options,args|
|
382
|
-
|
392
|
+
c.action do |global_options, options, args|
|
393
|
+
files = []
|
394
|
+
args.length.times do
|
395
|
+
arg = args.pop
|
396
|
+
if File.exist?(arg)
|
397
|
+
files.push(arg)
|
398
|
+
end
|
399
|
+
end
|
400
|
+
|
401
|
+
files.concat(@piped_content.split("\n")) if @piped_content
|
402
|
+
|
403
|
+
files.each do |file|
|
383
404
|
tags = @jt.post_tags(file)
|
384
405
|
tags.uniq!
|
385
406
|
tags.sort!
|
@@ -390,21 +411,21 @@ command :sort do |c|
|
|
390
411
|
console_log File.basename(file) + ":"
|
391
412
|
|
392
413
|
if tags.empty? || tags.nil?
|
393
|
-
console_log "No tags in post", {:err => true}
|
414
|
+
console_log "No tags in post", { :err => true }
|
394
415
|
else
|
395
|
-
output_tags(tags,{ :format => options[:format], :filename => file })
|
416
|
+
output_tags(tags, { :format => options[:format], :filename => file })
|
396
417
|
end
|
397
|
-
|
418
|
+
end
|
398
419
|
end
|
399
420
|
end
|
400
421
|
|
401
|
-
desc
|
402
|
-
long_desc
|
403
|
-
arg_name
|
422
|
+
desc "Merge multiple tags into one"
|
423
|
+
long_desc "Scans the specified posts for any of the tags, merging any found into the last one in the list"
|
424
|
+
arg_name "tags to merge merge_tag"
|
404
425
|
command :merge do |c|
|
405
|
-
c.desc
|
406
|
-
c.arg_name
|
407
|
-
c.default_value
|
426
|
+
c.desc "Format to use when outputting tags to console: list, json, plist, csv or yaml. Defaults to yaml."
|
427
|
+
c.arg_name "output_format"
|
428
|
+
c.default_value "yaml"
|
408
429
|
c.flag %i[f format], :must_match => /^(csv|list|yaml|json|plist)$/, :type => String
|
409
430
|
|
410
431
|
c.action do |global_options, options, args|
|
@@ -418,6 +439,9 @@ command :merge do |c|
|
|
418
439
|
tags.push(arg)
|
419
440
|
end
|
420
441
|
end
|
442
|
+
|
443
|
+
files.concat(@piped_content.split("\n")) if @piped_content
|
444
|
+
|
421
445
|
if files.empty?
|
422
446
|
if @jt.default_post_location && File.exist?(File.dirname(@jt.default_post_location))
|
423
447
|
files = Dir.glob(@jt.default_post_location)
|
@@ -428,8 +452,8 @@ command :merge do |c|
|
|
428
452
|
tags.reverse!
|
429
453
|
merge_tag = tags.pop
|
430
454
|
console_log %Q{Merging #{tags.join(", ")} to #{merge_tag}}
|
431
|
-
files.each {|file|
|
432
|
-
new_tags = @jt.merge_tags(tags,merge_tag,file)
|
455
|
+
files.each { |file|
|
456
|
+
new_tags = @jt.merge_tags(tags, merge_tag, file)
|
433
457
|
next unless new_tags
|
434
458
|
unless global_options[:t]
|
435
459
|
@jt.update_file_tags(file, new_tags)
|
@@ -439,20 +463,18 @@ command :merge do |c|
|
|
439
463
|
|
440
464
|
console_log
|
441
465
|
console_log File.basename(file) + ":"
|
442
|
-
output_tags(new_tags,{ :format => options[:format], :filename => file })
|
443
|
-
|
466
|
+
output_tags(new_tags, { :format => options[:format], :filename => file })
|
444
467
|
}
|
445
468
|
end
|
446
469
|
end
|
447
470
|
|
448
|
-
|
449
|
-
|
450
|
-
arg_name 'tag [tag2...]'
|
471
|
+
desc "Blacklist a specific tag"
|
472
|
+
arg_name "tag [tag2...]"
|
451
473
|
command :blacklist do |c|
|
452
474
|
c.desc "Remove (unblacklist) the arguments"
|
453
|
-
c.switch [:r,
|
475
|
+
c.switch [:r, "remove"]
|
454
476
|
|
455
|
-
c.action do |global_options,options,args|
|
477
|
+
c.action do |global_options, options, args|
|
456
478
|
if options[:r]
|
457
479
|
@jt.unblacklist(args)
|
458
480
|
console_log "Removed #{args.join(", ")} from blacklist."
|
@@ -463,17 +485,16 @@ command :blacklist do |c|
|
|
463
485
|
end
|
464
486
|
end
|
465
487
|
|
466
|
-
desc
|
467
|
-
arg_name
|
468
|
-
arg_name
|
488
|
+
desc "Add tags to post(s)"
|
489
|
+
arg_name "tags", :multiple
|
490
|
+
arg_name "file_pattern"
|
469
491
|
command :add do |c|
|
470
|
-
c.desc
|
471
|
-
c.arg_name
|
472
|
-
c.default_value
|
492
|
+
c.desc "Format to use when outputting tags to console: list, json, plist, csv or yaml. Defaults to yaml."
|
493
|
+
c.arg_name "output_format"
|
494
|
+
c.default_value "yaml"
|
473
495
|
c.flag %i[f format], :must_match => /^(csv|list|yaml|json|plist)$/, :type => String
|
474
496
|
|
475
|
-
|
476
|
-
c.action do |global_options,options,args|
|
497
|
+
c.action do |global_options, options, args|
|
477
498
|
files = []
|
478
499
|
new_tags = []
|
479
500
|
args.length.times do
|
@@ -484,6 +505,9 @@ command :add do |c|
|
|
484
505
|
new_tags.push(arg)
|
485
506
|
end
|
486
507
|
end
|
508
|
+
|
509
|
+
files.concat(@piped_content.split("\n")) if @piped_content
|
510
|
+
|
487
511
|
if files.empty?
|
488
512
|
if @jt.default_post_location && File.exist?(File.dirname(@jt.default_post_location))
|
489
513
|
files = Dir.glob(@jt.default_post_location)
|
@@ -492,7 +516,7 @@ command :add do |c|
|
|
492
516
|
exit_now! "No valid filename in arguments" if files.empty?
|
493
517
|
exit_now! "No tags found in arguments" if new_tags.empty?
|
494
518
|
|
495
|
-
files.each {|file|
|
519
|
+
files.each { |file|
|
496
520
|
tags = @jt.post_tags(file)
|
497
521
|
tags.concat(new_tags)
|
498
522
|
tags.uniq!
|
@@ -509,20 +533,20 @@ command :add do |c|
|
|
509
533
|
end
|
510
534
|
end
|
511
535
|
|
512
|
-
desc
|
513
|
-
arg_name
|
536
|
+
desc "Remove tags from post(s)"
|
537
|
+
arg_name "tags", :multiple
|
514
538
|
command :remove do |c|
|
515
|
-
c.desc
|
516
|
-
c.arg_name
|
517
|
-
c.default_value
|
539
|
+
c.desc "Format to use when outputting tags to console: list, json, plist, csv or yaml. Defaults to yaml."
|
540
|
+
c.arg_name "output_format"
|
541
|
+
c.default_value "yaml"
|
518
542
|
c.flag %i[f format], :must_match => /^(csv|list|yaml|json|plist)$/, :type => String
|
519
543
|
|
520
|
-
c.desc
|
521
|
-
c.long_desc
|
522
|
-
c.arg_name
|
544
|
+
c.desc "A filepath to a list of tags to be removed"
|
545
|
+
c.long_desc "One tag per line, and leading numbers and pipes (|) will be ignored. This file format is generated automatically by the `loners` command, but any text file will do the trick."
|
546
|
+
c.arg_name "input_file"
|
523
547
|
c.flag %i[p path], :type => String
|
524
548
|
|
525
|
-
c.action do |global_options,options,args|
|
549
|
+
c.action do |global_options, options, args|
|
526
550
|
files = []
|
527
551
|
remove_tags = []
|
528
552
|
args.length.times do
|
@@ -533,6 +557,9 @@ command :remove do |c|
|
|
533
557
|
remove_tags.push(arg) unless options[:p]
|
534
558
|
end
|
535
559
|
end
|
560
|
+
|
561
|
+
files.concat(@piped_content.split("\n")) if @piped_content
|
562
|
+
|
536
563
|
if files.empty?
|
537
564
|
if @jt.default_post_location && File.exist?(File.dirname(@jt.default_post_location))
|
538
565
|
files = Dir.glob(@jt.default_post_location)
|
@@ -543,7 +570,7 @@ command :remove do |c|
|
|
543
570
|
if options[:p]
|
544
571
|
path = File.expand_path(options[:p])
|
545
572
|
exit_now! "Input file does not appear to be where you think it is." unless File.exist?(path)
|
546
|
-
IO.read(path).each_line {|l|
|
573
|
+
IO.read(path).each_line { |l|
|
547
574
|
next if l =~ /^\s*#/
|
548
575
|
if l =~ /^(?:[\s\d])*(?:\|\s*)?(\S.*?)$/
|
549
576
|
remove_tags.push($1.strip)
|
@@ -554,7 +581,7 @@ command :remove do |c|
|
|
554
581
|
|
555
582
|
exit_now! "No tags found in input, my work here is done" if remove_tags.empty?
|
556
583
|
|
557
|
-
files.each {|file|
|
584
|
+
files.each { |file|
|
558
585
|
tags = @jt.post_tags(file)
|
559
586
|
remove_tags.each { |d|
|
560
587
|
tags.delete_if { |tag|
|
@@ -572,32 +599,41 @@ command :remove do |c|
|
|
572
599
|
|
573
600
|
console_log
|
574
601
|
console_log File.basename(file) + ":"
|
575
|
-
output_tags(tags,{ :format => options[:format], :filename => file })
|
602
|
+
output_tags(tags, { :format => options[:format], :filename => file })
|
576
603
|
}
|
577
604
|
end
|
578
605
|
end
|
579
606
|
|
580
|
-
desc
|
581
|
-
arg_name
|
607
|
+
desc "Generate a list of recommended tags, updating the file (unless dry run)"
|
608
|
+
arg_name "file_pattern", :multiple
|
582
609
|
command :tag do |c|
|
583
610
|
c.desc 'Format to use when outputting tags to console: list, json, plist, csv or yaml. Use "complete" to output full text when input is STDIN.'
|
584
|
-
c.arg_name
|
585
|
-
c.flag %i[f format], :must_match => /^(csv|list|yaml|json|plist|complete)$/, :type => String, :default_value =>
|
611
|
+
c.arg_name "output_format"
|
612
|
+
c.flag %i[f format], :must_match => /^(csv|list|yaml|json|plist|complete)$/, :type => String, :default_value => "yaml"
|
586
613
|
|
587
614
|
c.action do |global_options, options, args|
|
588
|
-
if @piped_content
|
615
|
+
if @piped_content && !@piped_content.file_list?
|
589
616
|
suggestions = @jt.suggest(@piped_content)
|
590
617
|
if args.length > 0
|
591
618
|
console_log
|
592
|
-
console_log
|
619
|
+
console_log "STDIN:", :err => true
|
593
620
|
end
|
594
|
-
if options[:format] ==
|
621
|
+
if options[:format] == "complete"
|
595
622
|
@jt.update_file_tags(@piped_content, suggestions, true)
|
596
623
|
else
|
597
624
|
output_tags(suggestions, :format => options[:format], :filename => nil)
|
598
625
|
end
|
599
626
|
end
|
600
|
-
|
627
|
+
|
628
|
+
files = []
|
629
|
+
args.length.times do
|
630
|
+
arg = args.pop
|
631
|
+
files.push(arg) if File.exist?(arg)
|
632
|
+
end
|
633
|
+
|
634
|
+
files.concat(@piped_content.split("\n")) if @piped_content && @piped_content.file_list?
|
635
|
+
|
636
|
+
files.each do |file|
|
601
637
|
if File.exist?(File.expand_path(file))
|
602
638
|
input = IO.read(File.expand_path(file))
|
603
639
|
suggestions = @jt.suggest(input)
|
@@ -616,26 +652,26 @@ command :tag do |c|
|
|
616
652
|
console_log
|
617
653
|
console_log File.basename(file) + ":", :err => true, :log => true
|
618
654
|
end
|
619
|
-
output_tags(suggestions, :format => options[:format], :filename => file
|
655
|
+
output_tags(suggestions, :format => options[:format], :filename => file)
|
620
656
|
end
|
621
657
|
suggestions = nil
|
622
658
|
else
|
623
659
|
raise "No such file: #{file}"
|
624
660
|
end
|
625
|
-
|
661
|
+
end
|
626
662
|
end
|
627
663
|
end
|
628
664
|
|
629
|
-
def output_tags(tags,options)
|
630
|
-
format = options[:format] ||
|
665
|
+
def output_tags(tags, options)
|
666
|
+
format = options[:format] || "yaml"
|
631
667
|
print0 = options[:print0] || false
|
632
668
|
filename = options[:filename] || false
|
633
669
|
case format
|
634
|
-
when
|
670
|
+
when "list"
|
635
671
|
unless print0
|
636
672
|
console_log tags.join("\n")
|
637
673
|
else
|
638
|
-
console_log tags.map {|tag|
|
674
|
+
console_log tags.map { |tag|
|
639
675
|
if tag.strip =~ /\b\s\b/
|
640
676
|
%Q{"#{tag.strip}"}
|
641
677
|
else
|
@@ -643,19 +679,19 @@ def output_tags(tags,options)
|
|
643
679
|
end
|
644
680
|
}.join(" ")
|
645
681
|
end
|
646
|
-
when
|
682
|
+
when "csv"
|
647
683
|
console_log tags.to_csv
|
648
|
-
when
|
684
|
+
when "json"
|
649
685
|
out = {}
|
650
|
-
out[
|
651
|
-
out[
|
686
|
+
out["tags"] = tags
|
687
|
+
out["path"] = filename if filename
|
652
688
|
console_log out.to_json
|
653
|
-
when
|
689
|
+
when "plist"
|
654
690
|
out = {}
|
655
|
-
out[
|
691
|
+
out["path"] = filename if filename
|
656
692
|
console_log tags.to_plist
|
657
693
|
else
|
658
|
-
|
694
|
+
out = {}
|
659
695
|
options[:grouping] ||= "tags"
|
660
696
|
out[options[:grouping]] = tags
|
661
697
|
console_log out.to_yaml
|
@@ -677,29 +713,31 @@ pre do |global, command, options, args|
|
|
677
713
|
# on that command only
|
678
714
|
@silent = global[:silent]
|
679
715
|
|
680
|
-
|
716
|
+
Signal.trap("PIPE", "EXIT")
|
717
|
+
|
718
|
+
@logfile = File.open(File.join(Dir.tmpdir, "jtag_actions.log"), "a")
|
681
719
|
|
682
720
|
@log = Logger.new(@logfile, shift_age = 7, shift_size = 1048576)
|
683
721
|
|
684
722
|
unless config_files_complete?
|
685
723
|
write_config
|
686
|
-
console_log "Missing config files written to #{@config_target}. Please check your configuration.", {:err => true}
|
724
|
+
console_log "Missing config files written to #{@config_target}. Please check your configuration.", { :err => true }
|
687
725
|
return false
|
688
726
|
end
|
689
727
|
|
690
728
|
configfile = File.expand_path("~/.jtag/config.yml")
|
691
729
|
|
692
|
-
global[:config] = YAML::load(File.open(configfile,"r"))
|
730
|
+
global[:config] = YAML::load(File.open(configfile, "r"))
|
693
731
|
global[:support] = File.expand_path("~/.jtag")
|
694
732
|
|
695
|
-
@piped_content =
|
733
|
+
@piped_content = $stdin.read if $stdin.fcntl(Fcntl::F_GETFL, 0) == 0 || $stdin.stat.pipe?
|
696
734
|
|
697
735
|
@jt = JTag.new(global[:support], global[:config])
|
698
736
|
|
699
737
|
true
|
700
738
|
end
|
701
739
|
|
702
|
-
post do |global,command,options,args|
|
740
|
+
post do |global, command, options, args|
|
703
741
|
# Post logic here
|
704
742
|
# Use skips_post before a command to skip this
|
705
743
|
# block on that command only
|
data/lib/jtag/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jtag
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.19
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brett Terpstra
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-09-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -124,7 +124,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
124
124
|
- !ruby/object:Gem::Version
|
125
125
|
version: '0'
|
126
126
|
requirements: []
|
127
|
-
rubygems_version: 3.
|
127
|
+
rubygems_version: 3.2.16
|
128
128
|
signing_key:
|
129
129
|
specification_version: 4
|
130
130
|
summary: Auto-tagging and tagging tools for Jekyll
|