nanoc 4.11.12 → 4.11.17

Sign up to get free protection for your applications and to get access to all the features.
Files changed (153) hide show
  1. checksums.yaml +4 -4
  2. data/NEWS.md +788 -743
  3. data/bin/nanoc +1 -1
  4. data/lib/nanoc.rb +6 -29
  5. data/lib/nanoc/data_sources/filesystem.rb +9 -3
  6. data/lib/nanoc/data_sources/filesystem/tools.rb +4 -4
  7. data/lib/nanoc/extra.rb +2 -1
  8. data/lib/nanoc/extra/core_ext.rb +0 -1
  9. data/lib/nanoc/extra/srcset_parser.rb +79 -0
  10. data/lib/nanoc/filters/colorize_syntax/colorizers.rb +1 -1
  11. data/lib/nanoc/filters/erb.rb +1 -5
  12. data/lib/nanoc/filters/relativize_paths.rb +62 -10
  13. data/lib/nanoc/filters/sass/functions.rb +1 -1
  14. data/lib/nanoc/helpers/blogging.rb +8 -8
  15. data/lib/nanoc/helpers/capturing.rb +1 -1
  16. data/lib/nanoc/helpers/link_to.rb +1 -1
  17. data/lib/nanoc/helpers/rendering.rb +5 -4
  18. data/lib/nanoc/orig_cli.rb +15 -0
  19. data/lib/nanoc/{cli → orig_cli}/commands/show-rules.rb +3 -3
  20. data/lib/nanoc/rule_dsl.rb +1 -0
  21. data/lib/nanoc/rule_dsl/action_provider.rb +6 -6
  22. data/lib/nanoc/rule_dsl/action_recorder.rb +4 -4
  23. data/lib/nanoc/rule_dsl/compilation_rule_context.rb +1 -1
  24. data/lib/nanoc/rule_dsl/compiler_dsl.rb +2 -2
  25. data/lib/nanoc/rule_dsl/errors.rb +25 -0
  26. data/lib/nanoc/rule_dsl/rule_context.rb +6 -6
  27. data/lib/nanoc/rule_dsl/rules_loader.rb +1 -1
  28. data/lib/nanoc/version.rb +1 -1
  29. metadata +23 -158
  30. data/lib/nanoc/base.rb +0 -16
  31. data/lib/nanoc/base/changes_stream.rb +0 -53
  32. data/lib/nanoc/base/error.rb +0 -7
  33. data/lib/nanoc/base/errors.rb +0 -163
  34. data/lib/nanoc/base/feature.rb +0 -104
  35. data/lib/nanoc/base/repos.rb +0 -4
  36. data/lib/nanoc/base/repos/config_loader.rb +0 -95
  37. data/lib/nanoc/base/repos/site_loader.rb +0 -102
  38. data/lib/nanoc/base/services.rb +0 -23
  39. data/lib/nanoc/base/services/compiler.rb +0 -214
  40. data/lib/nanoc/base/services/compiler/phases.rb +0 -19
  41. data/lib/nanoc/base/services/compiler/phases/abstract.rb +0 -50
  42. data/lib/nanoc/base/services/compiler/phases/cache.rb +0 -45
  43. data/lib/nanoc/base/services/compiler/phases/mark_done.rb +0 -25
  44. data/lib/nanoc/base/services/compiler/phases/notify.rb +0 -21
  45. data/lib/nanoc/base/services/compiler/phases/recalculate.rb +0 -51
  46. data/lib/nanoc/base/services/compiler/phases/resume.rb +0 -54
  47. data/lib/nanoc/base/services/compiler/phases/write.rb +0 -86
  48. data/lib/nanoc/base/services/compiler/stages.rb +0 -23
  49. data/lib/nanoc/base/services/compiler/stages/build_reps.rb +0 -38
  50. data/lib/nanoc/base/services/compiler/stages/calculate_checksums.rb +0 -44
  51. data/lib/nanoc/base/services/compiler/stages/cleanup.rb +0 -45
  52. data/lib/nanoc/base/services/compiler/stages/compile_reps.rb +0 -98
  53. data/lib/nanoc/base/services/compiler/stages/determine_outdatedness.rb +0 -51
  54. data/lib/nanoc/base/services/compiler/stages/forget_outdated_dependencies.rb +0 -22
  55. data/lib/nanoc/base/services/compiler/stages/load_stores.rb +0 -37
  56. data/lib/nanoc/base/services/compiler/stages/postprocess.rb +0 -23
  57. data/lib/nanoc/base/services/compiler/stages/preprocess.rb +0 -34
  58. data/lib/nanoc/base/services/compiler/stages/prune.rb +0 -32
  59. data/lib/nanoc/base/services/compiler/stages/store_post_compilation_state.rb +0 -22
  60. data/lib/nanoc/base/services/compiler/stages/store_pre_compilation_state.rb +0 -34
  61. data/lib/nanoc/base/services/compiler_loader.rb +0 -48
  62. data/lib/nanoc/base/services/executor.rb +0 -134
  63. data/lib/nanoc/base/services/filter.rb +0 -267
  64. data/lib/nanoc/base/services/item_rep_builder.rb +0 -54
  65. data/lib/nanoc/base/services/item_rep_selector.rb +0 -69
  66. data/lib/nanoc/base/services/item_rep_writer.rb +0 -86
  67. data/lib/nanoc/base/services/outdatedness_checker.rb +0 -222
  68. data/lib/nanoc/base/services/outdatedness_rules.rb +0 -18
  69. data/lib/nanoc/base/services/outdatedness_rules/attributes_modified.rb +0 -41
  70. data/lib/nanoc/base/services/outdatedness_rules/code_snippets_modified.rb +0 -31
  71. data/lib/nanoc/base/services/outdatedness_rules/content_modified.rb +0 -21
  72. data/lib/nanoc/base/services/outdatedness_rules/item_collection_extended.rb +0 -20
  73. data/lib/nanoc/base/services/outdatedness_rules/layout_collection_extended.rb +0 -20
  74. data/lib/nanoc/base/services/outdatedness_rules/not_written.rb +0 -17
  75. data/lib/nanoc/base/services/outdatedness_rules/rules_modified.rb +0 -45
  76. data/lib/nanoc/base/services/outdatedness_rules/uses_always_outdated_filter.rb +0 -26
  77. data/lib/nanoc/base/services/pruner.rb +0 -123
  78. data/lib/nanoc/base/views.rb +0 -40
  79. data/lib/nanoc/base/views/basic_item_rep_collection_view.rb +0 -86
  80. data/lib/nanoc/base/views/basic_item_rep_view.rb +0 -81
  81. data/lib/nanoc/base/views/basic_item_view.rb +0 -52
  82. data/lib/nanoc/base/views/compilation_item_rep_collection_view.rb +0 -10
  83. data/lib/nanoc/base/views/compilation_item_rep_view.rb +0 -49
  84. data/lib/nanoc/base/views/compilation_item_view.rb +0 -45
  85. data/lib/nanoc/base/views/config_view.rb +0 -68
  86. data/lib/nanoc/base/views/identifiable_collection_view.rb +0 -109
  87. data/lib/nanoc/base/views/item_collection_with_reps_view.rb +0 -10
  88. data/lib/nanoc/base/views/item_collection_without_reps_view.rb +0 -10
  89. data/lib/nanoc/base/views/layout_collection_view.rb +0 -10
  90. data/lib/nanoc/base/views/layout_view.rb +0 -7
  91. data/lib/nanoc/base/views/mixins/document_view_mixin.rb +0 -88
  92. data/lib/nanoc/base/views/mixins/mutable_document_view_mixin.rb +0 -58
  93. data/lib/nanoc/base/views/mutable_config_view.rb +0 -14
  94. data/lib/nanoc/base/views/mutable_identifiable_collection_view.rb +0 -17
  95. data/lib/nanoc/base/views/mutable_item_collection_view.rb +0 -32
  96. data/lib/nanoc/base/views/mutable_item_view.rb +0 -7
  97. data/lib/nanoc/base/views/mutable_layout_collection_view.rb +0 -24
  98. data/lib/nanoc/base/views/mutable_layout_view.rb +0 -7
  99. data/lib/nanoc/base/views/post_compile_item_collection_view.rb +0 -10
  100. data/lib/nanoc/base/views/post_compile_item_rep_collection_view.rb +0 -10
  101. data/lib/nanoc/base/views/post_compile_item_rep_view.rb +0 -31
  102. data/lib/nanoc/base/views/post_compile_item_view.rb +0 -18
  103. data/lib/nanoc/base/views/view.rb +0 -41
  104. data/lib/nanoc/checking.rb +0 -14
  105. data/lib/nanoc/checking/check.rb +0 -93
  106. data/lib/nanoc/checking/checks.rb +0 -14
  107. data/lib/nanoc/checking/checks/css.rb +0 -16
  108. data/lib/nanoc/checking/checks/external_links.rb +0 -151
  109. data/lib/nanoc/checking/checks/html.rb +0 -16
  110. data/lib/nanoc/checking/checks/internal_links.rb +0 -95
  111. data/lib/nanoc/checking/checks/mixed_content.rb +0 -37
  112. data/lib/nanoc/checking/checks/stale.rb +0 -41
  113. data/lib/nanoc/checking/checks/w3c_validator.rb +0 -31
  114. data/lib/nanoc/checking/dsl.rb +0 -27
  115. data/lib/nanoc/checking/issue.rb +0 -16
  116. data/lib/nanoc/checking/loader.rb +0 -50
  117. data/lib/nanoc/checking/runner.rb +0 -136
  118. data/lib/nanoc/cli.rb +0 -241
  119. data/lib/nanoc/cli/ansi_string_colorizer.rb +0 -28
  120. data/lib/nanoc/cli/cleaning_stream.rb +0 -160
  121. data/lib/nanoc/cli/command_runner.rb +0 -72
  122. data/lib/nanoc/cli/commands/check.rb +0 -43
  123. data/lib/nanoc/cli/commands/compile.rb +0 -57
  124. data/lib/nanoc/cli/commands/compile_listeners/abstract.rb +0 -58
  125. data/lib/nanoc/cli/commands/compile_listeners/aggregate.rb +0 -50
  126. data/lib/nanoc/cli/commands/compile_listeners/debug_printer.rb +0 -100
  127. data/lib/nanoc/cli/commands/compile_listeners/diff_generator.rb +0 -101
  128. data/lib/nanoc/cli/commands/compile_listeners/file_action_printer.rb +0 -76
  129. data/lib/nanoc/cli/commands/compile_listeners/timing_recorder.rb +0 -170
  130. data/lib/nanoc/cli/commands/create-site.rb +0 -257
  131. data/lib/nanoc/cli/commands/deploy.rb +0 -126
  132. data/lib/nanoc/cli/commands/nanoc.rb +0 -42
  133. data/lib/nanoc/cli/commands/prune.rb +0 -49
  134. data/lib/nanoc/cli/commands/shell.rb +0 -57
  135. data/lib/nanoc/cli/commands/show-data.rb +0 -185
  136. data/lib/nanoc/cli/commands/show-plugins.rb +0 -89
  137. data/lib/nanoc/cli/commands/view.rb +0 -68
  138. data/lib/nanoc/cli/error_handler.rb +0 -365
  139. data/lib/nanoc/cli/logger.rb +0 -75
  140. data/lib/nanoc/cli/stack_trace_writer.rb +0 -50
  141. data/lib/nanoc/cli/stream_cleaners.rb +0 -10
  142. data/lib/nanoc/cli/stream_cleaners/abstract.rb +0 -21
  143. data/lib/nanoc/cli/stream_cleaners/ansi_colors.rb +0 -13
  144. data/lib/nanoc/cli/stream_cleaners/utf8.rb +0 -17
  145. data/lib/nanoc/cli/transform.rb +0 -16
  146. data/lib/nanoc/deploying.rb +0 -10
  147. data/lib/nanoc/deploying/deployer.rb +0 -45
  148. data/lib/nanoc/deploying/deployers.rb +0 -11
  149. data/lib/nanoc/deploying/deployers/fog.rb +0 -220
  150. data/lib/nanoc/deploying/deployers/git.rb +0 -112
  151. data/lib/nanoc/deploying/deployers/rsync.rb +0 -68
  152. data/lib/nanoc/extra/core_ext/pathname.rb +0 -27
  153. data/lib/nanoc/spec.rb +0 -240
