usmu 0.3.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -2
  3. data/.travis.yml +3 -0
  4. data/CHANGELOG.md +21 -0
  5. data/Gemfile +7 -0
  6. data/Guardfile +7 -7
  7. data/README.md +5 -1
  8. data/Rakefile +16 -5
  9. data/lib/usmu.rb +3 -1
  10. data/lib/usmu/configuration.rb +25 -13
  11. data/lib/usmu/deployment.rb +12 -0
  12. data/lib/usmu/deployment/directory_diff.rb +64 -0
  13. data/lib/usmu/deployment/remote_file_interface.rb +25 -0
  14. data/lib/usmu/plugin.rb +5 -1
  15. data/lib/usmu/template/layout.rb +24 -17
  16. data/lib/usmu/version.rb +1 -1
  17. data/{test/spec → spec}/acceptance/full_site_build.feature +2 -2
  18. data/{test/spec → spec}/acceptance/steps/full_site_build_steps.rb +0 -0
  19. data/spec/configuration_spec.rb +257 -0
  20. data/spec/deployment/directory_diff_spec.rb +126 -0
  21. data/{test/spec → spec}/mock/usmu/mock_plugin.rb +0 -0
  22. data/spec/mock/usmu/mock_remote_files.rb +19 -0
  23. data/{test/spec → spec}/plugin/core_spec.rb +0 -0
  24. data/{test/spec → spec}/plugin_spec.rb +0 -0
  25. data/{test/spec → spec}/site_generator_spec.rb +1 -1
  26. data/{test/spec → spec}/spec_helper.rb +18 -4
  27. data/{test/spec → spec}/support/shared_layout.rb +0 -0
  28. data/{test/spec → spec}/template/layout_spec.rb +1 -1
  29. data/{test/spec → spec}/template/page_spec.rb +0 -0
  30. data/{test/spec → spec}/template/static_file_spec.rb +2 -2
  31. data/{test/spec → spec}/ui/console_spec.rb +4 -4
  32. data/{test/expected-site → test-site/content}/.dotfiletest.txt +0 -0
  33. data/{test/site → test-site}/content/css/_partial.scss +0 -0
  34. data/{test/site → test-site}/content/css/app.scss +0 -0
  35. data/{test/site → test-site}/content/default.md +0 -0
  36. data/{test/site → test-site}/content/embedded.md +0 -0
  37. data/{test/site → test-site}/content/embedded.meta.yml +0 -0
  38. data/{test/site → test-site}/content/index.md +0 -0
  39. data/{test/site → test-site}/content/index.meta.yml +0 -0
  40. data/{test/site → test-site}/content/posts/test-post.md +0 -0
  41. data/{test/expected-site → test-site/content}/robots.txt +0 -0
  42. data/{test/site/content → test-site/expected-site}/.dotfiletest.txt +0 -0
  43. data/{test → test-site}/expected-site/css/app.css +0 -0
  44. data/{test → test-site}/expected-site/default.html +0 -0
  45. data/{test → test-site}/expected-site/embedded.html +0 -0
  46. data/{test → test-site}/expected-site/index.html +0 -0
  47. data/{test → test-site}/expected-site/posts/test-post.html +0 -0
  48. data/{test/site/content → test-site/expected-site}/robots.txt +0 -0
  49. data/{test/site → test-site}/includes/footer.meta.yml +0 -0
  50. data/{test/site → test-site}/includes/footer.slim +0 -0
  51. data/{test/site → test-site}/layouts/embedded.meta.yml +0 -0
  52. data/{test/site → test-site}/layouts/embedded.slim +0 -0
  53. data/{test/site → test-site}/layouts/html.slim +0 -0
  54. data/{test/site → test-site}/usmu.yml +0 -0
  55. data/usmu-jruby.gemspec +1 -0
  56. data/usmu.gemspec +1 -2
  57. metadata +73 -105
  58. data/.cane +0 -4
  59. data/.simplecov +0 -4
  60. data/test/spec/configuration_spec.rb +0 -176
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8fc86dae15be6aceae0a11ed6b8d31b381eb2fda
4
- data.tar.gz: e86a3100c2b95c4f095597c12b302eee60e61352
3
+ metadata.gz: 82edd4386ce8ad7e313db42fcb53ae4b908f8988
4
+ data.tar.gz: bf0bbc5db654e595fccfaa5d65965976d2d2b75d
5
5
  SHA512:
