falsework 0.0.1
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/README.rdoc +86 -0
- data/Rakefile +69 -0
- data/bin/falsework +61 -0
- data/doc/LICENSE +22 -0
- data/doc/README.rdoc +86 -0
- data/doc/TODO.rdoc +4 -0
- data/etc/falsework.yaml +2 -0
- data/lib/falsework/meta.rb +6 -0
- data/lib/falsework/mould.rb +200 -0
- data/lib/falsework/templates/naive/.gitignore.erb +2 -0
- data/lib/falsework/templates/naive/README.rdoc.erb +57 -0
- data/lib/falsework/templates/naive/Rakefile.erb +44 -0
- data/lib/falsework/templates/naive/bin/.@project..erb +31 -0
- data/lib/falsework/templates/naive/doc/LICENSE.erb +22 -0
- data/lib/falsework/templates/naive/doc/README.rdoc.erb +57 -0
- data/lib/falsework/templates/naive/etc/.@project..yaml.erb +2 -0
- data/lib/falsework/templates/naive/lib/.@project./meta.rb.erb +6 -0
- data/lib/falsework/templates/naive/lib/.@project./utils.rb.erb +203 -0
- data/lib/falsework/templates/naive/test/helper.rb.erb +48 -0
- data/lib/falsework/templates/naive/test/test_.@project..rb.erb +13 -0
- data/lib/falsework/utils.rb +201 -0
- data/test/find_erb_templates.rb +60 -0
- data/test/helper.rb +46 -0
- data/test/templates/.keep_me +0 -0
- data/test/test_utils.rb +47 -0
- metadata +122 -0
data/README.rdoc
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
=Name
|
2
|
+
|
3
|
+
falsework--A primitive scaffold generator for writing CLI programs in
|
4
|
+
Ruby.
|
5
|
+
|
6
|
+
|
7
|
+
==Synopsis
|
8
|
+
|
9
|
+
falsework [options] command ...
|
10
|
+
|
11
|
+
|
12
|
+
==Description
|
13
|
+
|
14
|
+
The falsework utility generates a scaffold which have:
|
15
|
+
|
16
|
+
* <tt>gem</tt>, <tt>doc</tt>, <tt>test</tt> targers.
|
17
|
+
|
18
|
+
* easy to use configuraton parser/loader; this includes scanning for:
|
19
|
+
|
20
|
+
* env variables;
|
21
|
+
* the flat YAML configuration file;
|
22
|
+
* the command line.
|
23
|
+
|
24
|
+
* an ability to pick up a user name & an email for a github project.
|
25
|
+
|
26
|
+
The utility can also add skeletons for tests end executables
|
27
|
+
<i>after</i> the project generation.
|
28
|
+
|
29
|
+
The commands:
|
30
|
+
|
31
|
+
list:: Do nothing except listing all available
|
32
|
+
templates. You can add your own templates in
|
33
|
+
<tt>~/.falsework/templates</tt> directory.
|
34
|
+
|
35
|
+
new NAME:: Create a new project. It creates a directory
|
36
|
+
<i>NAME</i> and populates it with files.
|
37
|
+
|
38
|
+
exe NAME:: Add a new executable to an existing
|
39
|
+
project. You may use this command only in
|
40
|
+
the root project directory.
|
41
|
+
|
42
|
+
test NAME:: Add a new test to an existing
|
43
|
+
project. You may use this command only in
|
44
|
+
the root project directory.
|
45
|
+
|
46
|
+
The options are as follows:
|
47
|
+
|
48
|
+
-t:: A template name.
|
49
|
+
|
50
|
+
--config-dirs:: List all possible locations for the
|
51
|
+
configuration file. The first found wins.
|
52
|
+
|
53
|
+
--config NAME:: The name of the configuration file. If
|
54
|
+
it contains <tt>/</tt> in it, the list from
|
55
|
+
<tt>--config-dirs</tt> is ignored.
|
56
|
+
|
57
|
+
-V:: Show falsework version and exit.
|
58
|
+
|
59
|
+
-v:: Be more verbose. You can supply it several
|
60
|
+
times, viz. <tt>-vv</tt> dumps even more
|
61
|
+
debug info.
|
62
|
+
|
63
|
+
==Meta
|
64
|
+
|
65
|
+
Version & name of your project can be located at generated
|
66
|
+
<tt>myproject/lib/myproject/meta.rb</tt> file.
|
67
|
+
|
68
|
+
==Examples
|
69
|
+
|
70
|
+
Create a new project:
|
71
|
+
|
72
|
+
% falsework -v new foobar
|
73
|
+
|
74
|
+
Add another CL util to the existing project:
|
75
|
+
|
76
|
+
% pwd
|
77
|
+
.../foobar
|
78
|
+
% falsework exe foo
|
79
|
+
|
80
|
+
(It will appear in bin/ subdirectory.)
|
81
|
+
|
82
|
+
Add another test file:
|
83
|
+
|
84
|
+
% falsework test foo
|
85
|
+
|
86
|
+
(It will appear in test/ subdirectory.)
|
data/Rakefile
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
# -*-ruby-*-
|
2
|
+
|
3
|
+
require 'erb'
|
4
|
+
require 'rake'
|
5
|
+
require 'rake/gempackagetask'
|
6
|
+
require 'rake/clean'
|
7
|
+
require 'rake/rdoctask'
|
8
|
+
require 'rake/testtask'
|
9
|
+
|
10
|
+
NAME = 'falsework'
|
11
|
+
|
12
|
+
spec = Gem::Specification.new {|i|
|
13
|
+
i.name = NAME
|
14
|
+
i.version = `bin/#{i.name} -V`
|
15
|
+
i.summary = "A primitive scaffold generator for writing CLI programs in Ruby."
|
16
|
+
i.author = 'Alexander Gromnitsky'
|
17
|
+
i.email = 'alexander.gromnitsky@gmail.com'
|
18
|
+
i.homepage = "http://github.com/gromnitsky/#{i.name}"
|
19
|
+
i.platform = Gem::Platform::RUBY
|
20
|
+
i.required_ruby_version = '>= 1.9.2'
|
21
|
+
i.files = FileList.new('bin/*', 'doc/*',
|
22
|
+
'etc/*', '[A-Z]*', 'test/**/*') {|f|
|
23
|
+
f.exclude('test/templates/*')
|
24
|
+
f.include('test/templates/.keep_me')
|
25
|
+
f.include(Dir.glob('lib/**/*', File::FNM_DOTMATCH))
|
26
|
+
f.exclude('lib/**/{.*,*}/.gitignore')
|
27
|
+
}
|
28
|
+
|
29
|
+
i.executables = FileList['bin/*'].gsub(/^bin\//, '')
|
30
|
+
i.default_executable = i.name
|
31
|
+
|
32
|
+
i.test_files = FileList['test/test_*.rb']
|
33
|
+
|
34
|
+
i.rdoc_options << '-m' << 'doc/README.rdoc'
|
35
|
+
i.extra_rdoc_files = FileList['doc/*']
|
36
|
+
|
37
|
+
i.add_dependency('git', '>= 1.2.5')
|
38
|
+
i.add_dependency('open4', '>= 1.0.1')
|
39
|
+
}
|
40
|
+
|
41
|
+
Rake::GemPackageTask.new(spec).define
|
42
|
+
|
43
|
+
task default: [:naive, :repackage]
|
44
|
+
|
45
|
+
Rake::RDocTask.new('doc') do |i|
|
46
|
+
i.main = 'doc/README.rdoc'
|
47
|
+
i.rdoc_files = FileList['doc/*', 'lib/**/*.rb']
|
48
|
+
i.rdoc_files.exclude("lib/**/templates")
|
49
|
+
end
|
50
|
+
|
51
|
+
Rake::TestTask.new do |i|
|
52
|
+
i.test_files = FileList['test/test_*.rb']
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
#
|
57
|
+
# Generate dynamic targets
|
58
|
+
#
|
59
|
+
require_relative 'test/find_erb_templates'
|
60
|
+
|
61
|
+
ERB_DYN_SKELETON = erb_skeletons(NAME, 'naive')
|
62
|
+
ERB_DYN_SKELETON.each {|k, v|
|
63
|
+
file k => [v] do |t|
|
64
|
+
erb_make(NAME, t.name, t.prerequisites[0])
|
65
|
+
end
|
66
|
+
}
|
67
|
+
|
68
|
+
desc "Generate some erb templates for naive template"
|
69
|
+
task naive: ERB_DYN_SKELETON.keys
|
data/bin/falsework
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -*-ruby-*-
|
3
|
+
|
4
|
+
require_relative '../lib/falsework/mould'
|
5
|
+
|
6
|
+
include Falsework
|
7
|
+
|
8
|
+
$conf = Hash.new
|
9
|
+
u = Utils.new($conf)
|
10
|
+
|
11
|
+
$conf[:banner] = <<EOF
|
12
|
+
Usage: #{File.basename($0)} [options] command ...
|
13
|
+
Available commands: list, new NAME, exe NAME or test NAME.
|
14
|
+
EOF
|
15
|
+
$conf[:user] = nil
|
16
|
+
$conf[:gecos] = nil
|
17
|
+
$conf[:email] = nil
|
18
|
+
$conf[:template] = nil
|
19
|
+
|
20
|
+
# --[ main ]------------------------------------------------------------
|
21
|
+
|
22
|
+
u.config_parse(['foobar']) {|src|
|
23
|
+
o = u.cl_parse(src) # create an OptionParser object
|
24
|
+
o.on('--user STR', 'Github user') {|i| $conf[:user] = i}
|
25
|
+
o.on('--gecos STR', 'A gecos-like string') {|i| $conf[:gecos] = i}
|
26
|
+
o.on('--email STR') {|i| $conf[:email] = i}
|
27
|
+
o.on('-t NAME', 'A template name') {|i| $conf[:template] = i}
|
28
|
+
u.cl_parse(src, o) # run cl parser
|
29
|
+
}
|
30
|
+
|
31
|
+
Utils.errx(1, $conf[:banner]) if (ARGV.size < 2 && ARGV[0] != 'list')
|
32
|
+
|
33
|
+
# print our env
|
34
|
+
if $conf[:verbose] >= 2
|
35
|
+
puts 'Libs dir: '+Utils.gem_libdir
|
36
|
+
pp $conf
|
37
|
+
end
|
38
|
+
|
39
|
+
case ARGV[0]
|
40
|
+
when 'list'
|
41
|
+
Mould.templates.each_key {|i| puts(i)}
|
42
|
+
when /exe|test/
|
43
|
+
m = Mould.new('foo', $conf[:user], $conf[:email], $conf[:gecos])
|
44
|
+
ARGV[1..-1].each {|i|
|
45
|
+
u.veputs(1, "Generating #{i} as... __NNL__")
|
46
|
+
u.veputs(1, m.create($conf[:template], ARGV[0], i) + '... __NNL__')
|
47
|
+
u.veputs(1, 'OK')
|
48
|
+
}
|
49
|
+
when 'new'
|
50
|
+
Utils.errx(1, 'project name cannot start with a digit') if ARGV[1].strip[0] =~ /\d/
|
51
|
+
if File.dirname(ARGV[1]) != '.'
|
52
|
+
Dir.chdir(File.dirname(ARGV[1])) rescue Utils.errx(1, "cannot chdir to '#{File.dirname(ARGV[1])}'")
|
53
|
+
ARGV[1] = File.basename ARGV[1]
|
54
|
+
end
|
55
|
+
|
56
|
+
m = Mould.new(ARGV[1], $conf[:user], $conf[:email], $conf[:gecos])
|
57
|
+
m.verbose = true if $conf[:verbose] > 0
|
58
|
+
m.project_seed($conf[:template], nil)
|
59
|
+
else
|
60
|
+
Utils.errx(1, "unknown command: " + ARGV[0])
|
61
|
+
end
|
data/doc/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
(The MIT License)
|
2
|
+
|
3
|
+
Copyright (c) 2010 Alexander Gromnitsky.
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
'Software'), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
19
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
20
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
21
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
22
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/doc/README.rdoc
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
=Name
|
2
|
+
|
3
|
+
falsework--A primitive scaffold generator for writing CLI programs in
|
4
|
+
Ruby.
|
5
|
+
|
6
|
+
|
7
|
+
==Synopsis
|
8
|
+
|
9
|
+
falsework [options] command ...
|
10
|
+
|
11
|
+
|
12
|
+
==Description
|
13
|
+
|
14
|
+
The falsework utility generates a scaffold which have:
|
15
|
+
|
16
|
+
* <tt>gem</tt>, <tt>doc</tt>, <tt>test</tt> targers.
|
17
|
+
|
18
|
+
* easy to use configuraton parser/loader; this includes scanning for:
|
19
|
+
|
20
|
+
* env variables;
|
21
|
+
* the flat YAML configuration file;
|
22
|
+
* the command line.
|
23
|
+
|
24
|
+
* an ability to pick up a user name & an email for a github project.
|
25
|
+
|
26
|
+
The utility can also add skeletons for tests end executables
|
27
|
+
<i>after</i> the project generation.
|
28
|
+
|
29
|
+
The commands:
|
30
|
+
|
31
|
+
list:: Do nothing except listing all available
|
32
|
+
templates. You can add your own templates in
|
33
|
+
<tt>~/.falsework/templates</tt> directory.
|
34
|
+
|
35
|
+
new NAME:: Create a new project. It creates a directory
|
36
|
+
<i>NAME</i> and populates it with files.
|
37
|
+
|
38
|
+
exe NAME:: Add a new executable to an existing
|
39
|
+
project. You may use this command only in
|
40
|
+
the root project directory.
|
41
|
+
|
42
|
+
test NAME:: Add a new test to an existing
|
43
|
+
project. You may use this command only in
|
44
|
+
the root project directory.
|
45
|
+
|
46
|
+
The options are as follows:
|
47
|
+
|
48
|
+
-t:: A template name.
|
49
|
+
|
50
|
+
--config-dirs:: List all possible locations for the
|
51
|
+
configuration file. The first found wins.
|
52
|
+
|
53
|
+
--config NAME:: The name of the configuration file. If
|
54
|
+
it contains <tt>/</tt> in it, the list from
|
55
|
+
<tt>--config-dirs</tt> is ignored.
|
56
|
+
|
57
|
+
-V:: Show falsework version and exit.
|
58
|
+
|
59
|
+
-v:: Be more verbose. You can supply it several
|
60
|
+
times, viz. <tt>-vv</tt> dumps even more
|
61
|
+
debug info.
|
62
|
+
|
63
|
+
==Meta
|
64
|
+
|
65
|
+
Version & name of your project can be located at generated
|
66
|
+
<tt>myproject/lib/myproject/meta.rb</tt> file.
|
67
|
+
|
68
|
+
==Examples
|
69
|
+
|
70
|
+
Create a new project:
|
71
|
+
|
72
|
+
% falsework -v new foobar
|
73
|
+
|
74
|
+
Add another CL util to the existing project:
|
75
|
+
|
76
|
+
% pwd
|
77
|
+
.../foobar
|
78
|
+
% falsework exe foo
|
79
|
+
|
80
|
+
(It will appear in bin/ subdirectory.)
|
81
|
+
|
82
|
+
Add another test file:
|
83
|
+
|
84
|
+
% falsework test foo
|
85
|
+
|
86
|
+
(It will appear in test/ subdirectory.)
|
data/doc/TODO.rdoc
ADDED
data/etc/falsework.yaml
ADDED
@@ -0,0 +1,200 @@
|
|
1
|
+
require 'git'
|
2
|
+
require 'erb'
|
3
|
+
require 'digest/md5'
|
4
|
+
|
5
|
+
require_relative 'utils'
|
6
|
+
|
7
|
+
module Falsework
|
8
|
+
class Mould
|
9
|
+
GITCONFIG = '~/.gitconfig'
|
10
|
+
TEMPLATE_DIRS = [Utils.gem_libdir + '/templates',
|
11
|
+
File.expand_path('~/.' + Meta::NAME + '/templates')]
|
12
|
+
TEMPLATE_DEFAULT = 'naive'
|
13
|
+
IGNORE_FILES = ['.gitignore']
|
14
|
+
|
15
|
+
attr_accessor :verbose
|
16
|
+
|
17
|
+
def initialize(project, user = nil, email = nil, gecos = nil)
|
18
|
+
@verbose = false
|
19
|
+
|
20
|
+
gc = Git.global_config rescue gc = {}
|
21
|
+
@project = project
|
22
|
+
@user = user || gc['github.user']
|
23
|
+
@email = email || ENV['GIT_AUTHOR_EMAIL'] || ENV['GIT_COMMITTER_EMAIL'] || gc['user.email']
|
24
|
+
@gecos = gecos || ENV['GIT_AUTHOR_NAME'] || ENV['GIT_COMMITTER_NAME'] || gc['user.name']
|
25
|
+
|
26
|
+
[['github.user', @user],
|
27
|
+
['user.email', @email],
|
28
|
+
['user.name', @gecos]].each {|i|
|
29
|
+
Utils.errx(1, "missing #{i.first} in #{GITCONFIG}") if i.last.to_s == ''
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
33
|
+
# Return a hash {name => dir} with current possible template names
|
34
|
+
# and corresponding directories.
|
35
|
+
def self.templates
|
36
|
+
r = {}
|
37
|
+
TEMPLATE_DIRS.each {|i|
|
38
|
+
Dir.glob(i + '/*').each {|j|
|
39
|
+
r[File.basename(j)] = j if File.directory?(j)
|
40
|
+
}
|
41
|
+
}
|
42
|
+
r
|
43
|
+
end
|
44
|
+
|
45
|
+
# Generate a new project in @project directory from _template_.
|
46
|
+
#
|
47
|
+
# [template] If it's nil TEMPLATE_DEFAULT will be used.
|
48
|
+
# [filter] A regexp for matching particular files in the
|
49
|
+
# template directory.
|
50
|
+
#
|
51
|
+
# Return false if nothing was extracted.
|
52
|
+
def project_seed(template, filter)
|
53
|
+
sl = ->(is_dir, *args) {
|
54
|
+
is_dir ? Mould.erb_dirname(*args) : Mould.erb_filename(*args)
|
55
|
+
}
|
56
|
+
|
57
|
+
# check for existing project
|
58
|
+
Utils.errx(1, "directory '#{@project}' is not empty") if Dir.glob(@project + '/*').size > 0
|
59
|
+
|
60
|
+
Dir.mkdir(@project) unless File.directory?(@project)
|
61
|
+
prjdir = File.expand_path(@project)
|
62
|
+
puts "Project path: #{prjdir}" if @verbose
|
63
|
+
|
64
|
+
origdir = Dir.pwd;
|
65
|
+
Dir.chdir @project
|
66
|
+
|
67
|
+
r = false
|
68
|
+
start = Mould.templates[template || TEMPLATE_DEFAULT] || Utils.errx(1, "no such template: #{template}")
|
69
|
+
puts "Template: #{start}" if @verbose
|
70
|
+
symlinks = []
|
71
|
+
Mould.traverse(start) {|i|
|
72
|
+
file = i.sub(/^#{start}\//, '')
|
73
|
+
next if filter ? file =~ filter : false
|
74
|
+
next if IGNORE_FILES.index {|ign| file.match(/#{ign}$/) }
|
75
|
+
|
76
|
+
if File.symlink?(i)
|
77
|
+
# we'll process them later on
|
78
|
+
is_dir = File.directory?(start + '/' + File.readlink(i))
|
79
|
+
symlinks << [sl.call(is_dir, File.readlink(i), binding),
|
80
|
+
sl.call(is_dir, file, binding)]
|
81
|
+
elsif File.directory?(i)
|
82
|
+
puts("D: #{file}") if @verbose
|
83
|
+
file = Mould.erb_dirname(file, binding)
|
84
|
+
# FileUtils.mkdir_p(prjdir + '/' + file)
|
85
|
+
Dir.mkdir(prjdir + '/' + file)
|
86
|
+
Dir.chdir(prjdir + '/' + file)
|
87
|
+
else
|
88
|
+
puts("N: #{file}") if @verbose
|
89
|
+
to = File.basename(Mould.erb_filename(file, binding), '.erb')
|
90
|
+
Mould.extract(start + '/' + file, binding, to)
|
91
|
+
# make files in bin/ executable
|
92
|
+
File.chmod(0744, to) if file =~ /bin\//
|
93
|
+
end
|
94
|
+
r = true
|
95
|
+
}
|
96
|
+
|
97
|
+
# create saved symlinks
|
98
|
+
Dir.chdir prjdir
|
99
|
+
symlinks.each {|i|
|
100
|
+
src = i[0].sub(/#{File.extname(i[0])}$/, '')
|
101
|
+
dest = i[1].sub(/#{File.extname(i[1])}$/, '')
|
102
|
+
puts "L: #{dest} => #{src}" if @verbose
|
103
|
+
File.symlink(src, dest)
|
104
|
+
}
|
105
|
+
Dir.chdir origdir
|
106
|
+
r
|
107
|
+
end
|
108
|
+
|
109
|
+
# Create an executable or a test from the _template_.
|
110
|
+
#
|
111
|
+
# [mode] Is either 'exe' or 'test'.
|
112
|
+
# [what] A test/exe file to create.
|
113
|
+
#
|
114
|
+
# Return a name of a created file.
|
115
|
+
def create(template, mode, what)
|
116
|
+
start = Mould.templates[template || TEMPLATE_DEFAULT] || Utils.errx(1, "no such template: #{template}")
|
117
|
+
|
118
|
+
t = case mode
|
119
|
+
when 'exe'
|
120
|
+
to = ["bin/#{what}", true]
|
121
|
+
start + '/' + 'bin/.@project..erb'
|
122
|
+
when 'test'
|
123
|
+
to = ["#{mode}/test_#{what}.rb", false]
|
124
|
+
start + '/' + 'test/test_.@project..rb.erb'
|
125
|
+
else
|
126
|
+
fail "invalid mode #{mode}"
|
127
|
+
end
|
128
|
+
Mould.extract(t, binding, to[0])
|
129
|
+
File.chmod(0744, to[0]) if to[1]
|
130
|
+
return to[0]
|
131
|
+
end
|
132
|
+
|
133
|
+
# Walk through a directory tree, executing a block for each file or
|
134
|
+
# directory.
|
135
|
+
#
|
136
|
+
# [start] The directory to start with.
|
137
|
+
def self.traverse(start, &block)
|
138
|
+
l = Dir.glob(start + '/{*}', File::FNM_DOTMATCH)
|
139
|
+
# stop if directory is empty (contains only . and ..)
|
140
|
+
return if l.size <= 2
|
141
|
+
|
142
|
+
l.sort[2..-1].each {|i|
|
143
|
+
yield i
|
144
|
+
# recursion!
|
145
|
+
self.traverse(i) {|j| block.call j} if File.directory?(i)
|
146
|
+
}
|
147
|
+
end
|
148
|
+
|
149
|
+
# Extract into the current directory 1 file from _path_.
|
150
|
+
#
|
151
|
+
# [bin] A binding for eval.
|
152
|
+
# [to] If != nil write to a particular, not guessed file name.
|
153
|
+
def self.extract(path, bin, to = nil)
|
154
|
+
t = ERB.new(File.read(path))
|
155
|
+
t.filename = path # to report errors relative to this file
|
156
|
+
begin
|
157
|
+
# pp t.result
|
158
|
+
md5_system = Digest::MD5.hexdigest(t.result(bin))
|
159
|
+
rescue Exception
|
160
|
+
Utils.errx(1, "cannot read the template file: #{$!}")
|
161
|
+
end
|
162
|
+
|
163
|
+
skeleton = to || File.basename(path, '.erb')
|
164
|
+
if ! File.exists?(skeleton)
|
165
|
+
# write a skeleton
|
166
|
+
begin
|
167
|
+
File.open(skeleton, 'w+') { |fp| fp.puts t.result(bin) }
|
168
|
+
rescue
|
169
|
+
Utils.errx(1, "cannot write the skeleton: #{$!}")
|
170
|
+
end
|
171
|
+
elsif
|
172
|
+
# warn a careless user
|
173
|
+
if md5_system != Digest::MD5.file(skeleton).hexdigest
|
174
|
+
Utils.errx(1, "#{skeleton} already exists")
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
# Evaluate _t_ as a special directory name.
|
180
|
+
#
|
181
|
+
# [bin] A binding for eval.
|
182
|
+
def self.erb_dirname(t, bin)
|
183
|
+
if t =~ /^(.+\/)?\.(.+)\.$/
|
184
|
+
return ERB.new("#{$1}<%= #{$2} %>").result(bin)
|
185
|
+
end
|
186
|
+
return t
|
187
|
+
end
|
188
|
+
|
189
|
+
# Evaluate _t_ as a special file name.
|
190
|
+
#
|
191
|
+
# [bin] A binding for eval.
|
192
|
+
def self.erb_filename(t, bin)
|
193
|
+
if t =~ /^(.+)?\.(.+)\.(\..+)?.erb$/
|
194
|
+
return ERB.new("#{$1}<%= #{$2} %>#{$3}").result(bin)
|
195
|
+
end
|
196
|
+
return t
|
197
|
+
end
|
198
|
+
|
199
|
+
end # Mould
|
200
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
=Name
|
2
|
+
|
3
|
+
<%= @project %>--an util to put function in yo function so yo can return
|
4
|
+
while yo return.
|
5
|
+
|
6
|
+
|
7
|
+
==Synopsis
|
8
|
+
|
9
|
+
<%= @project %> [options]
|
10
|
+
|
11
|
+
|
12
|
+
==Description
|
13
|
+
|
14
|
+
The <%= @project %> utility does something.
|
15
|
+
|
16
|
+
The options are as follows:
|
17
|
+
|
18
|
+
--config-dirs:: List all possible locations for the
|
19
|
+
configuration file. The first found wins.
|
20
|
+
|
21
|
+
--config NAME:: The name of the configuration file. If
|
22
|
+
it contains <tt>/</tt> in it, the list from
|
23
|
+
<tt>--config-dirs</tt> is ignored.
|
24
|
+
|
25
|
+
-V:: Show falsework version and exit.
|
26
|
+
|
27
|
+
-v:: Be more verbose. You can supply it several
|
28
|
+
times, viz. <tt>-vv</tt> dumps even more
|
29
|
+
debug info.
|
30
|
+
|
31
|
+
--foobar NAME Huh?
|
32
|
+
|
33
|
+
==Configuration
|
34
|
+
|
35
|
+
<%= @project %> looks for its configuration at 3 places at start up.
|
36
|
+
|
37
|
+
1. At <tt><%= @project.upcase %>_CONF</tt> env variable.
|
38
|
+
(Its format is exactly similar to CL options.)
|
39
|
+
|
40
|
+
2. At the configuration file. Its default name is
|
41
|
+
<tt><%= @project %>.yaml</tt> and it can be stored in several
|
42
|
+
system directories which are observable by <tt>--config--dirs</tt> CL
|
43
|
+
option.
|
44
|
+
|
45
|
+
3. At command line.
|
46
|
+
|
47
|
+
Higher number levels overrides the values from lower number levels.
|
48
|
+
|
49
|
+
The configuration file must be in YAML format. Look into <tt>`gem env
|
50
|
+
gemdir`/gems/<%= @project %>-x.y.z/etc/</tt> directory for samples.
|
51
|
+
|
52
|
+
|
53
|
+
==Examples
|
54
|
+
|
55
|
+
% ri <%= @project.capitalize %>
|
56
|
+
% <%= @project %> --config-dirs
|
57
|
+
% <%= @project %> -V
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# -*-ruby-*-
|
2
|
+
|
3
|
+
require 'rake'
|
4
|
+
require 'rake/gempackagetask'
|
5
|
+
require 'rake/clean'
|
6
|
+
require 'rake/rdoctask'
|
7
|
+
require 'rake/testtask'
|
8
|
+
|
9
|
+
spec = Gem::Specification.new {|i|
|
10
|
+
i.name = '<%= @project %>'
|
11
|
+
i.version = `bin/#{i.name} -V`
|
12
|
+
i.summary = 'TO DO: fill this variable'
|
13
|
+
i.author = '<%= @gecos %>'
|
14
|
+
i.email = '<%= @email %>'
|
15
|
+
i.homepage = "http://github.com/<%= @user %>/#{i.name}"
|
16
|
+
i.platform = Gem::Platform::RUBY
|
17
|
+
i.required_ruby_version = '>= <%= RUBY_VERSION %>'
|
18
|
+
i.files = FileList['lib/**/*', 'bin/*', 'doc/*',
|
19
|
+
'etc/*', '[A-Z]*', 'test/**/*']
|
20
|
+
|
21
|
+
i.executables = FileList['bin/*'].gsub(/^bin\//, '')
|
22
|
+
i.default_executable = i.name
|
23
|
+
|
24
|
+
i.test_files = FileList['test/test_*.rb']
|
25
|
+
|
26
|
+
i.rdoc_options << '-m' << 'doc/README.rdoc'
|
27
|
+
i.extra_rdoc_files = FileList['doc/*']
|
28
|
+
|
29
|
+
i.add_dependency('open4', '>= 1.0.1')
|
30
|
+
}
|
31
|
+
|
32
|
+
Rake::GemPackageTask.new(spec).define
|
33
|
+
|
34
|
+
task default: [:repackage]
|
35
|
+
|
36
|
+
Rake::RDocTask.new('doc') {|i|
|
37
|
+
i.main = 'doc/README.rdoc'
|
38
|
+
i.rdoc_files = FileList['doc/*', 'lib/**/*.rb']
|
39
|
+
# i.rdoc_files.exclude("lib/**/some-nasty-staff")
|
40
|
+
}
|
41
|
+
|
42
|
+
Rake::TestTask.new {|i|
|
43
|
+
i.test_files = FileList['test/test_*.rb']
|
44
|
+
}
|
@@ -0,0 +1,31 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -*-ruby-*-
|
3
|
+
|
4
|
+
require_relative '../lib/<%= @project %>/utils.rb'
|
5
|
+
|
6
|
+
include <%= @project.capitalize %>
|
7
|
+
|
8
|
+
$conf = Hash.new
|
9
|
+
u = Utils.new($conf)
|
10
|
+
|
11
|
+
$conf[:banner] = "Usage: #{File.basename($0)} [options] hren'"
|
12
|
+
$conf[:foobar] = ''
|
13
|
+
|
14
|
+
|
15
|
+
# --[ main ]------------------------------------------------------------
|
16
|
+
|
17
|
+
u.config_parse(['foobar']) {|src|
|
18
|
+
o = u.cl_parse(src) # create an OptionParser object
|
19
|
+
o.on('--foobar STR', 'An example of the option --foobar') {|i|
|
20
|
+
$conf[:foobar] = i
|
21
|
+
}
|
22
|
+
u.cl_parse(src, o) # run cl parser
|
23
|
+
}
|
24
|
+
|
25
|
+
# print our env
|
26
|
+
if $conf[:verbose] >= 2
|
27
|
+
puts 'Libs dir: '+Utils.gem_libdir
|
28
|
+
pp $conf
|
29
|
+
end
|
30
|
+
|
31
|
+
puts 'Hello, World!'
|