bookbindery 2.1.5 → 3.0.1

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 (54) hide show
  1. checksums.yaml +4 -4
  2. data/lib/bookbinder.rb +0 -4
  3. data/lib/bookbinder/cf_command_runner.rb +11 -5
  4. data/lib/bookbinder/cli.rb +8 -12
  5. data/lib/bookbinder/colorizer.rb +1 -2
  6. data/lib/bookbinder/command_runner.rb +0 -2
  7. data/lib/bookbinder/commands/bind.rb +96 -99
  8. data/lib/bookbinder/commands/bind/directory_preparer.rb +60 -0
  9. data/lib/bookbinder/commands/build_and_push_tarball.rb +5 -4
  10. data/lib/bookbinder/commands/push_from_local.rb +56 -2
  11. data/lib/bookbinder/commands/push_to_prod.rb +6 -2
  12. data/lib/bookbinder/commands/tag.rb +15 -3
  13. data/lib/bookbinder/config/aws_credentials.rb +21 -0
  14. data/lib/bookbinder/config/cf_credentials.rb +87 -0
  15. data/lib/bookbinder/configuration.rb +4 -140
  16. data/lib/bookbinder/configuration_fetcher.rb +28 -4
  17. data/lib/bookbinder/configuration_validator.rb +11 -164
  18. data/lib/bookbinder/distributor.rb +16 -12
  19. data/lib/bookbinder/{dita_to_html_converter.rb → dita_command_creator.rb} +5 -17
  20. data/lib/bookbinder/dita_preprocessor.rb +14 -12
  21. data/lib/bookbinder/git_accessor.rb +21 -2
  22. data/lib/bookbinder/git_hub_repository.rb +0 -43
  23. data/lib/bookbinder/ingest/cloner_factory.rb +5 -4
  24. data/lib/bookbinder/ingest/destination_directory.rb +15 -0
  25. data/lib/bookbinder/ingest/git_hub_repository_cloner.rb +22 -13
  26. data/lib/bookbinder/ingest/local_filesystem_cloner.rb +38 -14
  27. data/lib/bookbinder/ingest/working_copy.rb +31 -0
  28. data/lib/bookbinder/local_dita_section_gatherer.rb +4 -3
  29. data/lib/bookbinder/local_file_system_accessor.rb +1 -4
  30. data/lib/bookbinder/middleman_runner.rb +22 -26
  31. data/lib/bookbinder/remote_yaml_credential_provider.rb +10 -10
  32. data/lib/bookbinder/repositories/command_repository.rb +18 -12
  33. data/lib/bookbinder/repositories/section_repository.rb +8 -8
  34. data/lib/bookbinder/server_director.rb +16 -33
  35. data/lib/bookbinder/sheller.rb +33 -7
  36. data/lib/bookbinder/spider.rb +3 -0
  37. data/lib/bookbinder/streams/switchable_stdout_and_red_stderr.rb +38 -0
  38. data/lib/bookbinder/terminal.rb +11 -1
  39. data/lib/bookbinder/validation_checkers/archive_menu_checker.rb +31 -0
  40. data/lib/bookbinder/validation_checkers/config_version_checker.rb +91 -0
  41. data/lib/bookbinder/validation_checkers/dita_section_checker.rb +20 -0
  42. data/lib/bookbinder/validation_checkers/duplicate_section_name_checker.rb +25 -0
  43. data/lib/bookbinder/validation_checkers/repository_name_presence_checker.rb +33 -0
  44. data/lib/bookbinder/validation_checkers/required_keys_checker.rb +43 -0
  45. data/lib/bookbinder/values/dita_section.rb +5 -1
  46. data/lib/bookbinder/values/output_locations.rb +25 -2
  47. data/lib/bookbinder/values/user_message.rb +2 -2
  48. data/master_middleman/bookbinder_helpers.rb +5 -15
  49. data/template_app/Gemfile.lock +1 -1
  50. metadata +60 -80
  51. data/lib/bookbinder/commands/generate_pdf.rb +0 -141
  52. data/lib/bookbinder/pdf_generator.rb +0 -73
  53. data/lib/bookbinder/publisher.rb +0 -58
  54. data/lib/bookbinder/user_message_presenter.rb +0 -21
