bookbindery 3.1.0 → 3.1.2

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 (53) hide show
  1. checksums.yaml +4 -4
  2. data/install_bin/bookbinder +1 -1
  3. data/lib/bookbinder/cf_command_runner.rb +1 -1
  4. data/lib/bookbinder/cli.rb +5 -5
  5. data/lib/bookbinder/code_example_reader.rb +57 -19
  6. data/lib/bookbinder/colorizer.rb +5 -2
  7. data/lib/bookbinder/commands/bind.rb +32 -42
  8. data/lib/bookbinder/commands/bind/bind_options.rb +6 -4
  9. data/lib/bookbinder/commands/bind/directory_preparer.rb +8 -13
  10. data/lib/bookbinder/{repositories/command_repository.rb → commands/collection.rb} +19 -37
  11. data/lib/bookbinder/config/archive_menu_configuration.rb +38 -0
  12. data/lib/bookbinder/config/checkers/archive_menu_checker.rb +35 -0
  13. data/lib/bookbinder/config/checkers/dita_section_checker.rb +24 -0
  14. data/lib/bookbinder/config/checkers/duplicate_section_name_checker.rb +29 -0
  15. data/lib/bookbinder/config/checkers/repository_name_presence_checker.rb +37 -0
  16. data/lib/bookbinder/config/checkers/required_keys_checker.rb +47 -0
  17. data/lib/bookbinder/config/configuration.rb +99 -0
  18. data/lib/bookbinder/config/fetcher.rb +61 -0
  19. data/lib/bookbinder/config/remote_yaml_credential_provider.rb +22 -0
  20. data/lib/bookbinder/config/validator.rb +30 -0
  21. data/lib/bookbinder/config/yaml_loader.rb +34 -0
  22. data/lib/bookbinder/ingest/git_cloner.rb +0 -1
  23. data/lib/bookbinder/ingest/local_filesystem_cloner.rb +22 -17
  24. data/lib/bookbinder/ingest/missing_working_copy.rb +21 -0
  25. data/lib/bookbinder/{repositories → ingest}/section_repository.rb +3 -4
  26. data/lib/bookbinder/{repositories → ingest}/section_repository_factory.rb +1 -1
  27. data/lib/bookbinder/ingest/working_copy.rb +12 -16
  28. data/lib/bookbinder/preprocessing/copy_to_site_gen_dir.rb +2 -3
  29. data/lib/bookbinder/preprocessing/dita_preprocessor.rb +5 -5
  30. data/lib/bookbinder/preprocessing/preprocessor.rb +1 -1
  31. data/lib/bookbinder/sheller.rb +3 -0
  32. data/lib/bookbinder/streams/colorized_stream.rb +1 -1
  33. data/lib/bookbinder/values/cf_routes.rb +17 -6
  34. data/lib/bookbinder/values/output_locations.rb +1 -12
  35. data/lib/bookbinder/values/section.rb +2 -7
  36. data/master_middleman/bookbinder_helpers.rb +23 -18
  37. data/master_middleman/quicklinks_renderer.rb +1 -0
  38. data/template_app/lib/rack_static.rb +2 -0
  39. data/template_app/lib/vienna_application.rb +2 -0
  40. metadata +51 -52
  41. data/lib/bookbinder.rb +0 -44
  42. data/lib/bookbinder/archive_menu_configuration.rb +0 -34
  43. data/lib/bookbinder/configuration.rb +0 -97
  44. data/lib/bookbinder/configuration_fetcher.rb +0 -59
  45. data/lib/bookbinder/configuration_validator.rb +0 -28
  46. data/lib/bookbinder/remote_yaml_credential_provider.rb +0 -20
  47. data/lib/bookbinder/shell_out.rb +0 -20
  48. data/lib/bookbinder/validation_checkers/archive_menu_checker.rb +0 -31
  49. data/lib/bookbinder/validation_checkers/dita_section_checker.rb +0 -20
  50. data/lib/bookbinder/validation_checkers/duplicate_section_name_checker.rb +0 -25
  51. data/lib/bookbinder/validation_checkers/repository_name_presence_checker.rb +0 -33
  52. data/lib/bookbinder/validation_checkers/required_keys_checker.rb +0 -43
  53. data/lib/bookbinder/yaml_loader.rb +0 -33
