bookbindery 1.0.0 → 2.0.0

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.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/lib/bookbinder/archive.rb +1 -1
  3. data/lib/bookbinder/archive_menu_configuration.rb +34 -0
  4. data/lib/bookbinder/book.rb +17 -17
  5. data/lib/bookbinder/cli.rb +25 -36
  6. data/lib/bookbinder/code_example.rb +5 -38
  7. data/lib/bookbinder/code_example_reader.rb +40 -0
  8. data/lib/bookbinder/colorizer.rb +14 -0
  9. data/lib/bookbinder/command_runner.rb +9 -16
  10. data/lib/bookbinder/command_validator.rb +14 -7
  11. data/lib/bookbinder/commands/bind.rb +321 -0
  12. data/lib/bookbinder/commands/build_and_push_tarball.rb +7 -6
  13. data/lib/bookbinder/commands/chain.rb +11 -0
  14. data/lib/bookbinder/commands/generate_pdf.rb +4 -3
  15. data/lib/bookbinder/commands/help.rb +49 -10
  16. data/lib/bookbinder/commands/naming.rb +9 -1
  17. data/lib/bookbinder/commands/push_local_to_staging.rb +4 -3
  18. data/lib/bookbinder/commands/push_to_prod.rb +36 -4
  19. data/lib/bookbinder/commands/run_publish_ci.rb +21 -24
  20. data/lib/bookbinder/commands/tag.rb +3 -3
  21. data/lib/bookbinder/commands/update_local_doc_repos.rb +5 -4
  22. data/lib/bookbinder/commands/version.rb +11 -8
  23. data/lib/bookbinder/configuration.rb +8 -3
  24. data/lib/bookbinder/configuration_fetcher.rb +7 -25
  25. data/lib/bookbinder/configuration_validator.rb +21 -0
  26. data/lib/bookbinder/distributor.rb +1 -1
  27. data/lib/bookbinder/dita_html_to_middleman_formatter.rb +37 -0
  28. data/lib/bookbinder/dita_section.rb +7 -0
  29. data/lib/bookbinder/dita_section_gatherer.rb +28 -0
  30. data/lib/bookbinder/git_accessor.rb +17 -0
  31. data/lib/bookbinder/git_client.rb +10 -7
  32. data/lib/bookbinder/git_hub_repository.rb +46 -41
  33. data/lib/bookbinder/local_dita_preprocessor.rb +27 -0
  34. data/lib/bookbinder/local_dita_to_html_converter.rb +49 -0
  35. data/lib/bookbinder/local_file_system_accessor.rb +68 -0
  36. data/lib/bookbinder/middleman_runner.rb +30 -17
  37. data/lib/bookbinder/pdf_generator.rb +1 -1
  38. data/lib/bookbinder/publisher.rb +16 -80
  39. data/lib/bookbinder/remote_yaml_credential_provider.rb +2 -3
  40. data/lib/bookbinder/repositories/command_repository.rb +156 -0
  41. data/lib/bookbinder/repositories/section_repository.rb +31 -0
  42. data/lib/bookbinder/section.rb +5 -67
  43. data/lib/bookbinder/shell_out.rb +1 -0
  44. data/lib/bookbinder/sheller.rb +19 -0
  45. data/lib/bookbinder/sieve.rb +6 -1
  46. data/lib/bookbinder/stabilimentum.rb +5 -1
  47. data/lib/bookbinder/terminal.rb +10 -0
  48. data/lib/bookbinder/user_message.rb +6 -0
  49. data/lib/bookbinder/user_message_presenter.rb +21 -0
  50. data/lib/bookbinder/yaml_loader.rb +18 -7
  51. data/lib/bookbinder.rb +2 -9
  52. data/master_middleman/archive_drop_down_menu.rb +46 -0
  53. data/master_middleman/bookbinder_helpers.rb +47 -40
  54. data/master_middleman/quicklinks_renderer.rb +1 -1
  55. metadata +33 -87
  56. data/lib/bookbinder/commands/publish.rb +0 -138
  57. data/lib/bookbinder/usage_messenger.rb +0 -33
  58. /data/{bin → install_bin}/bookbinder +0 -0
