scout-gear 1.1.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,120 @@
1
+ require_relative '../log'
2
+ module SOPT
3
+
4
+ class << self
5
+ attr_accessor :command, :summary, :synopsys, :description
6
+ end
7
+
8
+ def self.command
9
+ @command ||= File.basename($0)
10
+ end
11
+
12
+ def self.summary
13
+ @summary ||= ""
14
+ end
15
+
16
+ def self.synopsys
17
+ @synopsys ||= begin
18
+ "#{command} " <<
19
+ inputs.collect{|name|
20
+ "[" << input_format(name, input_types[name] || :string, input_defaults[name], input_shortcuts[name]).sub(/:$/,'') << "]"
21
+ } * " "
22
+ end
23
+ end
24
+
25
+ def self.description
26
+ @description ||= "Missing"
27
+ end
28
+
29
+ def self.input_format(name, type = nil, default = nil, short = nil)
30
+ input_str = (short.nil? or short.empty?) ? "--#{name}" : "-#{short},--#{name}"
31
+ input_str = Log.color(:blue, input_str)
32
+ extra = case type
33
+ when nil
34
+ ""
35
+ when :boolean
36
+ "[=false]"
37
+ when :tsv, :text
38
+ "=<file|->"
39
+ when :array
40
+ "=<list|file|->"
41
+ else
42
+ "=<#{ type }>"
43
+ end
44
+ #extra << " (default: #{Array === default ? (default.length > 3 ? default[0..2]*", " + ', ...' : default*", " ): default})" if default != nil
45
+ extra << " (default: #{Misc.fingerprint(default)})" if default != nil
46
+ input_str << Log.color(:green, extra)
47
+ end
48
+
49
+ def self.input_doc(inputs, input_types = nil, input_descriptions = nil, input_defaults = nil, input_shortcuts = nil)
50
+ type = description = default = nil
51
+ shortcut = ""
52
+ seen = []
53
+ inputs.collect do |name|
54
+ next if seen.include? name
55
+ seen << name
56
+
57
+ type = input_types[name] unless input_types.nil?
58
+ description = input_descriptions[name] unless input_descriptions.nil?
59
+ default = input_defaults[name] unless input_defaults.nil?
60
+
61
+ name = name.to_s
62
+
63
+ case input_shortcuts
64
+ when nil, FalseClass
65
+ shortcut = nil
66
+ when Hash
67
+ shortcut = input_shortcuts[name]
68
+ when TrueClass
69
+ shortcut = fix_shortcut(name[0], name)
70
+ end
71
+
72
+ type = :string if type.nil?
73
+ register(shortcut, name, type, description) unless self.inputs.include? name
74
+
75
+ name = SOPT.input_format(name, type.to_sym, default, shortcut)
76
+ description
77
+ Misc.format_definition_list_item(name, description, 80, 31, nil)
78
+ end * "\n"
79
+ end
80
+
81
+ def self.doc
82
+ doc = <<-EOF
83
+ #{Log.color :magenta}#{command}(1) -- #{summary}
84
+ #{"=" * (command.length + summary.length + 7)}#{Log.color :reset}
85
+
86
+ #{ Log.color :magenta, "## SYNOPSYS"}
87
+
88
+ #{Log.color :blue, synopsys}
89
+
90
+ #{ Log.color :magenta, "## DESCRIPTION"}
91
+
92
+ #{Misc.format_paragraph description}
93
+
94
+ #{ Log.color :magenta, "## OPTIONS"}
95
+
96
+ #{input_doc(inputs, input_types, input_descriptions, input_defaults, input_shortcuts)}
97
+ EOF
98
+ end
99
+
100
+ def self.doc
101
+ doc = <<-EOF
102
+ #{Log.color :magenta}#{command}(1) -- #{summary}
103
+ #{"=" * (command.length + summary.length + 7)}#{Log.color :reset}
104
+
105
+ EOF
106
+
107
+ if synopsys and not synopsys.empty?
108
+ doc << Log.color(:magenta, "## SYNOPSYS") << "\n\n"
109
+ doc << Log.color(:blue, synopsys) << "\n\n"
110
+ end
111
+
112
+ if description and not description.empty?
113
+ doc << Log.color(:magenta, "## DESCRIPTION") << "\n\n"
114
+ doc << Misc.format_paragraph(description) << "\n\n"
115
+ end
116
+
117
+ doc << Log.color(:magenta, "## OPTIONS") << "\n\n"
118
+ doc << input_doc(inputs, input_types, input_descriptions, input_defaults, input_shortcuts)
119
+ end
120
+ end
@@ -0,0 +1,57 @@
1
+ module SOPT
2
+ GOT_OPTIONS= IndiferentHash.setup({})
3
+ def self.current_options=(options)
4
+ @@current_options = options
5
+ end
6
+ def self.consume(args = ARGV)
7
+ i = 0
8
+ @@current_options ||= {}
9
+ while i < args.length do
10
+ current = args[i]
11
+ break if current == "--"
12
+ if m = current.match(/--?(.+?)(?:=(.+))?$/)
13
+ key = $1
14
+ value = $2
15
+
16
+ input = inputs.include?(key)? key : shortcuts[key]
17
+
18
+ if input.nil?
19
+ i += 1
20
+ next
21
+ else
22
+ args.delete_at i
23
+ end
24
+ else
25
+ i += 1
26
+ next
27
+ end
28
+
29
+ if input_types[input] == :string
30
+ value = args.delete_at(i) if value.nil?
31
+ @@current_options[input] = value
32
+ else
33
+ if value.nil? and %w(F false FALSE no).include?(args[i])
34
+ Log.warn "Boolean values are best specified as #{current}=[true|false], not #{ current } [true|false]. Token '#{args[i]}' following '#{current}' automatically assigned as value"
35
+ value = args.delete_at(i)
36
+ end
37
+ @@current_options[input] = %w(F false FALSE no).include?(value)? false : true
38
+ end
39
+ end
40
+
41
+ IndiferentHash.setup @@current_options
42
+ GOT_OPTIONS.merge! @@current_options
43
+
44
+ @@current_options
45
+ end
46
+
47
+ def self.get(opt_str)
48
+ SOPT.parse(opt_str)
49
+ SOPT.consume(ARGV)
50
+ end
51
+
52
+ def self.require(options, *parameters)
53
+ parameters.flatten.each do |parameter|
54
+ raise ParameterException, "Parameter '#{ Log.color :blue, parameter }' not given" if options[parameter].nil?
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,66 @@
1
+ module SOPT
2
+ def self.fix_shortcut(short, long)
3
+ return short unless short and shortcuts.include?(short)
4
+
5
+ current = shortcuts.select{|s,l| l == long}.collect{|s,l| s }.first
6
+ return current if current
7
+
8
+ chars = long.chars.to_a
9
+ current = [chars.shift]
10
+ short = current * ""
11
+
12
+ if (shortcuts.include?(short) and not shortcuts[short] == long)
13
+ if long.index "-" or long.index "_"
14
+ parts = long.split(/[_-]/)
15
+ acc = parts.collect{|s| s[0] } * ""
16
+ return acc unless shortcuts.include? acc
17
+ elsif m = long.match(/(\d+)/)
18
+ n = m[0]
19
+ acc = long[0] + n
20
+ return acc unless shortcuts.include? acc
21
+ end
22
+ end
23
+
24
+ while shortcuts.include?(short) && shortcuts[short] != long
25
+ next_letter = chars.shift
26
+ next_letter = chars.shift while %w(. - _).include?(next_letter)
27
+ return nil if next_letter.nil?
28
+ current << next_letter
29
+ short = current * ""
30
+ end
31
+
32
+ return nil if shortcuts.include? short
33
+
34
+ short
35
+ end
36
+
37
+ def self.register(short, long, asterisk, description)
38
+ short = fix_shortcut(short, long)
39
+ shortcuts[short] = long if short
40
+ inputs << long
41
+ input_shortcuts[long] = short
42
+ input_descriptions[long] = description
43
+ input_types[long] = asterisk ? :string : :boolean
44
+ end
45
+
46
+ def self.parse(opt_str)
47
+ info = {}
48
+
49
+ inputs = []
50
+ if opt_str.include? "\n"
51
+ re = /\n+/
52
+ else
53
+ re = /:/
54
+ end
55
+ opt_str.split(re).each do |entry|
56
+ entry.strip!
57
+ next if entry.empty?
58
+ names, _sep, description = entry.partition /\s+/
59
+ short, long, asterisk = names.match(/\s*(?:-(.+))?(?:--(.+?))([*])?$/).values_at 1,2,3
60
+
61
+ inputs << long
62
+ register short, long, asterisk, description
63
+ end
64
+ inputs
65
+ end
66
+ end
@@ -0,0 +1,26 @@
1
+ module SOPT
2
+
3
+ def self.setup(str)
4
+ parts = str.split(/\n\n+/)
5
+
6
+ summary = parts.shift unless parts.first =~ /^\s*\$-/
7
+ synopsys = parts.shift if parts.first =~ /^\s*\$/
8
+
9
+ description = []
10
+ while parts.first and parts.first !~ /^\s*-/
11
+ description << parts.shift
12
+ end
13
+ description = description * "\n\n"
14
+
15
+ options = parts.collect{|part| part.split("\n").select{|l| l=~ /^\s*-/ } }.flatten.compact * "\n"
16
+
17
+ synopsys.sub!(/^\$\s+/,'') if synopsys
18
+
19
+ SOPT.summary = summary.strip if summary
20
+ SOPT.synopsys = synopsys.strip if synopsys
21
+ SOPT.description = description.strip if description
22
+ SOPT.parse options if options
23
+
24
+ SOPT.consume
25
+ end
26
+ end
@@ -0,0 +1,5 @@
1
+ require_relative 'simple_opt/accessor'
2
+ require_relative 'simple_opt/parse'
3
+ require_relative 'simple_opt/doc'
4
+ require_relative 'simple_opt/get'
5
+ require_relative 'simple_opt/setup'
data/lib/scout/tmpfile.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'fileutils'
2
+ require_relative 'misc'
2
3
 