@@ -4,22 +4,23 @@ require_relative 'local_filesystem_cloner'
4
4
  module Bookbinder
5
5
  module Ingest
6
6
  class ClonerFactory
7
- def initialize(logger, version_control_system)
7
+ def initialize(logger, filesystem, version_control_system)
8
8
  @logger = logger
9
+ @filesystem = filesystem
9
10
  @version_control_system = version_control_system
10
11
  end
11
12
 
12
13
  def produce(source, user_repo_dir)
13
14
  if user_repo_dir
14
- LocalFilesystemCloner.new(logger, version_control_system, user_repo_dir)
15
+ LocalFilesystemCloner.new(logger, filesystem, user_repo_dir)
15
16
  else
16
- GitHubRepositoryCloner.new(logger, version_control_system)
17
+ GitHubRepositoryCloner.new(version_control_system)
17
18
  end
18
19
  end
19
20
 
20
21
  private
21
22
 
22
- attr_reader :logger, :version_control_system
23
+ attr_reader :logger, :filesystem, :version_control_system
23
24
  end
24
25
  end
25
26
  end
@@ -0,0 +1,15 @@
1
+ module Bookbinder
2
+ module Ingest
3
+ DestinationDirectory = Struct.new(:full_repo_name, :desired_destination_dir_name) do
4
+ def to_str
5
+ desired_destination_dir_name || full_repo_name.split('/')[1]
6
+ end
7
+
8
+ alias :to_s :to_str
9
+
10
+ def ==(other)
11
+ to_str == other
12
+ end
13
+ end
14
+ end
15
+ end
@@ -1,26 +1,35 @@
1
+ require_relative 'destination_directory'
2
+ require_relative 'working_copy'
3
+
1
4
  module Bookbinder
2
5
  module Ingest
3
6
  class GitHubRepositoryCloner
4
- def initialize(logger, version_control_system)
5
- @logger = logger
7
+ def initialize(version_control_system)
6
8
  @version_control_system = version_control_system
7
9
  end
8
10
 
9
- def call(from: nil,
10
- ref: nil,
11
- parent_dir: nil,
12
- dir_name: nil)
13
- GitHubRepository.
14
- build_from_remote(logger,
15
- {'repository' => {'name' => from},
16
- 'directory' => dir_name},
17
- version_control_system).
18
- tap { |repo| repo.copy_from_remote(parent_dir, ref) }
11
+ def call(source_repo_name: nil,
12
+ source_ref: "master",
13
+ destination_parent_dir: nil,
14
+ destination_dir_name: nil)
15
+ dest_dir = DestinationDirectory.new(source_repo_name, destination_dir_name)
16
+ copied_to = Pathname(destination_parent_dir).join(dest_dir)
17
+ version_control_system.clone(
18
+ "git@github.com:#{source_repo_name}",
19
+ dest_dir,
20
+ path: destination_parent_dir,
21
+ checkout: source_ref
22
+ )
23
+ WorkingCopy.new(
24
+ copied_to: copied_to,
25
+ directory: destination_dir_name,
26
+ full_name: source_repo_name,
27
+ )
19
28
  end
20
29
 
21
30
  private
22
31
 
23
- attr_reader :logger, :version_control_system
32
+ attr_reader :version_control_system
24
33
  end
25
34
  end
26
35
  end
@@ -1,28 +1,52 @@
1
+ require_relative '../deprecated_logger'
2
+ require_relative 'working_copy'
3
+
1
4
  module Bookbinder
2
5
  module Ingest
3
6
  class LocalFilesystemCloner
4
- def initialize(logger, version_control_system, user_repo_dir)
7
+ def initialize(logger, filesystem, user_repo_dir)
5
8
  @logger = logger
6
- @version_control_system = version_control_system
7
9
  @user_repo_dir = user_repo_dir
10
+ @filesystem = filesystem
8
11
  end
9
12
 