@@ -0,0 +1,321 @@
1
+ require_relative '../archive_menu_configuration'
2
+ require_relative '../book'
3
+ require_relative '../cli_error'
4
+ require_relative '../directory_helpers'
5
+ require_relative '../publisher'
6
+ require_relative '../section'
7
+ require_relative '../dita_section'
8
+ require_relative '../dita_section_gatherer'
9
+ require_relative 'naming'
10
+
11
+ module Bookbinder
12
+ module Commands
13
+ class Bind
14
+ VersionUnsupportedError = Class.new(RuntimeError)
15
+
16
+ include Bookbinder::DirectoryHelperMethods
17
+ include Commands::Naming
18
+
19
+ def initialize(logger,
20
+ config_fetcher,
21
+ archive_menu_config,
22
+ version_control_system,
23
+ file_system_accessor,
24
+ static_site_generator,
25
+ sitemap_generator,
26
+ final_app_directory,
27
+ server_director,
28
+ context_dir,
29
+ dita_preprocessor)
30
+ @logger = logger
31
+ @config_fetcher = config_fetcher
32
+ @archive_menu_config = archive_menu_config
33
+ @version_control_system = version_control_system
34
+ @file_system_accessor = file_system_accessor
35
+ @static_site_generator = static_site_generator
36
+ @sitemap_generator = sitemap_generator
37
+ @final_app_directory = final_app_directory
38
+ @server_director = server_director
39
+ @context_dir = context_dir
40
+ @dita_preprocessor = dita_preprocessor
41
+ end
42
+
43
+ def usage
44
+ ["bind <local|github> [--verbose]",
45
+ "Bind the sections specified in config.yml from <local> or <github> into the final_app directory"]
46
+ end
47
+
48
+ def command_for?(test_command_name)
49
+ %w(bind publish).include?(test_command_name)
50
+ end
51
+
52
+ def deprecated_command_for?(command_name)
53
+ %w(publish).include?(command_name)
54
+ end
55
+
56
+ def run(cli_arguments)
57
+ raise CliError::InvalidArguments unless arguments_are_valid?(cli_arguments)
58
+ @section_repository = Repositories::SectionRepository.new(logger)
59
+ @gem_root = File.expand_path('../../../../', __FILE__)
60
+
61
+ @publisher = Publisher.new(logger, sitemap_generator, static_site_generator, server_director, file_system_accessor)
62
+
63
+ location = cli_arguments[0]
64
+
65
+ output_paths = output_directory_paths(location)
66
+ publish_config = publish_config(location)
67
+ @versions = publish_config.fetch(:versions, [])
68
+ @book_repo = publish_config[:book_repo]
69
+
70
+ master_middleman_dir = output_paths.fetch(:master_middleman_dir)
71
+ output_dir = output_paths.fetch(:output_dir)
72
+
73
+ dita_processing_dir = File.join output_dir, 'dita'
74
+ dita_section_dir = File.join dita_processing_dir, 'dita_sections'
75
+ dita_processed_dir = File.join dita_processing_dir, 'html_from_dita'
76
+ formatted_dir = File.join dita_processing_dir, 'site_generator_ready'
77
+
78
+ master_dir = File.join output_dir, 'master_middleman'
79
+ workspace_dir = File.join master_dir, 'source'
80
+ prepare_directories(final_app_directory,
81
+ output_dir,
82
+ workspace_dir,
83
+ master_middleman_dir,
84
+ master_dir,
85
+ dita_processing_dir,
86
+ formatted_dir)
87
+
88
+ dita_section_config_hash = config.dita_sections || {}
89
+ dita_sections = dita_section_config_hash.map do |dita_section_config|
90
+ relative_path_to_dita_map = dita_section_config['ditamap_location']
91
+ full_name = dita_section_config.fetch('repository', {}).fetch('name')
92
+ target_ref = dita_section_config.fetch('repository', {})['ref']
93
+ directory = dita_section_config['directory']
94
+
95
+ DitaSection.new(nil, relative_path_to_dita_map, full_name, target_ref, directory)
96
+ end
97
+
98
+ if location == 'github'
99
+ dita_section_gatherer = DitaSectionGatherer.new(version_control_system, logger)
100
+ final_dita_sections = dita_section_gatherer.gather(dita_sections, to: dita_section_dir)
101
+ else
102
+ final_dita_sections = dita_sections.map do |dita_section|
103
+ relative_path_to_dita_map = dita_section.ditamap_location
104
+ full_name = dita_section.full_name
105
+ target_ref = dita_section.target_ref
106
+ directory = dita_section.directory
107
+
108
+ path_to_local_copy = File.join output_paths[:local_repo_dir], directory
109
+
110
+ DitaSection.new(path_to_local_copy, relative_path_to_dita_map, full_name, target_ref, directory)
111
+ end
112
+ end
113
+
114
+ dita_preprocessor.preprocess final_dita_sections, dita_processed_dir, formatted_dir, workspace_dir
115
+
116
+ sections = gather_sections(workspace_dir, output_paths)
117
+
118
+ subnavs = subnavs_by_dir_name(sections)
119
+
120
+ success = publisher.publish(
121
+ subnavs,
122
+ {verbose: cli_arguments.include?('--verbose')},
123
+ output_paths,
124
+ archive_menu_config.generate(publish_config, sections)
125
+ )
126
+
127
+ success ? 0 : 1
128
+ end
129
+
130
+ private
131
+
132
+ attr_reader :publisher,
133
+ :version_control_system,
134
+ :config_fetcher,
135
+ :archive_menu_config,
136
+ :logger,
137
+ :file_system_accessor,
138
+ :static_site_generator,
139
+ :final_app_directory,
140
+ :sitemap_generator,
141
+ :server_director,
142
+ :context_dir,
143
+ :dita_preprocessor
144
+
145
+ def gather_sections(workspace, output_paths)
146
+ config.sections.map do |attributes|
147
+
148
+ local_repo_dir = output_paths[:local_repo_dir]
149
+ vcs_repo =
150
+ if local_repo_dir
151
+ GitHubRepository.
152
+ build_from_local(logger, attributes, local_repo_dir, version_control_system).
153
+ tap { |repo| repo.copy_from_local(workspace) }
154
+ else
155
+ GitHubRepository.
156
+ build_from_remote(logger, attributes, nil, version_control_system).
157
+ tap { |repo| repo.copy_from_remote(workspace) }
158
+ end
159
+
160
+ @section_repository.get_instance(attributes,
161
+ vcs_repo: vcs_repo,
162
+ destination_dir: workspace,
163
+ build: ->(*args) { Section.new(*args) })
164
+ end
165
+ end
166
+
167
+ def prepare_directories(final_app,
168
+ output_dir,
169
+ middleman_source,
170
+ master_middleman_dir,
171
+ middleman_dir,
172
+ dita_processing_dir,
173
+ formatted_dir)
174
+ forget_sections(output_dir)
175
+ file_system_accessor.remove_directory File.join final_app, '.'
176
+ file_system_accessor.remove_directory dita_processing_dir
177
+ file_system_accessor.make_directory output_dir
178
+ file_system_accessor.make_directory formatted_dir
179
+ file_system_accessor.make_directory File.join dita_processing_dir, 'dita_sections'
180
+ file_system_accessor.make_directory File.join final_app, 'public'
181
+ file_system_accessor.make_directory middleman_source
182
+
183
+ copy_directory_from_gem 'template_app', final_app
184
+ copy_directory_from_gem 'master_middleman', middleman_dir
185
+ file_system_accessor.copy File.join(master_middleman_dir, '.'), middleman_dir
186
+
187
+ copy_version_master_middleman(middleman_source)
188
+ end
189
+
190
+ def forget_sections(middleman_scratch)
191
+ file_system_accessor.remove_directory File.join middleman_scratch, '.'
192
+ end
193
+
194
+ def copy_directory_from_gem(dir, output_dir)
195
+ file_system_accessor.copy File.join(@gem_root, "#{dir}/."), output_dir
196
+ end
197
+
198
+ # Copy the index file from each version into the version's directory. Because version
199
+ # subdirectories are sections, this is the only way they get content from their master
200
+ # middleman directory.
201
+ def copy_version_master_middleman(dest_dir)
202
+ @versions.each do |version|
203
+ Dir.mktmpdir(version) do |tmpdir|
204
+ book = Book.from_remote(logger: logger,
205
+ full_name: @book_repo,
206
+ destination_dir: tmpdir,
207
+ ref: version,
208
+ git_accessor: version_control_system)
209
+ index_source_dir = File.join(tmpdir, book.directory, 'master_middleman', source_dir_name)
210
+ index_dest_dir = File.join(dest_dir, version)
211
+ file_system_accessor.make_directory(index_dest_dir)
212
+
213
+ Dir.glob(File.join(index_source_dir, 'index.*')) do |f|
214
+ file_system_accessor.copy(File.expand_path(f), index_dest_dir)
215
+ end
216
+ end
217
+ end
218
+ end
219
+
220
+ def output_directory_paths(location)
221
+ local_repo_dir = (location == 'local') ? File.expand_path('..', context_dir) : nil
222
+
223
+ {
224
+ final_app_dir: final_app_directory,
225
+ local_repo_dir: local_repo_dir,
226
+ output_dir: File.join(context_dir, output_dir_name),
227
+ master_middleman_dir: layout_repo_path(local_repo_dir)
228
+ }
229
+ end
230
+
231
+ def publish_config(location)
232
+ arguments = {
233
+ sections: config.sections,
234
+ book_repo: config.book_repo,
235
+ host_for_sitemap: config.public_host,
236
+ archive_menu: config.archive_menu
237
+ }
238
+
239
+ optional_arguments = {}
240
+ optional_arguments.merge!(template_variables: config.template_variables) if config.respond_to?(:template_variables)
241
+ if publishing_to_github? location
242
+ config.versions.each { |version| arguments[:sections].concat sections_from version }
243
+ optional_arguments.merge!(versions: config.versions)
244
+ end
245
+
246
+ arguments.merge! optional_arguments
247
+ end
248
+
249
+ def config
250
+ config_fetcher.fetch_config
251
+ end
252
+
253
+ def sections_from(version)
254
+ Dir.mktmpdir('book_checkout') do |temp_workspace|
255
+ book = Book.from_remote(logger: logger,
256
+ full_name: config.book_repo,
257
+ destination_dir: temp_workspace,
258
+ ref: version,
259
+ git_accessor: version_control_system,
260
+ )
261
+
262
+ book_checkout_value = File.join temp_workspace, book.directory
263
+ config_file = File.join book_checkout_value, 'config.yml'
264
+ attrs = YAML.load(File.read(config_file))['sections']
265
+ raise VersionUnsupportedError.new(version) if attrs.nil?
266
+
267
+ attrs.map do |section_hash|
268
+ section_hash['repository']['ref'] = version
269
+ section_hash['directory'] = File.join(version, section_hash['directory'])
270
+ section_hash
271
+ end
272
+ end
273
+ end
274
+
275
+ def layout_repo_path(local_repo_dir)
276
+ if config.has_option?('layout_repo')
277
+ if local_repo_dir
278
+ File.join(local_repo_dir, config.layout_repo.split('/').last)
279
+ else
280
+ section = {'repository' => {'name' => config.layout_repo}}
281
+ destination_dir = Dir.mktmpdir
282
+ repository = GitHubRepository.build_from_remote(logger,
283
+ section,
284
+ 'master',
285
+ version_control_system)
286
+ repository.copy_from_remote(destination_dir)
287
+ if repository
288
+ File.join(destination_dir, repository.directory)
289
+ else
290
+ raise 'failed to fetch repository'
291
+ end
292
+ end
293
+ else
294
+ File.absolute_path('master_middleman')
295
+ end
296
+ end
297
+
298
+ def arguments_are_valid?(arguments)
299
+ return false unless arguments.any?
300
+ verbose = arguments[1] && arguments[1..-1].include?('--verbose')
301
+ tag_provided = arguments[1] && (arguments[1..-1] - ['--verbose']).any?
302
+ nothing_special = arguments[1..-1].empty?
303
+
304
+ %w(local github).include?(arguments[0]) && (tag_provided || verbose || nothing_special)
305
+ end
306
+
307
+ def publishing_to_github?(publish_location)
308
+ config.has_option?('versions') && publish_location != 'local'
309
+ end
310
+
311
+ def subnavs_by_dir_name(sections)
312
+ sections.reduce({}) do |subnavs, section|
313
+ namespace = section.directory.gsub('/', '_')
314
+ template = section.subnav_template || 'default'
315
+
316
+ subnavs.merge(namespace => template)
317
+ end
318
+ end
319
+ end
320
+ end
321
+ end
@@ -5,7 +5,7 @@ require_relative '../archive'
5
5
  module Bookbinder