@@ -1,10 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # @api private
4
- module Nanoc::CLI::StreamCleaners
5
- end
6
-
7
- require_relative 'stream_cleaners/abstract'
8
-
9
- require_relative 'stream_cleaners/ansi_colors'
10
- require_relative 'stream_cleaners/utf8'
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Nanoc::CLI::StreamCleaners
4
- # Superclass for all stream cleaners. Stream cleaners have a single method,
5
- # {#clean}, that takes a string and returns a cleaned string. Stream cleaners
6
- # can have state, so they can act as a FSM.
7
- #
8
- # @abstract Subclasses must implement {#clean}
9
- #
10
- # @api private
11
- class Abstract
12
- # Returns a cleaned version of the given string.
13
- #
14
- # @param [String] str The string to clean
15
- #
16
- # @return [String] The cleaned string
17
- def clean(str) # rubocop:disable Lint/UnusedMethodArgument
18
- raise NotImplementedError, 'Subclasses of Nanoc::CLI::StreamCleaners::Abstract must implement #clean'
19
- end
20
- end
21
- end
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Nanoc::CLI::StreamCleaners
4
- # Removes ANSI color escape sequences.
5
- #
6
- # @api private
7
- class ANSIColors < Abstract
8
- # @see Nanoc::CLI::StreamCleaners::Abstract#clean
9
- def clean(str)
10
- str.gsub(/\e\[.+?m/, '')
11
- end
12
- end
13
- end
@@ -1,17 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Nanoc::CLI::StreamCleaners
4
- # Simplifies output by replacing UTF-8 characters with their ASCII decompositions.
5
- #
6
- # @api private
7
- class UTF8 < Abstract
8
- # @see Nanoc::CLI::StreamCleaners::Abstract#clean
9
- def clean(str)
10
- # FIXME: this decomposition is not generally usable
11
- str
12
- .unicode_normalize(:nfkd)
13
- .tr('─┼“”‘’', '-+""\'\'')
14
- .gsub('©', '(c)')
15
- end
16
- end
17
- end
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Nanoc::CLI
4
- # @api private
5
- module Transform
6
- module Port
7
- RANGE = (0x0001..0xffff).freeze
8
-
9
- def self.call(data)
10
- Integer(data).tap do |int|
11
- raise 'not a valid port' unless RANGE.cover?(int)
12
- end
13
- end
14
- end
15
- end
16
- end
@@ -1,10 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Nanoc
4
- # @api private
5
- module Deploying
6
- end
7
- end
8
-
9
- require 'nanoc/deploying/deployer'
10
- require 'nanoc/deploying/deployers'
@@ -1,45 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Nanoc::Deploying
4
- # Represents a deployer, an object that allows uploading the compiled site
5
- # to a specific (remote) location.
6
- #
7
- # @abstract Subclass and override {#run} to implement a custom filter.
8
- #
9
- # @api private
10
- class Deployer
11
- extend DDPlugin::Plugin
12
-
13
- # @return [String] The path to the directory that contains the files to
14
- # upload. It should not have a trailing slash.
15
- attr_reader :source_path
16
-
17
- # @return [Hash] The deployer configuration
18
- attr_reader :config
19
-
20
- # @return [Boolean] true if the deployer should only show what would be
21
- # deployed instead of doing the actual deployment
22
- attr_reader :dry_run
23
- alias dry_run? dry_run
24
-
25
- # @param [String] source_path The path to the directory that contains the
26
- # files to upload. It should not have a trailing slash.
27
- #
28
- # @return [Hash] config The deployer configuration
29
- #
30
- # @param [Boolean] dry_run true if the deployer should
31
- # only show what would be deployed instead actually deploying
32
- def initialize(source_path, config, dry_run: false)
33
- @source_path = source_path
34
- @config = config
35
- @dry_run = dry_run
36
- end
37
-
38
- # Performs the actual deployment.
39
- #
40
- # @abstract
41
- def run
42
- raise NotImplementedError.new('Nanoc::Deploying::Deployer subclasses must implement #run')
43
- end
44
- end
45
- end
@@ -1,11 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'tty-command'
4
-
5
- # @api private
6
- module Nanoc::Deploying::Deployers
7
- end
8
-
9
- require_relative 'deployers/fog'
10
- require_relative 'deployers/git'
11
- require_relative 'deployers/rsync'
@@ -1,220 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Nanoc::Deploying::Deployers
4
- # A deployer that deploys a site using [fog](https://github.com/fog/fog).
5
- #
6
- # @example A deployment configuration with public and staging configurations
7
- #
8
- # deploy:
9
- # public:
10
- # kind: fog
11
- # bucket: nanoc-site
12
- # cdn_id: XXXXXX
13
- # preprod:
14
- # kind: fog
15
- # provider: local
16
- # local_root: ~/myCloud
17
- # bucket: nanoc-site
18
- # staging:
19
- # kind: fog
20
- # provider: local
21
- # local_root: ~/myCloud
22
- # bucket: nanoc-site-staging
23
- #
24
- # @api private
25
- class Fog < ::Nanoc::Deploying::Deployer
26
- identifier :fog
27
-
28
- class FogWrapper
29
- def initialize(directory, is_dry_run)
30
- @directory = directory
31
- @is_dry_run = is_dry_run
32
- end
33
-
34
- def upload(source_filename, destination_key)
35
- log_effectful("uploading #{source_filename} -> #{destination_key}")
36
-
37
- unless dry_run?
38
- File.open(source_filename) do |io|
39
- @directory.files.create(
40
- key: destination_key,
41
- body: io,
42
- public: true,
43
- )
44
- end
45
- end
46
- end
47
-
48
- def remove(keys)
49
- keys.each do |key|
50
- log_effectful("removing #{key}")
51
-
52
- unless dry_run?
53
- @directory.files.get(key).destroy
54
- end
55
- end
56
- end
57
-
58
- def invalidate(keys, cdn, distribution)
59
- keys.each_slice(1000) do |keys_slice|
60
- keys_slice.each do |key|
61
- log_effectful("invalidating #{key}")
62
- end
63
-
64
- unless dry_run?
65
- cdn.post_invalidation(distribution, keys_slice)
66
- end
67
- end
68
- end
69
-
70
- def dry_run?
71
- @is_dry_run
72
- end
73
-
74
- def log_effectful(str)
75
- if @is_dry_run
76
- puts "[dry run] #{str}"
77
- else
78
- puts str
79
- end
80
- end
81
- end
82
-
83
- # @see Nanoc::Deploying::Deployer#run
84
- def run
85
- require 'fog/core'
86
-
87
- src = File.expand_path(source_path)
88
- bucket = config[:bucket] || config[:bucket_name]
89
- path = config[:path]
90
- cdn_id = config[:cdn_id]
91
-
92
- if path&.end_with?('/')
93
- raise "The path `#{path}` is not supposed to have a trailing slash"
94
- end
95
-
96
- connection = connect
97
- directory = get_or_create_bucket(connection, bucket, path)
98
- wrapper = FogWrapper.new(directory, dry_run?)
99
-
100
- remote_files = list_remote_files(directory)
101
- etags = read_etags(remote_files)
102
-
103
- modified_keys, retained_keys = upload_all(src, path, etags, wrapper)
104
-
105
- removed_keys = remote_files.map(&:key) - retained_keys - modified_keys
106
- wrapper.remove(removed_keys)
107
-
108
- if cdn_id
109
- cdn = ::Fog::CDN.new(config_for_fog)
110
- distribution = cdn.get_distribution(cdn_id)
111
- wrapper.invalidate(modified_keys + removed_keys, cdn, distribution)
112
- end
113
- end
114
-
115
- private
116
-
117
- def config_for_fog
118
- config.dup.tap do |c|
119
- c.delete(:bucket)
120
- c.delete(:bucket_name)
121
- c.delete(:path)
122
- c.delete(:cdn_id)
123
- c.delete(:kind)
124
- end
125
- end
126
-
127
- def connect
128
- ::Fog::Storage.new(config_for_fog)
129
- rescue ArgumentError
130
- require "fog/#{config[:provider]}"
131
- ::Fog::Storage.new(config_for_fog)
132
- end
133
-
134
- def get_or_create_bucket(connection, bucket, path)
135
- directory =
136
- begin
137
- connection.directories.get(bucket, prefix: path)
138
- rescue ::Excon::Errors::NotFound
139
- nil
140
- end
141
-
142
- if directory
143
- directory
144
- elsif dry_run?
145
- puts '[dry run] creating bucket'
146
- else
147
- puts 'creating bucket'
148
- connection.directories.create(key: bucket, prefix: path)
149
- end
150
- end
151
-
152
- def remote_key_for_local_filename(local_filename, src, path)
153
- relative_local_filename = local_filename.sub(/\A#{src}\//, '')
154
-
155
- if path
156
- File.join(path, relative_local_filename)
157
- else
158
- relative_local_filename
159
- end
160
- end
161
-
162
- def list_remote_files(directory)
163
- if directory
164
- [].tap do |files|
165
- directory.files.each { |file| files << file }
166
- end
167
- else
168
- []
169
- end
170
- end
171
-
172
- def list_local_files(src)
173
- Dir[src + '/**/*'].select { |f| File.file?(f) }
174
- end
175
-
176
- def upload_all(src, path, etags, wrapper)
177
- modified_keys = []
178
- retained_keys = []
179
-
180
- local_files = list_local_files(src)
181
- local_files.each do |file_path|
182
- key = remote_key_for_local_filename(file_path, src, path)
183
- if needs_upload?(key, file_path, etags)
184
- wrapper.upload(file_path, key)
185
- modified_keys.push(key)
186
- else
187
- retained_keys.push(key)
188
- end
189
- end
190
-
191
- [modified_keys, retained_keys]
192
- end
193
-
194
- def needs_upload?(key, file_path, etags)
195
- remote_etag = etags[key]
196
- return true if remote_etag.nil?
197
-
198
- local_etag = calc_local_etag(file_path)
199
- remote_etag != local_etag
200
- end
201
-
202
- def read_etags(files)
203
- case config[:provider]
204
- when 'aws'
205
- files.each_with_object({}) do |file, etags|
206
- etags[file.key] = file.etag
207
- end
208
- else
209
- {}
210
- end
211
- end
212
-
213
- def calc_local_etag(file_path)
214
- case config[:provider]
215
- when 'aws'
216
- Digest::MD5.file(file_path).hexdigest
217
- end
218
- end
219
- end
220
- end
@@ -1,112 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Nanoc::Deploying::Deployers
4
- # A deployer that deploys a site using [Git](https://git-scm.com).
5
- #
6
- # @example A deployment configuration for GitHub Pages:
7
- #
8
- # deploy:
9
- # default:
10
- # kind: git
11
- # remote: git@github.com:myself/myproject.git
12
- # branch: gh-pages
13
- # forced: true
14
- #
15
- class Git < ::Nanoc::Deploying::Deployer
16
- identifier :git
17
-
18
- module Errors
19
- class Generic < ::Nanoc::Core::Error
20
- end
21
-
22
- class OutputDirDoesNotExist < Generic
23
- def initialize(path)
24
- super("The directory to deploy, #{path}, does not exist.")
25
- end
26
- end
27
-
28
- class OutputDirIsNotAGitRepo < Generic
29
- def initialize(path)
30
- super("The directory to deploy, #{path}, is not a Git repository.")
31
- end
32
- end
33
-
34
- class RemoteDoesNotExist < Generic
35
- def initialize(remote)
36
- super("The remote to deploy to, #{remote}, does not exist.")
37
- end
38
- end
39
-
40
- class BranchDoesNotExist < Generic
41
- def initialize(branch)
42
- super("The branch to deploy, #{branch}, does not exist.")
43
- end
44
- end
45
- end
46
-
47
- def run
48
- unless File.exist?(source_path)
49
- raise Errors::OutputDirDoesNotExist.new(source_path)
50
- end
51
-
52
- remote = config.fetch(:remote, 'origin')
53
- branch = config.fetch(:branch, 'master')
54
- forced = config.fetch(:forced, false)
55
-
56
- puts "Deploying via Git to branch “#{branch}” on remote “#{remote}”…"
57
-
58
- Dir.chdir(source_path) do
59
- unless File.exist?('.git')
60
- raise Errors::OutputDirIsNotAGitRepo.new(source_path)
61
- end
62
-
63
- # Verify existence of remote, if remote is not a URL
64
- if remote_is_name?(remote)
65
- begin
66
- run_cmd(%W[git config --get remote.#{remote}.url])
67
- rescue TTY::Command::ExitError
68
- raise Errors::RemoteDoesNotExist.new(remote)
69
- end
70
- end
71
-
72
- # If the branch exists then switch to it, otherwise prompt the user to create one.
73
- begin
74
- run_cmd_unless_dry(%W[git checkout #{branch}])
75
- rescue TTY::Command::ExitError
76
- raise Errors::BranchDoesNotExist.new(branch)
77
- end
78
-
79
- return if clean_repo?
80
-
81
- msg = "Automated commit at #{Time.now.utc} by Nanoc #{Nanoc::VERSION}"
82
- author = 'Nanoc <>'
83
- run_cmd_unless_dry(%w[git add -A])
84
- run_cmd_unless_dry(%W[git commit -a --author #{author} -m #{msg}])
85
-
86
- if forced
87
- run_cmd_unless_dry(%W[git push -f #{remote} #{branch}])
88
- else
89
- run_cmd_unless_dry(%W[git push #{remote} #{branch}])
90
- end
91
- end
92
- end
93
-
94
- private
95
-
96
- def remote_is_name?(remote)
97
- remote !~ /:\/\/|@.+:/
98
- end
99
-
100
- def run_cmd(cmd, dry_run: false)
101
- TTY::Command.new(printer: :null).run(*cmd, dry_run: dry_run)
102
- end
103
-
104
- def run_cmd_unless_dry(cmd)
105
- run_cmd(cmd, dry_run: dry_run)
106
- end
107
-
108
- def clean_repo?
109
- TTY::Command.new(printer: :null).run('git status --porcelain').out.empty?
110
- end
111
- end
112
- end