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.
@@ -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
@@ -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
- get_renderables @configuration.layouts_path, true
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
- get_renderables @configuration.source_path, false
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
@@ -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(File.join(@configuration.source_path, @name))
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
@@ -1,25 +1,53 @@
1
1
  require 'usmu'
2
- require 'trollop'
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
- attr_reader :configuration
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
- @args = args
15
- @configuration = Usmu::Configuration.from_file(File.join(args[0] || '.', 'usmu.yml'))
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
- # This will run the command as setup in `#initialize`
19
- #
20
- # @return [void]
21
- def execute
22
- Usmu::SiteGenerator.new(@configuration).generate
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,5 +1,5 @@
1
1
 
2
2
  module Usmu
3
- # The current versions string for the gem
4
- VERSION = '0.1.0'
3
+ # The current version string for the gem
4
+ VERSION = '0.2.0'
5
5
  end
@@ -1,3 +1,14 @@
1
- <h1>Default output</h1>
2
-
3
- <p>No metadata for this file. Uh oh!</p>
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>
@@ -1,2 +1,3 @@
1
1
  ---
2
2
  title: Default Title
3
+ layout: none
@@ -8,3 +8,4 @@ Feature:
8
8
  Given I have a site at "test/site"
9
9
  When I generate the site
10
10
  Then the destination directory should match "test/expected-site"
11
+ And the modification time for the input file "index.md" should match the output file "index.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
@@ -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.from_file('test/site/usmu.yml') }
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
- rendered = layout.render({'content' => 'test'})
13
- expect(rendered).to eq(<<-EOF)
14
- <!DOCTYPE html>
15
- <html>
16
- <head>
17
- <title>Default Title | Testing website</title>
18
- </head>
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
@@ -0,0 +1,8 @@
1
+
2
+ module Usmu
3
+ class MockPlugin
4
+ # This will be stubbed in with a mock if important. This is simply a placeholder to make sure #respond_to? replies
5
+ # correctly
6
+ def test(*args); end
7
+ end
8
+ end
@@ -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.from_file('test/site/usmu.yml') }
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
- rendered = page.render({})
13
- expect(rendered).to eq(File.read('test/expected-site/index.html'))
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
@@ -0,0 +1,5 @@
1
+ require 'usmu/plugin/core'
2
+
3
+ RSpec.describe Usmu::Plugin::Core do
4
+
5
+ end