nanoc 4.9.4 → 4.9.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/NEWS.md +6 -0
  3. data/lib/nanoc/base/assertions.rb +10 -0
  4. data/lib/nanoc/base/contracts_support.rb +9 -0
  5. data/lib/nanoc/base/core_ext/array.rb +1 -0
  6. data/lib/nanoc/base/core_ext/hash.rb +1 -0
  7. data/lib/nanoc/base/entities/configuration.rb +18 -14
  8. data/lib/nanoc/base/entities/directed_graph.rb +1 -0
  9. data/lib/nanoc/base/entities/identifier.rb +1 -0
  10. data/lib/nanoc/base/entities/item_rep.rb +1 -1
  11. data/lib/nanoc/base/entities/site.rb +1 -0
  12. data/lib/nanoc/base/repos/config_loader.rb +5 -2
  13. data/lib/nanoc/base/repos/site_loader.rb +0 -8
  14. data/lib/nanoc/base/repos/store.rb +6 -2
  15. data/lib/nanoc/base/services/checksummer.rb +6 -5
  16. data/lib/nanoc/base/services/compilation_context.rb +1 -0
  17. data/lib/nanoc/base/services/executor.rb +1 -0
  18. data/lib/nanoc/base/services/filter.rb +1 -0
  19. data/lib/nanoc/base/services/item_rep_router.rb +1 -1
  20. data/lib/nanoc/base/services/item_rep_writer.rb +6 -0
  21. data/lib/nanoc/base/services/pruner.rb +5 -4
  22. data/lib/nanoc/base/views/basic_item_rep_view.rb +1 -0
  23. data/lib/nanoc/base/views/config_view.rb +5 -0
  24. data/lib/nanoc/checking/check.rb +8 -1
  25. data/lib/nanoc/checking/checks/internal_links.rb +5 -2
  26. data/lib/nanoc/checking/checks/mixed_content.rb +1 -0
  27. data/lib/nanoc/checking/checks/w3c_validator.rb +1 -1
  28. data/lib/nanoc/checking/runner.rb +2 -0
  29. data/lib/nanoc/cli.rb +10 -14
  30. data/lib/nanoc/cli/command_runner.rb +2 -0
  31. data/lib/nanoc/cli/commands/compile_listeners/aggregate.rb +1 -0
  32. data/lib/nanoc/cli/commands/compile_listeners/diff_generator.rb +6 -0
  33. data/lib/nanoc/cli/commands/compile_listeners/file_action_printer.rb +6 -0
  34. data/lib/nanoc/cli/commands/deploy.rb +1 -1
  35. data/lib/nanoc/cli/commands/view.rb +2 -2
  36. data/lib/nanoc/cli/error_handler.rb +1 -0
  37. data/lib/nanoc/data_sources/filesystem.rb +1 -0
  38. data/lib/nanoc/data_sources/filesystem/parser.rb +1 -0
  39. data/lib/nanoc/filters/colorize_syntax.rb +1 -0
  40. data/lib/nanoc/filters/less.rb +1 -0
  41. data/lib/nanoc/helpers/link_to.rb +2 -0
  42. data/lib/nanoc/helpers/rendering.rb +1 -0
  43. data/lib/nanoc/spec.rb +1 -1
  44. data/lib/nanoc/version.rb +1 -1
  45. metadata +4 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c20cba14ea42f548aa3d9b8d04673dfb71caeaf66196aa9ca23d7a48548ab55d
4
- data.tar.gz: bdfec8da51cf47946e97dc3121027c3519ef5e735ad744c5dea93237e8366f3a
3
+ metadata.gz: f224f071cecc273a23f6d961d106991618d769889c3eef050ef9d7fd3f9381de
4
+ data.tar.gz: 4759d9512e3262e94e4ded8025362d7722d3b2ad1eab03228754a0c2c7b56479
5
5
  SHA512:
6
- metadata.gz: 59c881e40b1e5fbb07888cc80cce9f7d994d0b3869b8e03b5d8e8f21cd9f1272f594250345ad1ed0fb10b9926b3098672cb62e6e759e4979bcc79e1ef4f55b27
7
- data.tar.gz: e6ce2fa2784b0c942690eeeb7c564fed7ae8a15924a4737fe9b84a519e71e8551c877ca476bceb463b2c6137352976e46d4a378aa21199a6dfe8ed0453fad779
6
+ metadata.gz: 176c04992e95e48e76c85ada608de2d526471749302dc0c6474467e1f340374db6b227501b07d65851e80f7641ac92ebb29526b6f652fbaf5289fb14e994bf45
7
+ data.tar.gz: 9836c7964b3567b6d17c9366c20fde2ecb73f2e0d01a48a29fd2d88182b8ae777b2a89e37fce45f01694bdcf040a245a0b543c9929eb981bf7ef5c6a0e30b443
data/NEWS.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Nanoc news
2
2
 
