nanoc 2.0 → 2.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/ChangeLog +54 -0
- data/LICENSE +1 -1
- data/README +63 -3
- data/Rakefile +61 -14
- data/bin/nanoc +7 -199
- data/lib/nanoc/base/asset.rb +113 -0
- data/lib/nanoc/base/asset_defaults.rb +21 -0
- data/lib/nanoc/base/asset_rep.rb +277 -0
- data/lib/nanoc/base/binary_filter.rb +44 -0
- data/lib/nanoc/base/code.rb +41 -0
- data/lib/nanoc/base/compiler.rb +46 -34
- data/lib/nanoc/base/core_ext/hash.rb +51 -7
- data/lib/nanoc/base/core_ext/string.rb +8 -0
- data/lib/nanoc/base/data_source.rb +253 -20
- data/lib/nanoc/base/defaults.rb +30 -0
- data/lib/nanoc/base/enhancements.rb +9 -84
- data/lib/nanoc/base/filter.rb +109 -6
- data/lib/nanoc/base/layout.rb +91 -0
- data/lib/nanoc/base/notification_center.rb +66 -0
- data/lib/nanoc/base/page.rb +94 -121
- data/lib/nanoc/base/page_defaults.rb +20 -0
- data/lib/nanoc/base/page_rep.rb +318 -0
- data/lib/nanoc/base/plugin.rb +57 -9
- data/lib/nanoc/base/proxies/asset_proxy.rb +29 -0
- data/lib/nanoc/base/proxies/asset_rep_proxy.rb +26 -0
- data/lib/nanoc/base/proxies/layout_proxy.rb +25 -0
- data/lib/nanoc/base/proxies/page_proxy.rb +35 -0
- data/lib/nanoc/base/proxies/page_rep_proxy.rb +28 -0
- data/lib/nanoc/base/proxy.rb +37 -0
- data/lib/nanoc/base/router.rb +72 -0
- data/lib/nanoc/base/site.rb +220 -91
- data/lib/nanoc/base/template.rb +64 -0
- data/lib/nanoc/binary_filters/image_science_thumbnail.rb +28 -0
- data/lib/nanoc/cli/base.rb +219 -0
- data/lib/nanoc/cli/cli.rb +16 -0
- data/lib/nanoc/cli/command.rb +105 -0
- data/lib/nanoc/cli/commands/autocompile.rb +80 -0
- data/lib/nanoc/cli/commands/compile.rb +273 -0
- data/lib/nanoc/cli/commands/create_layout.rb +85 -0
- data/lib/nanoc/cli/commands/create_page.rb +85 -0
- data/lib/nanoc/cli/commands/create_site.rb +327 -0
- data/lib/nanoc/cli/commands/create_template.rb +76 -0
- data/lib/nanoc/cli/commands/help.rb +69 -0
- data/lib/nanoc/cli/commands/info.rb +114 -0
- data/lib/nanoc/cli/commands/switch.rb +141 -0
- data/lib/nanoc/cli/commands/update.rb +91 -0
- data/lib/nanoc/cli/ext.rb +37 -0
- data/lib/nanoc/cli/logger.rb +66 -0
- data/lib/nanoc/cli/option_parser.rb +168 -0
- data/lib/nanoc/cli.rb +1 -0
- data/lib/nanoc/data_sources/filesystem.rb +650 -215
- data/lib/nanoc/data_sources/filesystem_combined.rb +495 -0
- data/lib/nanoc/extra/auto_compiler.rb +265 -0
- data/lib/nanoc/extra/context.rb +22 -0
- data/lib/nanoc/extra/core_ext/hash.rb +54 -0
- data/lib/nanoc/extra/core_ext/time.rb +13 -0
- data/lib/nanoc/extra/file_proxy.rb +29 -0
- data/lib/nanoc/extra/vcs.rb +48 -0
- data/lib/nanoc/extra/vcses/bazaar.rb +21 -0
- data/lib/nanoc/extra/vcses/dummy.rb +20 -0
- data/lib/nanoc/extra/vcses/git.rb +21 -0
- data/lib/nanoc/extra/vcses/mercurial.rb +21 -0
- data/lib/nanoc/extra/vcses/subversion.rb +21 -0
- data/lib/nanoc/filters/bluecloth.rb +13 -0
- data/lib/nanoc/filters/erb.rb +6 -22
- data/lib/nanoc/filters/erubis.rb +14 -0
- data/lib/nanoc/filters/haml.rb +11 -6
- data/lib/nanoc/filters/markaby.rb +5 -5
- data/lib/nanoc/filters/maruku.rb +14 -0
- data/lib/nanoc/filters/old.rb +19 -0
- data/lib/nanoc/filters/rdiscount.rb +13 -0
- data/lib/nanoc/filters/rdoc.rb +5 -4
- data/lib/nanoc/filters/redcloth.rb +14 -0
- data/lib/nanoc/filters/rubypants.rb +14 -0
- data/lib/nanoc/filters/sass.rb +13 -0
- data/lib/nanoc/helpers/blogging.rb +170 -0
- data/lib/nanoc/helpers/capturing.rb +59 -0
- data/lib/nanoc/helpers/html_escape.rb +23 -0
- data/lib/nanoc/helpers/link_to.rb +69 -0
- data/lib/nanoc/helpers/render.rb +47 -0
- data/lib/nanoc/helpers/tagging.rb +52 -0
- data/lib/nanoc/helpers/xml_sitemap.rb +58 -0
- data/lib/nanoc/routers/default.rb +54 -0
- data/lib/nanoc/routers/no_dirs.rb +66 -0
- data/lib/nanoc/routers/versioned.rb +79 -0
- data/lib/nanoc.rb +83 -12
- metadata +144 -47
- data/lib/nanoc/base/auto_compiler.rb +0 -124
- data/lib/nanoc/base/layout_processor.rb +0 -33
- data/lib/nanoc/base/page_proxy.rb +0 -31
- data/lib/nanoc/base/plugin_manager.rb +0 -33
- data/lib/nanoc/data_sources/database.rb +0 -259
- data/lib/nanoc/data_sources/trivial.rb +0 -145
- data/lib/nanoc/filters/markdown.rb +0 -13
- data/lib/nanoc/filters/smartypants.rb +0 -13
- data/lib/nanoc/filters/textile.rb +0 -13
- data/lib/nanoc/layout_processors/erb.rb +0 -35
- data/lib/nanoc/layout_processors/haml.rb +0 -18
- data/lib/nanoc/layout_processors/markaby.rb +0 -16
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
module Nanoc::CLI
|
|
2
|
+
|
|
3
|
+
class CreateSiteCommand < Command # :nodoc:
|
|
4
|
+
|
|
5
|
+
DEFAULT_PAGE = <<EOS
|
|
6
|
+
<h1>A Brand New nanoc Site</h1>
|
|
7
|
+
<p>You’ve just created a new nanoc site. The page you are looking at right now is the home page for your site (and it’s probably the only page).</p>
|
|
8
|
+
<p>To get started, consider replacing this default homepage with your own customized homepage. Some pointers on how to do so:</p>
|
|
9
|
+
<ul>
|
|
10
|
+
<li><strong>Change this page’s content</strong> by editing “content.txt” file in the “content” directory. This is the actual page content, and therefore doesn’t include the header, sidebar or style information (those are part of the layout).</li>
|
|
11
|
+
<li><strong>Change the layout</strong>, which is the “default.txt” file in the “layouts/default” directory, and create something unique (and hopefully less bland).</li>
|
|
12
|
+
</ul>
|
|
13
|
+
<p>If you need any help with customizing your nanoc web site, be sure to check out the documentation (see sidebar), and be sure to subscribe to the discussion group (also see sidebar). Enjoy!</p>
|
|
14
|
+
EOS
|
|
15
|
+
|
|
16
|
+
DEFAULT_LAYOUT = <<EOS
|
|
17
|
+
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
|
18
|
+
<html>
|
|
19
|
+
<head>
|
|
20
|
+
<title>A Brand New nanoc Site - <%= @page.title %></title>
|
|
21
|
+
<style type="text/css" media="screen">
|
|
22
|
+
* {
|
|
23
|
+
margin: 0;
|
|
24
|
+
padding: 0;
|
|
25
|
+
|
|
26
|
+
font-family: Georgia, Palatino, Times, 'Times New Roman', sans-serif;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
body {
|
|
30
|
+
background: #fff;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
a {
|
|
34
|
+
text-decoration: none;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
a:link,
|
|
38
|
+
a:visited {
|
|
39
|
+
color: #f30;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
a:hover {
|
|
43
|
+
color: #f90;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
#main {
|
|
47
|
+
position: absolute;
|
|
48
|
+
|
|
49
|
+
top: 20px;
|
|
50
|
+
left: 280px;
|
|
51
|
+
|
|
52
|
+
width: 500px;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
#main h1 {
|
|
56
|
+
font-size: 40px;
|
|
57
|
+
font-weight: normal;
|
|
58
|
+
|
|
59
|
+
line-height: 40px;
|
|
60
|
+
|
|
61
|
+
padding: 20px 0 20px 0;
|
|
62
|
+
|
|
63
|
+
letter-spacing: -1px;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
#main p {
|
|
67
|
+
margin: 0 0 20px 0;
|
|
68
|
+
|
|
69
|
+
font-size: 15px;
|
|
70
|
+
|
|
71
|
+
line-height: 20px;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
#main ul {
|
|
75
|
+
padding: 0 0 0 20px;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
#main li {
|
|
79
|
+
margin: 0 0 20px 0;
|
|
80
|
+
|
|
81
|
+
list-style-type: square;
|
|
82
|
+
|
|
83
|
+
font-size: 15px;
|
|
84
|
+
|
|
85
|
+
line-height: 20px;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
#sidebar {
|
|
89
|
+
position: absolute;
|
|
90
|
+
|
|
91
|
+
top: 40px;
|
|
92
|
+
left: 20px;
|
|
93
|
+
width: 200px;
|
|
94
|
+
|
|
95
|
+
padding: 20px 20px 0 0;
|
|
96
|
+
|
|
97
|
+
border-right: 1px solid #ccc;
|
|
98
|
+
|
|
99
|
+
text-align: right;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
#sidebar h2 {
|
|
103
|
+
text-transform: uppercase;
|
|
104
|
+
|
|
105
|
+
font-size: 13px;
|
|
106
|
+
|
|
107
|
+
color: #333;
|
|
108
|
+
|
|
109
|
+
letter-spacing: 1px;
|
|
110
|
+
|
|
111
|
+
line-height: 20px;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
#sidebar ul {
|
|
115
|
+
list-style-type: none;
|
|
116
|
+
|
|
117
|
+
margin: 20px 0;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
#sidebar li {
|
|
121
|
+
font-size: 14px;
|
|
122
|
+
|
|
123
|
+
line-height: 20px;
|
|
124
|
+
}
|
|
125
|
+
</style>
|
|
126
|
+
</head>
|
|
127
|
+
<body>
|
|
128
|
+
<div id="main">
|
|
129
|
+
<%= @page.content %>
|
|
130
|
+
</div>
|
|
131
|
+
<div id="sidebar">
|
|
132
|
+
<h2>Documentation</h2>
|
|
133
|
+
<ul>
|
|
134
|
+
<li><a href="http://nanoc.stoneship.org/help/tutorial/">Tutorial</a></li>
|
|
135
|
+
<li><a href="http://nanoc.stoneship.org/help/manual/">Manual</a></li>
|
|
136
|
+
</ul>
|
|
137
|
+
<h2>Community</h2>
|
|
138
|
+
<ul>
|
|
139
|
+
<li><a href="http://groups.google.com/group/nanoc/">Discussion Group</a></li>
|
|
140
|
+
<li><a href="http://groups.google.com/group/nanoc-es/">Spanish Discussion Group</a></li>
|
|
141
|
+
<li><a href="http://nanoc.stoneship.org/trac/">Wiki</a></li>
|
|
142
|
+
</ul>
|
|
143
|
+
</div>
|
|
144
|
+
</body>
|
|
145
|
+
</html>
|
|
146
|
+
EOS
|
|
147
|
+
|
|
148
|
+
def name
|
|
149
|
+
'create_site'
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def aliases
|
|
153
|
+
[ 'cs' ]
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def short_desc
|
|
157
|
+
'create a site'
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def long_desc
|
|
161
|
+
'Create a new site at the given path. The site will use the ' +
|
|
162
|
+
'filesystem data source (but this can be changed later on). It will ' +
|
|
163
|
+
'also include a few stub rakefiles to make adding new tasks easier.'
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def usage
|
|
167
|
+
"nanoc create_site [path]"
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def option_definitions
|
|
171
|
+
[
|
|
172
|
+
# --datasource
|
|
173
|
+
{
|
|
174
|
+
:long => 'datasource', :short => 'd', :argument => :required,
|
|
175
|
+
:desc => 'specify the data source for the new site'
|
|
176
|
+
}
|
|
177
|
+
]
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def run(options, arguments)
|
|
181
|
+
# Check arguments
|
|
182
|
+
if arguments.length != 1
|
|
183
|
+
$stderr.puts "usage: #{usage}"
|
|
184
|
+
exit 1
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
# Extract arguments and options
|
|
188
|
+
path = arguments[0]
|
|
189
|
+
data_source = options[:datasource] || 'filesystem'
|
|
190
|
+
|
|
191
|
+
# Check whether site exists
|
|
192
|
+
if File.exist?(path)
|
|
193
|
+
$stderr.puts "A site at '#{path}' already exists."
|
|
194
|
+
exit 1
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
# Check whether data source exists
|
|
198
|
+
if Nanoc::DataSource.named(data_source).nil?
|
|
199
|
+
$stderr.puts "Unrecognised data source: #{data_source}"
|
|
200
|
+
exit 1
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
# Setup notifications
|
|
204
|
+
Nanoc::NotificationCenter.on(:file_created) do |file_path|
|
|
205
|
+
Nanoc::CLI::Logger.instance.file(:high, :create, file_path)
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
# Build entire site
|
|
209
|
+
FileUtils.mkdir_p(path)
|
|
210
|
+
begin
|
|
211
|
+
FileUtils.cd(File.join(path))
|
|
212
|
+
|
|
213
|
+
site_create_minimal(data_source)
|
|
214
|
+
site_setup
|
|
215
|
+
site_populate
|
|
216
|
+
ensure
|
|
217
|
+
FileUtils.cd(File.join(path.map { |n| '..' }))
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
puts "Created a blank nanoc site at '#{path}'. Enjoy!"
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
protected
|
|
224
|
+
|
|
225
|
+
# Creates a configuration file and a output directory for this site, as
|
|
226
|
+
# well as a rakefile and a 'tasks' directory because raking is fun.
|
|
227
|
+
def site_create_minimal(data_source)
|
|
228
|
+
# Create output
|
|
229
|
+
FileUtils.mkdir_p('output')
|
|
230
|
+
|
|
231
|
+
# Create config
|
|
232
|
+
File.open('config.yaml', 'w') do |io|
|
|
233
|
+
io.write "output_dir: \"output\"\n"
|
|
234
|
+
io.write "data_source: \"#{data_source}\"\n"
|
|
235
|
+
io.write "router: \"default\"\n"
|
|
236
|
+
end
|
|
237
|
+
Nanoc::NotificationCenter.post(:file_created, 'config.yaml')
|
|
238
|
+
|
|
239
|
+
# Create rakefile
|
|
240
|
+
File.open('Rakefile', 'w') do |io|
|
|
241
|
+
io.write "Dir['tasks/**/*.rake'].sort.each { |rakefile| load rakefile }\n"
|
|
242
|
+
io.write "\n"
|
|
243
|
+
io.write "task :default do\n"
|
|
244
|
+
io.write " puts 'This is an example rake task.'\n"
|
|
245
|
+
io.write "end\n"
|
|
246
|
+
end
|
|
247
|
+
Nanoc::NotificationCenter.post(:file_created, 'Rakefile')
|
|
248
|
+
|
|
249
|
+
# Create tasks
|
|
250
|
+
FileUtils.mkdir_p('tasks')
|
|
251
|
+
File.open('tasks/default.rake', 'w') do |io|
|
|
252
|
+
io.write "task :example do\n"
|
|
253
|
+
io.write " puts 'This is an example rake task in tasks/default.rake.'\n"
|
|
254
|
+
io.write "end\n"
|
|
255
|
+
end
|
|
256
|
+
Nanoc::NotificationCenter.post(:file_created, 'tasks/default.rake')
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
# Sets up the site's data source, i.e. creates the bare essentials for
|
|
260
|
+
# this data source to work.
|
|
261
|
+
def site_setup
|
|
262
|
+
# Get site
|
|
263
|
+
site = Nanoc::Site.new(YAML.load_file('config.yaml'))
|
|
264
|
+
|
|
265
|
+
# Set up data source
|
|
266
|
+
site.data_source.loading do
|
|
267
|
+
site.data_source.setup
|
|
268
|
+
end
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
# Populates the site with some initial data, such as a root page, a
|
|
272
|
+
# default layout, a default template, and so on.
|
|
273
|
+
def site_populate
|
|
274
|
+
# Get site
|
|
275
|
+
site = Nanoc::Site.new(YAML.load_file('config.yaml'))
|
|
276
|
+
|
|
277
|
+
# Create page
|
|
278
|
+
page = Nanoc::Page.new(
|
|
279
|
+
DEFAULT_PAGE,
|
|
280
|
+
{ :title => 'Home' },
|
|
281
|
+
'/'
|
|
282
|
+
)
|
|
283
|
+
page.site = site
|
|
284
|
+
page.save
|
|
285
|
+
|
|
286
|
+
# Fill asset defaults
|
|
287
|
+
Nanoc::Asset::DEFAULTS.each_pair do |key, value|
|
|
288
|
+
site.asset_defaults.attributes[key] = value
|
|
289
|
+
end
|
|
290
|
+
site.asset_defaults.save
|
|
291
|
+
|
|
292
|
+
# Fill page defaults
|
|
293
|
+
Nanoc::Page::DEFAULTS.each_pair do |key, value|
|
|
294
|
+
site.page_defaults.attributes[key] = value
|
|
295
|
+
end
|
|
296
|
+
site.page_defaults.save
|
|
297
|
+
|
|
298
|
+
# Create layout
|
|
299
|
+
layout = Nanoc::Layout.new(
|
|
300
|
+
DEFAULT_LAYOUT,
|
|
301
|
+
{ :filter => 'erb' },
|
|
302
|
+
'/default/'
|
|
303
|
+
)
|
|
304
|
+
layout.site = site
|
|
305
|
+
layout.save
|
|
306
|
+
|
|
307
|
+
# Create template
|
|
308
|
+
template = Nanoc::Template.new(
|
|
309
|
+
"Hi, I'm a new page!\n",
|
|
310
|
+
{ :title => "A New Page" },
|
|
311
|
+
'default'
|
|
312
|
+
)
|
|
313
|
+
template.site = site
|
|
314
|
+
template.save
|
|
315
|
+
|
|
316
|
+
# Fill code
|
|
317
|
+
code = Nanoc::Code.new(
|
|
318
|
+
"\# All files in the 'lib' directory will be loaded\n" +
|
|
319
|
+
"\# before nanoc starts compiling.\n"
|
|
320
|
+
)
|
|
321
|
+
code.site = site
|
|
322
|
+
code.save
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
end
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
module Nanoc::CLI
|
|
2
|
+
|
|
3
|
+
class CreateTemplateCommand < Command # :nodoc:
|
|
4
|
+
|
|
5
|
+
def name
|
|
6
|
+
'create_template'
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def aliases
|
|
10
|
+
[ 'ct' ]
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def short_desc
|
|
14
|
+
'create a template'
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def long_desc
|
|
18
|
+
'Create a new template in the current site.'
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def usage
|
|
22
|
+
"nanoc create_template [name]"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def option_definitions
|
|
26
|
+
[
|
|
27
|
+
# --vcs
|
|
28
|
+
{
|
|
29
|
+
:long => 'vcs', :short => 'c', :argument => :required,
|
|
30
|
+
:desc => 'select the VCS to use'
|
|
31
|
+
}
|
|
32
|
+
]
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def run(options, arguments)
|
|
36
|
+
# Check arguments
|
|
37
|
+
if arguments.length != 1
|
|
38
|
+
$stderr.puts "usage: #{usage}"
|
|
39
|
+
exit 1
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Extract arguments
|
|
43
|
+
name = arguments[0]
|
|
44
|
+
|
|
45
|
+
# Check template name
|
|
46
|
+
if name.include?('/')
|
|
47
|
+
$stderr.puts 'Template names cannot contain slashes; aborting.'
|
|
48
|
+
exit 1
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Make sure we are in a nanoc site directory
|
|
52
|
+
@base.require_site
|
|
53
|
+
|
|
54
|
+
# Set VCS if possible
|
|
55
|
+
@base.set_vcs(options[:vcs])
|
|
56
|
+
|
|
57
|
+
# Setup notifications
|
|
58
|
+
Nanoc::NotificationCenter.on(:file_created) do |file_path|
|
|
59
|
+
Nanoc::CLI::Logger.instance.file(:high, :create, file_path)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Create template
|
|
63
|
+
template = Nanoc::Template.new(
|
|
64
|
+
"Hi, I'm a new template. Please edit me!",
|
|
65
|
+
{ :title => "A Title" },
|
|
66
|
+
name
|
|
67
|
+
)
|
|
68
|
+
template.site = @base.site
|
|
69
|
+
template.save
|
|
70
|
+
|
|
71
|
+
puts "A template named '#{name}' has been created."
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
module Nanoc::CLI
|
|
2
|
+
|
|
3
|
+
class HelpCommand < Command # :nodoc:
|
|
4
|
+
|
|
5
|
+
def name
|
|
6
|
+
'help'
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def aliases
|
|
10
|
+
[]
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def short_desc
|
|
14
|
+
'show help for a command'
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def long_desc
|
|
18
|
+
'Show help for the given command, or show general help. When no ' +
|
|
19
|
+
'command is given, a list of available commands is displayed, as ' +
|
|
20
|
+
'well as a list of global commandline options. When a command is ' +
|
|
21
|
+
'given, a command description as well as command-specific ' +
|
|
22
|
+
'commandline options are shown.'
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def usage
|
|
26
|
+
"nanoc help [command]"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def run(options, arguments)
|
|
30
|
+
# Check arguments
|
|
31
|
+
if arguments.size > 1
|
|
32
|
+
$stderr.puts "usage: #{usage}"
|
|
33
|
+
exit 1
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
if arguments.length == 0
|
|
37
|
+
# Build help text
|
|
38
|
+
text = ''
|
|
39
|
+
|
|
40
|
+
# Add title
|
|
41
|
+
text << "nanoc, a static site compiler written in Ruby.\n"
|
|
42
|
+
|
|
43
|
+
# Add available commands
|
|
44
|
+
text << "\n"
|
|
45
|
+
text << "Available commands:\n"
|
|
46
|
+
text << "\n"
|
|
47
|
+
@base.commands.sort.each do |command|
|
|
48
|
+
text << sprintf(" %-20s %s\n", command.name, command.short_desc)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Add global options
|
|
52
|
+
text << "\n"
|
|
53
|
+
text << "Global options:\n"
|
|
54
|
+
text << "\n"
|
|
55
|
+
@base.global_option_definitions.sort { |x,y| x[:long] <=> y[:long] }.each do |opt_def|
|
|
56
|
+
text << sprintf(" -%1s --%-15s %s\n", opt_def[:short], opt_def[:long], opt_def[:desc])
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Display text
|
|
60
|
+
puts text
|
|
61
|
+
elsif arguments.length == 1
|
|
62
|
+
command = @base.command_named(arguments[0])
|
|
63
|
+
puts command.help
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
end
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
module Nanoc::CLI
|
|
2
|
+
|
|
3
|
+
class InfoCommand < Command # :nodoc:
|
|
4
|
+
|
|
5
|
+
def name
|
|
6
|
+
'info'
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def aliases
|
|
10
|
+
[]
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def short_desc
|
|
14
|
+
'show info about available plugins'
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def long_desc
|
|
18
|
+
'Show a list of available plugins, including filters, data sources ' +
|
|
19
|
+
'and routers. If the current directory contains a nanoc web site, ' +
|
|
20
|
+
'the plugins defined in this site will be shown as well.'
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def usage
|
|
24
|
+
"nanoc info"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def option_definitions
|
|
28
|
+
[]
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def run(options, arguments)
|
|
32
|
+
# Check arguments
|
|
33
|
+
if arguments.size != 0
|
|
34
|
+
$stderr.puts "usage: #{usage}"
|
|
35
|
+
exit 1
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Get list of plugins (before and after)
|
|
39
|
+
plugins_before = find_all_plugins
|
|
40
|
+
@base.site
|
|
41
|
+
plugins_after = find_all_plugins
|
|
42
|
+
|
|
43
|
+
# Get structured list of plugins
|
|
44
|
+
plugins = {}
|
|
45
|
+
plugin_classes.each do |klass|
|
|
46
|
+
plugins[klass] = {
|
|
47
|
+
:builtin => plugins_before[klass],
|
|
48
|
+
:custom => plugins_after[klass] - plugins_before[klass]
|
|
49
|
+
}
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Find longest name
|
|
53
|
+
max_length = plugins.values.map { |k| k.values }.flatten.map { |k| k.identifiers.join(', ').length }.max + 2
|
|
54
|
+
|
|
55
|
+
plugins.each_pair do |superclass, structured_plugins|
|
|
56
|
+
# Print kind
|
|
57
|
+
kind = name_for_plugin_class(superclass)
|
|
58
|
+
puts "#{kind}:"
|
|
59
|
+
puts
|
|
60
|
+
|
|
61
|
+
# Print plugins organised by subtype
|
|
62
|
+
[ :builtin, :custom ].each do |type|
|
|
63
|
+
# Find relevant plugins
|
|
64
|
+
subclasses = structured_plugins[type]
|
|
65
|
+
|
|
66
|
+
# Print type
|
|
67
|
+
puts " #{type}:"
|
|
68
|
+
if subclasses.empty?
|
|
69
|
+
puts " (none)"
|
|
70
|
+
next
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Print plugins
|
|
74
|
+
subclasses.sort_by { |k| k.identifier.to_s }.each do |klass|
|
|
75
|
+
# Get data
|
|
76
|
+
is_custom = !plugins_before[superclass].include?(klass)
|
|
77
|
+
klass_name = klass.to_s
|
|
78
|
+
klass_id = klass.identifiers.join(', ')
|
|
79
|
+
|
|
80
|
+
# Display
|
|
81
|
+
puts sprintf(" %-#{max_length}s (%s)", klass_id, klass_name)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
puts
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
private
|
|
90
|
+
|
|
91
|
+
PLUGIN_CLASSES = {
|
|
92
|
+
Nanoc::Filter => 'Filters',
|
|
93
|
+
Nanoc::DataSource => 'Data Sources',
|
|
94
|
+
Nanoc::Router => 'Routers',
|
|
95
|
+
Nanoc::Extra::VCS => 'VCSes'
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
def find_all_plugins
|
|
99
|
+
plugin_classes.inject({}) do |memo, klass|
|
|
100
|
+
memo.merge(klass => Nanoc::Plugin::MAP[klass].values.uniq)
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def plugin_classes
|
|
105
|
+
PLUGIN_CLASSES.keys
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def name_for_plugin_class(klass)
|
|
109
|
+
PLUGIN_CLASSES[klass]
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
end
|