bookbindery 3.1.0 → 3.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/install_bin/bookbinder +1 -1
- data/lib/bookbinder/cf_command_runner.rb +1 -1
- data/lib/bookbinder/cli.rb +5 -5
- data/lib/bookbinder/code_example_reader.rb +57 -19
- data/lib/bookbinder/colorizer.rb +5 -2
- data/lib/bookbinder/commands/bind.rb +32 -42
- data/lib/bookbinder/commands/bind/bind_options.rb +6 -4
- data/lib/bookbinder/commands/bind/directory_preparer.rb +8 -13
- data/lib/bookbinder/{repositories/command_repository.rb → commands/collection.rb} +19 -37
- data/lib/bookbinder/config/archive_menu_configuration.rb +38 -0
- data/lib/bookbinder/config/checkers/archive_menu_checker.rb +35 -0
- data/lib/bookbinder/config/checkers/dita_section_checker.rb +24 -0
- data/lib/bookbinder/config/checkers/duplicate_section_name_checker.rb +29 -0
- data/lib/bookbinder/config/checkers/repository_name_presence_checker.rb +37 -0
- data/lib/bookbinder/config/checkers/required_keys_checker.rb +47 -0
- data/lib/bookbinder/config/configuration.rb +99 -0
- data/lib/bookbinder/config/fetcher.rb +61 -0
- data/lib/bookbinder/config/remote_yaml_credential_provider.rb +22 -0
- data/lib/bookbinder/config/validator.rb +30 -0
- data/lib/bookbinder/config/yaml_loader.rb +34 -0
- data/lib/bookbinder/ingest/git_cloner.rb +0 -1
- data/lib/bookbinder/ingest/local_filesystem_cloner.rb +22 -17
- data/lib/bookbinder/ingest/missing_working_copy.rb +21 -0
- data/lib/bookbinder/{repositories → ingest}/section_repository.rb +3 -4
- data/lib/bookbinder/{repositories → ingest}/section_repository_factory.rb +1 -1
- data/lib/bookbinder/ingest/working_copy.rb +12 -16
- data/lib/bookbinder/preprocessing/copy_to_site_gen_dir.rb +2 -3
- data/lib/bookbinder/preprocessing/dita_preprocessor.rb +5 -5
- data/lib/bookbinder/preprocessing/preprocessor.rb +1 -1
- data/lib/bookbinder/sheller.rb +3 -0
- data/lib/bookbinder/streams/colorized_stream.rb +1 -1
- data/lib/bookbinder/values/cf_routes.rb +17 -6
- data/lib/bookbinder/values/output_locations.rb +1 -12
- data/lib/bookbinder/values/section.rb +2 -7
- data/master_middleman/bookbinder_helpers.rb +23 -18
- data/master_middleman/quicklinks_renderer.rb +1 -0
- data/template_app/lib/rack_static.rb +2 -0
- data/template_app/lib/vienna_application.rb +2 -0
- metadata +51 -52
- data/lib/bookbinder.rb +0 -44
- data/lib/bookbinder/archive_menu_configuration.rb +0 -34
- data/lib/bookbinder/configuration.rb +0 -97
- data/lib/bookbinder/configuration_fetcher.rb +0 -59
- data/lib/bookbinder/configuration_validator.rb +0 -28
- data/lib/bookbinder/remote_yaml_credential_provider.rb +0 -20
- data/lib/bookbinder/shell_out.rb +0 -20
- data/lib/bookbinder/validation_checkers/archive_menu_checker.rb +0 -31
- data/lib/bookbinder/validation_checkers/dita_section_checker.rb +0 -20
- data/lib/bookbinder/validation_checkers/duplicate_section_name_checker.rb +0 -25
- data/lib/bookbinder/validation_checkers/repository_name_presence_checker.rb +0 -33
- data/lib/bookbinder/validation_checkers/required_keys_checker.rb +0 -43
- 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
|
data/lib/bookbinder/shell_out.rb
DELETED
@@ -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
|