3
+ ## 4.9.5 (2018-09-15)
4
+
5
+ Fixes:
6
+
7
+ * Fixed an issue which would cause Nanoc to trip up when the working directory changes during compilation (#1338, #1353, #1354, #1357)
8
+
3
9
  ## 4.9.4 (2018-08-19)
4
10
 
5
11
  Fixes:
@@ -33,5 +33,15 @@ module Nanoc
33
33
  end
34
34
  end
35
35
  end
36
+
37
+ class PathIsAbsolute < Nanoc::Assertions::Base
38
+ def initialize(path:)
39
+ @path = path
40
+ end
41
+
42
+ def call
43
+ Pathname.new(@path).absolute?
44
+ end
45
+ end
36
46
  end
37
47
  end
@@ -31,6 +31,7 @@ module Nanoc::Int
31
31
  Named = Ignorer.instance
32
32
  IterOf = Ignorer.instance
33
33
  HashOf = Ignorer.instance
34
+ AbsolutePathString = Ignorer.instance
34
35
 
35
36
  def contract(*args); end
36
37
  end
@@ -70,6 +71,12 @@ module Nanoc::Int
70
71
  end
71
72
  end
72
73
 
74
+ class AbsolutePathString < AbstractContract
75
+ def self.valid?(val)
76
+ val.is_a?(String) && Pathname.new(val).absolute?
77
+ end
78
+ end
79
+
73
80
  def contract(*args)
74
81
  Contract(*args)
75
82
  end
@@ -78,6 +85,7 @@ module Nanoc::Int
78
85
  def self.setup_once
79
86
  @_contracts_support__setup ||= false
80
87
  return @_contracts_support__should_enable if @_contracts_support__setup
88
+
81
89
  @_contracts_support__setup = true
82
90
 
83
91
  contracts_loadable =
@@ -94,6 +102,7 @@ module Nanoc::Int
94
102
  # FIXME: ugly
95
103
  ::Contracts.const_set('Named', EnabledContracts::Named)
96
104
  ::Contracts.const_set('IterOf', EnabledContracts::IterOf)
105
+ ::Contracts.const_set('AbsolutePathString', EnabledContracts::AbsolutePathString)
97
106
  end
98
107
 
99
108
  @_contracts_support__should_enable
@@ -24,6 +24,7 @@ module Nanoc::ArrayExtensions
24
24
  # @return [void]
25
25
  def __nanoc_freeze_recursively
26
26
  return if frozen?
27
+
27
28
  freeze
28
29
  each do |value|
29
30
  if value.respond_to?(:__nanoc_freeze_recursively)
@@ -26,6 +26,7 @@ module Nanoc::HashExtensions
26
26
  # @return [void]
27
27
  def __nanoc_freeze_recursively
28
28
  return if frozen?
29
+
29
30
  freeze
30
31
  each_pair do |_key, value|
31
32
  if value.respond_to?(:__nanoc_freeze_recursively)
@@ -39,19 +39,19 @@ module Nanoc::Int
39
39
  # @return [String, nil] The active environment for the configuration
40
40
  attr_reader :env_name
41
41
 
42
+ contract C::None => C::AbsolutePathString
43
+ attr_reader :dir
44
+
42
45
  # Configuration environments property key
43
46
  ENVIRONMENTS_CONFIG_KEY = :environments
44
47
  NANOC_ENV = 'NANOC_ENV'
45
48
  NANOC_ENV_DEFAULT = 'default'
46
49
 
47
- contract C::KeywordArgs[hash: C::Optional[Hash], env_name: C::Maybe[String]] => C::Any
48
- # Creates a new configuration with the given hash.
49
- #
50
- # @param [Hash] hash The actual configuration hash
51
- # @param [String, nil] env_name The active environment for this configuration
52
- def initialize(hash: {}, env_name: nil)
50
+ contract C::KeywordArgs[hash: C::Optional[Hash], env_name: C::Maybe[String], dir: C::AbsolutePathString] => C::Any
51
+ def initialize(hash: {}, dir:, env_name: nil)
53
52
  @env_name = env_name
54
53
  @wrapped = hash.__nanoc_symbolize_keys_recursively
54
+ @dir = dir
55
55
  end
56
56
 
57
57
  contract C::None => self
@@ -61,7 +61,7 @@ module Nanoc::Int
61
61
  DEFAULT_DATA_SOURCE_CONFIG.merge(ds)
62
62
  end
63
63
 
64
- self.class.new(hash: new_wrapped, env_name: @env_name)
64
+ self.class.new(hash: new_wrapped, dir: @dir, env_name: @env_name)
65
65
  end
66
66
 
67
67
  def with_environment
@@ -73,7 +73,7 @@ module Nanoc::Int
73
73
  # Load given environment configuration
74
74
  env_config = @wrapped[ENVIRONMENTS_CONFIG_KEY].fetch(env_name.to_sym, {})
75
75
 
76
- self.class.new(hash: @wrapped, env_name: env_name).merge(env_config)
76
+ self.class.new(hash: @wrapped, dir: @dir, env_name: env_name).merge(env_config)
77
77
  end
78
78
 
79
79
  contract C::None => Hash
@@ -122,12 +122,12 @@ module Nanoc::Int
122
122
 
123
123
  contract C::Or[Hash, self] => self
124
124
  def merge(hash)
125
- self.class.new(hash: merge_recursively(@wrapped, hash.to_h), env_name: @env_name)
125
+ self.class.new(hash: merge_recursively(@wrapped, hash.to_h), dir: @dir, env_name: @env_name)
126
126
  end
127
127
 
128
128
  contract C::Any => self
129
129
  def without(key)
130
- self.class.new(hash: @wrapped.reject { |k, _v| k == key }, env_name: @env_name)
130
+ self.class.new(hash: @wrapped.reject { |k, _v| k == key }, dir: @dir, env_name: @env_name)
131
131
  end
132
132
 
133
133
  contract C::Any => self
@@ -149,9 +149,9 @@ module Nanoc::Int
149
149
  self
150
150
  end
151
151
 
152
- contract C::None => String
152
+ contract C::None => C::AbsolutePathString
153
153
  def output_dir
154
- self[:output_dir]
154
+ make_absolute(self[:output_dir]).freeze
155
155
  end
156
156
 
157
157
  contract C::None => Symbol
@@ -159,10 +159,10 @@ module Nanoc::Int
159
159
  self[:action_provider].to_sym
160
160
  end
161
161
 
162
- contract C::None => C::IterOf[String]
162
+ contract C::None => C::IterOf[C::AbsolutePathString]
163
163
  def output_dirs
164
164
  envs = @wrapped.fetch(ENVIRONMENTS_CONFIG_KEY, {})
165
- res = [output_dir] + envs.values.map { |v| v[:output_dir] }
165
+ res = [output_dir] + envs.values.map { |v| make_absolute(v[:output_dir]) }
166
166
  res.uniq.compact
167
167
  end
168
168
 
@@ -179,6 +179,10 @@ module Nanoc::Int
179
179
 
180
180
  private
181
181
 
182
+ def make_absolute(path)
183
+ path && @dir && File.absolute_path(path, @dir).encode('UTF-8')
184
+ end
185
+
182
186
  def merge_recursively(config1, config2)
183
187
  config1.merge(config2) do |_, value1, value2|
184
188
  if value1.is_a?(Hash) && value2.is_a?(Hash)
@@ -179,6 +179,7 @@ module Nanoc::Int
179
179
  # Get next unprocessed vertex
180
180
  vertex = unprocessed_vertices.pop
181
181
  next if processed_vertices.include?(vertex)
182
+
182
183
  processed_vertices << vertex
183
184
 
184
185
  # Add predecessors of this vertex
@@ -141,6 +141,7 @@ module Nanoc
141
141
  if string !~ /\A\//
142
142
  raise InvalidPrefixError.new(string)
143
143
  end
144
+
144
145
  Nanoc::Identifier.new(string.sub(/\/+\z/, '') + @string, type: @type)
145
146
  end
146
147
 
@@ -44,7 +44,7 @@ module Nanoc::Int
44
44
  @modified = false
45
45
  end
46
46
 
47
- contract C::HashOf[Symbol => C::IterOf[String]] => C::HashOf[Symbol => C::IterOf[String]]
47
+ contract C::HashOf[Symbol => C::IterOf[C::AbsolutePathString]] => C::HashOf[Symbol => C::IterOf[C::AbsolutePathString]]
48
48
  def raw_paths=(val)
49
49
  @raw_paths = val
50
50
  end
@@ -59,6 +59,7 @@ module Nanoc::Int
59
59
  if seen.include?(obj.identifier)
60
60
  raise Nanoc::Int::Errors::DuplicateIdentifier.new(obj.identifier, type)
61
61
  end
62
+
62
63
  seen << obj.identifier
63
64
  end
64
65
  self
@@ -46,7 +46,10 @@ module Nanoc::Int
46
46
  # Read
47
47
  config =
48
48
  apply_parent_config(
49
- Nanoc::Int::Configuration.new(hash: load_file(filename)),
49
+ Nanoc::Int::Configuration.new(
50
+ hash: load_file(filename),
51
+ dir: File.dirname(filename),
52
+ ),
50
53
  [filename],
51
54
  ).with_defaults
52
55
 
@@ -82,7 +85,7 @@ module Nanoc::Int
82
85
  end
83
86
 
84
87
  # Load
85
- parent_config = Nanoc::Int::Configuration.new(hash: load_file(parent_path))
88
+ parent_config = Nanoc::Int::Configuration.new(hash: load_file(parent_path), dir: config.dir)
86
89
  full_parent_config = apply_parent_config(parent_config, processed_paths + [parent_path])
87
90
  full_parent_config.merge(config.without(:parent_config_file))
88
91
  end
@@ -2,14 +2,6 @@
2
2
 
3
3
  module Nanoc::Int
4
4
  class SiteLoader
5
- def new_empty
6
- site_from_config(Nanoc::Int::Configuration.new.with_defaults)
7
- end
8
-
9
- def new_with_config(hash)
10
- site_from_config(Nanoc::Int::Configuration.new(hash: hash).with_defaults)
11
- end
12
-
13
5
  def new_from_cwd
14
6
  site_from_config(Nanoc::Int::ConfigLoader.new.new_from_cwd)
15
7
  end
@@ -40,9 +40,12 @@ module Nanoc::Int
40
40
 
41
41
  # Logic for building tmp path from active environment and store name
42
42
  # @api private
43
- contract C::KeywordArgs[config: Nanoc::Int::Configuration, store_name: String] => String
43
+ contract C::KeywordArgs[config: Nanoc::Int::Configuration, store_name: String] => C::AbsolutePathString
44
44
  def self.tmp_path_for(store_name:, config:)
45
- File.join(tmp_path_prefix(config.output_dir), store_name)
45
+ File.absolute_path(
46
+ File.join(tmp_path_prefix(config.output_dir), store_name),
47
+ config.dir,
48
+ )
46
49
  end
47
50
 
48
51
  def self.tmp_path_prefix(output_dir)
@@ -78,6 +81,7 @@ module Nanoc::Int
78
81
  begin
79
82
  pstore.transaction do
80
83
  return if pstore[:version] != version
84
+
81
85
  self.data = pstore[:data]
82
86
  end
83
87
  rescue
@@ -260,11 +260,12 @@ module Nanoc::Int
260
260
  return
261
261
  end
262
262
 
263
- data = begin
264
- Marshal.dump(obj)
265
- rescue
266
- obj.inspect
267
- end
263
+ data =
264
+ begin
265
+ Marshal.dump(obj)
266
+ rescue
267
+ obj.inspect
268
+ end
268
269
 
269
270
  digest.update(data)
270
271
  end
@@ -19,6 +19,7 @@ module Nanoc::Int
19
19
  if seq.nil? || seq.size != 1 || !seq[0].is_a?(Nanoc::Int::ProcessingActions::Filter)
20
20
  raise Nanoc::Int::Errors::UndefinedFilterForLayout.new(layout)
21
21
  end
22
+
22
23
  [seq[0].filter_name, seq[0].params]
23
24
  end
24
25
 
@@ -40,6 +40,7 @@ module Nanoc
40
40
  if filter_name.nil?
41
41
  raise Nanoc::Int::Errors::Generic, "Cannot find rule for layout matching #{layout_identifier}"
42
42
  end
43
+
43
44
  filter_args = filter_args.merge(extra_filter_args || {})
44
45
  filter_args.freeze
45
46
 
@@ -42,6 +42,7 @@ module Nanoc
42
42
  def named!(name)
43
43
  klass = named(name)
44
44
  raise Nanoc::Int::Errors::UnknownFilter.new(name) if klass.nil?
45
+
45
46
  klass
46
47
  end
47
48
 
@@ -75,7 +75,7 @@ module Nanoc::Int
75
75
 
76
76
  # Assign
77
77
  snapshot_names.each do |snapshot_name|
78
- rep.raw_paths[snapshot_name] = paths.map { |path| @site.config[:output_dir] + path }
78
+ rep.raw_paths[snapshot_name] = paths.map { |path| @site.config.output_dir + path }
79
79
  rep.paths[snapshot_name] = paths.map { |path| strip_index_filename(path) }
80
80
  end
81
81
  end
@@ -3,6 +3,9 @@
3
3
  module Nanoc::Int
4
4
  # @api private
5
5
  class ItemRepWriter
6
+ include Nanoc::Int::ContractsSupport
7
+ include Nanoc::Assertions::Mixin
8
+
6
9
  TMP_TEXT_ITEMS_DIR = 'text_items'
7
10
 
8
11
  def write_all(item_rep, snapshot_repo)
@@ -20,9 +23,12 @@ module Nanoc::Int
20
23
  end
21
24
 
22
25
  def write_single(item_rep, snapshot_repo, snapshot_name, raw_path, written_paths)
26
+ assert Nanoc::Assertions::PathIsAbsolute.new(path: raw_path)
27
+
23
28
  # Don’t write twice
24
29
  # TODO: test written_paths behavior
25
30
  return if written_paths.include?(raw_path)
31
+
26
32
  written_paths << raw_path
27
33
 
28
34
  # Create parent directory
@@ -25,10 +25,10 @@ module Nanoc
25
25
  end
26
26
 
27
27
  def run
28
- return unless File.directory?(@config[:output_dir])
28
+ return unless File.directory?(@config.output_dir)
29
29
 
30
30
  compiled_files = @reps.flat_map { |r| r.raw_paths.values.flatten }.compact
31
- present_files, present_dirs = files_and_dirs_in(@config[:output_dir] + '/')
31
+ present_files, present_dirs = files_and_dirs_in(@config.output_dir + '/')
32
32
 
33
33
  remove_stray_files(present_files, compiled_files)
34
34
  remove_empty_directories(present_dirs)
@@ -42,8 +42,8 @@ module Nanoc
42
42
 
43
43
  contract String => String
44
44
  def strip_output_dir(filename)
45
- if filename.start_with?(@config[:output_dir])
46
- filename[@config[:output_dir].size..-1]
45
+ if filename.start_with?(@config.output_dir)
46
+ filename[@config.output_dir.size..-1]
47
47
  else
48
48
  filename
49
49
  end
@@ -77,6 +77,7 @@ module Nanoc
77
77
  present_dirs.reverse_each do |dir|
78
78
  next if Dir.foreach(dir) { |n| break true if n !~ /\A\.\.?\z/ }
79
79
  next if filename_excluded?(dir)
80
+
80
81
  delete_dir(dir)
81
82
  end
82
83
  self
@@ -70,6 +70,7 @@ module Nanoc
70
70
  def binary?
71
71
  snapshot_def = _unwrap.snapshot_defs.find { |sd| sd.name == :last }
72
72
  raise Nanoc::Int::Errors::NoSuchSnapshot.new(_unwrap, :last) if snapshot_def.nil?
73
+
73
74
  snapshot_def.binary?
74
75
  end
75
76
 
@@ -16,6 +16,11 @@ module Nanoc
16
16
  @config
17
17
  end
18
18
 
19
+ # @api private
20
+ def output_dir
21
+ @config.output_dir
22
+ end
23
+
19
24
  # @see Hash#fetch
20
25
  def fetch(key, fallback = NONE, &_block)
21
26
  @context.dependency_tracker.bounce(_unwrap, attributes: [key])
@@ -22,10 +22,11 @@ module Nanoc::Checking
22
22
  end
23
23
 
24
24
  def self.create(site)
25
- output_dir = site.config[:output_dir]
25
+ output_dir = site.config.output_dir
26
26
  unless File.exist?(output_dir)
27
27
  raise Nanoc::Checking::OutputDirNotFoundError.new(output_dir)
28
28
  end
29
+
29
30
  output_filenames = Dir[output_dir + '/**/*'].select { |f| File.file?(f) }
30
31
 
31
32
  # FIXME: ugly
@@ -56,6 +57,12 @@ module Nanoc::Checking
56
57
  end
57
58
 
58
59
  def add_issue(desc, subject: nil)
60
+ # Simplify subject
61
+ # FIXME: do not depend on working directory
62
+ if subject&.start_with?(Dir.getwd)
63
+ subject = subject[(Dir.getwd.size + 1)..subject.size]
64
+ end
65
+
59
66
  @issues << Issue.new(desc, subject, self.class)
60
67
  end
61
68
 
@@ -56,7 +56,7 @@ module Nanoc::Checking::Checks
56
56
  # Make absolute
57
57
  path =
58
58
  if path[0, 1] == '/'
59
- @config[:output_dir] + path
59
+ @config.output_dir + path
60
60
  else
61
61
  ::File.expand_path(path, ::File.dirname(origin))
62
62
  end
@@ -82,7 +82,10 @@ module Nanoc::Checking::Checks
82
82
  end
83
83
 
84
84
  def excluded_origin?(origin, config)
85
- relative_origin = origin[@config[:output_dir].size..-1]
85
+ # FIXME: do not depend on current working directory
86
+ origin = File.absolute_path(origin)
87
+
88
+ relative_origin = origin[@config.output_dir.size..-1]
86
89
  excludes = config.fetch(:exclude_origins, [])
87
90
  excludes.any? { |pattern| Regexp.new(pattern).match(relative_origin) }
88
91
  end
@@ -16,6 +16,7 @@ module Nanoc::Checking::Checks
16
16
 
17
17
  resource_uris_with_filenames.each_pair do |uri, fns|
18
18
  next unless guaranteed_insecure?(uri)
19
+
19
20
  fns.each do |filename|
20
21
  add_issue(
21
22
  "mixed content include: #{uri}",
@@ -7,7 +7,7 @@ module ::Nanoc::Checking::Checks
7
7
  require 'w3c_validators'
8
8
  require 'resolv-replace'
9
9
 
10
- Dir[@config[:output_dir] + '/**/*.' + extension].each do |filename|
10
+ Dir[@config.output_dir + '/**/*.' + extension].each do |filename|
11
11
  results = validator_class.new.validate_file(filename)
12
12
  lines = File.readlines(filename)
13
13
  results.errors.each do |e|
@@ -81,6 +81,7 @@ module Nanoc::Checking
81
81
  name = name.to_s.tr('-', '_').to_sym
82
82
  klass = Nanoc::Checking::Check.named(name)
83
83
  raise Nanoc::Int::Errors::GenericTrivial, "Unknown check: #{name}" if klass.nil?
84
+
84
85
  klass
85
86
  end
86
87
  end
@@ -118,6 +119,7 @@ module Nanoc::Checking
118
119
  require 'colored'
119
120
 
120
121
  return if issues.empty?
122
+
121
123
  puts 'Issues found!'
122
124
  issues.group_by(&:subject).to_a.sort_by { |s| subject_to_s(s.first) }.each do |pair|
123
125
  subject = pair.first
@@ -106,7 +106,7 @@ module Nanoc::CLI
106
106
 
107
107
  # Add root command
108
108
  filename = __dir__ + '/cli/commands/nanoc.rb'
109
- @root_command = load_command_at(filename)
109
+ @root_command = Cri::Command.load_file(filename, infer_name: true)
110
110
 
111
111
  # Add help command
112
112
  help_cmd = Cri::Command.new_basic_help
@@ -119,7 +119,7 @@ module Nanoc::CLI
119
119
 
120
120
  next if basename == 'nanoc'
121
121
 
122
- cmd = load_command_at(cmd_filename)
122
+ cmd = Cri::Command.load_file(cmd_filename, infer_name: true)
123
123
  add_command(cmd)
124
124
  end
125
125
 
@@ -150,7 +150,7 @@ module Nanoc::CLI
150
150
  def self.load_commands_at(path)
151
151
  recursive_contents_of(path).each do |filename|
152
152
  # Create command
153
- command = Nanoc::CLI.load_command_at(filename)
153
+ command = Cri::Command.load_file(filename, infer_name: true)
154
154
 
155
155
  # Get supercommand
156
156
  pieces = filename.gsub(/^#{path}\/|\.rb$/, '').split('/')
@@ -164,6 +164,7 @@ module Nanoc::CLI
164
164
  if supercommand.nil?
165
165
  raise "Cannot load command at #{filename} because its supercommand cannot be found"
166
166
  end
167
+
167
168
  supercommand.add_command(command)
168
169
  end
169
170
  end
@@ -173,22 +174,17 @@ module Nanoc::CLI
173
174
  # @param [String] filename The name of the file that contains the command
174
175
  #
175
176
  # @return [Cri::Command] The loaded command
176
- def self.load_command_at(filename, command_name = nil)
177
- # Load
178
- code = File.read(filename, encoding: 'UTF-8')
179
- cmd = Cri::Command.define(code, filename)
180
-
181
- # Set name
182
- command_name ||= File.basename(filename, '.rb')
183
- cmd.modify { name command_name }
184
-
185
- # Done
186
- cmd
177
+ #
178
+ # @deprecated
179
+ def self.load_command_at(filename)
180
+ # TODO: remove me one guard-nanoc is in this repo
181
+ Cri::Command.load_file(filename, infer_name: true)
187
182
  end
188
183
 
189
184
  # @return [Array] The directory contents
190
185
  def self.recursive_contents_of(path)
191
186
  return [] unless File.directory?(path)
187
+
192
188
  files, dirs = *Dir[path + '/*'].sort.partition { |e| File.file?(e) }
193
189
  dirs.each { |d| files.concat recursive_contents_of(d) }
194
190
  files
@@ -28,6 +28,7 @@ module Nanoc::CLI
28
28
  until Nanoc::Int::SiteLoader.cwd_is_nanoc_site?
29
29
  Dir.chdir('..')
30
30
  return nil if Dir.pwd == here
31
+
31
32
  here = Dir.pwd
32
33
  end
33
34
  here
@@ -42,6 +43,7 @@ module Nanoc::CLI
42
43
  end
43
44
 
44
45
  return if Dir.getwd == dir
46
+
45
47
  $stderr.puts "Using Nanoc site in #{dir}"
46
48
  Dir.chdir(dir)
47
49
  end
@@ -43,6 +43,7 @@ module Nanoc::CLI::Commands::CompileListeners
43
43
 
44
44
  def teardown_listeners
45
45
  return unless @listeners
46
+
46
47
  @listeners.reverse_each(&:stop_safely)
47
48
  end
48
49
  end
@@ -51,6 +51,12 @@ module Nanoc::CLI::Commands::CompileListeners
51
51
  return if old_content == new_content
52
52
 
53
53
  @diff_threads << Thread.new do
54
+ # Simplify path
55
+ # FIXME: do not depend on working directory
56
+ if path.start_with?(Dir.getwd)
57
+ path = path[(Dir.getwd.size + 1)..path.size]
58
+ end
59
+
54
60
  # Generate diff
55
61
  diff = diff_strings(old_content, new_content)
56
62
  diff.sub!(/^--- .*/, '--- ' + path)
@@ -48,6 +48,12 @@ module Nanoc::CLI::Commands::CompileListeners
48
48
  elsif is_modified then :high
49
49
  else :low
50
50
  end
51
+
52
+ # FIXME: do not depend on working directory
53
+ if path.start_with?(Dir.getwd)
54
+ path = path[(Dir.getwd.size + 1)..path.size]
55
+ end
56
+
51
57
  log(level, action, path, duration)
52
58
  end
53
59
  end
@@ -81,7 +81,7 @@ module Nanoc::CLI::Commands
81
81
 
82
82
  def deployer_for(config)
83
83
  deployer_class_for_config(config).new(
84
- @site.config[:output_dir],
84
+ @site.config.output_dir,
85
85
  config,
86
86
  dry_run: options[:'dry-run'],
87
87
  )
@@ -24,11 +24,11 @@ module Nanoc::CLI::Commands
24
24
  config = Nanoc::Int::ConfigLoader.new.new_from_cwd
25
25
 
26
26
  # Create output dir so that viewer/watcher doesn’t explode.
27
- FileUtils.mkdir_p(config[:output_dir])
27
+ FileUtils.mkdir_p(config.output_dir)
28
28
 
29
29
  server =
30
30
  Adsf::Server.new(
31
- root: File.absolute_path(config[:output_dir]),
31
+ root: File.absolute_path(config.output_dir),
32
32
  live: options[:'live-reload'],
33
33
  index_filenames: config[:index_filenames],
34
34
  host: options.fetch(:host),
@@ -260,6 +260,7 @@ module Nanoc::CLI
260
260
  def gem_name_from_load_error(error)
261
261
  matches = error.message.match(/(no such file to load|cannot load such file) -- ([^\s]+)/)
262
262
  return nil if matches.nil?
263
+
263
264
  GEM_NAMES[matches[2]]
264
265
  end
265
266
 
@@ -287,6 +287,7 @@ module Nanoc::DataSources
287
287
  unless [0, 1].include?(meta_filenames.size)
288
288
  raise Errors::MultipleMetaFiles.new(meta_filenames, basename)
289
289
  end
290
+
290
291
  unless config[:identifier_type] == 'full'
291
292
  unless [0, 1].include?(content_filenames.size)
292
293
  raise Errors::MultipleContentFiles.new(meta_filenames, basename)
@@ -72,6 +72,7 @@ class Nanoc::DataSources::Filesystem
72
72
 
73
73
  def verify_meta(meta, filename)
74
74
  return if meta.is_a?(Hash)
75
+
75
76
  raise Errors::InvalidMetadata.new(filename, meta.class)
76
77
  end
77
78
  end
@@ -141,6 +141,7 @@ module Nanoc::Filters
141
141
  unless colorizer
142
142
  raise "I don’t know how to highlight code using the “#{name}” colorizer"
143
143
  end
144
+
144
145
  colorizer
145
146
  end
146
147
 
@@ -49,6 +49,7 @@ module Nanoc::Filters
49
49
  # Find matching item
50
50
  @items.find do |i|
51
51
  next if i[:content_filename].nil?
52
+
52
53
  item_path = Pathname.new(i[:content_filename]).realpath
53
54
  full_paths.any? { |fp| fp == item_path }
54
55
  end
@@ -19,6 +19,7 @@ module Nanoc::Helpers
19
19
  target
20
20
  when Nanoc::CompilationItemView, Nanoc::BasicItemView, Nanoc::BasicItemRepView
21
21
  raise "Cannot create a link to #{target.inspect} because this target is not outputted (its routing rule returns nil)" if target.path.nil?
22
+
22
23
  target.path
23
24
  else
24
25
  raise ArgumentError, "Cannot link to #{target.inspect} (expected a string or an item, not a #{target.class.name})"
@@ -74,6 +75,7 @@ module Nanoc::Helpers
74
75
  # TODO: get proper error
75
76
  raise "Cannot get the relative path to #{path} because the current item representation, #{@item_rep.inspect}, is not outputted (its routing rule returns nil)"
76
77
  end
78
+
77
79
  src_path = Pathname.new(@item_rep.path)
78
80
 
79
81
  # Calculate the relative path (method depends on whether destination is
@@ -18,6 +18,7 @@ module Nanoc::Helpers
18
18
  layout_view = @layouts[identifier]
19
19
  layout_view ||= @layouts[identifier.__nanoc_cleaned_identifier]
20
20
  raise Nanoc::Int::Errors::UnknownLayout.new(identifier) if layout_view.nil?
21
+
21
22
  layout = layout_view._unwrap
22
23
 
23
24
  # Visit
@@ -58,7 +58,7 @@ module Nanoc
58
58
 
59
59
  @erbout = +''
60
60
  @action_sequence = {}
61
- @config = Nanoc::Int::Configuration.new.with_defaults
61
+ @config = Nanoc::Int::Configuration.new(dir: Dir.getwd).with_defaults
62
62
  @reps = Nanoc::Int::ItemRepRepo.new
63
63
  @items = Nanoc::Int::ItemCollection.new(@config)
64
64
  @layouts = Nanoc::Int::LayoutCollection.new(@config)
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Nanoc
4
4
  # The current Nanoc version.
5
- VERSION = '4.9.4'
5
+ VERSION = '4.9.5'
6
6
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nanoc
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.9.4
4
+ version: 4.9.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Denis Defreyne
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-08-19 00:00:00.000000000 Z
11
+ date: 2018-09-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '2.13'
33
+ version: '2.15'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '2.13'
40
+ version: '2.15'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: ddmemoize
43
43
  requirement: !ruby/object:Gem::Requirement