10
- def call(from: nil,
11
- ref: nil,
12
- parent_dir: nil,
13
- dir_name: nil)
14
- GitHubRepository.
15
- build_from_local(logger,
16
- {'repository' => {'name' => from},
17
- 'directory' => dir_name},
18
- user_repo_dir,
19
- version_control_system).
20
- tap { |repo| repo.copy_from_local(parent_dir) }
13
+ def call(source_repo_name: nil,
14
+ source_ref: nil,
15
+ destination_parent_dir: nil,
16
+ destination_dir_name: nil)
17
+ copied_to = copy!(
18
+ WorkingCopy.new(repo_dir: user_repo_dir, full_name: source_repo_name),
19
+ Pathname(destination_parent_dir).join(DestinationDirectory.new(source_repo_name, destination_dir_name))
20
+ )
21
+ WorkingCopy.new(
22
+ copied_to: copied_to,
23
+ directory: destination_dir_name,
24
+ full_name: source_repo_name,
25
+ )
21
26
  end
22
27
 
23
28
  private
24
29
 
25
- attr_reader :logger, :version_control_system, :user_repo_dir
30
+ attr_reader :logger, :filesystem, :user_repo_dir
31
+
32
+ def copy!(source_copy, dest_dir)
33
+ source_exists = filesystem.file_exist?(source_copy.path)
34
+
35
+ if source_exists && filesystem.file_exist?(dest_dir)
36
+ announce_copy(source_copy)
37
+ dest_dir
38
+ elsif source_exists
39
+ announce_copy(source_copy)
40
+ filesystem.copy_contents(source_copy.path, dest_dir)
41
+ dest_dir
42
+ else
43
+ logger.log ' skipping (not found) '.magenta + source_copy.path.to_s
44
+ end
45
+ end
46
+
47
+ def announce_copy(source_copy)
48
+ logger.log ' copying '.yellow + source_copy.path.to_s
49
+ end
26
50
  end
27
51
  end
28
52
  end
@@ -0,0 +1,31 @@
1
+ require_relative 'destination_directory'
2
+
3
+ module Bookbinder
4
+ module Ingest
5
+ class WorkingCopy
6
+ def initialize(repo_dir: nil,
7
+ copied_to: nil,
8
+ directory: nil,
9
+ full_name: nil)
10
+ @repo_dir = repo_dir
11
+ @copied_to = copied_to
12
+ @directory = directory
13
+ @full_name = full_name
14
+ end
15
+
16
+ attr_reader :copied_to, :full_name
17
+
18
+ def copied?
19
+ ! copied_to.nil?
20
+ end
21
+
22
+ def directory
23
+ DestinationDirectory.new(full_name, @directory).to_s
24
+ end
25
+
26
+ def path
27
+ Pathname(@repo_dir).join(directory)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -10,15 +10,16 @@ module Bookbinder
10
10
  relative_path_to_dita_val = dita_section_config['ditaval_location']
11
11
  full_name = dita_section_config.fetch('repository', {}).fetch('name')
12
12
  target_ref = dita_section_config.fetch('repository', {})['ref']
13
- directory = dita_section_config['directory']
14
- path_to_local_copy = output_locations.local_repo_dir.join(directory)
13
+ desired_destination_directory_name = dita_section_config['directory']
14
+ local_source_directory_name = full_name.split('/').last
15
+ path_to_local_copy = output_locations.local_repo_dir.join(local_source_directory_name)
15
16
 
16
17
  DitaSection.new(path_to_local_copy,
17
18
  relative_path_to_dita_map,
18
19
  relative_path_to_dita_val,
19
20
  full_name,
20
21
  target_ref,
21
- directory,
22
+ desired_destination_directory_name,
22
23
  output_locations)
23
24
  end
24
25
  end
@@ -44,10 +44,7 @@ module Bookbinder
44
44
  FileUtils.mkdir_p(dest)
45
45
  end
46
46
 
47
- contents = Dir.glob File.join(src, '**')
48
- contents.each do |dir|
49
- FileUtils.cp_r dir, dest
50
- end
47
+ FileUtils.cp_r "#{src}/.", dest
51
48
  end
52
49
 
53
50
  def copy_including_intermediate_dirs(file, root, dest)
@@ -37,24 +37,21 @@ module Bookbinder
37
37
  @git_accessor = git_accessor
38
38
  end
39
39
 
40
- def run(middleman_dir,
41
- workspace_dir,
42
- template_variables,
43
- local_repo_dir,
40
+ def run(output_locations,
41
+ config,
42
+ cloner,
44
43
  verbose = false,
45
- subnav_templates_by_directory = {},
46
- production_host=nil,
47
- archive_menu=nil)
44
+ subnav_templates_by_directory = {})
48
45
  @logger.log "\nRunning middleman...\n\n"
