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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9145c662e51c06125b270f02345e729323320e06
|
4
|
+
data.tar.gz: 3ad74fdce1d7f26fbe3dc3aebcffd95e4dbe78f0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 914950c2007bb0f7bf2b42f0361b4dcfb7f3584561c955c5b7301d51c8dcd921c6372dde7f47c1a41b7be383fc8bd4adf3c54dd71675330fa71475455ab91edf
|
7
|
+
data.tar.gz: 7ad1d0fe258d9d137b0a671b9f55580696d9dc75919f709f2b1ca551c19ad3f9f0293f65d2ae27abf02183f310742f1a8dcdad6f355aed6e394005f6ff762b80
|
data/.gitignore
CHANGED
data/.rspec
CHANGED
data/.simplecov
ADDED
data/.travis.yml
CHANGED
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
## Bug reports
|
2
|
+
|
3
|
+
If you have a bug report, please include as much information as possible to help us diagnose the issue:
|
4
|
+
|
5
|
+
* A log of the console output if available
|
6
|
+
* A backtrace or log file (--trace and --log)
|
7
|
+
* If possible, a link to the source code for the website that is causing issues or a small example site that shows the
|
8
|
+
same issues.
|
9
|
+
|
10
|
+
## Contributing code to usmu
|
11
|
+
|
12
|
+
1. Fork it
|
13
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
14
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
15
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
16
|
+
5. Create a new Pull Request
|
data/Guardfile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
guard :rspec, cmd: 'rspec', spec_paths: ['test/spec'] do
|
5
|
+
watch(%r{^test/spec/.+_spec\.rb$})
|
6
|
+
watch(%r{^lib/usmu/(.+)\.rb$}) { |m| "test/spec/#{m[1]}_spec.rb" }
|
7
|
+
watch(%r{^test/spec/support}) { 'test/spec' }
|
8
|
+
watch('test/spec/spec_helper.rb') { 'test/spec' }
|
9
|
+
|
10
|
+
# Turnip features and steps
|
11
|
+
#watch(%r{^spec/acceptance/(.+)\.feature$})
|
12
|
+
#watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' }
|
13
|
+
end
|
data/README.md
CHANGED
@@ -35,16 +35,17 @@ slim:
|
|
35
35
|
:pretty: true
|
36
36
|
```
|
37
37
|
|
38
|
-
|
38
|
+
### Ruby Compatibility
|
39
39
|
|
40
|
-
1.
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
40
|
+
Officially, we support MRI 1.9.3 and onwards, however we recommend the latest versions. [1.9.3 is no longer maintained][ruby-maint]
|
41
|
+
and is only supported here to help out the Rubinius and JRuby folks.
|
42
|
+
|
43
|
+
We only officially support MRI, however Travis does run against both Rubinius and JRuby to track compatibility and
|
44
|
+
there's a reasonable track record so far. Compatibility patches are very welcome.
|
45
45
|
|
46
46
|
[gh-contrib]: https://github.com/usmu/usmu/graphs/contributors
|
47
47
|
[gh-issues]: https://github.com/usmu/usmu/issues
|
48
48
|
[license]: https://github.com/usmu/usmu/blob/master/LICENSE.md
|
49
49
|
[tilt-support]: https://github.com/rtomayko/tilt/blob/master/README.md
|
50
50
|
[template-options]: https://github.com/rtomayko/tilt/blob/master/docs/TEMPLATES.md
|
51
|
+
[ruby-maint]: https://bugs.ruby-lang.org/projects/ruby/wiki/ReleaseEngineering
|
data/Rakefile
CHANGED
@@ -2,8 +2,6 @@ lib = File.expand_path('../lib', __FILE__)
|
|
2
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
3
|
|
4
4
|
require 'rspec/core/rake_task'
|
5
|
-
require 'cucumber'
|
6
|
-
require 'cucumber/rake/task'
|
7
5
|
require 'usmu/version'
|
8
6
|
|
9
7
|
def current_gems
|
@@ -11,23 +9,24 @@ def current_gems
|
|
11
9
|
end
|
12
10
|
|
13
11
|
RSpec::Core::RakeTask.new(:spec) do |t|
|
14
|
-
t.pattern = 'test/spec
|
15
|
-
end
|
16
|
-
|
17
|
-
Cucumber::Rake::Task.new(:features) do |t|
|
18
|
-
t.cucumber_opts = 'test/features'
|
12
|
+
t.pattern = 'test/spec'
|
19
13
|
end
|
20
14
|
|
21
15
|
desc 'Run all test scripts'
|
22
|
-
task :test => [:clean, :spec
|
16
|
+
task :test => [:clean, :spec]
|
23
17
|
|
24
18
|
desc 'Run CI test suite'
|
25
19
|
task :ci => [:test]
|
26
20
|
|
27
21
|
desc 'Clean up after tests'
|
28
22
|
task :clean do
|
29
|
-
|
30
|
-
|
23
|
+
[
|
24
|
+
'test/coverage',
|
25
|
+
'test/site/site',
|
26
|
+
current_gems,
|
27
|
+
].flatten.each do |f|
|
28
|
+
rm_r f if File.exist? f
|
29
|
+
end
|
31
30
|
end
|
32
31
|
|
33
32
|
namespace :gem do
|
data/bin/usmu
CHANGED
data/lib/usmu.rb
CHANGED
@@ -1,3 +1,74 @@
|
|
1
|
+
require 'logging'
|
2
|
+
require 'rubygems'
|
3
|
+
|
4
|
+
Logging.init :debug, :info, :success, :warn, :error, :fatal
|
5
|
+
Logging.color_scheme(
|
6
|
+
'console',
|
7
|
+
:lines => {
|
8
|
+
:success => :green,
|
9
|
+
:warn => :yellow,
|
10
|
+
:error => :red,
|
11
|
+
:fatal => :red,
|
12
|
+
},
|
13
|
+
)
|
14
|
+
|
15
|
+
# This module contains all the code for the Usmu site generator
|
16
|
+
module Usmu
|
17
|
+
@log = Logging.logger['Usmu']
|
18
|
+
@log.level = :all
|
19
|
+
@log.additive = false
|
20
|
+
@log.appenders = Logging.appenders.stdout(
|
21
|
+
'usmu-stdout',
|
22
|
+
:level => :info,
|
23
|
+
:layout => Logging.layouts.pattern(
|
24
|
+
:pattern => '%m\n',
|
25
|
+
:color_scheme => 'console',
|
26
|
+
),
|
27
|
+
)
|
28
|
+
|
29
|
+
# Enable logging of all events to the console
|
30
|
+
#
|
31
|
+
# @return [void]
|
32
|
+
def self.verbose_logging
|
33
|
+
Logging.appenders['usmu-stdout'].level = :all
|
34
|
+
nil
|
35
|
+
end
|
36
|
+
|
37
|
+
# Disable all log messages other than errors. Warnings will be suppressed.
|
38
|
+
#
|
39
|
+
# @return [void]
|
40
|
+
def self.quiet_logging
|
41
|
+
Logging.appenders['usmu-stdout'].level = :error
|
42
|
+
nil
|
43
|
+
end
|
44
|
+
|
45
|
+
# Adds a file-based logger
|
46
|
+
#
|
47
|
+
# @param [String] filename Filename of the file to log to.
|
48
|
+
# @return [void]
|
49
|
+
def self.add_file_logger(filename)
|
50
|
+
@log.add_appenders(Logging.appenders.file(filename, :filename => filename, :level => :all))
|
51
|
+
nil
|
52
|
+
end
|
53
|
+
|
54
|
+
# :nocov:
|
55
|
+
# This is primarily a testing helper
|
56
|
+
|
57
|
+
# Disables stdout logging across the application. This is used to hide stack traces but still log them to the file
|
58
|
+
# log if it is in use.
|
59
|
+
#
|
60
|
+
# @return [void]
|
61
|
+
def self.disable_stdout_logging
|
62
|
+
@log.remove_appenders('usmu-stdout')
|
63
|
+
nil
|
64
|
+
end
|
65
|
+
# :nocov:
|
66
|
+
|
67
|
+
def self.plugins
|
68
|
+
@plugins ||= Usmu::Plugin.new
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
1
72
|
%W{
|
2
73
|
usmu/version
|
3
74
|
usmu/configuration
|
@@ -5,8 +76,6 @@
|
|
5
76
|
usmu/layout
|
6
77
|
usmu/page
|
7
78
|
usmu/site_generator
|
79
|
+
usmu/plugin
|
80
|
+
usmu/plugin/core
|
8
81
|
}.each { |f| require f }
|
9
|
-
|
10
|
-
# This module contains all the code for the Usmu site generator
|
11
|
-
module Usmu
|
12
|
-
end
|
data/lib/usmu/configuration.rb
CHANGED
@@ -4,10 +4,12 @@ module Usmu
|
|
4
4
|
# This class is used to represent a configuration file. This file should be a YAML file and called `usmu.yml`
|
5
5
|
# by default.
|
6
6
|
class Configuration
|
7
|
+
@log = Logging.logger[self]
|
8
|
+
|
7
9
|
# @!attribute [r] config_file
|
8
10
|
# @return [String] the name of the file used to load the configuration.
|
9
11
|
attr_reader :config_file
|
10
|
-
# @!attribute [r]
|
12
|
+
# @!attribute [r] config_dir
|
11
13
|
# @return [String] the folder that the configuration was loaded from.
|
12
14
|
attr_reader :config_dir
|
13
15
|
|
@@ -15,6 +17,7 @@ module Usmu
|
|
15
17
|
#
|
16
18
|
# @return [Usmu::Configuration]
|
17
19
|
def self.from_file(filename)
|
20
|
+
@log.debug("Loading configuration from #{filename}")
|
18
21
|
from_hash(YAML.load_file(filename), filename)
|
19
22
|
end
|
20
23
|
|
@@ -31,6 +34,12 @@ module Usmu
|
|
31
34
|
get_path @config['source'] || 'src'
|
32
35
|
end
|
33
36
|
|
37
|
+
# @!attribute [r] source_files
|
38
|
+
# @return [Array<String>] a list of renderable files in the source folder
|
39
|
+
def source_files
|
40
|
+
get_files source_path
|
41
|
+
end
|
42
|
+
|
34
43
|
# @!attribute [r] destination_path
|
35
44
|
# @return [String] the full path to the destination folder
|
36
45
|
def destination_path
|
@@ -43,6 +52,12 @@ module Usmu
|
|
43
52
|
get_path @config['layouts'] || 'layouts'
|
44
53
|
end
|
45
54
|
|
55
|
+
# @!attribute [r] layouts_files
|
56
|
+
# @return [Array<String>] a list of renderable files in the layouts folder
|
57
|
+
def layouts_files
|
58
|
+
get_files layouts_path
|
59
|
+
end
|
60
|
+
|
46
61
|
# An index accessor to directly access the configuration file. It should be noted that `['source']` and
|
47
62
|
# `#source_path` and other similar pairs will have different values. `['source']` is the raw value from the
|
48
63
|
# configuration file while the latter is a path on the system, potentially altered by the path from the current
|
@@ -63,6 +78,7 @@ module Usmu
|
|
63
78
|
# @see Usmu::Configuration.from_file
|
64
79
|
# @see Usmu::Configuration.from_hash
|
65
80
|
def initialize(hash, config_path)
|
81
|
+
@log = Logging.logger[self]
|
66
82
|
@config = hash
|
67
83
|
@config_file = config_path
|
68
84
|
@config_dir = config_path ? File.dirname(config_path) : nil
|
@@ -79,5 +95,28 @@ module Usmu
|
|
79
95
|
File.join(@config_dir, path)
|
80
96
|
end
|
81
97
|
end
|
98
|
+
|
99
|
+
# Helper to determine if a filename is excluded according to the exclude configuration parameter.
|
100
|
+
#
|
101
|
+
# @return [Boolean]
|
102
|
+
def excluded?(filename)
|
103
|
+
flags = defined?(File::FNM_EXTGLOB) ? File::FNM_EXTGLOB | File::FNM_PATHNAME : File::FNM_PATHNAME
|
104
|
+
(@config['exclude'] || []).each do |f|
|
105
|
+
f += '**/*' if f[-1] == '/'
|
106
|
+
return true if File.fnmatch(f, filename, flags)
|
107
|
+
end
|
108
|
+
false
|
109
|
+
end
|
110
|
+
|
111
|
+
# Helper function to search a directory recursively and return a list of files that are renderable.
|
112
|
+
#
|
113
|
+
# @param [String] directory the directory to search
|
114
|
+
# @param [Boolean] layout is this directory a layouts_path
|
115
|
+
# @return [Array<Usmu::Layout>, Array<Usmu::StaticFile>] Either an array of Layouts or StaticFiles in the directory
|
116
|
+
def get_files(directory)
|
117
|
+
Dir["#{directory}/**/*"].select {|f| !f.match(/\.meta.yml$/) }.map do |f|
|
118
|
+
f[(directory.length + 1)..f.length]
|
119
|
+
end.select {|f| not excluded? f}
|
120
|
+
end
|
82
121
|
end
|
83
122
|
end
|
data/lib/usmu/layout.rb
CHANGED
@@ -42,7 +42,8 @@ module Usmu
|
|
42
42
|
end
|
43
43
|
@metadata = metadata
|
44
44
|
|
45
|
-
@parent =
|
45
|
+
@parent = nil
|
46
|
+
@parent = Layout.find_layout(configuration, self.metadata['layout'])
|
46
47
|
end
|
47
48
|
|
48
49
|
# @!attribute [r] metadata
|
@@ -53,9 +54,9 @@ module Usmu
|
|
53
54
|
# This will include any metadata from parent templates and default metadata
|
54
55
|
def metadata
|
55
56
|
if @parent.nil?
|
56
|
-
|
57
|
+
(@configuration['default meta'] || {}).dup.deep_merge!(@metadata)
|
57
58
|
else
|
58
|
-
@metadata.deep_merge(@
|
59
|
+
@parent.metadata.deep_merge!(@metadata)
|
59
60
|
end
|
60
61
|
end
|
61
62
|
|
@@ -75,10 +76,25 @@ module Usmu
|
|
75
76
|
end
|
76
77
|
end
|
77
78
|
|
79
|
+
# @!attribute [r] input_path
|
80
|
+
# @return [String] the full path to the file in the source directory
|
81
|
+
def input_path
|
82
|
+
File.join(content_path, @name)
|
83
|
+
end
|
84
|
+
|
78
85
|
# @!attribute [r] output_extension
|
79
86
|
# @return [String] the extension to use with the output file.
|
80
87
|
def output_extension
|
81
|
-
|
88
|
+
case @type
|
89
|
+
when 'erb', 'rhtml', 'erubis', 'liquid'
|
90
|
+
nil
|
91
|
+
when 'coffee'
|
92
|
+
'js'
|
93
|
+
when 'less', 'sass', 'scss'
|
94
|
+
'css'
|
95
|
+
else
|
96
|
+
'html'
|
97
|
+
end
|
82
98
|
end
|
83
99
|
|
84
100
|
# @!attribute [r] output_filename
|
@@ -86,7 +102,11 @@ module Usmu
|
|
86
102
|
#
|
87
103
|
# Returns the filename to use for the output directory with any modifications to the input filename required.
|
88
104
|
def output_filename
|
89
|
-
|
105
|
+
if output_extension
|
106
|
+
@name[0..@name.rindex('.')] + output_extension
|
107
|
+
else
|
108
|
+
@name[0..@name.rindex('.') - 1]
|
109
|
+
end
|
90
110
|
end
|
91
111
|
|
92
112
|
# Static method to create a layout for a given configuration by it's name if it exists. This differs from
|
@@ -100,13 +120,16 @@ module Usmu
|
|
100
120
|
# that name is nilable and can also be passed in as an Usmu::Layout already for testing purposes.
|
101
121
|
# @return [Usmu::Layout]
|
102
122
|
def self.find_layout(configuration, name)
|
103
|
-
if name
|
123
|
+
if name === 'none'
|
124
|
+
nil
|
125
|
+
elsif name.class.name == 'String'
|
104
126
|
Dir["#{configuration.layouts_path}/#{name}.*"].each do |f|
|
105
127
|
filename = File.basename(f)
|
106
128
|
if filename != "#{name}.meta.yml"
|
107
129
|
return new(configuration, f[(configuration.layouts_path.length + 1)..f.length])
|
108
130
|
end
|
109
131
|
end
|
132
|
+
nil
|
110
133
|
else
|
111
134
|
name
|
112
135
|
end
|
@@ -160,7 +183,7 @@ module Usmu
|
|
160
183
|
#
|
161
184
|
# @return [Hash]
|
162
185
|
def get_variables(variables)
|
163
|
-
|
186
|
+
{site: @configuration}.deep_merge!(metadata).deep_merge!(variables)
|
164
187
|
end
|
165
188
|
end
|
166
189
|
end
|
data/lib/usmu/page.rb
CHANGED
data/lib/usmu/plugin.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
|
2
|
+
module Usmu
|
3
|
+
class Plugin
|
4
|
+
def initialize
|
5
|
+
@log = Logging.logger['Usmu::Plugin']
|
6
|
+
end
|
7
|
+
|
8
|
+
# Loads all plugins that are available as gems. This is determined by looking at the gem's name. Anything prefixed
|
9
|
+
# with the string 'usmu-' will be recognised as a plugin. This will load the gem according to the RubyGems
|
10
|
+
# recommendations for naming schemes. A gem named `usmu-s3_uploader` will be loaded by requiring the path
|
11
|
+
# `'usmu/s3_uploader'` and then then the class `Usmu::S3Uploader` will be instantiated as the plugins interface.
|
12
|
+
#
|
13
|
+
# @return [void]
|
14
|
+
def load_plugins
|
15
|
+
loaded = []
|
16
|
+
@log.debug('Loading plugins')
|
17
|
+
@log.debug('Loaded Usmu::Plugin::Core')
|
18
|
+
plugins.push Usmu::Plugin::Core.new
|
19
|
+
Gem::Specification.find_all { |s| s.name =~ /^usmu-/ }.each do |spec|
|
20
|
+
load_path = spec.name.gsub('-', '/')
|
21
|
+
require load_path
|
22
|
+
|
23
|
+
unless loaded.include? load_path
|
24
|
+
loaded << load_path
|
25
|
+
klass = load_path.split('/').map {|s| s.split('_').map(&:capitalize).join }.join('::')
|
26
|
+
@log.debug("Loading plugin #{klass} from '#{load_path}'")
|
27
|
+
plugins.push plugin_get(klass)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
@log.debug("Loaded: #{plugins.inspect}")
|
31
|
+
end
|
32
|
+
|
33
|
+
# @!attribute [r] plugins
|
34
|
+
# @return [Array] a list of all plugins discovered and loaded.
|
35
|
+
def plugins
|
36
|
+
@plugins ||= []
|
37
|
+
end
|
38
|
+
|
39
|
+
# Call all plugins and collate any data returned. nil can be returned explicitly to say this plugin has nothing to
|
40
|
+
# return.
|
41
|
+
# @param [Symbol] method The name of the method to call. This should be namespaced somehow. For example, a plugin
|
42
|
+
# called `usmu-s3` could use the method namespace `s3` and have a hook called `:s3_upload`
|
43
|
+
# @param [Array] args The arguments to pass through to plugins. Can be empty.
|
44
|
+
def invoke(method, *args)
|
45
|
+
@log.debug("Invoking plugin API #{method}")
|
46
|
+
plugins.map do |p|
|
47
|
+
if p.respond_to? method
|
48
|
+
@log.debug("Sending message to #{p.class.name}")
|
49
|
+
p.public_send method, *args
|
50
|
+
else
|
51
|
+
nil
|
52
|
+
end
|
53
|
+
end.select {|i| i}
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def plugin_get(klass)
|
59
|
+
object.const_get(klass).new
|
60
|
+
rescue NameError
|
61
|
+
# Ruby 1.9.3, dowp
|
62
|
+
klass.split('::').reduce(Object) {|memo, o| memo.const_get o }.new
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|