gm 0.1.6 → 1.0.4
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/lib/gm/rubygems_plugin.rb +131 -0
- data/lib/rubygems_plugin.rb +1 -0
- metadata +17 -186
- data/LICENSE.txt +0 -22
- data/README.textile +0 -13
- data/bin/gem-make +0 -6
- data/bin/gm +0 -6
- data/gm_behaviors/author_behavior.rb +0 -29
- data/gm_behaviors/bin_files_behavior.rb +0 -10
- data/gm_behaviors/dependencies_behavior.rb +0 -22
- data/gm_behaviors/executables_behavior.rb +0 -13
- data/gm_behaviors/general_behavior.rb +0 -41
- data/gm_behaviors/github_behavior.rb +0 -14
- data/gm_behaviors/gm_files_behavior.rb +0 -13
- data/gm_behaviors/lib_files_behavior.rb +0 -10
- data/gm_behaviors/rails_behavior.rb +0 -11
- data/gm_behaviors/rdoc_behavior.rb +0 -34
- data/gm_behaviors/rspec_behavior.rb +0 -10
- data/gm_behaviors/rubigen_behavior.rb +0 -13
- data/gm_behaviors/rubyforge_behavior.rb +0 -12
- data/gm_behaviors/test_behavior.rb +0 -10
- data/gm_behaviors/text_files_behavior.rb +0 -10
- data/gm_commands/build_command.rb +0 -25
- data/gm_commands/build_gemspec_command.rb +0 -34
- data/gm_commands/clean_command.rb +0 -14
- data/gm_commands/config_command.rb +0 -42
- data/gm_commands/create_command.rb +0 -10
- data/gm_commands/gen_command.rb +0 -31
- data/gm_commands/help_command.rb +0 -246
- data/gm_commands/install_command.rb +0 -17
- data/gm_commands/publish_command.rb +0 -34
- data/gm_commands/spec_command.rb +0 -14
- data/gm_generators/bin/bin_generator.rb +0 -22
- data/gm_generators/bin/templates/bin/bin.rb +0 -3
- data/gm_generators/gem/gem_generator.rb +0 -38
- data/gm_generators/gem/templates/Gmfile +0 -4
- data/gm_generators/gem/templates/README.textile +0 -0
- data/gm_generators/gem/templates/lib/module.rb +0 -4
- data/gm_generators/mit_license/mit_license_generator.rb +0 -17
- data/gm_generators/mit_license/templates/LICENSE.txt +0 -22
- data/gm_generators/rails/rails_generator.rb +0 -18
- data/gm_generators/rails/templates/rails/init.rb +0 -1
- data/gm_generators/test/templates/test_case.rb.erb +0 -5
- data/gm_generators/test/templates/test_helper.rb.erb +0 -7
- data/gm_generators/test/test_generator.rb +0 -26
- data/gm_networks/github_network.rb +0 -72
- data/gm_networks/rubyforge_network.rb +0 -90
- data/lib/autotest/discover.rb +0 -3
- data/lib/autotest/gm.rb +0 -37
- data/lib/extentions/gem.rb +0 -27
- data/lib/gm.rb +0 -30
- data/lib/gm/app.rb +0 -111
- data/lib/gm/behavior.rb +0 -25
- data/lib/gm/command.rb +0 -66
- data/lib/gm/configuration.rb +0 -20
- data/lib/gm/documentation.rb +0 -38
- data/lib/gm/helpers.rb +0 -24
- data/lib/gm/loader.rb +0 -84
- data/lib/gm/network.rb +0 -29
- data/lib/gm/system.rb +0 -16
- data/test/command_test.rb +0 -106
- data/test/gem_extentions_test.rb +0 -31
- data/test/system_test.rb +0 -17
- data/test/test_helper.rb +0 -12
@@ -1,22 +0,0 @@
|
|
1
|
-
|
2
|
-
class DependenciesBehavior < GM::Behavior
|
3
|
-
|
4
|
-
specify_conf do |root|
|
5
|
-
|
6
|
-
# root.list :dependencies do |dependency|
|
7
|
-
# dependency.conf do |c|
|
8
|
-
# c.should_be_a String
|
9
|
-
# c.should_not_be_empty
|
10
|
-
# end
|
11
|
-
# end
|
12
|
-
|
13
|
-
end
|
14
|
-
|
15
|
-
def run
|
16
|
-
(config[:dependencies] || []).each do |dependency|
|
17
|
-
gem, requirement = dependency.strip.split(/\s+/, 2)
|
18
|
-
spec.add_dependency gem.strip, requirement.strip
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
end
|
@@ -1,41 +0,0 @@
|
|
1
|
-
|
2
|
-
class GeneralBehavior < GM::Behavior
|
3
|
-
|
4
|
-
specify_conf do |root|
|
5
|
-
|
6
|
-
root.map :general do |general|
|
7
|
-
general.should_be_present
|
8
|
-
|
9
|
-
general.conf(:name) do |s|
|
10
|
-
s.should_be_present
|
11
|
-
s.should_be_a String
|
12
|
-
s.should_not_be_empty
|
13
|
-
end
|
14
|
-
|
15
|
-
general.conf(:version) do |s|
|
16
|
-
s.should_be_present
|
17
|
-
s.should_be_a String
|
18
|
-
s.should_not_be_empty
|
19
|
-
end
|
20
|
-
|
21
|
-
general.conf(:summary) do |s|
|
22
|
-
s.should_be_a String
|
23
|
-
s.should_not_be_empty
|
24
|
-
end
|
25
|
-
|
26
|
-
general.conf(:homepage) do |s|
|
27
|
-
s.should_be_a String
|
28
|
-
s.should_not_be_empty
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
end
|
33
|
-
|
34
|
-
def run
|
35
|
-
spec.name ||= config[:general][:name]
|
36
|
-
spec.version = config[:general][:version]
|
37
|
-
spec.summary = config[:general][:summary]
|
38
|
-
spec.homepage = config[:general][:homepage]
|
39
|
-
end
|
40
|
-
|
41
|
-
end
|
@@ -1,14 +0,0 @@
|
|
1
|
-
|
2
|
-
class GithubBehavior < GM::Behavior
|
3
|
-
|
4
|
-
def run
|
5
|
-
emulate = !command.options.no_emulation?
|
6
|
-
emulate &= (config[:github] != nil) && (config[:github][:emulate] == true)
|
7
|
-
|
8
|
-
if emulate
|
9
|
-
name = config[:github][:project] || config[:general][:name]
|
10
|
-
spec.name = "#{config[:github][:username]}-#{name}"
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
|
2
|
-
class GmFilesBehavior < GM::Behavior
|
3
|
-
|
4
|
-
desc "Collect all GM related files (generators, commands, networks, behaviors)"
|
5
|
-
|
6
|
-
def run
|
7
|
-
spec.files += Dir.glob('gm_commands/*_command.rb')
|
8
|
-
spec.files += Dir.glob('gm_behaviors/*_behavior.rb')
|
9
|
-
spec.files += Dir.glob('gm_networks/*_network.rb')
|
10
|
-
spec.files += Dir.glob('gm_generators/**/*')
|
11
|
-
end
|
12
|
-
|
13
|
-
end
|
@@ -1,34 +0,0 @@
|
|
1
|
-
|
2
|
-
class RdocBehavior < GM::Behavior
|
3
|
-
|
4
|
-
specify_conf do |root|
|
5
|
-
|
6
|
-
root.map :rdoc do |rdoc|
|
7
|
-
|
8
|
-
rdoc.conf(:enabled) do |s|
|
9
|
-
s.should_be_present
|
10
|
-
end
|
11
|
-
|
12
|
-
rdoc.conf(:extra_files) do |s|
|
13
|
-
end
|
14
|
-
|
15
|
-
rdoc.conf(:options) do |s|
|
16
|
-
s.should_be_a String
|
17
|
-
s.should_not_be_empty
|
18
|
-
end
|
19
|
-
|
20
|
-
end
|
21
|
-
|
22
|
-
end
|
23
|
-
|
24
|
-
def run
|
25
|
-
if config[:rdoc] and config[:rdoc][:enabled]
|
26
|
-
spec.has_rdoc = true
|
27
|
-
spec.extra_rdoc_files = config[:rdoc][:extra_files]
|
28
|
-
spec.rdoc_options = config[:rdoc][:options]
|
29
|
-
else
|
30
|
-
spec.has_rdoc = false
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
|
2
|
-
class RubigenBehavior < GM::Behavior
|
3
|
-
|
4
|
-
desc "Collect rubigen files"
|
5
|
-
|
6
|
-
def run
|
7
|
-
paths = Dir.glob('*generators/**/*')
|
8
|
-
paths.reject! { |path| File.directory? path }
|
9
|
-
paths.reject! { |path| File.basename(path)[0,1] == "." }
|
10
|
-
spec.files += paths
|
11
|
-
end
|
12
|
-
|
13
|
-
end
|
@@ -1,25 +0,0 @@
|
|
1
|
-
|
2
|
-
class BuildCommand < GM::Command
|
3
|
-
|
4
|
-
desc "Build the gem"
|
5
|
-
banner "build"
|
6
|
-
doc <<-DOC
|
7
|
-
build a gem and put the result in pkg/
|
8
|
-
DOC
|
9
|
-
|
10
|
-
def add_options(p)
|
11
|
-
p.flag 'E', 'no-emulation', :desc => 'Don\'t emulate any network'
|
12
|
-
end
|
13
|
-
|
14
|
-
def run
|
15
|
-
GM::Command.run(:build_gemspec, [(options.no_emulation? ? '-E' : nil)].compact)
|
16
|
-
|
17
|
-
app.info "Building your gem..."
|
18
|
-
builder = Gem::Builder.new app.spec
|
19
|
-
builder.build
|
20
|
-
sh("rm -f pkg/#{gem_file_name}",
|
21
|
-
"mkdir -p pkg",
|
22
|
-
"mv #{gem_file_name} pkg/")
|
23
|
-
end
|
24
|
-
|
25
|
-
end
|
@@ -1,34 +0,0 @@
|
|
1
|
-
|
2
|
-
class BuildGemspecCommand < GM::Command
|
3
|
-
|
4
|
-
def add_options(p)
|
5
|
-
p.flag 'E', 'no-emulation', :desc => 'Don\'t emulate any network'
|
6
|
-
end
|
7
|
-
|
8
|
-
def run
|
9
|
-
app.info "Generating your gemspec..."
|
10
|
-
|
11
|
-
GM::Behavior.behaviors.each do |name,klass|
|
12
|
-
behavior = klass.new
|
13
|
-
behavior.command = self
|
14
|
-
behavior.run
|
15
|
-
end
|
16
|
-
|
17
|
-
clean_file_list
|
18
|
-
spec.validate
|
19
|
-
end
|
20
|
-
|
21
|
-
private
|
22
|
-
|
23
|
-
def clean_file_list
|
24
|
-
spec.files.reject! { |path| File.directory? path }
|
25
|
-
spec.files.reject! { |path| File.basename(path) == '.DS_Store' }
|
26
|
-
spec.files.reject! { |path| File.basename(path) == '.gitignore' }
|
27
|
-
spec.files.reject! { |path| path.include? '/.svn' }
|
28
|
-
spec.files.reject! { |path| path.include? '/.git' }
|
29
|
-
spec.files.uniq!
|
30
|
-
spec.files.compact!
|
31
|
-
spec.files.sort!
|
32
|
-
end
|
33
|
-
|
34
|
-
end
|
@@ -1,42 +0,0 @@
|
|
1
|
-
|
2
|
-
class ConfigCommand < GM::Command
|
3
|
-
|
4
|
-
desc "Manage your GM configurations."
|
5
|
-
banner "config [show edit]"
|
6
|
-
doc <<-DOC
|
7
|
-
With the edit argument the config command allows you to edit your glabal GM configurations.
|
8
|
-
With the show argument the config command will display all the configurations made in your environment.
|
9
|
-
|
10
|
-
The edit option is the default.
|
11
|
-
DOC
|
12
|
-
|
13
|
-
EMPTY_CONFIG = <<-EOC
|
14
|
-
author:
|
15
|
-
name:
|
16
|
-
email:
|
17
|
-
github:
|
18
|
-
username:
|
19
|
-
EOC
|
20
|
-
|
21
|
-
def run
|
22
|
-
case argv.first
|
23
|
-
when 'edit' then run_edit
|
24
|
-
when 'show' then run_show
|
25
|
-
else run_edit
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def run_edit
|
30
|
-
path = File.expand_path('~/.gmrc')
|
31
|
-
unless File.exist? path
|
32
|
-
File.open(path, 'w+') { |f| f.write EMPTY_CONFIG }
|
33
|
-
end
|
34
|
-
sh("$EDITOR '#{path}'")
|
35
|
-
end
|
36
|
-
|
37
|
-
def run_show
|
38
|
-
GM::Command.run(:build_gemspec, ['-E'])
|
39
|
-
puts config.to_yaml
|
40
|
-
end
|
41
|
-
|
42
|
-
end
|
data/gm_commands/gen_command.rb
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
|
2
|
-
class GenCommand < GM::Command
|
3
|
-
|
4
|
-
def self.generator_names
|
5
|
-
RubiGen::Base.use_component_sources!(:gm)
|
6
|
-
RubiGen::Base.sources.collect do |s|
|
7
|
-
s.collect do |g|
|
8
|
-
g.name if g.path.include?('gm_generators') and g.name != 'gem'
|
9
|
-
end
|
10
|
-
end.flatten.compact.sort
|
11
|
-
end
|
12
|
-
|
13
|
-
desc "Use a generator"
|
14
|
-
banner "gen generator options..."
|
15
|
-
doc <<-DOC
|
16
|
-
The gen command allows you to generate code using rubigen compatible generators.
|
17
|
-
The generators must be on the search path (any gem with a gm_generator directory).
|
18
|
-
</p><p>
|
19
|
-
#{generator_names.join(', ')}
|
20
|
-
DOC
|
21
|
-
|
22
|
-
def run
|
23
|
-
GM::Command.run(:build_gemspec, ['-E']) if File.exist?('./Gmfile')
|
24
|
-
@gen_name = self.argv.shift
|
25
|
-
@gen_options = self.argv
|
26
|
-
|
27
|
-
RubiGen::Base.use_component_sources!(:gm)
|
28
|
-
RubiGen::Scripts::Generate.new.run(@gen_options, :generator => @gen_name)
|
29
|
-
end
|
30
|
-
|
31
|
-
end
|
data/gm_commands/help_command.rb
DELETED
@@ -1,246 +0,0 @@
|
|
1
|
-
|
2
|
-
class HelpCommand < GM::Command
|
3
|
-
|
4
|
-
desc "Get help with GM"
|
5
|
-
banner "help [doc]"
|
6
|
-
doc <<-DOC
|
7
|
-
The help command will display a help message by default but when the doc argument is provided it will open and HTML version of the documentation.
|
8
|
-
DOC
|
9
|
-
|
10
|
-
def run
|
11
|
-
case argv.first
|
12
|
-
when 'doc' then run_doc
|
13
|
-
else run_help
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
private
|
18
|
-
|
19
|
-
def run_doc
|
20
|
-
path = File.expand_path("~/.gmdoc.html")
|
21
|
-
File.open(path, 'w+') { |f| f.write doc }
|
22
|
-
sh %{ open "#{path}" }
|
23
|
-
end
|
24
|
-
|
25
|
-
def doc
|
26
|
-
%{
|
27
|
-
<html>
|
28
|
-
<head>
|
29
|
-
<title>GM documentation</title>
|
30
|
-
<style>
|
31
|
-
body {
|
32
|
-
font-family: Arial;
|
33
|
-
font-size: 12px;
|
34
|
-
text-align:center;
|
35
|
-
background-color:#e0e0e0;
|
36
|
-
margin:25px
|
37
|
-
}
|
38
|
-
#wrapper {
|
39
|
-
width:800px;
|
40
|
-
text-align:left;
|
41
|
-
margin:0px auto;
|
42
|
-
}
|
43
|
-
#content {
|
44
|
-
padding:50px 50px 1px;
|
45
|
-
width:500px;
|
46
|
-
margin: 0 100px;
|
47
|
-
background-color:#fff;
|
48
|
-
}
|
49
|
-
#menu {
|
50
|
-
position:fixed;
|
51
|
-
top:25px;
|
52
|
-
width:100px;
|
53
|
-
}
|
54
|
-
#menu a {
|
55
|
-
padding:10px;
|
56
|
-
display:block;
|
57
|
-
color:#000;
|
58
|
-
text-decoration:none;
|
59
|
-
font-weight:bold;
|
60
|
-
background-color:#fff;
|
61
|
-
margin-bottom:2px;
|
62
|
-
}
|
63
|
-
#menu a:hover {
|
64
|
-
background-color:#000;
|
65
|
-
color:#fff;
|
66
|
-
}
|
67
|
-
h1 {
|
68
|
-
margin-top:0;
|
69
|
-
}
|
70
|
-
h2 {
|
71
|
-
margin:0;
|
72
|
-
}
|
73
|
-
h3 {
|
74
|
-
float:left;
|
75
|
-
margin: 0;
|
76
|
-
width:75px;
|
77
|
-
font-size:12px;
|
78
|
-
}
|
79
|
-
.description {
|
80
|
-
color:#999
|
81
|
-
}
|
82
|
-
#commands, #networks, #passes {
|
83
|
-
margin:50px 0;
|
84
|
-
padding-top:50px;
|
85
|
-
border-top:2px solid #e0e0e0;
|
86
|
-
}
|
87
|
-
.command, .network, .pass {
|
88
|
-
margin: 30px 0;
|
89
|
-
border-left:10px solid #e0e0e0;
|
90
|
-
padding-left:10px;
|
91
|
-
margin-left:-20px;
|
92
|
-
}
|
93
|
-
.options {
|
94
|
-
font-family: monospace;
|
95
|
-
}
|
96
|
-
|
97
|
-
.pass h3 {
|
98
|
-
float:none;
|
99
|
-
width:auto;
|
100
|
-
}
|
101
|
-
</style>
|
102
|
-
</head>
|
103
|
-
<body>
|
104
|
-
<div id="wrapper">
|
105
|
-
<div id="menu">
|
106
|
-
<a href="#commands">Commands</a>
|
107
|
-
<a href="#networks">Network</a>
|
108
|
-
<a href="#passes">Passes</a>
|
109
|
-
</div>
|
110
|
-
<div id="content">
|
111
|
-
<h1>GM documentation</h1>
|
112
|
-
#{doc_commands}
|
113
|
-
#{doc_networks}
|
114
|
-
#{doc_passes}
|
115
|
-
</div>
|
116
|
-
</div>
|
117
|
-
</body>
|
118
|
-
</html>
|
119
|
-
}
|
120
|
-
end
|
121
|
-
|
122
|
-
def doc_commands
|
123
|
-
commands = GM::Command.commands.values
|
124
|
-
commands.sort! { |a,b| a.name.to_s <=> b.name.to_s }
|
125
|
-
commands.collect! { |command| doc_command(command) }
|
126
|
-
commands = commands.join
|
127
|
-
%{
|
128
|
-
<div id="commands">
|
129
|
-
<h2>Commands</h2>
|
130
|
-
#{commands}
|
131
|
-
</div>
|
132
|
-
}
|
133
|
-
end
|
134
|
-
|
135
|
-
def doc_command(command)
|
136
|
-
options = Clip { |p|
|
137
|
-
p.banner = command.banner_text
|
138
|
-
command.new.options(p)
|
139
|
-
}.to_s
|
140
|
-
options.gsub!(/Usage:\n/, '')
|
141
|
-
%{
|
142
|
-
<div class="command">
|
143
|
-
<h3>#{command.name}</h3>
|
144
|
-
<p class="description">#{command.description}</p>
|
145
|
-
<p class="options">#{options}</p>
|
146
|
-
<p class="documentation">#{command.documentation}</p>
|
147
|
-
</div>
|
148
|
-
}
|
149
|
-
end
|
150
|
-
|
151
|
-
def doc_networks
|
152
|
-
networks = GM::Network.networks.values
|
153
|
-
networks.sort! { |a,b| a.name.to_s <=> b.name.to_s }
|
154
|
-
networks.collect! { |network| doc_network(network) }
|
155
|
-
networks = networks.join
|
156
|
-
%{
|
157
|
-
<div id="networks">
|
158
|
-
<h2>Networks</h2>
|
159
|
-
#{networks}
|
160
|
-
</div>
|
161
|
-
}
|
162
|
-
end
|
163
|
-
|
164
|
-
def doc_network(network)
|
165
|
-
%{
|
166
|
-
<div class="network" id="network_#{network.name}">
|
167
|
-
<h3>#{network.name}</h3>
|
168
|
-
<p class="description">#{network.description}</p>
|
169
|
-
<p class="documentation">#{network.documentation}</p>
|
170
|
-
</div>
|
171
|
-
}
|
172
|
-
end
|
173
|
-
|
174
|
-
def doc_passes
|
175
|
-
%{
|
176
|
-
<div id="passes">
|
177
|
-
<h2>Passes</h2>
|
178
|
-
#{doc_passes_in_fase(:initialization)}
|
179
|
-
#{doc_passes_in_fase(:configuration)}
|
180
|
-
#{doc_passes_in_fase(:normal)}
|
181
|
-
#{doc_passes_in_fase(:finalization)}
|
182
|
-
</div>
|
183
|
-
}
|
184
|
-
end
|
185
|
-
|
186
|
-
def doc_passes_in_fase(fase)
|
187
|
-
passes = []
|
188
|
-
GM::ConfigurationPassQueue.new(fase).each_with_index do |pass, idx|
|
189
|
-
passes << doc_pass(fase, pass, idx)
|
190
|
-
end
|
191
|
-
passes = passes.join
|
192
|
-
end
|
193
|
-
|
194
|
-
def doc_pass(fase, pass, idx)
|
195
|
-
%{
|
196
|
-
<div class="pass">
|
197
|
-
<h3>##{idx + 1} - #{fase}:#{pass.name}</h3>
|
198
|
-
<p class="documentation">#{pass.description}</p>
|
199
|
-
</div>
|
200
|
-
}
|
201
|
-
end
|
202
|
-
|
203
|
-
def run_help
|
204
|
-
puts "#{File.basename($0)} <command> <options>"
|
205
|
-
puts options.to_s
|
206
|
-
puts ""
|
207
|
-
puts "Commands:"
|
208
|
-
command_descriptions
|
209
|
-
puts ""
|
210
|
-
puts "Passes:"
|
211
|
-
passes_in_running_order
|
212
|
-
end
|
213
|
-
|
214
|
-
def passes_in_running_order
|
215
|
-
format = "% 3d %- 20s %s"
|
216
|
-
|
217
|
-
puts "- initialization"
|
218
|
-
GM::ConfigurationPassQueue.new(:initialization).each_with_index do |pass, idx|
|
219
|
-
puts format % [idx+1, pass.name, pass.description]
|
220
|
-
end
|
221
|
-
puts "- configuration"
|
222
|
-
GM::ConfigurationPassQueue.new(:configuration).each_with_index do |pass, idx|
|
223
|
-
puts format % [idx+1, pass.name, pass.description]
|
224
|
-
end
|
225
|
-
puts "- normal"
|
226
|
-
GM::ConfigurationPassQueue.new(:normal).each_with_index do |pass, idx|
|
227
|
-
puts format % [idx+1, pass.name, pass.description]
|
228
|
-
end
|
229
|
-
puts "- finalization"
|
230
|
-
GM::ConfigurationPassQueue.new(:finalization).each_with_index do |pass, idx|
|
231
|
-
puts format % [idx+1, pass.name, pass.description]
|
232
|
-
end
|
233
|
-
end
|
234
|
-
|
235
|
-
def command_descriptions
|
236
|
-
descriptions = []
|
237
|
-
GM::Command.commands.each do |name, cmd|
|
238
|
-
descriptions << [name.to_s, cmd.description]
|
239
|
-
end
|
240
|
-
descriptions.sort { |a,b| a.first <=> b.first }
|
241
|
-
descriptions.collect do |(name, desc)|
|
242
|
-
puts "%- 17s %s" % [name, desc]
|
243
|
-
end
|
244
|
-
end
|
245
|
-
|
246
|
-
end
|