6
- metadata.gz: f198fb4e39bf471a56324c001216e2eee1041b9c04ec8f842d2c62c36dc0524f1e15598ae097aaf6af395b2ca8f249030f7748d1bd9636351f2c4d2afe86fade
7
- data.tar.gz: bfee2b4b896e7d1dd990beb33eb0c76c9e80647f29e4cb6cbc9afee036a6aff166b7a1ce3f57e83d4c304a0086fec0c9cad2b294fd29fb9423ca776170be8279
6
+ metadata.gz: 19a6e9d124cefab1e4068b5c29da0eb1656cf7e10bf844e5b7ae29fc03d7e39966e5d11785a13fdf28eeb8e6d7d14f5acf41c37cda6cf51dbdc5d9b99df24860
7
+ data.tar.gz: 181da46641fa0d63e0359f069bba71d2deca24fac77fb03ee801be16bebc769361d3c5fd4584023f039a38616b24c52d32a198f52fc4f5e515eac0823cc6f187
data/.gitignore CHANGED
@@ -3,7 +3,6 @@
3
3
  /.sass-cache
4
4
  /Gemfile*.lock
5
5
  /_yardoc/
6
- /test/coverage/
7
6
  /doc/
8
7
  /pkg/
9
8
  /spec/reports/
@@ -16,4 +15,4 @@
16
15
  mkmf.log
17
16
 
18
17
  # Generated test site
19
- /test/site/site
18
+ /test-site/site
@@ -32,3 +32,6 @@ matrix:
32
32
  - rvm: rbx-2.2
33
33
  - rvm: rbx-2.3
34
34
  - rvm: rbx-2.4
35
+ addons:
36
+ code_climate:
37
+ repo_token: 5ac0735331c1749a461eae94f89cd2011cc001979f9941d7241f97caeff7bde1
@@ -1,5 +1,26 @@
1
1
  # Usmu Change Log
2
2
 
3
+ ## 0.3.2
4
+
5
+ Matthew Scharley <matt.scharley@gmail.com>
6
+
7
+ * Add Code Climate (740713e6fb181036fa0e071149b0f85fbb44e520)
8
+ * Use Code Climate's coverage tracking (536365b3c821d7ab145fd9e6241a1cd5302ca986)
9
+ * First pass of a directory diff for deployment plugins (47f0dccbb3b330dcf8821248d4cd964b0564e50c)
10
+ * Add some more tests for coverage of DirectoryDiff (8ae3a9311c395a3f09f3cc4d0e6753a24a6b9f99)
11
+ * Cleanup code complexity (2d4cbfc9ae78cda8a0607c3998bda016b65f041b)
12
+ * Try to cleanup Layout a little (a2c6ce32fa16075ba332932b9a542ff1c8a35732)
13
+ * Install mutant (6f170c6a3181c9a071c930a949058e3d6e760b6b)
14
+ * Move spec folder into root directory (571451ddd9403ede4f097072facf443178428953)
15
+ * Finalise mutant configuration (2e6fd8239112ca7f3cb9ab75424b82606835b944)
16
+ * Don't allow reporting code climate for mutant tests (cca22b243a052165173e04dde8294864aa639c0c)
17
+ * Add a guard to only run on MRI (1035ea042f12dfe7bd9ce7d632245b7c59e48d3f)
18
+ * Stop mutant attempting to run where it won't (38aa6c042c9d8bb3eacd75e7b8a937c538ca729f)
19
+ * Don't run mutant on CI (b5d6d9f6f50e9331a0ec07d50596d605829d0d8e)
20
+ * Don't mask errors from mutant (6257b3b02749ba07f697014562f2768198cd12c0)
21
+ * Convert existing coverage for Configuration to proper unit tests (536df7c3a17268920bbb7bbc4de74f38d224755f)
22
+ * 100% mutant coverage for Configuration (6d616736dd01971c842f870164b1b0612ebd80aa)
23
+
3
24
  ## 0.3.1
4
25
 
5
26
  Matthew Scharley <matt.scharley@gmail.com>