49
46
 
50
- within(middleman_dir) do
51
- invoke_against_current_dir(local_repo_dir,
52
- workspace_dir,
53
- production_host,
47
+ within(output_locations.master_dir) do
48
+ invoke_against_current_dir(output_locations.workspace_dir,
49
+ config[:host_for_sitemap],
54
50
  subnav_templates_by_directory,
55
- template_variables,
56
- archive_menu,
57
- verbose)
51
+ config.fetch(:template_variables, {}),
52
+ config[:archive_menu],
53
+ verbose,
54
+ cloner)
58
55
  end
59
56
  end
60
57
 
@@ -65,31 +62,30 @@ module Bookbinder
65
62
  def within(temp_root, &block)
66
63
  Middleman::Cli::Build.instance_variable_set(:@_shared_instance, nil)
67
64
  original_mm_root = ENV['MM_ROOT']
68
- ENV['MM_ROOT'] = temp_root
65
+ ENV['MM_ROOT'] = temp_root.to_s
69
66
 
70
67
  Dir.chdir(temp_root) { block.call }
71
68
 
72
69
  ENV['MM_ROOT'] = original_mm_root
73
70
  end
74
71
 
75
- def invoke_against_current_dir(local_repo_dir,
76
- workspace_dir,
72
+ def invoke_against_current_dir(workspace_dir,
77
73
  production_host,
78
74
  subnav_templates,
79
75
  template_variables,
80
76
  archive_menu,
81
- verbose)
77
+ verbose,
78
+ cloner)
82
79
  builder = Middleman::Cli::Build.shared_instance(verbose)
83
80
 
84
81
  config = {
85
- local_repo_dir: local_repo_dir,
86
- workspace: workspace_dir,
87
- production_host: production_host,
88
- git_accessor: git_accessor,
89
- template_variables: template_variables,
90
- relative_links: false,
91
- subnav_templates: subnav_templates,
92
- archive_menu: archive_menu
82
+ archive_menu: archive_menu,
83
+ cloner: cloner,
84
+ production_host: production_host,
85
+ relative_links: false,
86
+ subnav_templates: subnav_templates,
87
+ template_variables: template_variables,
88
+ workspace: workspace_dir,
93
89
  }
94
90
 
95
91
  config.each { |k, v| builder.config[k] = v }
@@ -1,20 +1,20 @@
1
1
  require 'yaml'
2
- require 'tempfile'
2
+ require 'ansi/code'
3
3
 
4
4
  module Bookbinder
5
5
  class RemoteYamlCredentialProvider
6
- def initialize(logger, repository)
6
+ def initialize(logger, version_control_system)
7
7
  @logger = logger
8
- @repository = repository
8
+ @version_control_system = version_control_system
9
9
  end
10
10
 
11
- def credentials
12
- @logger.log "Processing #{@repository.full_name.cyan}"
13
- Dir.mktmpdir do |destination_dir|
14
- @repository.copy_from_remote(destination_dir, 'master')
15
- cred_file_yaml = File.join(destination_dir, @repository.short_name, 'credentials.yml')
16
- YAML.load_file(cred_file_yaml)
17
- end
11
+ def credentials(repo_url)
12
+ logger.log "Processing #{ANSI.cyan{repo_url}}"
13
+ YAML.load(version_control_system.read_file("credentials.yml", from_repo: repo_url))
18
14
  end
15
+
16
+ private
17
+
18
+ attr_reader :logger, :version_control_system
19
19
  end
20
20
  end
@@ -1,19 +1,24 @@
1
1
  Dir.glob(File.expand_path('../../commands/*.rb', __FILE__)).each do |command_file|
2
2
  require command_file
3
3
  end
4
+
5
+ require_relative '../commands/bind/directory_preparer'
6
+ require_relative '../config/bind_config_factory'
4
7
  require_relative '../configuration_fetcher'
5
8
  require_relative '../configuration_validator'
9
+ require_relative '../dita_command_creator'
6
10
  require_relative '../dita_html_to_middleman_formatter'
7
11
  require_relative '../dita_preprocessor'
8
12
  require_relative '../html_document_manipulator'
9
13
  require_relative '../ingest/cloner_factory'