6
6
  module Commands
7
7
  class BuildAndPushTarball < BookbinderCommand
8
- extend Commands::Naming
8
+ include Commands::Naming
9
9
 
10
10
  class MissingBuildNumber < StandardError
11
11
  def initialize
@@ -13,17 +13,18 @@ module Bookbinder
13
13
  end
14
14
  end
15
15
 
16
- def self.usage
17
- "build_and_push_tarball \t \t \t Create a tarball from the final_app directory and push to the S3 bucket specified in your credentials.yml"
16
+ def usage
17
+ [command_name,
18
+ "Create a tarball from the final_app directory and push to the S3 bucket specified in your credentials.yml"]
18
19
  end
19
20
 
20
21
  def run(_)
21
22
  raise MissingBuildNumber unless ENV['BUILD_NUMBER']
22
23
  config = configuration_fetcher.fetch_config
23
24
  aws_credentials = config.aws_credentials
24
- repository = Archive.new(logger: @logger, key: aws_credentials.access_key, secret: aws_credentials.secret_key)
25
- repository.create_and_upload_tarball(build_number: ENV['BUILD_NUMBER'], bucket: aws_credentials.green_builds_bucket,
26
- namespace: GitHubRepository.new(logger: @logger, full_name: config.book_repo).short_name)
25
+ archive = Archive.new(logger: @logger, key: aws_credentials.access_key, secret: aws_credentials.secret_key)
26
+ archive.create_and_upload_tarball(build_number: ENV['BUILD_NUMBER'], bucket: aws_credentials.green_builds_bucket,
27
+ namespace: GitHubRepository.new(logger: @logger, full_name: config.book_repo, git_accessor: Git).short_name)
27
28
  0
