falsework 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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!'
|