10
- require_relative '../dita_to_html_converter'
11
14
  require_relative '../local_file_system_accessor'
12
15
  require_relative '../middleman_runner'
13
16
  require_relative '../post_production/sitemap_writer'
17
+ require_relative '../remote_yaml_credential_provider'
18
+ require_relative '../sheller'
14
19
  require_relative '../subnav_formatter'
15
20
  require_relative '../yaml_loader'
16
- require_relative '../config/bind_config_factory'
21
+ require_relative 'section_repository'
17
22
 
18
23
  module Bookbinder
19
24
  module Repositories
@@ -51,7 +56,6 @@ module Bookbinder
51
56
  def standard_commands
52
57
  @standard_commands ||= [
53
58
  build_and_push_tarball,
54
- Commands::GeneratePDF.new(logger, configuration_fetcher),
55
59
  bind,
56
60
  Commands::PushFromLocal.new(logger, configuration_fetcher, 'acceptance'),
57
61
  push_local_to_staging,
@@ -82,8 +86,12 @@ module Bookbinder
82
86
  final_app_directory,
83
87
  File.absolute_path('.'),
84
88
  dita_preprocessor,
85
- Ingest::ClonerFactory.new(logger, version_control_system),
86
- DitaSectionGathererFactory.new(version_control_system, logger)
89
+ Ingest::ClonerFactory.new(logger, local_file_system_accessor, version_control_system),
90
+ DitaSectionGathererFactory.new(version_control_system, logger),
91
+ Repositories::SectionRepository.new(logger),
92
+ dita_command_creator,
93
+ Sheller.new,
94
+ Commands::BindComponents::DirectoryPreparer.new(logger, local_file_system_accessor, version_control_system)
87
95
  )
88
96
  end
89
97
 
@@ -110,7 +118,8 @@ module Bookbinder
110
118
  @configuration_fetcher ||= ConfigurationFetcher.new(
111
119
  logger,
112
120
  ConfigurationValidator.new(logger, local_file_system_accessor),
113
- config_loader
121
+ config_loader,
122
+ RemoteYamlCredentialProvider.new(logger, version_control_system)
114
123
  ).tap do |fetcher|
115
124
  fetcher.set_config_file_path './config.yml'
116
125
  end
@@ -126,15 +135,12 @@ module Bookbinder
126
135
 
127
136
  def dita_preprocessor
128
137
  @dita_preprocessor ||=
129
- DitaPreprocessor.new(local_dita_processor,
130
- dita_html_to_middleman_formatter,
138
+ DitaPreprocessor.new(dita_html_to_middleman_formatter,
131
139
  local_file_system_accessor)
132
140
  end
133
141
 
134
- def local_dita_processor
135
- @local_dita_processor ||=
136
- DitaToHtmlConverter.new(Sheller.new(logger),
137
- ENV['PATH_TO_DITA_OT_LIBRARY'])
142
+ def dita_command_creator
143
+ @dita_command_creator ||= DitaCommandCreator.new(ENV['PATH_TO_DITA_OT_LIBRARY'])
138
144
  end
139
145
 
140
146
  def dita_html_to_middleman_formatter
@@ -7,20 +7,20 @@ module Bookbinder
7
7
  @logger = logger
8
8
  end
9
9
 
10
- def get_instance(attributes,
11
- vcs_repo: nil,
10
+ def get_instance(section_config,
11
+ working_copy: nil,
12
12
  destination_dir: Dir.mktmpdir,
13
13
  &build)
14
- repository_config = attributes['repository']
14
+ repository_config = section_config['repository']
15
15
  raise "section repository '#{repository_config}' is not a hash" unless repository_config.is_a?(Hash)
16
16
  raise "section repository '#{repository_config}' missing name key" unless repository_config['name']
17
17
  logger.log "Gathering #{repository_config['name'].cyan}"
18
- build[vcs_repo.copied_to,
19
- vcs_repo.full_name,
20
- vcs_repo.copied?,
21
- attributes['subnav_template'],
18
+ build[working_copy.copied_to,
19
+ working_copy.full_name,
20
+ working_copy.copied?,
21
+ section_config['subnav_template'],
22
22
  destination_dir,
23
- vcs_repo.directory]
23
+ working_copy.directory]
24
24
  end
25
25
 
26
26
  private