28
29
  end
29
30
  end
@@ -0,0 +1,11 @@
1
+ module Bookbinder
2
+ module Commands
3
+ module Chain
4
+ private
5
+
6
+ def command_chain(*commands)
7
+ commands.all? {|command| command[] == 0} ? 0 : 1
8
+ end
9
+ end
10
+ end
11
+ end
@@ -6,7 +6,7 @@ require_relative 'naming'
6
6
  module Bookbinder
7
7
  module Commands
8
8
  class GeneratePDF < BookbinderCommand
9
- extend Commands::Naming
9
+ include Commands::Naming
10
10
 
11
11
  class AppNotPublished < StandardError
12
12
  def initialize(msg='You must publish locally before you generate a PDF.')
@@ -32,8 +32,9 @@ module Bookbinder
32
32
  end
33
33
  end
34
34
 
35
- def self.usage
36
- "generate_pdf [<file_name>.yml] \t \t Generate a PDF from the files specified in <file_name.yml>"
35
+ def usage
36
+ ["generate_pdf [<file_name>.yml]",
37
+ "Generate a PDF from the files specified in <file_name.yml>"]
37
38
  end
38
39
 
39
40
  def run(params)
@@ -1,21 +1,21 @@
1
+ require_relative 'naming'
2
+
1
3
  module Bookbinder
