bookbindery 3.1.0 → 3.1.2

Sign up to get free protection for your applications and to get access to all the features.
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