data/Gemfile CHANGED
@@ -2,3 +2,10 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in usmu.gemspec
4
4
  gemspec name: 'usmu'
5
+
6
+ gem 'codeclimate-test-reporter', group: :test, require: nil
7
+
8
+ if RUBY_VERSION.to_f >= 2
9
+ gem 'mutant', '~> 0.7'
10
+ gem 'mutant-rspec', '~> 0.7'
11
+ end
data/Guardfile CHANGED
@@ -1,13 +1,13 @@
1
1
  # A sample Guardfile
2
2
  # More info at https://github.com/guard/guard#readme
3
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' }
4
+ guard :rspec, cmd: 'rspec', spec_paths: ['spec'] do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^lib/usmu/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
7
+ watch(%r{^test/spec/support}) { 'spec' }
8
+ watch('test/spec/spec_helper.rb') { 'spec' }
9
9
 
10
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' }
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
13
  end
data/README.md CHANGED
@@ -1,4 +1,8 @@
1
- # usmu [![Build Status](https://travis-ci.org/usmu/usmu.svg?branch=master)](https://travis-ci.org/usmu/usmu) [![Dependency Status](https://gemnasium.com/usmu/usmu.svg)](https://gemnasium.com/usmu/usmu)
1
+ # usmu
2
+
3
+ [![Build Status](https://travis-ci.org/usmu/usmu.svg?branch=master)](https://travis-ci.org/usmu/usmu)
4
+ [![Dependency Status](https://gemnasium.com/usmu/usmu.svg)](https://gemnasium.com/usmu/usmu)
5
+ [![Code Climate](https://codeclimate.com/github/usmu/usmu/badges/gpa.svg)](https://codeclimate.com/github/usmu/usmu)
2
6
 
3
7
  **Source:** [https://github.com/usmu/usmu](https://github.com/usmu/usmu)
4
8
  **Author:** Matthew Scharley
data/Rakefile CHANGED
@@ -5,11 +5,11 @@ require 'rspec/core/rake_task'
5
5
  require 'usmu/version'
6
6
 
7
7
  def current_gems
8
- Dir["pkg/usmu-#{Usmu::VERSION}*.gem"]
8
+ Dir["pkg/usmu-#{Usmu::VERSION}*.gem"].sort_by &:length
9
9
  end
10
10
 
11
11
  RSpec::Core::RakeTask.new(:spec) do |t|
12
- t.pattern = 'test/spec'
12
+ t.pattern = 'spec'
13
13
  end
14
14
 
15
15
  desc 'Start an IRB session with local code available'
@@ -18,10 +18,21 @@ task :irb do
18
18
  end
19
19
 
20
20
  desc 'Run all test scripts'
21
- task :test => [:clean, :spec]
21
+ task :test => [:clean, :spec, :mutant]
22
+
23
+ desc 'Run mutation tests'
24
+ task :mutant, [:target] => [:clean] do |t,args|
25
+ old = ENV.delete('CODECLIMATE_REPO_TOKEN')
26
+ if `which mutant 2>&1 > /dev/null; echo \$?`.to_i != 0
27
+ puts 'Mutant isn\'t supported on your platform. Please run these tests on MRI <= 2.1.5.'
28
+ else
29
+ sh('bundle', 'exec', 'mutant', '--include', 'lib', '--require', 'usmu', '--use', 'rspec', args[:target] || 'Usmu*')
30
+ end
31
+ ENV['CODECLIMATE_REPO_TOKEN'] = old unless old.nil?
32
+ end
22
33
 
23
34
  desc 'Run CI test suite'
24
- task :ci => [:test]
35
+ task :ci => [:clean, :spec]
25
36
 
26
37
  desc 'Clean up after tests'
27
38
  task :clean do
@@ -68,7 +79,7 @@ end
68
79
  # (mostly) borrowed from: https://gist.github.com/mcansky/802396
69
80
  desc 'generate changelog with nice clean output'
70
81
  task :changelog, :since_c, :until_c do |t,args|
71
- since_c = args[:since_c] || `git tag | head -1`.chomp
82
+ since_c = args[:since_c] || `git tag | egrep '^[0-9]+\\.[0-9]+\\.[0-9]+\$' | sort -Vr | head -n 1`.chomp
72
83
  until_c = args[:until_c]
73
84
  cmd=`git log --pretty='format:%ci::::%an <%ae>::::%s::::%H' #{since_c}..#{until_c}`
74
85
 
@@ -16,7 +16,6 @@ Logging.color_scheme(
16
16
  module Usmu
17
17
  @log = Logging.logger['Usmu']
18
18
  @log.level = :all
19
- @log.additive = false
20
19
  @log.appenders = Logging.appenders.stdout(
21
20
  'usmu-stdout',
22
21
  :level => :info,
@@ -26,6 +25,9 @@ module Usmu
26
25
  ),
27
26
  )
28
27
 
28
+ # Globbing flags. Correct across 1.9.3 and 2.0+, enabling as many features as available
29
+ FILE_GLOB_FLAGS = defined?(File::FNM_EXTGLOB) ? File::FNM_EXTGLOB | File::FNM_PATHNAME : File::FNM_PATHNAME
30
+
29
31
  # Enable logging of all events to the console
30
32
  #
31
33
  # @return [void]
@@ -17,21 +17,22 @@ module Usmu
17
17
  #
18
18
  # @return [Usmu::Configuration]
19
19
  def self.from_file(filename)
20
+ raise ArgumentError, "File not found: #{filename}" if filename.nil? || (not File.exist? filename)
20
21
  @log.debug("Loading configuration from #{filename}")
21
- from_hash(YAML.load_file(filename), filename)
22
+ new(YAML.load_file(filename), filename)
22
23
  end
23
24
 
24
25
  # Load a configuration from a hash.
25
26
  #
26
27
  # @return [Usmu::Configuration]
27
28
  def self.from_hash(hash, config_path = nil)
28
- self.new(hash, config_path)
29
+ new(hash, config_path)
29
30
  end
30
31
 
31
32
  # @!attribute [r] source_path
32
33
  # @return [String] the full path to the source folder
33
34
  def source_path
34
- get_path @config['source'] || 'src'
35
+ get_path self['source'] || 'src'
35
36
  end
36
37
 
37
38
  # @!attribute [r] source_files
@@ -43,13 +44,13 @@ module Usmu
43
44
  # @!attribute [r] destination_path
44
45
  # @return [String] the full path to the destination folder
45
46
  def destination_path
46
- get_path @config['destination'] || 'site'
47
+ get_path self['destination'] || 'site'
47
48
  end
48
49
 
49
50
  # @!attribute [r] layouts_path
50
51
  # @return [String] the full path to the layouts folder
51
52
  def layouts_path
52
- get_path @config['layouts'] || 'layouts'
53
+ get_path self['layouts'] || 'layouts'
53
54
  end
54
55
 
55
56
  # @!attribute [r] layouts_files
@@ -61,7 +62,7 @@ module Usmu
61
62
  # @!attribute [r] layouts_path
62
63
  # @return [String] the full path to the layouts folder
63
64
  def includes_path
64
- get_path @config['includes'] || 'includes'
65
+ get_path self['includes'] || 'includes'
65
66
  end
66
67
 
67
68
  # @!attribute [r] layouts_files
@@ -86,7 +87,7 @@ module Usmu
86
87
  # Returns a value from the hash loaded from YAML. The type of value will ultimately depend on the configuration
87
88
  # file and the indices provided.
88
89
  def [](*indices)
89
- if indices[-1].class.name == 'Hash'
90
+ if indices.last.instance_of? Hash
90
91
  opts = indices.pop
91
92
  else
92
93
  opts = {}
@@ -105,8 +106,18 @@ module Usmu
105
106
  value
106
107
  end
107
108
 
109
+ # Returns an array of exclusions
110
+ #
111
+ # @return [Array]
112
+ def exclude
113
+ self['exclude'] || []
114
+ end
115
+
108
116
  private
109
117
 
118
+ attr_reader :log
119
+ attr_reader :config
120
+
110
121
  # This class has a private constructor.
111
122
  #
112
123
  # @see Usmu::Configuration.from_file
@@ -115,7 +126,9 @@ module Usmu
115
126
  @log = Logging.logger[self]
116
127
  @config = hash
117
128
  @config_file = config_path
118
- @config_dir = config_path ? File.dirname(config_path) : nil
129
+ @config_dir = if config_path
130
+ File.dirname(config_path)
131
+ end
119
132
  end
120
133
 
121
134
  # Helper function to transform a relative path in the configuration file to a relative path from the current
@@ -134,10 +147,9 @@ module Usmu
134
147
  #
135
148
  # @return [Boolean]
136
149
  def excluded?(filename)
137
- flags = defined?(File::FNM_EXTGLOB) ? File::FNM_EXTGLOB | File::FNM_PATHNAME : File::FNM_PATHNAME
138
- (@config['exclude'] || []).each do |f|
139
- f += '**/*' if f[-1] == '/'
140
- return true if File.fnmatch(f, filename, flags)
150
+ exclude.each do |f|
151
+ f += '**/*' if f.end_with? '/'
152
+ return true if File.fnmatch(f, filename, FILE_GLOB_FLAGS)
141
153
  end
142
154
  false
143
155
  end
@@ -150,7 +162,7 @@ module Usmu
150
162
  Dir["#{directory}/**/{*,.??*}"].
151
163
  select {|f| not File.directory? f }.
152
164
  select {|f| !f.match(/\.meta.yml$/) }.
153
- map {|f| f[(directory.length + 1)..f.length] }.
165
+ map {|f| f[directory.length + 1, f.length] }.
154
166
  select {|f| not excluded? f }
155
167
  end
156
168
  end
@@ -0,0 +1,12 @@
1
+
2
+ module Usmu
3
+ # This module is a namespace for all common deployment related classes. This includes some helpers for deployment
4
+ # plugins such as the S3 plugin.
5
+ module Deployment
6
+ end
7
+ end
8
+
9
+ %w{
10
+ usmu/deployment/directory_diff
11
+ usmu/deployment/remote_file_interface
12
+ }.each {|f| require f }
@@ -0,0 +1,64 @@
1
+ require 'digest'
2
+
3
+ module Usmu
4
+ module Deployment
5
+ class DirectoryDiff
6
+ # @param [Usmu::Configuration] configuration
7
+ # @param [Usmu::Deployment::RemoteFileInterface] remote_files
8
+ def initialize(configuration, remote_files)
9
+ @configuration = configuration
10
+ @remote_files = remote_files
11
+ end
12
+
13
+ # @return [Hash]
14
+ # A hash of arrays of filenames:
15
+ #
16
+ # * `:local` - local-only files
17
+ # * `:remote` - remote-only files
18
+ # * `:updated` - files that were updated
19
+ def get_diffs
20
+ local_files = local_files_list
21
+ remote_files = @remote_files.files_list
22
+
23
+ updated_files = (local_files & remote_files).select &method(:filter_files)
24
+
25
+ {
26
+ :local => local_files - remote_files,
27
+ :remote => remote_files - local_files,
28
+ :updated => updated_files,
29
+ }
30
+ end
31
+
32
+ private
33
+
34
+ def filter_files(f)
35
+ lstat = File.stat("#{@configuration.destination_path}/#{f}")
36
+ rstat = @remote_files.stat(f)
37
+ lhash = File.read("#{@configuration.destination_path}/#{f}")
38
+
39
+ hash_comparison = check_hash(lhash, rstat)
40
+ time_comparison = lstat.mtime > rstat[:mtime]
41
+
42
+ time_comparison || hash_comparison
43
+ end
44
+
45
+ def check_hash(lhash, rstat)
46
+ if not rstat[:md5].nil?
47
+ rhash = rstat[:md5]
48
+ Digest::MD5.hexdigest(lhash) != rhash
49
+ elsif not rstat[:sha1].nil?
50
+ rhash = rstat[:sha1]
51
+ Digest::SHA1.hexdigest(lhash) != rhash
52
+ else
53
+ false
54
+ end
55
+ end
56
+
57
+ def local_files_list
58
+ Dir[@configuration.destination_path + '/**/{*,.??*}'].map do |f|
59
+ f[(@configuration.destination_path.length + 1)..f.length]
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,25 @@
1
+
2
+ module Usmu
3
+ module Deployment
4
+ module RemoteFileInterface
5
+ # Returns a complete list of files on the remote server.
6
+ #
7
+ # @return [Array<String>] An array of filenames including paths.
8
+ def files_list
9
+ raise NotImplementedError
10
+ end
11
+
12
+ # Returns a hash of information about the named file, including at a minimum the following:
13
+ #
14
+ # * `:mtime` - DateTime representing when the file was last modified.
15
+ # * One of `:md5` or `:sha1` - A hash of the remote file.
16
+ #
17
+ # @param [String] filename The full path and filename as returned from #files_list.
18
+ #
19
+ # @return [Hash]
20
+ def stat(filename)
21
+ raise NotImplementedError
22
+ end
23
+ end
24
+ end
25
+ end
@@ -68,11 +68,15 @@ module Usmu
68
68
 
69
69
  unless @loaded.include? load_path
70
70
  @loaded << load_path
71
- klass = load_path.split('/').map {|s| s.split('_').map(&:capitalize).join }.join('::')
71
+ klass = path_to_class(load_path)
72
72
  @log.debug("Loading plugin #{klass} from '#{load_path}'")
73
73
  plugins.push plugin_get(klass)
74
74
  end
75
75
  nil
76
76
  end
77
+
78
+ def path_to_class(load_path)
79
+ load_path.split('/').map { |s| s.split('_').map(&:capitalize).join }.join('::')
80
+ end
77
81
  end
78
82
  end
@@ -7,6 +7,9 @@ module Usmu
7
7
  module Template
8
8
  # Class to represent files templated with a Tilt library. Most of the custom rendering logic is contained here.
9
9
  class Layout < StaticFile
10
+ @layout_history = Hash.new({})
11
+ @log = Logging.logger[self]
12
+
10
13
  # @!attribute [r] type
11
14
  # @return [String] the type of file this is. This is used to determine which template engine to use.
12
15
  attr_reader :type
@@ -44,7 +47,6 @@ module Usmu
44
47
  end
45
48
  @metadata = metadata
46
49
 
47
- @parent = nil
48
50
  @parent = Layout.find_layout(configuration, self.metadata['layout'])
49
51
 
50
52
  # Don't use the parent if it would result in weirdness
@@ -139,31 +141,18 @@ module Usmu
139
141
  def self.find_layout(configuration, name)
140
142
  return nil if name.nil?
141
143
 
142
- @layout_history = @layout_history || {}
143
- @layout_history[configuration] = @layout_history[configuration] || {}
144
144
  if @layout_history[configuration][name]
145
- Logging.logger[self].debug(
145
+ @log.debug(
146
146
  'Layout loop detected. Current loaded layouts: ' +
147
147
  @layout_history[configuration].inspect
148
148
  )
149
149
  return nil
150
150
  else
151
- Logging.logger[self].debug("Loading layout '#{name}'")
151
+ @log.debug("Loading layout '#{name}'")
152
152
  @layout_history[configuration][name] = true
153
153
  end
154
154
 
155
- ret = nil
156
- if name === 'none' || name.nil?
157
- elsif name.class.name == 'String'
158
- Dir["#{configuration.layouts_path}/#{name}.*"].each do |f|
159
- filename = File.basename(f)
160
- if filename != "#{name}.meta.yml"
161
- ret = new(configuration, f[(configuration.layouts_path.length + 1)..f.length])
162
- end
163
- end
164
- else
165
- ret = name
166
- end
155
+ ret = search_layout(configuration, name)
167
156
 
168
157
  @layout_history[configuration][name] = nil
169
158
  return ret
@@ -252,6 +241,24 @@ module Usmu
252
241
  def get_variables(variables)
253
242
  {'site' => @configuration}.deep_merge!(metadata).deep_merge!(variables)
254
243
  end
244
+
245
+ # @see Usmu::Template::Layout#find_layout
246
+ # @return [Usmu::Template::Layout]
247
+ def self.search_layout(configuration, name)
248
+ if name === 'none' || name.nil?
249
+ return nil
250
+ elsif name.class.name == 'String'
251
+ layouts_path = configuration.layouts_path
252
+ Dir["#{layouts_path}/#{name}.*"].each do |f|
253
+ filename = File.basename(f)
254
+ if filename != "#{name}.meta.yml"
255
+ return new(configuration, f[(layouts_path.length + 1)..f.length])
256
+ end
257
+ end
258
+ else
259
+ return name
260
+ end
261
+ end
255
262
  end
256
263
  end
257
264
  end