usmu 0.1.0-java → 0.2.0-java
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.
- checksums.yaml +4 -4
- data/.gitignore +1 -1
- data/.rspec +1 -0
- data/.simplecov +4 -0
- data/.travis.yml +3 -0
- data/CONTRIBUTING.md +16 -0
- data/Guardfile +13 -0
- data/README.md +7 -6
- data/Rakefile +9 -10
- data/bin/usmu +5 -1
- data/lib/usmu.rb +73 -4
- data/lib/usmu/configuration.rb +40 -1
- data/lib/usmu/layout.rb +30 -7
- data/lib/usmu/page.rb +1 -0
- data/lib/usmu/plugin.rb +65 -0
- data/lib/usmu/plugin/core.rb +23 -0
- data/lib/usmu/site_generator.rb +17 -24
- data/lib/usmu/static_file.rb +10 -1
- data/lib/usmu/ui/console.rb +38 -10
- data/lib/usmu/version.rb +2 -2
- data/test/expected-site/default.html +14 -3
- data/test/site/layouts/html.meta.yml +1 -0
- data/test/{features/generator.feature → spec/acceptance/full_site_build.feature} +1 -0
- data/test/spec/acceptance/steps/full_site_build_steps.rb +24 -0
- data/test/spec/configuration_spec.rb +90 -1
- data/test/spec/layout_spec.rb +9 -17
- data/test/spec/mock/usmu/mock_plugin.rb +8 -0
- data/test/spec/page_spec.rb +9 -5
- data/test/spec/plugin/core_spec.rb +5 -0
- data/test/spec/plugin_spec.rb +49 -0
- data/test/spec/site_generator_spec.rb +0 -2
- data/test/spec/spec_helper.rb +12 -1
- data/test/spec/static_file_spec.rb +7 -1
- data/test/spec/support/shared_layout.rb +89 -5
- data/test/spec/ui/console_spec.rb +20 -0
- data/usmu-jruby.gemspec +6 -3
- data/usmu.gemspec +7 -6
- metadata +76 -21
- data/test/features/step_definitions/step_general.rb +0 -18
@@ -0,0 +1,23 @@
|
|
1
|
+
|
2
|
+
module Usmu
|
3
|
+
class Plugin
|
4
|
+
class Core
|
5
|
+
def commands(ui, c)
|
6
|
+
@log = Logging.logger[self]
|
7
|
+
@log.debug('Adding core console commands...')
|
8
|
+
@ui = ui
|
9
|
+
c.command(:generate) do |command|
|
10
|
+
command.syntax = 'usmu generate'
|
11
|
+
command.description = 'Generates your website using the configuration specified.'
|
12
|
+
command.action &method(:command_generate)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# @return [void]
|
17
|
+
def command_generate(args, options)
|
18
|
+
@site_generator = Usmu::SiteGenerator.new(@ui.configuration)
|
19
|
+
@site_generator.generate
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/usmu/site_generator.rb
CHANGED
@@ -1,17 +1,21 @@
|
|
1
1
|
require 'fileutils'
|
2
|
+
require 'usmu/configuration'
|
3
|
+
require 'usmu/page'
|
4
|
+
require 'usmu/static_file'
|
2
5
|
|
3
6
|
module Usmu
|
4
7
|
# This is the class that brings everything together to generate a new website.
|
5
8
|
class SiteGenerator
|
6
9
|
# @param [Usmu::Configuration] configuration The configuration to use for generating the website
|
7
10
|
def initialize(configuration)
|
11
|
+
@log = Logging.logger[self]
|
8
12
|
@configuration = configuration
|
9
13
|
end
|
10
14
|
|
11
15
|
# @!attribute [r] layouts
|
12
16
|
# @return [Array<Usmu::Layout>] a list of layouts available in this website.
|
13
17
|
def layouts
|
14
|
-
|
18
|
+
@configuration.layouts_files.map {|l| Usmu::Layout.new(@configuration, l) }
|
15
19
|
end
|
16
20
|
|
17
21
|
# @!attribute [r] renderables
|
@@ -24,7 +28,13 @@ module Usmu
|
|
24
28
|
# The only guarantee made for individual files is that they will conform to the interface defined by
|
25
29
|
# Usmu::StaticFile and thus be renderable, however most files will be one of the subclasses of that class.
|
26
30
|
def renderables
|
27
|
-
|
31
|
+
@configuration.source_files.map do |filename|
|
32
|
+
if Usmu::Layout.is_valid_file? 'source', filename
|
33
|
+
Usmu::Page.new(@configuration, filename)
|
34
|
+
else
|
35
|
+
Usmu::StaticFile.new(@configuration, filename)
|
36
|
+
end
|
37
|
+
end
|
28
38
|
end
|
29
39
|
|
30
40
|
# @!attribute [r] pages
|
@@ -44,7 +54,11 @@ module Usmu
|
|
44
54
|
#
|
45
55
|
# @return [void]
|
46
56
|
def generate
|
57
|
+
@log.info("Source: #{@configuration.source_path}")
|
58
|
+
@log.info("Destination: #{@configuration.destination_path}")
|
59
|
+
|
47
60
|
renderables.each do |page|
|
61
|
+
@log.success("creating #{page.output_filename}...")
|
48
62
|
file = File.join(@configuration.destination_path, page.output_filename)
|
49
63
|
directory = File.dirname(file)
|
50
64
|
|
@@ -53,30 +67,9 @@ module Usmu
|
|
53
67
|
end
|
54
68
|
|
55
69
|
File.write file, page.render
|
70
|
+
FileUtils.touch file, :mtime => File.stat(page.input_path).mtime
|
56
71
|
end
|
57
72
|
nil
|
58
73
|
end
|
59
|
-
|
60
|
-
private
|
61
|
-
|
62
|
-
# Helper function to search a directory recursively and return a list of files that are renderable.
|
63
|
-
#
|
64
|
-
# @param [String] directory the directory to search
|
65
|
-
# @param [Boolean] layout is this directory a layouts_path
|
66
|
-
# @return [Array<Usmu::Layout>, Array<Usmu::StaticFile>] Either an array of Layouts or StaticFiles in the directory
|
67
|
-
def get_renderables(directory, layout)
|
68
|
-
Dir["#{directory}/**/*"].select {|f| !f.match(/\.meta.yml$/) }.map do |f|
|
69
|
-
filename = f[(directory.length + 1)..f.length]
|
70
|
-
if layout
|
71
|
-
Usmu::Layout.new(@configuration, filename)
|
72
|
-
else
|
73
|
-
if Usmu::Layout.is_valid_file? 'source', filename
|
74
|
-
Usmu::Page.new(@configuration, filename)
|
75
|
-
else
|
76
|
-
Usmu::StaticFile.new(@configuration, filename)
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
81
74
|
end
|
82
75
|
end
|
data/lib/usmu/static_file.rb
CHANGED
@@ -1,8 +1,11 @@
|
|
1
|
+
require 'usmu/configuration'
|
1
2
|
|
2
3
|
module Usmu
|
3
4
|
# Represents a static file which should be transferred to the destination unchanged. This also acts as the base
|
4
5
|
# class for all layouts and page types. The basic interface defined here is used to process all types of files.
|
5
6
|
class StaticFile
|
7
|
+
@log = Logging.logger[self]
|
8
|
+
|
6
9
|
# @!attribute [r] name
|
7
10
|
# @return [String] the name of the file in the source directory
|
8
11
|
attr_reader :name
|
@@ -25,7 +28,13 @@ module Usmu
|
|
25
28
|
# @param variables [Hash] Variables to be used in the template.
|
26
29
|
# @return [String] The rendered file
|
27
30
|
def render(variables = {})
|
28
|
-
@content || File.read(
|
31
|
+
@content || File.read(input_path)
|
32
|
+
end
|
33
|
+
|
34
|
+
# @!attribute [r] input_path
|
35
|
+
# @return [String] the full path to the file in the source directory
|
36
|
+
def input_path
|
37
|
+
File.join(@configuration.source_path, @name)
|
29
38
|
end
|
30
39
|
|
31
40
|
# @!attribute [r] output_filename
|
data/lib/usmu/ui/console.rb
CHANGED
@@ -1,25 +1,53 @@
|
|
1
1
|
require 'usmu'
|
2
|
-
require '
|
2
|
+
require 'commander'
|
3
3
|
|
4
4
|
module Usmu
|
5
5
|
module Ui
|
6
6
|
# This is the CLI UI controller. This is initialised by the usmu binary to control the generation process.
|
7
7
|
class Console
|
8
|
+
# @!attribute [r] site_generator
|
9
|
+
# @return [Usmu::SiteGenerator]
|
10
|
+
attr_reader :site_generator
|
11
|
+
|
8
12
|
# @!attribute [r] configuration
|
13
|
+
# Do not access this till your command starts running, eg. in Hooks#commands, otherwise you may not get the right
|
14
|
+
# value for the configuration as option parsing may not have happened yet.
|
9
15
|
# @return [Usmu::Configuration] the configuration for the site we will generate.
|
10
|
-
|
16
|
+
def configuration
|
17
|
+
@configuration || load_configuration('usmu.yml')
|
18
|
+
end
|
11
19
|
|
12
|
-
# @param [Array<String>] args Command line arguments. Typically ARGV should be passed here.
|
13
20
|
def initialize(args)
|
14
|
-
@
|
15
|
-
@
|
21
|
+
@log = Logging.logger[self]
|
22
|
+
@commander = Commander::Runner.new args
|
23
|
+
|
24
|
+
@commander.program :version, Usmu::VERSION
|
25
|
+
@commander.program :description, 'Static site generator powered by Tilt'
|
26
|
+
@commander.program :int_message, 'Interrupt received, closing...'
|
27
|
+
|
28
|
+
@commander.global_option('-v', '--verbose') { Usmu.verbose_logging }
|
29
|
+
@commander.global_option('-q', '--quiet') { Usmu.quiet_logging }
|
30
|
+
@commander.global_option('--log STRING', String) {|log| Usmu.add_file_logger(log) }
|
31
|
+
@commander.global_option('--config STRING', String, &method(:load_configuration))
|
32
|
+
|
33
|
+
Usmu.plugins.load_plugins
|
34
|
+
Usmu.plugins.invoke :commands, self, @commander
|
35
|
+
|
36
|
+
@commander.default_command :generate
|
37
|
+
@commander.run!
|
16
38
|
end
|
17
39
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
40
|
+
def load_configuration(config)
|
41
|
+
@log.info("Usmu v#{Usmu::VERSION}")
|
42
|
+
@log.info('')
|
43
|
+
|
44
|
+
if File.readable? config
|
45
|
+
@configuration = Usmu::Configuration.from_file(config)
|
46
|
+
@log.info("Configuration: #{config}")
|
47
|
+
else
|
48
|
+
@log.fatal("Unable to find configuration file at #{config}")
|
49
|
+
raise
|
50
|
+
end
|
23
51
|
end
|
24
52
|
end
|
25
53
|
end
|
data/lib/usmu/version.rb
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
<
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>Default Title | Testing website</title>
|
5
|
+
</head>
|
6
|
+
<body>
|
7
|
+
<div id="content">
|
8
|
+
<h1>Default output</h1>
|
9
|
+
|
10
|
+
<p>No metadata for this file. Uh oh!</p>
|
11
|
+
|
12
|
+
</div>
|
13
|
+
</body>
|
14
|
+
</html>
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'usmu/ui/console'
|
2
|
+
require 'open3'
|
3
|
+
|
4
|
+
step 'I have a site at :location' do |location|
|
5
|
+
@location = "#{location}/usmu.yml"
|
6
|
+
end
|
7
|
+
|
8
|
+
step 'I generate the site' do
|
9
|
+
@site = Usmu::Ui::Console.new(['generate', '--config', @location])
|
10
|
+
end
|
11
|
+
|
12
|
+
step 'the destination directory should match :test_folder' do |test_folder|
|
13
|
+
run = %W{diff -qr #{@site.configuration.destination_path} #{test_folder}}
|
14
|
+
Open3.popen2e(*run) do |i, o, t|
|
15
|
+
output = run.join(' ') + "\n" + o.read
|
16
|
+
fail output if t.value != 0
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
step 'the modification time for the input file :input should match the output file :output' do |input, output|
|
21
|
+
input_mtime = File.stat(File.join(@site.configuration.source_path, input)).mtime
|
22
|
+
output_mtime = File.stat(File.join(@site.configuration.destination_path, output)).mtime
|
23
|
+
expect(input_mtime).to eq(output_mtime)
|
24
|
+
end
|
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'rspec'
|
2
1
|
require 'usmu/configuration'
|
3
2
|
|
4
3
|
RSpec.describe Usmu::Configuration do
|
@@ -44,8 +43,98 @@ RSpec.describe Usmu::Configuration do
|
|
44
43
|
end
|
45
44
|
end
|
46
45
|
|
46
|
+
it 'should have a list of source files' do
|
47
|
+
@configuration = Usmu::Configuration.from_hash({})
|
48
|
+
allow(Dir).to receive(:'[]').with('src/**/*').and_return(%w(src/index.md src/test.md))
|
49
|
+
expect(@configuration.source_files).to eq(%w(index.md test.md))
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should ignore metadata files in the source folder' do
|
53
|
+
@configuration = Usmu::Configuration.from_hash({})
|
54
|
+
allow(Dir).to receive(:'[]').with('src/**/*').and_return(%w(src/index.md src/index.meta.yml src/test.md))
|
55
|
+
expect(@configuration.source_files).to eq(%w(index.md test.md))
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'should have a list of layouts files' do
|
59
|
+
@configuration = Usmu::Configuration.from_hash({})
|
60
|
+
allow(Dir).to receive(:'[]').with('layouts/**/*').and_return(%w(layouts/html.slim layouts/page.slim))
|
61
|
+
expect(@configuration.layouts_files).to eq(%w(html.slim page.slim))
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'should ignore metadata files in the layouts folder' do
|
65
|
+
@configuration = Usmu::Configuration.from_hash({})
|
66
|
+
allow(Dir).to receive(:'[]').with('layouts/**/*').and_return(%w(layouts/html.slim layouts/html.meta.yml layouts/page.slim))
|
67
|
+
expect(@configuration.layouts_files).to eq(%w(html.slim page.slim))
|
68
|
+
end
|
69
|
+
|
47
70
|
it 'should remember arbitrary configuration' do
|
48
71
|
configuration = Usmu::Configuration.from_hash({:test => 'foo'})
|
49
72
|
expect(configuration[:test]).to eq('foo')
|
50
73
|
end
|
74
|
+
|
75
|
+
context 'should exclude files from source' do
|
76
|
+
it 'as specified' do
|
77
|
+
@configuration = Usmu::Configuration.from_hash({'exclude' => ['foo.md']})
|
78
|
+
allow(Dir).to receive(:'[]').with('src/**/*').and_return(%w(src/index.md src/foo.md))
|
79
|
+
expect(@configuration.source_files).to eq(%w(index.md))
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'in ignored folders if trailing "/" is used' do
|
83
|
+
@configuration = Usmu::Configuration.from_hash({'exclude' => ['test/']})
|
84
|
+
allow(Dir).to receive(:'[]').with('src/**/*').and_return(%w(src/index.md src/test/foo/test.md src/test/foo.md))
|
85
|
+
expect(@configuration.source_files).to eq(%w(index.md))
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'and honor *' do
|
89
|
+
@configuration = Usmu::Configuration.from_hash({'exclude' => ['*/foo.md']})
|
90
|
+
allow(Dir).to receive(:'[]').with('src/**/*').and_return(%w(src/index.md src/test/foo/foo.md src/test/foo.md))
|
91
|
+
expect(@configuration.source_files).to eq(%w(index.md test/foo/foo.md))
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'and * ignores folders without a trailing /' do
|
95
|
+
@configuration = Usmu::Configuration.from_hash({'exclude' => ['*']})
|
96
|
+
allow(Dir).to receive(:'[]').with('src/**/*').and_return(%w(src/index.md src/test/foo.md src/test.md))
|
97
|
+
expect(@configuration.source_files).to eq(%w(test/foo.md))
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'and honor **' do
|
101
|
+
@configuration = Usmu::Configuration.from_hash({'exclude' => ['**/foo.md']})
|
102
|
+
allow(Dir).to receive(:'[]').with('src/**/*').and_return(%w(src/index.md src/test/foo/foo.md src/test/foo.md))
|
103
|
+
expect(@configuration.source_files).to eq(%w(index.md))
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'and honor []' do
|
107
|
+
@configuration = Usmu::Configuration.from_hash({'exclude' => ['[ab].md']})
|
108
|
+
allow(Dir).to receive(:'[]').with('src/**/*').and_return(%w(src/index.md src/a.md src/b.md))
|
109
|
+
expect(@configuration.source_files).to eq(%w(index.md))
|
110
|
+
end
|
111
|
+
|
112
|
+
# FNM_EXTGLOB is supported from MRI 2.0 onwards. We also support the 1.9.3 ABI for JRuby and Rubinius sake. Only
|
113
|
+
# run this test if it's possible for it to pass.
|
114
|
+
if defined?(File::FNM_EXTGLOB)
|
115
|
+
it 'and honor {a,b}' do
|
116
|
+
@configuration = Usmu::Configuration.from_hash({'exclude' => ['{a,b}.md']})
|
117
|
+
allow(Dir).to receive(:'[]').with('src/**/*').and_return(%w(src/index.md src/a.md src/b.md))
|
118
|
+
expect(@configuration.source_files).to eq(%w(index.md))
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'and honor \\ as an escape' do
|
123
|
+
@configuration = Usmu::Configuration.from_hash({'exclude' => ['\*.md']})
|
124
|
+
allow(Dir).to receive(:'[]').with('src/**/*').and_return(%w(src/index.md src/*.md))
|
125
|
+
expect(@configuration.source_files).to eq(%w(index.md))
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'and honor ?' do
|
129
|
+
@configuration = Usmu::Configuration.from_hash({'exclude' => ['?.md']})
|
130
|
+
allow(Dir).to receive(:'[]').with('src/**/*').and_return(%w(src/index.md src/a.md src/b.md))
|
131
|
+
expect(@configuration.source_files).to eq(%w(index.md))
|
132
|
+
end
|
133
|
+
|
134
|
+
it 'and ignore files inside folders specified via globs with trailing "/"' do
|
135
|
+
@configuration = Usmu::Configuration.from_hash({'exclude' => ['test/*/']})
|
136
|
+
allow(Dir).to receive(:'[]').with('src/**/*').and_return(%w(src/index.md src/test/foo/foo.md src/test/foo.md))
|
137
|
+
expect(@configuration.source_files).to eq(%w(index.md test/foo.md))
|
138
|
+
end
|
139
|
+
end
|
51
140
|
end
|
data/test/spec/layout_spec.rb
CHANGED
@@ -1,27 +1,19 @@
|
|
1
|
-
require 'rspec'
|
2
1
|
require 'support/shared_layout'
|
3
2
|
require 'usmu/layout'
|
4
3
|
|
5
4
|
RSpec.describe Usmu::Layout do
|
6
5
|
it_behaves_like 'an embeddable layout'
|
7
6
|
|
8
|
-
let(:configuration) { Usmu::Configuration.
|
7
|
+
let(:configuration) { Usmu::Configuration.from_hash({}) }
|
9
8
|
|
10
9
|
it 'uses the \'layouts\' folder' do
|
11
|
-
layout = Usmu::Layout.new(configuration, 'html.slim')
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
<body>
|
20
|
-
<div id="content">
|
21
|
-
test
|
22
|
-
</div>
|
23
|
-
</body>
|
24
|
-
</html>
|
25
|
-
EOF
|
10
|
+
layout = Usmu::Layout.new(configuration, 'html.slim', 'slim', "head\nbody", {})
|
11
|
+
expect(layout.send :content_path).to eq('layouts')
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'has an input path' do
|
15
|
+
layout = Usmu::Layout.new(configuration, 'html.slim', 'slim', "head\nbody", {})
|
16
|
+
expect(layout.respond_to? :input_path).to eq(true)
|
17
|
+
expect(layout.input_path).to eq('layouts/html.slim')
|
26
18
|
end
|
27
19
|
end
|
data/test/spec/page_spec.rb
CHANGED
@@ -1,15 +1,19 @@
|
|
1
|
-
require 'rspec'
|
2
1
|
require 'support/shared_layout'
|
3
2
|
require 'usmu/page'
|
4
3
|
|
5
4
|
RSpec.describe Usmu::Page do
|
6
5
|
it_behaves_like 'an embeddable layout'
|
7
6
|
|
8
|
-
let(:configuration) { Usmu::Configuration.
|
7
|
+
let(:configuration) { Usmu::Configuration.from_hash({}) }
|
9
8
|
|
10
9
|
it 'uses the \'source\' folder' do
|
11
|
-
page = Usmu::Page.new(configuration, 'index.md')
|
12
|
-
|
13
|
-
|
10
|
+
page = Usmu::Page.new(configuration, 'index.md', 'md', '# test', {})
|
11
|
+
expect(page.send :content_path).to eq('src')
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'has an input path' do
|
15
|
+
page = Usmu::Page.new(configuration, 'index.md', 'md', '# test', {})
|
16
|
+
expect(page.respond_to? :input_path).to eq(true)
|
17
|
+
expect(page.input_path).to eq('src/index.md')
|
14
18
|
end
|
15
19
|
end
|