data/lib/bookbinder.rb DELETED
@@ -1,44 +0,0 @@
1
- require 'fog/aws'
2
- require 'tmpdir'
3
- require 'ansi'
4
- require 'middleman-syntax'
5
- require 'middleman-core/cli'
6
- require 'middleman-core/profiling'
7
- require 'anemone'
8
- require 'css_parser'
9
- require 'vienna'
10
- require 'puma'
11
-
12
- require_relative 'bookbinder/deprecated_logger'
13
- require_relative 'bookbinder/values/section'
14
- require_relative 'bookbinder/remote_yaml_credential_provider'
15
- require_relative 'bookbinder/configuration'
16
- require_relative 'bookbinder/configuration_fetcher'
17
- require_relative 'bookbinder/configuration_validator'
18
- require_relative 'bookbinder/css_link_checker'
19
- require_relative 'bookbinder/sitemap_generator'
20
- require_relative 'bookbinder/sieve'
21
- require_relative 'bookbinder/stabilimentum'
22
- require_relative 'bookbinder/server_director'
23
- require_relative 'bookbinder/spider'
24
-
25
- require_relative 'bookbinder/archive'
26
- require_relative 'bookbinder/middleman_runner'
27
- require_relative 'bookbinder/cf_command_runner'
28
- require_relative 'bookbinder/pusher'
29
- require_relative 'bookbinder/artifact_namer'
30
- require_relative 'bookbinder/distributor'
31
-
32
- require_relative 'bookbinder/commands/bookbinder_command'
33
- require_relative 'bookbinder/commands/build_and_push_tarball'
34
- require_relative 'bookbinder/commands/bind'
35
- require_relative 'bookbinder/commands/push_from_local'
36
- require_relative 'bookbinder/commands/push_to_prod'
37
- require_relative 'bookbinder/commands/run_publish_ci'
38
- require_relative 'bookbinder/commands/update_local_doc_repos'
39
- require_relative 'bookbinder/commands/tag'
40
-
41
- require_relative 'bookbinder/cli'
42
-
43
- # Finds the project root for both spec & production
44
- GEM_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
@@ -1,34 +0,0 @@
1
- module Bookbinder
2
- class ArchiveMenuConfiguration
3
- def initialize(loader: nil, config_filename: nil)
4
- @loader = loader
5
- @config_filename = config_filename
6
- end
7
-
8
- def generate(base_config, sections)
9
- base_config.merge(
10
- Configuration.parse(
11
- 'archive_menu' => root_config(base_config).merge(section_config(sections))))
12
- end
13
-
14
- private
15
-
16
- attr_reader :loader, :config_filename
17
-
18
- def root_config(base_config)
19
- { '.' => base_config.archive_menu }
20
- end
21
-
22
- def section_config(sections)
23
- sections.reduce({}) {|config, section|
24
- config_path = section.path_to_repository.join(config_filename)
25
- archive_config = loader.load_key(config_path, 'archive_menu')
26
- if archive_config
27
- config.merge(section.desired_directory_name => archive_config)
28
- else
29
- config
30
- end
31
- }
32
- end
33
- end
34
- end
@@ -1,97 +0,0 @@
1
- require_relative 'ingest/repo_identifier'
2
- require_relative 'config/section_config'
3
-
4
- module Bookbinder
5
- class Configuration
6
- class << self
7
- def parse(input_config)
8
- new(symbolize_keys(input_config).
9
- merge(expand_repo_identifiers(input_config)).
10
- merge(sections: combined_sections(input_config)))
11
- end
12
-
13
- private
14
-
15
- def symbolize_keys(h)
16
- h.reduce({}) {|acc, (k, v)| acc.merge(k.to_sym => v) }
17
- end
18
-
19
- def expand_repo_identifiers(input_config)
20
- input_config.select {|k, _| k.match(/_repo$/)}.
21
- reduce({}) {|h, (k, v)| h.merge(:"#{k}_url" => Ingest::RepoIdentifier.new(v))}
22
- end
23
-
24
- def combined_sections(input_config)
25
- (regular_sections(input_config) + dita_sections(input_config)).
26
- map { |section| Config::SectionConfig.new(section) }
27
- end
28
-
29
- def regular_sections(input_config)
30
- input_config['sections'] || []
31
- end
32
-
33
- def dita_sections(input_config)
34
- (input_config['dita_sections'] || []).map { |dita_section|
35
- dita_section.merge(
36
- 'preprocessor_config' => {
37
- 'ditamap_location' => dita_section['ditamap_location'],
38
- 'ditaval_location' => dita_section['ditaval_location']
39
- },
40
- 'subnav_template' => 'dita_subnav'
41
- ).reject { |k, _|
42
- %w(ditamap_location ditaval_location).include?(k)
43
- }
44
- }
45
- end
46
- end
47
-
48
- def initialize(config)
49
- @config = config
50
- end
51
-
52
- CONFIG_REQUIRED_KEYS = %w(book_repo public_host)
53
- CONFIG_OPTIONAL_KEYS = %w(archive_menu book_repo_url cred_repo cred_repo_url layout_repo layout_repo_url sections)
54
-
55
- CONFIG_REQUIRED_KEYS.each do |method_name|
56
- define_method(method_name) do
57
- config.fetch(method_name.to_sym)
58
- end
59
- end
60
-
61
- CONFIG_OPTIONAL_KEYS.each do |method_name|
62
- define_method(method_name) do
63
- config[method_name.to_sym]
64
- end
65
- end
66
-
67
- def template_variables
68
- config.fetch(:template_variables, {})
69
- end
70
-
71
- def versions
72
- config.fetch(:versions, [])
73
- end
74
-
75
- def merge(other_configuration)
76
- Configuration.new(config.merge(other_configuration.instance_variable_get(:@config)))
77
- end
78
-
79
- def merge_sections(incoming_sections)
80
- merge(Configuration.new(sections: sections + incoming_sections))
81
- end
82
-
83
- def has_option?(key)
84
- !!config[key.to_sym]
85
- end
86
-
87
- def ==(o)
88
- o.class == self.class && o.instance_variable_get(:@config) == @config
89
- end
90
-
91
- alias_method :eql?, :==
92
-
93
- private
94
-
95
- attr_reader :config
96
- end
97
- end
@@ -1,59 +0,0 @@
1
- require_relative 'config/aws_credentials'
2
- require_relative 'config/cf_credentials'
3
- require_relative 'configuration'
4
- require_relative 'yaml_loader'
5
-
6
- module Bookbinder
7
- class ConfigurationFetcher
8
- def initialize(logger, configuration_validator, loader, credentials_provider)
9
- @loader = loader
10
- @logger = logger
11
- @configuration_validator = configuration_validator
12
- @credentials_provider = credentials_provider
13
- end
14
-
15
- def fetch_config
16
- @config ||= validate(read_config_file)
17
- end
18
-
19
- def fetch_credentials(environment = 'null-environment')
20
- @credentials ||= credentials_provider.credentials(fetch_config.cred_repo_url)
21
- {
22
- aws: Config::AwsCredentials.new(
23
- @credentials.fetch('aws', {})
24
- ),
25
- cloud_foundry: Config::CfCredentials.new(
26
- @credentials.fetch('cloud_foundry', {}),
27
- environment
28
- )
29
- }
30
- end
31
-
32
- def set_config_file_path config_file_path
33
- @config_file_path = File.expand_path config_file_path
34
- end
35
-
36
- private
37
-
38
- attr_reader(:loader, :logger, :configuration_validator, :config, :config_file_path,
39
- :credentials_provider)
40
-
41
- def read_config_file
42
- loader.load(config_file_path)
43
-
44
- rescue FileNotFoundError => e
45
- raise "The configuration file specified does not exist. Please create a config #{e} file at #{config_file_path} and try again."
46
- rescue InvalidSyntaxError => e
47
- raise "There is a syntax error in your config file: \n #{e}"
48
- end
49
-
50
- def validate(config_hash)
51
- raise 'Your config.yml appears to be empty. Please check and try again.' unless config_hash
52
-
53
- errors = configuration_validator.exceptions(config_hash)
54
- raise errors.first if errors.any?
55
-
56
- Configuration.parse(config_hash)
57
- end
58
- end
59
- end
@@ -1,28 +0,0 @@
1
- require_relative 'validation_checkers/duplicate_section_name_checker'
2
- require_relative 'validation_checkers/archive_menu_checker'
3
- require_relative 'validation_checkers/required_keys_checker'
4
- require_relative 'validation_checkers/repository_name_presence_checker'
5
- require_relative 'validation_checkers/dita_section_checker'
6
-
7
- module Bookbinder
8
- class ConfigurationValidator
9
- def initialize(logger, file_system_accessor)
10
- @logger = logger
11
- @file_system_accessor = file_system_accessor
12
- end
13
-
14
- def exceptions(config_hash)
15
- exceptions = [
16
- RequiredKeysChecker.new,
17
- DuplicateSectionNameChecker.new,
18
- RepositoryNamePresenceChecker.new,
19
- DitaSectionChecker.new,
20
- ArchiveMenuChecker.new(@file_system_accessor)
21
- ].map do |checker|
22
- checker.check(config_hash)
23
- end
24
-
25
- exceptions.compact
26
- end
27
- end
28
- end
@@ -1,20 +0,0 @@
1
- require 'yaml'
2
- require 'ansi/code'
3
-
4
- module Bookbinder
5
- class RemoteYamlCredentialProvider
6
- def initialize(logger, version_control_system)
7
- @logger = logger
8
- @version_control_system = version_control_system
9
- end
10
-
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))
14
- end
15
-
16
- private
17
-
18
- attr_reader :logger, :version_control_system
19
- end
20
- end
@@ -1,20 +0,0 @@
1
- require 'open3'
2
-
3
- module Bookbinder
4
- module ShellOut
5
- def shell_out(command, failure_okay = false)
6
- Open3.popen3(command) do |input, stdout, stderr, wait_thr|
7
-
8
- command_failed = (wait_thr.value != 0)
9
- announce_failure(failure_okay, stderr, stdout) if command_failed
10
- stdout.read
11
- end
12
- end
13
-
14
- def announce_failure(failure_okay, stderr, stdout)
15
- contents_of_stderr = stderr.read
16
- error_message = contents_of_stderr.empty? ? stdout.read : contents_of_stderr
17
- raise "\n#{error_message}" unless failure_okay
18
- end
19
- end
20
- end
@@ -1,31 +0,0 @@
1
- module Bookbinder
2
- class ArchiveMenuChecker
3
- MissingArchiveMenuPartialError = Class.new(RuntimeError)
4
- ArchiveMenuNotDefinedError = Class.new(RuntimeError)
5
- EmptyArchiveItemsError = Class.new(RuntimeError)
6
-
7
- def initialize(file_system_accessor)
8
- @file_system_accessor = file_system_accessor
9
- end
10
-
11
- def check(config)
12
- partial_location = './master_middleman/source/archive_menus/_default.erb'
13
- if config.has_key?("archive_menu") && config["archive_menu"].nil?
14
- ArchiveMenuNotDefinedError.new 'Did you mean to provide an archive menu value to display? If you use the archive_menu key, you must provide at least one value.'
15
- elsif archive_items(config).include?(nil)
16
- EmptyArchiveItemsError.new 'Did you forget to add a value to the archive_menu?'
17
- elsif config.has_key?("archive_menu") && !file_system_accessor.file_exist?(partial_location)
18
- MissingArchiveMenuPartialError.new "You must provide a template partial named at #{partial_location}"
19
- end
20
- end
21
-
22
- private
23
-
24
- attr_reader :file_system_accessor
25
-
26
- def archive_items(config)
27
- config.fetch('archive_menu', [])
28
- end
29
-
30
- end
31
- end
@@ -1,20 +0,0 @@
1
- module Bookbinder
2
- class DitaSectionChecker
3
- DitamapLocationError = Class.new(RuntimeError)
4
-
5
- def check(config)
6
- dita_sections = config['dita_sections'].to_a
7
-
8
- sum = 0
9
- dita_sections.each do |section|
10
- if section['ditamap_location']
11
- sum += 1
12
- end
13
- end
14
-
15
- if !dita_sections.empty? && (sum < 1)
16
- DitamapLocationError.new "You must have at least one 'ditamap_location' key in dita_sections."
17
- end
18
- end
19
- end
20
- end
@@ -1,25 +0,0 @@
1
- module Bookbinder
2
- class DuplicateSectionNameChecker
3
- DuplicateSectionNameError = Class.new(RuntimeError)
4
-
5
- def check(config)
6
- if duplicate_section_names?(config)
7
- DuplicateSectionNameError.new error_message
8
- end
9
- end
10
-
11
- private
12
-
13
- def duplicate_section_names?(config)
14
- sections = config['sections'].to_a + config['dita_sections'].to_a
15
- directory_names = sections.map {|section| section['directory']}
16
- directory_names.length != directory_names.uniq.length
17
- end
18
-
19
- def error_message
20
- <<-ERROR
21
- Duplicate repository names are not allowed.
22
- ERROR
23
- end
24
- end
25
- end
@@ -1,33 +0,0 @@
1
- module Bookbinder
2
- class RepositoryNamePresenceChecker
3
- MissingRepositoryNameError = Class.new(RuntimeError)
4
-
5
- def check(config)
6
- all_sections = config['sections'].to_a + config['dita_sections'].to_a
7
- failures = all_sections.map do |section|
8
- if !section['repository'] || !section['repository']['name']
9
- true
10
- end
11
- end
12
-
13
- if failures.compact.empty?
14
- nil
15
- else
16
- MissingRepositoryNameError.new error_message
17
- end
18
- end
19
-
20
- private
21
-
22
- def error_message
23
- <<-ERROR
24
- Cannot locate a specific section.
25
- All sections must provide the section 'name' key under the 'repository' key:
26
-
27
- sections:
28
- - repository:
29
- name: 'your-org/your-repo'
30
- ERROR
31
- end
32
- end
33
- end
@@ -1,43 +0,0 @@
1
- require_relative '../configuration'
2
-
3
- module Bookbinder
4
- class RequiredKeysChecker
5
- MissingRequiredKeyError = Class.new(RuntimeError)
6
- SectionAbsenceError = Class.new(RuntimeError)
7
-
8
- def check(config)
9
- missing_keys = []
10
-
11
- Configuration::CONFIG_REQUIRED_KEYS.map do |required_key|
12
- config_keys = config.keys
13
- unless config_keys.include?(required_key)
14
- missing_keys.push(required_key)
15
- end
16
- end
17
-
18
- if missing_keys.length > 0
19
- MissingRequiredKeyError.new("Your config.yml is missing required key(s). Required keys are #{missing_keys.join(", ")}.")
20
- elsif !config['sections'] && !config['dita_sections']
21
- SectionAbsenceError.new error_message
22
- end
23
- end
24
-
25
- private
26
-
27
- def error_message
28
- <<-ERROR
29
- Cannot locate your sections.
30
- Must specify at least one of 'sections' and/or 'dita_sections' in config.yml:
31
-
32
- sections:
33
- - repository:
34
- name: 'your-org/your-repo'
35
-
36
- dita_sections:
37
- - repository:
38
- name: 'dita-org/dita-repo'
39
- ditamap_location: 'example.ditamap'
40
- ERROR
41
- end
42
- end
43
- end