3
4
  module TmpFile
4
5
  def self.user_tmp(subdir = nil)
@@ -83,13 +84,8 @@ module TmpFile
83
84
 
84
85
  def self.in_dir(*args)
85
86
  with_dir(*args) do |dir|
86
- old_pwd = FileUtils.pwd
87
- begin
88
- FileUtils.mkdir_p dir unless File.exist?(dir)
89
- FileUtils.cd dir
87
+ Misc.in_dir dir do
90
88
  yield dir
91
- ensure
92
- FileUtils.cd old_pwd
93
89
  end
94
90
  end
95
91
  end
data/lib/scout-gear.rb CHANGED
@@ -1,3 +1,5 @@
1
1
  require_relative 'scout/indiferent_hash'
2
2
  require_relative 'scout/tmpfile'
3
3
  require_relative 'scout/log'
4
+ require_relative 'scout/path'
5
+ require_relative 'scout/simple_opt'
data/scout-gear.gemspec CHANGED
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Juwelier::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: scout-gear 1.1.1 ruby lib
5
+ # stub: scout-gear 2.0.0 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "scout-gear".freeze
9
- s.version = "1.1.1"
9
+ s.version = "2.0.0"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib".freeze]
13
13
  s.authors = ["Miguel Vazquez".freeze]