2
4
  module Commands
3
5
  class Help
4
- def initialize(logger, usage_message)
5
- @logger = logger
6
- @usage_message = usage_message
7
- end
6
+ include Commands::Naming
8
7
 
9
- def self.to_s
10
- 'help'
8
+ def initialize(logger, other_commands)
9
+ @logger = logger
10
+ @other_commands = other_commands
11
11
  end
12
12
 
13
- def self.command_name
13
+ def command_name
14
14
  '--help'
15
15
  end
16
16
 
17
- def self.usage
18
- "--help \t \t \t \t \t Print this message"
17
+ def usage
18
+ [command_name, "Print this message"]
19
19
  end
20
20
 
21
21
  def run(*)
@@ -23,9 +23,48 @@ module Bookbinder
23
23
  0
24
24
  end
25
25
 
26
+ def usage_message
27
+ [usage_header, command_usage_messages].join("\n")
28
+ end
29
+
26
30
  private
27
31
 
28
- attr_reader :logger, :usage_message
32
+ def command_usage_messages
33
+ (flags + standard_commands).reduce('') { |message, command|
34
+ "#{message}#{usage_indent}#{formatted_usage(command)}\n"
35
+ }
36
+ end
37
+
38
+ def formatted_usage(command)
39
+ "#{command.usage[0].ljust(chars_for_usage_definition)}#{command.usage[1]}"
40
+ end
41
+
42
+ def usage_indent
43
+ " " * 4
44
+ end
45
+
46
+ def chars_for_usage_definition
47
+ 33
48
+ end
49
+
50
+ def flags
51
+ other_commands.select(&:flag?) + [self]
52
+ end
53
+
54
+ def standard_commands
55
+ other_commands.reject(&:flag?)
56
+ end
57
+
58
+ def usage_header
59
+ <<TEXT
60
+
61
+ \e[1;39;49mDocumentation\e[0m: https://github.com/pivotal-cf/docs-bookbinder
62
+
63
+ \e[1;39;49mUsage\e[0m: bookbinder <command|flag> [args]
64
+ TEXT
65
+ end
66
+
67
+ attr_reader :logger, :other_commands
29
68
  end
30
69
  end
31
70
  end
@@ -2,7 +2,15 @@ module Bookbinder
2
2
  module Commands
3
3
  module Naming
4
4
  def command_name
5
- name.demodulize.underscore
5
+ self.class.name.demodulize.underscore
6
+ end
7
+
8
+ def command_for?(test_command_name)
9
+ command_name == test_command_name
10
+ end
11
+
12
+ def flag?
13
+ command_name.match(/^--/)
6
14
  end
7
15
  end
8
16
  end
@@ -5,10 +5,11 @@ require_relative 'naming'
5
5
  module Bookbinder
6
6
  module Commands
7
7
  class PushLocalToStaging < BookbinderCommand
8
- extend Commands::Naming
8
+ include Commands::Naming
9
9
 
10
- def self.usage
11
- "push_local_to_staging \t \t \t Push the contents of final_app to the staging host specified in credentials.yml"
10
+ def usage
11
+ [command_name,
12
+ "Push the contents of final_app to the staging host specified in credentials.yml"]
12
13
  end
13
14
 
14
15
  def run(_)
@@ -3,21 +3,35 @@ require_relative 'bookbinder_command'
3
3
  require_relative 'naming'
4
4
 
5
5
  module Bookbinder
6
+ class PushToProdValidator
7
+ MissingRequiredKeyError = Class.new(RuntimeError)
8
+ end
9
+
6
10
  module Commands
7
- class PushToProd < BookbinderCommand
8
- extend Commands::Naming
11
+ class PushToProd
12
+ include Commands::Naming
13
+ CONFIG_REQUIRED_KEYS = %w(cred_repo)
14
+
15
+ def initialize(logger, configuration_fetcher)
16
+ @logger = logger
17
+ @configuration_fetcher = configuration_fetcher
18
+ end
9
19
 
10
- def self.usage
11
- "push_to_prod [build_#] \t \t \t Push latest or <build_#> from your S3 bucket to the production host specified in credentials.yml"
20
+ def usage
21
+ ["push_to_prod [build_#]",
22
+ "Push latest or <build_#> from your S3 bucket to the production host specified in credentials.yml"]
12
23
  end
13
24
 
14
25
  def run(arguments)
26
+ validate
15
27
  Distributor.build(@logger, options(arguments)).distribute
16
28
  0
17
29
  end
18
30
 
19
31
  private
20
32
 
33
+ attr_reader :configuration_fetcher
34
+
21
35
  def options(arguments)
22
36
  {
23
37
  app_dir: Dir.mktmpdir,
@@ -30,6 +44,24 @@ module Bookbinder
30
44
  production: true
31
45
  }
32
46
  end
47
+
48
+ def config
49
+ @config ||= configuration_fetcher.fetch_config
50
+ end
51
+
52
+ def validate
53
+ missing_keys = []
54
+ CONFIG_REQUIRED_KEYS.map do |required_key|
55
+ unless config.has_option?(required_key)
56
+ missing_keys.push(required_key)
57
+ end
58
+ end
59
+
60
+ if missing_keys.length > 0
61
+ raise PushToProdValidator::MissingRequiredKeyError.new "Your config.yml is missing required key(s). The require keys for this commands are " + missing_keys.join(", ")
62
+ end
63
+ end
64
+
33
65
  end
34
66
  end
35
67
  end
@@ -1,42 +1,39 @@
1
- require_relative 'bookbinder_command'
1
+ require_relative 'bind'
2
+ require_relative 'build_and_push_tarball'
3
+ require_relative 'chain'
2
4
  require_relative 'naming'
3
- require_relative 'publish'
4
5
  require_relative 'push_local_to_staging'
5
- require_relative 'build_and_push_tarball'
6
6
 
7
7
  module Bookbinder
8
8
  module Commands
9
- class RunPublishCI < BookbinderCommand
10
- extend Commands::Naming
9
+ class RunPublishCI
10
+ include Commands::Naming
11
+ include Commands::Chain
11
12
 
12
- def self.usage
13
- "run_publish_ci \t \t \t \t Run publish, push_local_to_staging, and build_and_push_tarball for CI purposes"
13
+ def usage
14
+ [command_name,
15
+ "Run publish, push_local_to_staging, and build_and_push_tarball for CI purposes"]
14
16
  end
15
17
 
16
- def run(cli_args)
17
- check_params
18
- all_successfully_ran = publish(cli_args) == 0 && push_to_staging == 0 && push_tarball == 0
19
- all_successfully_ran ? 0 : 1
18
+ def initialize(publish_command, push_local_to_staging_command, build_and_push_tarball_command)
19
+ @publish_command = publish_command
20
+ @push_local_to_staging_command = push_local_to_staging_command
21
+ @build_and_push_tarball_command = build_and_push_tarball_command
20
22
  end
21
23
 
22
- private
23
-
24
- def check_params
24
+ def run(cli_args)
25
25
  raise BuildAndPushTarball::MissingBuildNumber unless ENV['BUILD_NUMBER']
26
- config.book_repo
27
- end
28
26
 
29
- def publish(cli_args)
30
- Publish.new(@logger, @configuration_fetcher).run(['github'] + cli_args)
27
+ command_chain(
28
+ ->{publish_command.run(['github'] + cli_args)},
29
+ ->{push_local_to_staging_command.run([])},
30
+ ->{build_and_push_tarball_command.run([])}
31
+ )
31
32
  end
32
33
 
33
- def push_to_staging
34
- PushLocalToStaging.new(@logger, @configuration_fetcher).run []
35
- end
34
+ private
36
35
 
37
- def push_tarball
38
- BuildAndPushTarball.new(@logger, @configuration_fetcher).run []
39
- end
36
+ attr_reader :publish_command, :push_local_to_staging_command, :build_and_push_tarball_command
40
37
  end
41
38
  end
42
39
  end
@@ -8,10 +8,10 @@ require_relative 'naming'
8
8
  module Bookbinder
9
9
  module Commands
10
10
  class Tag < BookbinderCommand
11
- extend Commands::Naming
11
+ include Commands::Naming
12
12
 
13
- def self.usage
14
- "tag <git tag> \t \t \t \t Apply the specified <git tag> to your book and all sections of your book"
13
+ def usage
14
+ ["tag <git tag>", "Apply the specified <git tag> to your book and all sections of your book"]
15
15
  end
16
16
 
17
17
  def run(params)
@@ -4,10 +4,11 @@ require_relative 'naming'
4
4
  module Bookbinder
5
5
  module Commands
6
6
  class UpdateLocalDocRepos < BookbinderCommand
7
- extend Commands::Naming
7
+ include Commands::Naming
8
8
 
9
- def self.usage
10
- "update_local_doc_repos \t \t \t Run `git pull` on all sections that exist at the same directory level as your book directory"
9
+ def usage
10
+ [command_name,
11
+ "Run `git pull` on all sections that exist at the same directory level as your book directory"]
11
12
  end
12
13
 
13
14
  def run(_)
@@ -20,7 +21,7 @@ module Bookbinder
20
21
  def repo_for(section_config)
21
22
  local_repo_dir = File.absolute_path('../')
22
23
  GitHubRepository.new(logger: @logger, full_name: section_config['repository']['name'],
23
- local_repo_dir: local_repo_dir)
24
+ local_repo_dir: local_repo_dir, git_accessor: Git)
24
25
  end
25
26
  end
26
27
  end