falsework 1.3.0 → 2.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.
- data/Gemfile +1 -1
- data/Gemfile.lock +2 -2
- data/README.rdoc +6 -5
- data/Rakefile +14 -10
- data/bin/falsework +25 -25
- data/doc/NEWS.rdoc +18 -0
- data/doc/README.rdoc +6 -5
- data/doc/TODO.org +2 -1
- data/lib/falsework/cliconfig.rb +135 -0
- data/lib/falsework/cliutils.rb +112 -0
- data/lib/falsework/meta.rb +1 -1
- data/lib/falsework/mould.rb +23 -20
- data/lib/falsework/templates/{ruby-naive → ruby-cli}/#config.yaml +0 -0
- data/lib/falsework/templates/{ruby-naive → ruby-cli}/.gitignore.#erb +0 -0
- data/lib/falsework/templates/{ruby-naive → ruby-cli}/Gemfile +1 -1
- data/lib/falsework/templates/{ruby-naive/doc → ruby-cli}/README.rdoc +1 -1
- data/lib/falsework/templates/{ruby-naive → ruby-cli}/Rakefile +0 -0
- data/lib/falsework/templates/ruby-cli/bin/%%@project%% +26 -0
- data/lib/falsework/templates/{ruby-naive → ruby-cli}/doc/#doc.rdoc +1 -1
- data/lib/falsework/templates/{ruby-naive → ruby-cli}/doc/LICENSE +0 -0
- data/lib/falsework/templates/{ruby-naive → ruby-cli}/doc/NEWS.rdoc +0 -0
- data/lib/falsework/templates/{ruby-naive → ruby-cli/doc}/README.rdoc +1 -1
- data/lib/falsework/templates/{ruby-naive → ruby-cli}/etc/%%@project%%.yaml +0 -0
- data/lib/falsework/templates/ruby-cli/lib/%%@project%%/cliconfig.rb +137 -0
- data/lib/falsework/templates/ruby-cli/lib/%%@project%%/cliutils.rb +114 -0
- data/lib/falsework/templates/{ruby-naive → ruby-cli}/lib/%%@project%%/meta.rb +0 -0
- data/lib/falsework/templates/{ruby-naive → ruby-cli}/test/helper.rb +1 -1
- data/lib/falsework/templates/{ruby-naive/test/helper_trestle.rb → ruby-cli/test/helper_cliutils.rb} +4 -4
- data/lib/falsework/templates/{ruby-naive → ruby-cli}/test/rake_git.rb +2 -2
- data/lib/falsework/templates/{ruby-naive → ruby-cli}/test/test_%%@project%%.rb +0 -0
- data/test/helper.rb +1 -1
- data/test/{helper_trestle.rb → helper_cliutils.rb} +3 -3
- data/test/rake_erb_templates.rb +3 -3
- data/test/rake_git.rb +1 -1
- data/test/templates/config-02.yaml +2 -0
- data/test/test_cl.rb +9 -5
- data/test/test_exe.rb +26 -21
- metadata +31 -26
- data/lib/falsework/templates/ruby-naive/bin/%%@project%% +0 -31
- data/lib/falsework/templates/ruby-naive/lib/%%@project%%/trestle.rb +0 -230
- data/lib/falsework/trestle.rb +0 -228
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
data/README.rdoc
CHANGED
@@ -10,7 +10,7 @@ falsework--A primitive scaffold generator for writing CLI programs.
|
|
10
10
|
|
11
11
|
==Description
|
12
12
|
|
13
|
-
The falsework utility ships with 2 templates: <tt>ruby-
|
13
|
+
The falsework utility ships with 2 templates: <tt>ruby-cli</tt> and
|
14
14
|
<tt>c-glib</tt>.
|
15
15
|
|
16
16
|
Initially the template spec was designed only for Ruby projects but
|
@@ -53,8 +53,9 @@ list:: Do nothing except listing all available
|
|
53
53
|
|
54
54
|
listdirs:: Do nothing except listing all available
|
55
55
|
templates directories. You can add another
|
56
|
-
directory
|
57
|
-
the config file. (<tt>tdir</tt> is an
|
56
|
+
directory by modifying <tt>tdir</tt> option
|
57
|
+
in the config file. (<tt>tdir</tt> is an
|
58
|
+
array).
|
58
59
|
|
59
60
|
new NAME:: Create a new project. It creates a directory
|
60
61
|
<i>NAME</i> and populates it with files.
|
@@ -73,7 +74,7 @@ test NAME:: Add a new test in
|
|
73
74
|
|
74
75
|
upgrade:: 'Inject' or upgrade some vital files from the
|
75
76
|
template into the project. Currently only
|
76
|
-
'ruby-
|
77
|
+
'ruby-cli' template supports this.
|
77
78
|
|
78
79
|
The options are as follows:
|
79
80
|
|
@@ -82,7 +83,7 @@ The options are as follows:
|
|
82
83
|
-b:: A batch mode. (No questions asked.)
|
83
84
|
|
84
85
|
--no-git:: Don't create a Git repository. Don't use
|
85
|
-
this for 'ruby-
|
86
|
+
this for 'ruby-cli' template.
|
86
87
|
|
87
88
|
--config-dirs:: List all possible locations for the
|
88
89
|
configuration file. The first found wins.
|
data/Rakefile
CHANGED
@@ -18,15 +18,15 @@ require_relative 'test/rake_git'
|
|
18
18
|
#
|
19
19
|
require_relative 'test/rake_erb_templates'
|
20
20
|
|
21
|
-
ERB_DYN_SKELETON = erb_skeletons(Meta::NAME, 'ruby-
|
21
|
+
ERB_DYN_SKELETON = erb_skeletons(Meta::NAME, 'ruby-cli')
|
22
22
|
ERB_DYN_SKELETON.each {|k, v|
|
23
23
|
file k => [v] do |t|
|
24
|
-
erb_make(Meta::NAME, 'ruby-
|
24
|
+
erb_make(Meta::NAME, 'ruby-cli', t.name, t.prerequisites[0])
|
25
25
|
end
|
26
26
|
}
|
27
27
|
|
28
|
-
desc "Generate some erb templates for ruby-
|
29
|
-
task
|
28
|
+
desc "Generate some erb templates for ruby-cli template"
|
29
|
+
task cli: ERB_DYN_SKELETON.keys
|
30
30
|
|
31
31
|
CLOBBER.concat ERB_DYN_SKELETON.keys
|
32
32
|
#pp CLOBBER
|
@@ -35,6 +35,10 @@ CLOBBER.concat ERB_DYN_SKELETON.keys
|
|
35
35
|
# Gem staff
|
36
36
|
#
|
37
37
|
|
38
|
+
rdoc_task_excl = 'lib/**/templates/**/*'
|
39
|
+
rdoc_spec_excl = 'lib/.+/templates/'
|
40
|
+
rdoc_main = 'doc/README.rdoc'
|
41
|
+
|
38
42
|
spec = Gem::Specification.new {|i|
|
39
43
|
i.name = Meta::NAME
|
40
44
|
i.version = `bin/#{i.name} -V`
|
@@ -53,25 +57,25 @@ spec = Gem::Specification.new {|i|
|
|
53
57
|
|
54
58
|
i.test_files = FileList['test/test_*.rb']
|
55
59
|
|
56
|
-
i.rdoc_options << '-m' << '
|
60
|
+
i.rdoc_options << '-m' << rdoc_main << '-x' << rdoc_spec_excl
|
57
61
|
i.extra_rdoc_files = FileList['doc/*']
|
58
62
|
|
59
63
|
i.add_dependency('git', '>= 1.2.5')
|
60
|
-
i.add_dependency('open4', '>= 1.
|
64
|
+
i.add_dependency('open4', '>= 1.3.0')
|
61
65
|
}
|
62
66
|
|
63
67
|
Gem::PackageTask.new(spec).define
|
64
68
|
|
65
|
-
task default: [:
|
69
|
+
task default: [:cli, :repackage]
|
66
70
|
|
67
71
|
RDoc::Task.new('html') do |i|
|
68
|
-
i.main =
|
72
|
+
i.main = rdoc_main
|
69
73
|
i.rdoc_files = FileList['doc/*', 'lib/**/*.rb']
|
70
|
-
i.rdoc_files.exclude
|
74
|
+
i.rdoc_files.exclude rdoc_task_excl
|
71
75
|
end
|
72
76
|
|
73
77
|
Rake::TestTask.new do |i|
|
74
78
|
i.test_files = FileList['test/test_*.rb']
|
75
79
|
end
|
76
80
|
|
77
|
-
task test: [:
|
81
|
+
task test: [:cli]
|
data/bin/falsework
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# -*-ruby-*-
|
3
3
|
|
4
|
+
require_relative '../lib/falsework/cliconfig'
|
4
5
|
require_relative '../lib/falsework/mould'
|
5
6
|
|
6
7
|
include Falsework
|
7
8
|
|
8
|
-
$conf =
|
9
|
-
$t = Trestle.new($conf)
|
10
|
-
|
9
|
+
$conf = CliConfig.new
|
11
10
|
$conf[:banner] = <<EOF
|
12
11
|
Usage: #{File.basename($0)} [options] command ...
|
13
12
|
Available commands: list, listdirs, (new|exe|doc|test) NAME, upgrade.
|
@@ -24,9 +23,9 @@ def add_files(mode, files)
|
|
24
23
|
m = Mould.new(File.basename(Dir.pwd), $conf[:template],
|
25
24
|
$conf[:user], $conf[:email], $conf[:gecos])
|
26
25
|
files.each {|i|
|
27
|
-
created = m.add(mode, i) rescue
|
26
|
+
created = m.add(mode, i) rescue CliUtils.errx(1, $!.to_s)
|
28
27
|
if created.size > 0
|
29
|
-
created.each {|idx|
|
28
|
+
created.each {|idx| CliUtils.veputs(1, idx) }
|
30
29
|
else
|
31
30
|
r = false
|
32
31
|
end
|
@@ -35,34 +34,35 @@ def add_files(mode, files)
|
|
35
34
|
r
|
36
35
|
end
|
37
36
|
|
38
|
-
# --[ main ]------------------------------------------------------------
|
39
37
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
o.on('--
|
44
|
-
o.on('--
|
45
|
-
o.on('--
|
46
|
-
o.on('-
|
47
|
-
|
48
|
-
|
38
|
+
### main
|
39
|
+
|
40
|
+
$conf.load {|o|
|
41
|
+
o.on('--user STR', 'Github user.') {|i| $conf[:user] = i }
|
42
|
+
o.on('--gecos STR', 'A gecos-like string.') {|i| $conf[:gecos] = i }
|
43
|
+
o.on('--email STR') {|i| $conf[:email] = i }
|
44
|
+
o.on('--no-git', "Don't create a git repo.",
|
45
|
+
"(Will break 'ruby-cli'.)") { $conf[:git] = false }
|
46
|
+
o.on('-t NAME', 'A template name.') {|i| $conf[:template] = i }
|
47
|
+
o.on('-b', 'Run in a batch mode and',
|
48
|
+
'don\'t ask any questions.') { $conf[:batch] = true }
|
49
49
|
}
|
50
50
|
|
51
|
-
|
51
|
+
CliUtils.errx(EX_USAGE, $conf[:banner]) if (ARGV.size < 2 && ARGV[0] !~ /list|upgrade/)
|
52
52
|
|
53
53
|
# print our env
|
54
54
|
if $conf[:verbose] >= 2
|
55
|
-
puts
|
55
|
+
puts "Lib dir: #{CliUtils::DIR_LIB_SRC}"
|
56
56
|
pp $conf
|
57
57
|
end
|
58
58
|
|
59
59
|
# modify a list of available template directories
|
60
|
-
Mould.template_dirs_add $conf[:tdir]
|
60
|
+
Mould.template_dirs_add $conf[:tdir].map {|i| Pathname.new i} if $conf[:tdir]
|
61
61
|
|
62
62
|
case ARGV[0]
|
63
63
|
when 'list'
|
64
64
|
Mould.templates.each {|name, loc|
|
65
|
-
loc = '(system)' if loc == Mould.class_variable_get(:@@template_dirs)[0] +
|
65
|
+
loc = '(system)' if loc == (Mould.class_variable_get(:@@template_dirs)[0] + name).to_s
|
66
66
|
puts "%-30s %s" % [name, loc]
|
67
67
|
}
|
68
68
|
|
@@ -82,11 +82,11 @@ when 'upgrade'
|
|
82
82
|
$conf[:user], $conf[:email], $conf[:gecos])
|
83
83
|
m.verbose = true if $conf[:verbose] > 0
|
84
84
|
m.batch = $conf[:batch]
|
85
|
-
m.upgrade() rescue
|
85
|
+
m.upgrade() rescue CliUtils.errx(1, $!.to_s)
|
86
86
|
|
87
87
|
when 'new'
|
88
88
|
if File.dirname(ARGV[1]) != '.'
|
89
|
-
Dir.chdir(File.dirname(ARGV[1])) rescue
|
89
|
+
Dir.chdir(File.dirname(ARGV[1])) rescue CliUtils.errx(1, "cannot chdir to '#{File.dirname(ARGV[1])}'")
|
90
90
|
ARGV[1] = File.basename ARGV[1]
|
91
91
|
end
|
92
92
|
|
@@ -94,7 +94,7 @@ when 'new'
|
|
94
94
|
m = Mould.new(ARGV[1], $conf[:template],
|
95
95
|
$conf[:user], $conf[:email], $conf[:gecos])
|
96
96
|
rescue
|
97
|
-
|
97
|
+
CliUtils.errx 1, $!
|
98
98
|
end
|
99
99
|
m.verbose = true if $conf[:verbose] > 0
|
100
100
|
m.project_seed
|
@@ -102,12 +102,12 @@ when 'new'
|
|
102
102
|
# create a git repository
|
103
103
|
if $conf[:git]
|
104
104
|
Dir.chdir m.project
|
105
|
-
|
105
|
+
CliUtils.veputs(1, "Creating a git repository in #{Dir.pwd}... __NNL__")
|
106
106
|
g = Git.init
|
107
107
|
g.add '.'
|
108
108
|
g.commit "Initial import from #{Falsework::Meta::NAME} #{Falsework::Meta::VERSION}."
|
109
|
-
|
109
|
+
CliUtils.veputs(1, 'OK')
|
110
110
|
end
|
111
111
|
else
|
112
|
-
|
112
|
+
CliUtils.errx(1, "unknown command: " + ARGV[0])
|
113
113
|
end
|
data/doc/NEWS.rdoc
CHANGED
@@ -1,3 +1,21 @@
|
|
1
|
+
=== 2.0.0
|
2
|
+
|
3
|
+
Fri Jan 27 22:11:06 EET 2012
|
4
|
+
|
5
|
+
* <b>WARNING:</b> 'ruby-naive' template is now called 'ruby-cli'. <b>You
|
6
|
+
cannot upgrade to it</b> because everything changed in it to be more
|
7
|
+
pretty.
|
8
|
+
|
9
|
+
* New command: listdirs.
|
10
|
+
|
11
|
+
* User can specify additional directories for templates.
|
12
|
+
|
13
|
+
=== 1.3.1
|
14
|
+
|
15
|
+
Fri Jan 27 12:07:55 EET 2012
|
16
|
+
|
17
|
+
* Fixed exclude pattern in gemspec for rdoc.
|
18
|
+
|
1
19
|
=== 1.3.0
|
2
20
|
|
3
21
|
Mon Nov 7 07:15:00 EET 2011
|
data/doc/README.rdoc
CHANGED
@@ -10,7 +10,7 @@ falsework--A primitive scaffold generator for writing CLI programs.
|
|
10
10
|
|
11
11
|
==Description
|
12
12
|
|
13
|
-
The falsework utility ships with 2 templates: <tt>ruby-
|
13
|
+
The falsework utility ships with 2 templates: <tt>ruby-cli</tt> and
|
14
14
|
<tt>c-glib</tt>.
|
15
15
|
|
16
16
|
Initially the template spec was designed only for Ruby projects but
|
@@ -53,8 +53,9 @@ list:: Do nothing except listing all available
|
|
53
53
|
|
54
54
|
listdirs:: Do nothing except listing all available
|
55
55
|
templates directories. You can add another
|
56
|
-
directory
|
57
|
-
the config file. (<tt>tdir</tt> is an
|
56
|
+
directory by modifying <tt>tdir</tt> option
|
57
|
+
in the config file. (<tt>tdir</tt> is an
|
58
|
+
array).
|
58
59
|
|
59
60
|
new NAME:: Create a new project. It creates a directory
|
60
61
|
<i>NAME</i> and populates it with files.
|
@@ -73,7 +74,7 @@ test NAME:: Add a new test in
|
|
73
74
|
|
74
75
|
upgrade:: 'Inject' or upgrade some vital files from the
|
75
76
|
template into the project. Currently only
|
76
|
-
'ruby-
|
77
|
+
'ruby-cli' template supports this.
|
77
78
|
|
78
79
|
The options are as follows:
|
79
80
|
|
@@ -82,7 +83,7 @@ The options are as follows:
|
|
82
83
|
-b:: A batch mode. (No questions asked.)
|
83
84
|
|
84
85
|
--no-git:: Don't create a Git repository. Don't use
|
85
|
-
this for 'ruby-
|
86
|
+
this for 'ruby-cli' template.
|
86
87
|
|
87
88
|
--config-dirs:: List all possible locations for the
|
88
89
|
configuration file. The first found wins.
|
data/doc/TODO.org
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
* TODO In the distant future [3/
|
1
|
+
* TODO In the distant future [3/7] [42%]
|
2
2
|
|
3
3
|
- [-] more templates [1/4]
|
4
4
|
- [X] c glib
|
@@ -11,3 +11,4 @@
|
|
11
11
|
- [ ] describe c-glib template
|
12
12
|
- [X] normalize 'name' of the project before actually making a template
|
13
13
|
- [X] target_uuid variable for exe/doc/test templates
|
14
|
+
- [ ] relocate templates from lib/falsework directory to project root
|
@@ -0,0 +1,135 @@
|
|
1
|
+
# :erb: ruby-cli
|
2
|
+
|
3
|
+
require 'pathname'
|
4
|
+
require 'yaml'
|
5
|
+
require 'optparse'
|
6
|
+
require 'shellwords'
|
7
|
+
|
8
|
+
require_relative 'cliutils'
|
9
|
+
|
10
|
+
module Falsework
|
11
|
+
|
12
|
+
# Load configuration from 3 places (starting from least significant):
|
13
|
+
# config file, env variable, command line.
|
14
|
+
class CliConfig
|
15
|
+
# Possible config file locations.
|
16
|
+
DIR_CONFIG = [Pathname.new(Dir.home) + ".#{Meta::NAME}",
|
17
|
+
Pathname.new('/etc'),
|
18
|
+
Pathname.new('/usr/etc'),
|
19
|
+
Pathname.new('/usr/local/etc'),
|
20
|
+
CliUtils::DIR_LIB_SRC.parent.parent + 'etc']
|
21
|
+
|
22
|
+
# Example:
|
23
|
+
#
|
24
|
+
# conf = CliConfig.new
|
25
|
+
# conf[:my_option] = 123
|
26
|
+
# conf.load
|
27
|
+
def initialize
|
28
|
+
@conf = Hash.new
|
29
|
+
@conf[:verbose] = 0
|
30
|
+
@conf[:banner] = "Usage: #{File.basename($0)} [options]"
|
31
|
+
@conf[:config_name] = Meta::NAME + '.yaml'
|
32
|
+
@conf[:config_env] = Meta::NAME.upcase + '_CONF'
|
33
|
+
@conf[:config_dirs] = DIR_CONFIG
|
34
|
+
end
|
35
|
+
|
36
|
+
# Setter for @conf
|
37
|
+
def []=(key, val)
|
38
|
+
CliUtils.verbose = val if key == :verbose # sync verbosity levels
|
39
|
+
@conf[key] = val
|
40
|
+
end
|
41
|
+
|
42
|
+
# Getter for @conf
|
43
|
+
def [](key)
|
44
|
+
@conf[key]
|
45
|
+
end
|
46
|
+
|
47
|
+
# Return a full path to a config file or nil if no config file found.
|
48
|
+
def getConfigPath
|
49
|
+
if @conf[:config_name].index('/')
|
50
|
+
return @conf[:config_name] if File.file?(@conf[:config_name])
|
51
|
+
else
|
52
|
+
@conf[:config_dirs].each {|i|
|
53
|
+
r = Pathname.new(i) + @conf[:config_name]
|
54
|
+
return r if File.file?(r)
|
55
|
+
}
|
56
|
+
end
|
57
|
+
|
58
|
+
CliUtils.warnx "no config file '#{@conf[:config_name]}' found" if @conf[:verbose] >= 2
|
59
|
+
return nil
|
60
|
+
end
|
61
|
+
|
62
|
+
# Load a config from file. Return true on success or false otherwise.
|
63
|
+
def loadFile
|
64
|
+
file = getConfigPath
|
65
|
+
return false unless file
|
66
|
+
|
67
|
+
CliUtils::veputs(2, "Loading #{File.basename(file)}... " + CliUtils::NNL_MARK)
|
68
|
+
myconf = YAML.load_file(file) rescue CliUtils.errx(1, "cannot parse config #{file}: #{$!}")
|
69
|
+
# preserve existing values
|
70
|
+
@conf.merge!(myconf) {|key, oldval, newval| oldval }
|
71
|
+
CliUtils::veputs(2, "OK")
|
72
|
+
return true
|
73
|
+
end
|
74
|
+
|
75
|
+
# Check if options in array opts are in @conf.
|
76
|
+
def requiredOptions?(opts)
|
77
|
+
opts.each {|idx|
|
78
|
+
if !@conf.key?(idx.to_sym) || !@conf[idx.to_sym]
|
79
|
+
CliUtils.errx(1, "option #{idx} is either nil or missing")
|
80
|
+
end
|
81
|
+
}
|
82
|
+
end
|
83
|
+
|
84
|
+
# Parse CLO and env variable. If block is given it is passed with
|
85
|
+
# OptionParser object as a parameter.
|
86
|
+
def optParse
|
87
|
+
o = OptionParser.new do |o|
|
88
|
+
o.banner = @conf[:banner]
|
89
|
+
o.banner = @conf[:banner]
|
90
|
+
o.on('-v', 'Be more verbose.') { |i|
|
91
|
+
self[:verbose] += 1
|
92
|
+
}
|
93
|
+
o.on('-V', '--version', 'Show version & exit.') { |i|
|
94
|
+
puts Meta::VERSION
|
95
|
+
exit 0
|
96
|
+
}
|
97
|
+
o.on('--config NAME',
|
98
|
+
"Set a config name or file",
|
99
|
+
"(default is #{@conf[:config_name]}).") {|arg|
|
100
|
+
@conf[:config_name] = arg
|
101
|
+
}
|
102
|
+
o.on('--config-dirs', 'Show possible config locations.') {
|
103
|
+
mark = false
|
104
|
+
@conf[:config_dirs].each { |idx|
|
105
|
+
f = Pathname(idx) + @conf[:config_name]
|
106
|
+
if File.file?(f) && !mark
|
107
|
+
puts "* #{f}"
|
108
|
+
mark = true
|
109
|
+
else
|
110
|
+
puts " #{f}"
|
111
|
+
end
|
112
|
+
}
|
113
|
+
exit 0
|
114
|
+
}
|
115
|
+
|
116
|
+
yield o if block_given?
|
117
|
+
|
118
|
+
env = nil
|
119
|
+
env = ENV[@conf[:config_env]].shellsplit if ENV.key?(@conf[:config_env])
|
120
|
+
[env, ARGV].each { |i| o.parse!(i) if i }
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# Parse CLO, env variables and load config file.
|
125
|
+
#
|
126
|
+
# [reqOpts] an array of requied options
|
127
|
+
# [&block] a optional block for OptionParser
|
128
|
+
def load(reqOpts = [], &block)
|
129
|
+
optParse &block
|
130
|
+
loadFile
|
131
|
+
requiredOptions?(reqOpts)
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
135
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
# :erb: ruby-cli
|
2
|
+
|
3
|
+
require 'pp'
|
4
|
+
require 'open4'
|
5
|
+
require 'pathname'
|
6
|
+
|
7
|
+
require_relative 'meta'
|
8
|
+
|
9
|
+
module Falsework
|
10
|
+
|
11
|
+
# Preferable exit codes. See sysexits(3) in FreeBSD.
|
12
|
+
EX_OK = 0
|
13
|
+
EX_USAGE = 64
|
14
|
+
EX_DATAERR = 65
|
15
|
+
EX_NOINPUT = 66
|
16
|
+
EX_NOUSER = 67
|
17
|
+
EX_NOHOST = 68
|
18
|
+
EX_UNAVAILABLE = 69
|
19
|
+
EX_SOFTWARE = 70
|
20
|
+
EX_OSERR = 71
|
21
|
+
EX_OSFILE = 72
|
22
|
+
EX_CANTCREAT = 73
|
23
|
+
EX_IOERR = 74
|
24
|
+
EX_TEMPFAIL = 75
|
25
|
+
EX_PROTOCOL = 76
|
26
|
+
EX_NOPERM = 77
|
27
|
+
EX_CONFIG = 78
|
28
|
+
|
29
|
+
# Common routines useful in any CLI program.
|
30
|
+
class CliUtils
|
31
|
+
# Physical location of program libraries.
|
32
|
+
DIR_LIB_SRC = Pathname.new File.dirname(__FILE__)
|
33
|
+
# veputs uses this to decide to put a newline or not to put.
|
34
|
+
NNL_MARK = '__NNL__'
|
35
|
+
|
36
|
+
# Class-wide verbosity level.
|
37
|
+
@@verbose = 0
|
38
|
+
|
39
|
+
# Setter.
|
40
|
+
def self.verbose=(val)
|
41
|
+
@@verbose = val
|
42
|
+
end
|
43
|
+
|
44
|
+
# Getter.
|
45
|
+
def self.getVerbose
|
46
|
+
@@verbose
|
47
|
+
end
|
48
|
+
|
49
|
+
# A handy check. Use it like:
|
50
|
+
#
|
51
|
+
# puts (CliUtils.debug ? "DEBUG mode" : "")
|
52
|
+
def self.debug
|
53
|
+
@@verbose >= 2
|
54
|
+
end
|
55
|
+
|
56
|
+
# A handy method that return a nicely formatted current global
|
57
|
+
# backtrace.
|
58
|
+
def self.getBacktrace
|
59
|
+
"#{$!}\n\nBacktrace:\n\n#{$!.backtrace.join("\n")}"
|
60
|
+
end
|
61
|
+
|
62
|
+
# Print an error msg & exit if exit_code > 0.
|
63
|
+
def self.errx(exit_code = 0, msg)
|
64
|
+
$stderr.puts File.basename($0) + ' error: ' + msg.to_s
|
65
|
+
exit exit_code if exit_code > 0
|
66
|
+
end
|
67
|
+
|
68
|
+
# Print a warning.
|
69
|
+
def self.warnx(msg)
|
70
|
+
$stderr.puts File.basename($0) + ' warning: ' + msg.to_s
|
71
|
+
end
|
72
|
+
|
73
|
+
# [level] Verbosity level.
|
74
|
+
# [msg] A message to print.
|
75
|
+
#
|
76
|
+
# Don't print msg with a newline if it contains NNL_MARK at the end.
|
77
|
+
def self.veputs(level, msg)
|
78
|
+
t = msg.dup
|
79
|
+
|
80
|
+
nnl = false
|
81
|
+
if t.match(/#{NNL_MARK}$/)
|
82
|
+
t.sub!(/#{$&}/, '')
|
83
|
+
nnl = true
|
84
|
+
end
|
85
|
+
|
86
|
+
if @@verbose >= level
|
87
|
+
nnl ? print(t) : print("#{t}\n")
|
88
|
+
$stdout.flush
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# Analogue to a shell command +which+.
|
93
|
+
def self.which(file)
|
94
|
+
return true if file =~ %r%\A/% and File.exist? file
|
95
|
+
|
96
|
+
ENV['PATH'].split(File::PATH_SEPARATOR).any? do |path|
|
97
|
+
File.exist? File.join(path, file)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# Execute cmd and return an array [exit_status, stderr, stdout].
|
102
|
+
def self.exec(cmd)
|
103
|
+
so = sr = ''
|
104
|
+
status = Open4::popen4(cmd) { |pid, stdin, stdout, stderr|
|
105
|
+
so = stdout.read
|
106
|
+
sr = stderr.read
|
107
|
+
}
|
108
|
+
[status.exitstatus, sr, so]
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|