14
- s.date = "2023-03-24"
14
+ s.date = "2023-03-30"
15
15
  s.description = "Temporary files, logs, etc.".freeze
16
16
  s.email = "mikisvaz@gmail.com".freeze
17
17
  s.executables = ["scout".freeze]
@@ -21,6 +21,7 @@ Gem::Specification.new do |s|
21
21
  ]
22
22
  s.files = [
23
23
  ".document",
24
+ ".gitmodules",
24
25
  ".vimproject",
25
26
  "LICENSE.txt",
26
27
  "README.rdoc",
@@ -40,16 +41,31 @@ Gem::Specification.new do |s|
40
41
  "lib/scout/log/progress/report.rb",
41
42
  "lib/scout/log/progress/util.rb",
42
43
  "lib/scout/meta_extension.rb",
44
+ "lib/scout/misc.rb",
45
+ "lib/scout/misc/format.rb",
43
46
  "lib/scout/path.rb",
44
47
  "lib/scout/path/find.rb",
48
+ "lib/scout/path/util.rb",
49
+ "lib/scout/simple_opt.rb",
50
+ "lib/scout/simple_opt/accessor.rb",
51
+ "lib/scout/simple_opt/doc.rb",
52
+ "lib/scout/simple_opt/get.rb",
53
+ "lib/scout/simple_opt/parse.rb",
54
+ "lib/scout/simple_opt/setup.rb",
45
55
  "lib/scout/tmpfile.rb",
46
56
  "scout-gear.gemspec",
57
+ "test/scout/indiferent_hash/test_case_insensitive.rb",
47
58
  "test/scout/indiferent_hash/test_options.rb",
48
59
  "test/scout/log/test_progress.rb",
49
60
  "test/scout/path/test_find.rb",
61
+ "test/scout/path/test_util.rb",
62
+ "test/scout/simple_opt/test_get.rb",
63
+ "test/scout/simple_opt/test_parse.rb",
64
+ "test/scout/simple_opt/test_setup.rb",
50
65
  "test/scout/test_indiferent_hash.rb",
51
66
  "test/scout/test_log.rb",
52
67
  "test/scout/test_meta_extension.rb",
68
+ "test/scout/test_misc.rb",
53
69
  "test/scout/test_path.rb",
54
70
  "test/scout/test_tmpfile.rb",
55
71
  "test/test_helper.rb"
@@ -0,0 +1,16 @@
1
+ require File.expand_path(__FILE__).sub(%r(/test/.*), '/test/test_helper.rb')
2
+ require File.expand_path(__FILE__).sub(%r(.*/test/), '').sub(/test_(.*)\.rb/,'\1')
3
+
4
+ class TestCaseInsensitiveHash < Test::Unit::TestCase
5
+ def test_case_insensitive_hash
6
+ a = {:a => 1, "b" => 2}
7
+ a.extend CaseInsensitiveHash
8
+
9
+ assert_equal 1, a[:a]
10
+ assert_equal 1, a["A"]
11
+ assert_equal 1, a[:A]
12
+ assert_equal 2, a["B"]
13
+ assert_equal 2, a[:b]
14
+ end
15
+ end
16
+
@@ -1,6 +1,8 @@
1
1
  require File.expand_path(__FILE__).sub(%r(/test/.*), '/test/test_helper.rb')
2
2
  require 'scout/path'
3
+ require 'scout/misc'
3
4
  require File.expand_path(__FILE__).sub(%r(.*/test/), '').sub(/test_(.*)\.rb/,'\1')
5
+
4
6
  class TestPathFind < Test::Unit::TestCase
5
7
  def test_parts
6
8
  path = Path.setup("share/data/some_file", 'scout')
@@ -8,7 +10,7 @@ class TestPathFind < Test::Unit::TestCase
8
10
  assert_equal "data/some_file", path._subpath
9
11
 
10
12
  path = Path.setup("data", 'scout')
11
- assert_equal nil, path._toplevel
13
+ assert_equal "", path._toplevel
12
14
  assert_equal "data", path._subpath
13
15
  end
14
16
 
@@ -30,5 +32,44 @@ class TestPathFind < Test::Unit::TestCase
30
32
  assert_equal File.join(tmpdir,"share/data/some_file"), path.find(:current)
31
33
  end
32
34
  end
35
+
36
+ def test_current_find
37
+ path = Path.setup("share/data/some_file", 'scout')
38
+ TmpFile.in_dir do |tmpdir|
39
+ FileUtils.mkdir_p(File.dirname(File.join(tmpdir, path)))
40
+ File.write(File.join(tmpdir, path), 'string')
41
+ assert_equal File.join(tmpdir,"share/data/some_file"), path.find
42
+ assert_equal :current, path.find.where
43
+ assert_equal "share/data/some_file", path.find.original
44
+ end
45
+ end
46
+
47
+ def test_current_find_all
48
+ path = Path.setup("share/data/some_file", 'scout')
49
+ TmpFile.with_dir do |tmpdir|
50
+ Path.setup tmpdir
51
+
52
+ FileUtils.mkdir_p(tmpdir.lib)
53
+ FileUtils.mkdir_p(tmpdir.share.data)
54
+ File.write(tmpdir.share.data.some_file, 'string')
55
+
56
+ FileUtils.mkdir_p(tmpdir.subdir.share.data)
57
+ File.write(tmpdir.subdir.share.data.some_file, 'string')
58
+
59
+ path.libdir = tmpdir
60
+ Misc.in_dir tmpdir.subdir do
61
+ assert_equal 2, path.find_all.length
62
+ end
63
+ end
64
+ end
65
+
66
+ def test_located?
67
+
68
+ p = Path.setup("/tmp/foo/bar")
69
+ assert p.located?
70
+ assert_equal p, p.find
71
+
72
+ end
73
+
33
74
  end
34
75
 
@@ -0,0 +1,22 @@
1
+ require File.expand_path(__FILE__).sub(%r(/test/.*), '/test/test_helper.rb')
2
+ require 'scout/path'
3
+ require File.expand_path(__FILE__).sub(%r(.*/test/), '').sub(/test_(.*)\.rb/,'\1')
4
+
5
+ class TestPathUtil < Test::Unit::TestCase
6
+ def test_dirname
7
+ p = Path.setup("/usr/share/scout/data")
8
+
9
+ assert_equal "/usr/share/scout", p.dirname
10
+ end
11
+
12
+ def test_glob
13
+ TmpFile.in_dir :erase => false do |tmpdir|
14
+ Path.setup tmpdir
15
+ File.write(tmpdir.foo, 'foo')
16
+ File.write(tmpdir.bar, 'bar')
17
+ assert_equal 2, tmpdir.glob.length
18
+ assert_equal %w(foo bar).sort, tmpdir.glob.collect{|p| p.basename }.sort
19
+ end
20
+ end
21
+ end
22
+
@@ -0,0 +1,11 @@
1
+ require File.expand_path(__FILE__).sub(%r(/test/.*), '/test/test_helper.rb')
2
+ require 'scout/simple_opt'
3
+ require File.expand_path(__FILE__).sub(%r(.*/test/), '').sub(/test_(.*)\.rb/,'\1')
4
+
5
+ class TestSOPTParse < Test::Unit::TestCase
6
+ def test_consume
7
+ SOPT.parse("-f--first* first arg:-f--fun")
8
+ args = "-f myfile --fun".split(" ")
9
+ assert_equal "myfile", SOPT.consume(args)[:first]
10
+ end
11
+ end
@@ -0,0 +1,10 @@
1
+ require File.expand_path(__FILE__).sub(%r(/test/.*), '/test/test_helper.rb')
2
+ require 'scout/path'
3
+ require File.expand_path(__FILE__).sub(%r(.*/test/), '').sub(/test_(.*)\.rb/,'\1')
4
+
5
+ class TestSOPTParse < Test::Unit::TestCase
6
+ def test_parse
7
+ SOPT.parse("-f--first* first arg:-f--fun")
8
+ assert_equal "fun", SOPT.shortcuts["fu"]
9
+ end
10
+ end
@@ -0,0 +1,77 @@
1
+ require File.expand_path(__FILE__).sub(%r(/test/.*), '/test/test_helper.rb')
2
+ require 'scout/simple_opt'
3
+ require File.expand_path(__FILE__).sub(%r(.*/test/), '').sub(/test_(.*)\.rb/,'\1')
4
+
5
+ class TestSOPTSetup < Test::Unit::TestCase
6
+ def setup
7
+ SOPT.inputs = nil
8
+ SOPT.input_types = nil
9
+ SOPT.input_descriptions = nil
10
+ SOPT.input_shortcuts = nil
11
+ end
12
+
13
+ def test_setup
14
+ SOPT.setup <<-EOF
15
+ Test application
16
+
17
+ $ test cmd -arg 1
18
+
19
+ It does some imaginary stuff
20
+
21
+ -a--arg* Argument
22
+ -a2--arg2* Argument
23
+
24
+ EOF
25
+
26
+ assert_equal "test cmd -arg 1", SOPT.synopsys
27
+ assert SOPT.inputs.include? "arg"
28
+ assert SOPT.inputs.include? "arg2"
29
+ end
30
+
31
+ def test_setup_alt
32
+ SOPT.setup <<-EOF
33
+ Test application
34
+
35
+ It does some imaginary stuff
36
+
37
+ -a--arg* Argument
38
+ -a2--arg2* Argument
39
+
40
+ EOF
41
+
42
+ assert SOPT.inputs.include? "arg"
43
+ assert SOPT.inputs.include? "arg2"
44
+ end
45
+
46
+ def test_setup_alt2
47
+ SOPT.setup <<-EOF
48
+ Test application
49
+
50
+ -a--arg* Argument
51
+ -a2--arg2* Argument
52
+
53
+ EOF
54
+
55
+ assert SOPT.inputs.include? "arg"
56
+ assert SOPT.inputs.include? "arg2"
57
+ end
58
+
59
+ def test_setup_alt3
60
+ SOPT.setup <<-EOF
61
+ Pulls the values from a tsv colum
62
+
63
+ $ rbbt tsv values [options] <filename.tsv|->
64
+
65
+ Use - to read from STDIN
66
+
67
+ -tch--tokyocabinet File is a tokyocabinet hash database
68
+ -tcb--tokyocabinet_bd File is a tokyocabinet B database
69
+ -h--help Print this help
70
+ EOF
71
+
72
+ assert SOPT.inputs.include? "tokyocabinet"
73
+ end
74
+
75
+ end
76
+
77
+
@@ -5,10 +5,10 @@ class TestMetaExtension < Test::Unit::TestCase
5
5
  module ExtensionClass
6
6
  extend MetaExtension
7
7
 
8
- extension_attr :code
8
+ extension_attr :code, :code2
9
9
  end
10
10
 
11
- def test_setup
11
+ def test_setup_annotate
12
12
  str = "String"
13
13
  ExtensionClass.setup(str, :code)
14
14
  assert ExtensionClass === str
@@ -18,5 +18,19 @@ class TestMetaExtension < Test::Unit::TestCase
18
18
  str.annotate(str2)
19
19
  assert_equal :code, str2.code
20
20
  end
21
+
22
+ def test_setup_alternatives
23
+ str = "String"
24
+
25
+ ExtensionClass.setup(str, :code2 => :code)
26
+ assert_equal :code, str.code2
27
+
28
+ ExtensionClass.setup(str, code2: :code)
29
+ assert_equal :code, str.code2
30
+
31
+ ExtensionClass.setup(str, "code2" => :code)
32
+ assert_equal :code, str.code2
33
+
34
+ end
21
35
  end
22
36
 
@@ -0,0 +1,13 @@
1
+ require File.expand_path(__FILE__).sub(%r(/test/.*), '/test/test_helper.rb')
2
+ require File.expand_path(__FILE__).sub(%r(.*/test/), '').sub(/test_(.*)\.rb/,'\1')
3
+
4
+ class TestMisc < Test::Unit::TestCase
5
+ def test_in_dir
6
+ TmpFile.with_file do |tmpdir|
7
+ Misc.in_dir tmpdir do
8
+ assert_equal tmpdir, FileUtils.pwd
9
+ end
10
+ end
11
+ end
12
+ end
13
+
@@ -32,5 +32,21 @@ class TestPath < Test::Unit::TestCase
32
32
  assert_equal 'scout', path.pkgdir
33
33
  assert path.libdir.end_with?("scout-gear")
34
34
  end
35
+
36
+ def test_lib_dir
37
+ TmpFile.with_file do |tmpdir|
38
+ Path.setup tmpdir
39
+ FileUtils.mkdir_p tmpdir.lib
40
+ File.write tmpdir.lib.file, <<-EOR
41
+ require '#{File.expand_path(__FILE__).sub(%r(.*/test/), '').sub(/test_(.*)\.rb/,'\1')}'
42
+ a = "1"
43
+ Path.setup(a)
44
+ print a.libdir
45
+ EOR
46
+ Misc.in_dir tmpdir.tmp do
47
+ assert_equal tmpdir, `ruby #{tmpdir.lib.file}`
48
+ end
49
+ end
50
+ end
35
51
  end
36
52