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.
- checksums.yaml +4 -4
- data/lib/bookbinder.rb +0 -4
- data/lib/bookbinder/cf_command_runner.rb +11 -5
- data/lib/bookbinder/cli.rb +8 -12
- data/lib/bookbinder/colorizer.rb +1 -2
- data/lib/bookbinder/command_runner.rb +0 -2
- data/lib/bookbinder/commands/bind.rb +96 -99
- data/lib/bookbinder/commands/bind/directory_preparer.rb +60 -0
- data/lib/bookbinder/commands/build_and_push_tarball.rb +5 -4
- data/lib/bookbinder/commands/push_from_local.rb +56 -2
- data/lib/bookbinder/commands/push_to_prod.rb +6 -2
- data/lib/bookbinder/commands/tag.rb +15 -3
- data/lib/bookbinder/config/aws_credentials.rb +21 -0
- data/lib/bookbinder/config/cf_credentials.rb +87 -0
- data/lib/bookbinder/configuration.rb +4 -140
- data/lib/bookbinder/configuration_fetcher.rb +28 -4
- data/lib/bookbinder/configuration_validator.rb +11 -164
- data/lib/bookbinder/distributor.rb +16 -12
- data/lib/bookbinder/{dita_to_html_converter.rb → dita_command_creator.rb} +5 -17
- data/lib/bookbinder/dita_preprocessor.rb +14 -12
- data/lib/bookbinder/git_accessor.rb +21 -2
- data/lib/bookbinder/git_hub_repository.rb +0 -43
- data/lib/bookbinder/ingest/cloner_factory.rb +5 -4
- data/lib/bookbinder/ingest/destination_directory.rb +15 -0
- data/lib/bookbinder/ingest/git_hub_repository_cloner.rb +22 -13
- data/lib/bookbinder/ingest/local_filesystem_cloner.rb +38 -14
- data/lib/bookbinder/ingest/working_copy.rb +31 -0
- data/lib/bookbinder/local_dita_section_gatherer.rb +4 -3
- data/lib/bookbinder/local_file_system_accessor.rb +1 -4
- data/lib/bookbinder/middleman_runner.rb +22 -26
- data/lib/bookbinder/remote_yaml_credential_provider.rb +10 -10
- data/lib/bookbinder/repositories/command_repository.rb +18 -12
- data/lib/bookbinder/repositories/section_repository.rb +8 -8
- data/lib/bookbinder/server_director.rb +16 -33
- data/lib/bookbinder/sheller.rb +33 -7
- data/lib/bookbinder/spider.rb +3 -0
- data/lib/bookbinder/streams/switchable_stdout_and_red_stderr.rb +38 -0
- data/lib/bookbinder/terminal.rb +11 -1
- data/lib/bookbinder/validation_checkers/archive_menu_checker.rb +31 -0
- data/lib/bookbinder/validation_checkers/config_version_checker.rb +91 -0
- data/lib/bookbinder/validation_checkers/dita_section_checker.rb +20 -0
- data/lib/bookbinder/validation_checkers/duplicate_section_name_checker.rb +25 -0
- data/lib/bookbinder/validation_checkers/repository_name_presence_checker.rb +33 -0
- data/lib/bookbinder/validation_checkers/required_keys_checker.rb +43 -0
- data/lib/bookbinder/values/dita_section.rb +5 -1
- data/lib/bookbinder/values/output_locations.rb +25 -2
- data/lib/bookbinder/values/user_message.rb +2 -2
- data/master_middleman/bookbinder_helpers.rb +5 -15
- data/template_app/Gemfile.lock +1 -1
- metadata +60 -80
- data/lib/bookbinder/commands/generate_pdf.rb +0 -141
- data/lib/bookbinder/pdf_generator.rb +0 -73
- data/lib/bookbinder/publisher.rb +0 -58
- data/lib/bookbinder/user_message_presenter.rb +0 -21
@@ -1,6 +1,7 @@
|
|
1
|
-
require_relative 'naming'
|
2
|
-
require_relative 'bookbinder_command'
|
3
1
|
require_relative '../archive'
|
2
|
+
require_relative '../ingest/destination_directory'
|
3
|
+
require_relative 'bookbinder_command'
|
4
|
+
require_relative 'naming'
|
4
5
|
|
5
6
|
module Bookbinder
|
6
7
|
module Commands
|
@@ -21,10 +22,10 @@ module Bookbinder
|
|
21
22
|
def run(_)
|
22
23
|
raise MissingBuildNumber unless ENV['BUILD_NUMBER']
|
23
24
|
config = configuration_fetcher.fetch_config
|
24
|
-
aws_credentials =
|
25
|
+
aws_credentials = configuration_fetcher.fetch_credentials[:aws]
|
25
26
|
archive = Archive.new(logger: @logger, key: aws_credentials.access_key, secret: aws_credentials.secret_key)
|
26
27
|
archive.create_and_upload_tarball(build_number: ENV['BUILD_NUMBER'], bucket: aws_credentials.green_builds_bucket,
|
27
|
-
namespace:
|
28
|
+
namespace: Ingest::DestinationDirectory.new(config.book_repo, nil))
|
28
29
|
0
|
29
30
|
end
|
30
31
|
end
|
@@ -7,6 +7,10 @@ module Bookbinder
|
|
7
7
|
class PushFromLocal
|
8
8
|
include Commands::Naming
|
9
9
|
|
10
|
+
CredentialKeyError = Class.new(RuntimeError)
|
11
|
+
REQUIRED_AWS_KEYS = %w(access_key secret_key green_builds_bucket)
|
12
|
+
REQUIRED_CF_KEYS = %w(username password api_endpoint organization app_name)
|
13
|
+
|
10
14
|
def initialize(logger, configuration_fetcher, environment)
|
11
15
|
@logger = logger
|
12
16
|
@configuration_fetcher = configuration_fetcher
|
@@ -19,6 +23,7 @@ module Bookbinder
|
|
19
23
|
end
|
20
24
|
|
21
25
|
def run(_)
|
26
|
+
validate
|
22
27
|
Distributor.build(@logger, options).distribute
|
23
28
|
0
|
24
29
|
end
|
@@ -36,16 +41,65 @@ module Bookbinder
|
|
36
41
|
end
|
37
42
|
|
38
43
|
def options
|
44
|
+
credentials = configuration_fetcher.fetch_credentials(environment)
|
39
45
|
{
|
40
46
|
app_dir: './final_app',
|
41
47
|
build_number: ENV['BUILD_NUMBER'],
|
42
48
|
|
43
|
-
aws_credentials:
|
44
|
-
cf_credentials:
|
49
|
+
aws_credentials: credentials[:aws],
|
50
|
+
cf_credentials: credentials[:cloud_foundry],
|
45
51
|
|
46
52
|
book_repo: config.book_repo,
|
47
53
|
}
|
48
54
|
end
|
55
|
+
|
56
|
+
def error_message
|
57
|
+
<<-ERROR
|
58
|
+
Cannot locate a specific key in credentials.yml.
|
59
|
+
Your credentials file should follow this format:
|
60
|
+
|
61
|
+
aws:
|
62
|
+
access_key: <your_AWS_access_key>
|
63
|
+
secret_key: <your_AWS_secret_key>
|
64
|
+
green_builds_bucket: <your_AWS_bucket>
|
65
|
+
|
66
|
+
cloud_foundry:
|
67
|
+
username: <your_CF_account>
|
68
|
+
password: <your_CF_password>
|
69
|
+
staging_space: <your_CF_staging_space_name>
|
70
|
+
staging_host: <your_CF_staging_host_name>
|
71
|
+
<your-domain.com>:
|
72
|
+
- <your_hostname>
|
73
|
+
production_space: <your_CF_production_space_name>
|
74
|
+
production_host: <your_CF_production_host_name>
|
75
|
+
<your-domain.com>:
|
76
|
+
- <your_hostname>
|
77
|
+
app_name: <your_app_name>
|
78
|
+
api_endpoint: <your_api_endpoint>
|
79
|
+
organization: <your_organization>
|
80
|
+
ERROR
|
81
|
+
end
|
82
|
+
|
83
|
+
def validate
|
84
|
+
missing_keys = []
|
85
|
+
|
86
|
+
creds = configuration_fetcher.fetch_credentials(environment)
|
87
|
+
aws_creds = creds[:aws]
|
88
|
+
cf_creds = creds[:cloud_foundry]
|
89
|
+
|
90
|
+
missing_keys << 'aws' unless aws_creds
|
91
|
+
missing_keys << 'cloud_foundry' unless cf_creds
|
92
|
+
|
93
|
+
REQUIRED_AWS_KEYS.map do |key|
|
94
|
+
missing_keys << key unless aws_creds.send(key)
|
95
|
+
end
|
96
|
+
|
97
|
+
REQUIRED_CF_KEYS.each do |key|
|
98
|
+
missing_keys << key unless cf_creds.send(key)
|
99
|
+
end
|
100
|
+
|
101
|
+
raise CredentialKeyError.new error_message if missing_keys.any?
|
102
|
+
end
|
49
103
|
end
|
50
104
|
end
|
51
105
|
end
|
@@ -37,13 +37,17 @@ module Bookbinder
|
|
37
37
|
app_dir: Dir.mktmpdir,
|
38
38
|
build_number: arguments[0],
|
39
39
|
|
40
|
-
aws_credentials:
|
41
|
-
cf_credentials:
|
40
|
+
aws_credentials: credentials[:aws],
|
41
|
+
cf_credentials: credentials[:cloud_foundry],
|
42
42
|
|
43
43
|
book_repo: config.book_repo,
|
44
44
|
}
|
45
45
|
end
|
46
46
|
|
47
|
+
def credentials
|
48
|
+
configuration_fetcher.fetch_credentials('production')
|
49
|
+
end
|
50
|
+
|
47
51
|
def config
|
48
52
|
@config ||= configuration_fetcher.fetch_config
|
49
53
|
end
|
@@ -1,14 +1,18 @@
|
|
1
1
|
require_relative '../book'
|
2
|
-
require_relative '../errors/cli_error'
|
3
2
|
require_relative '../deprecated_logger'
|
4
|
-
require_relative '
|
3
|
+
require_relative '../errors/cli_error'
|
5
4
|
require_relative 'naming'
|
6
5
|
|
7
6
|
module Bookbinder
|
8
7
|
module Commands
|
9
|
-
class Tag
|
8
|
+
class Tag
|
10
9
|
include Commands::Naming
|
11
10
|
|
11
|
+
def initialize(logger, configuration_fetcher)
|
12
|
+
@logger = logger
|
13
|
+
@configuration_fetcher = configuration_fetcher
|
14
|
+
end
|
15
|
+
|
12
16
|
def usage
|
13
17
|
["tag <git tag>", "Apply the specified <git tag> to your book and all sections of your book"]
|
14
18
|
end
|
@@ -25,6 +29,14 @@ module Bookbinder
|
|
25
29
|
@logger.log " #{book.full_name.yellow} and its sections were tagged with #{tag.blue}"
|
26
30
|
0
|
27
31
|
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
attr_reader :configuration_fetcher
|
36
|
+
|
37
|
+
def config
|
38
|
+
@config ||= configuration_fetcher.fetch_config
|
39
|
+
end
|
28
40
|
end
|
29
41
|
end
|
30
42
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Bookbinder
|
2
|
+
module Config
|
3
|
+
class AwsCredentials
|
4
|
+
REQUIRED_KEYS = %w(access_key secret_key green_builds_bucket)
|
5
|
+
|
6
|
+
def initialize(aws_cred_hash)
|
7
|
+
@creds = aws_cred_hash
|
8
|
+
end
|
9
|
+
|
10
|
+
REQUIRED_KEYS.each do |method_name|
|
11
|
+
define_method(method_name) do
|
12
|
+
creds[method_name]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
attr_reader :creds
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module Bookbinder
|
2
|
+
module Config
|
3
|
+
class CfCredentials
|
4
|
+
REQUIRED_KEYS = %w(username password api_endpoint organization app_name)
|
5
|
+
CredentialKeyError = Class.new(RuntimeError)
|
6
|
+
|
7
|
+
def initialize(cf_cred_hash, environment)
|
8
|
+
@creds = cf_cred_hash
|
9
|
+
@environment = environment
|
10
|
+
end
|
11
|
+
|
12
|
+
REQUIRED_KEYS.each do |method_name|
|
13
|
+
define_method(method_name) do
|
14
|
+
creds[method_name]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def ==(other)
|
19
|
+
[@creds, @environment] == [
|
20
|
+
other.instance_variable_get(:@creds),
|
21
|
+
other.instance_variable_get(:@environment)
|
22
|
+
]
|
23
|
+
end
|
24
|
+
|
25
|
+
def download_archive_before_push?
|
26
|
+
production?
|
27
|
+
end
|
28
|
+
|
29
|
+
def push_warning
|
30
|
+
if production?
|
31
|
+
'Warning: You are pushing to CF Docs production. Be careful.'
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def routes
|
36
|
+
fetch(host_key) if correctly_formatted_domain_and_routes?(host_key)
|
37
|
+
end
|
38
|
+
|
39
|
+
def flat_routes
|
40
|
+
routes.reduce([]) do |all_routes, domain_apps|
|
41
|
+
domain, apps = domain_apps
|
42
|
+
all_routes + apps.map { |app| [domain, app] }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def space
|
47
|
+
fetch(space_key)
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
attr_reader :creds, :environment
|
53
|
+
|
54
|
+
def production?
|
55
|
+
environment == 'production'
|
56
|
+
end
|
57
|
+
|
58
|
+
def fetch(key)
|
59
|
+
creds.fetch(key)
|
60
|
+
rescue KeyError => e
|
61
|
+
raise CredentialKeyError, e
|
62
|
+
end
|
63
|
+
|
64
|
+
def correctly_formatted_domain_and_routes?(deploy_environment)
|
65
|
+
routes_hash = fetch(deploy_environment)
|
66
|
+
domains = routes_hash.keys
|
67
|
+
domains.each { |domain| correctly_formatted_domain?(domain, routes_hash) }
|
68
|
+
end
|
69
|
+
|
70
|
+
def correctly_formatted_domain?(domain, routes_hash)
|
71
|
+
raise 'Each domain in credentials must be a single string.' unless domain.is_a? String
|
72
|
+
raise "Domain #{domain} in credentials must contain a web extension, e.g. '.com'." unless domain.include?('.')
|
73
|
+
raise "Did you mean to add a list of hosts for domain #{domain}? Check your credentials.yml." unless routes_hash[domain]
|
74
|
+
raise "Hosts in credentials must be nested as an array under the desired domain #{domain}." unless routes_hash[domain].is_a? Array
|
75
|
+
raise "Did you mean to provide a hostname for the domain #{domain}? Check your credentials.yml." if routes_hash[domain].any?(&:nil?)
|
76
|
+
end
|
77
|
+
|
78
|
+
def host_key
|
79
|
+
"#{environment}_host"
|
80
|
+
end
|
81
|
+
|
82
|
+
def space_key
|
83
|
+
"#{environment}_space"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -1,128 +1,10 @@
|
|
1
|
-
require 'git'
|
2
|
-
require_relative 'git_hub_repository'
|
3
|
-
require_relative 'remote_yaml_credential_provider'
|
4
|
-
|
5
1
|
module Bookbinder
|
6
2
|
class Configuration
|
7
3
|
|
8
4
|
CURRENT_SCHEMA_VERSION = '1.0.0'
|
9
5
|
STARTING_SCHEMA_VERSION = '1.0.0'
|
10
6
|
|
11
|
-
|
12
|
-
ConfigSchemaUnsupportedError = Class.new(StandardError)
|
13
|
-
|
14
|
-
class AwsCredentials
|
15
|
-
REQUIRED_KEYS = %w(access_key secret_key green_builds_bucket)
|
16
|
-
|
17
|
-
def initialize(cred_hash)
|
18
|
-
@creds = cred_hash
|
19
|
-
end
|
20
|
-
|
21
|
-
REQUIRED_KEYS.each do |method_name|
|
22
|
-
define_method(method_name) do
|
23
|
-
begin
|
24
|
-
creds.fetch(method_name)
|
25
|
-
rescue KeyError => e
|
26
|
-
raise CredentialKeyError, e
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
private
|
32
|
-
|
33
|
-
attr_reader :creds
|
34
|
-
end
|
35
|
-
|
36
|
-
class CfCredentials
|
37
|
-
REQUIRED_KEYS = %w(api_endpoint organization app_name)
|
38
|
-
|
39
|
-
def initialize(cred_hash, environment)
|
40
|
-
@creds = cred_hash
|
41
|
-
@environment = environment
|
42
|
-
end
|
43
|
-
|
44
|
-
REQUIRED_KEYS.each do |method_name|
|
45
|
-
define_method(method_name) do
|
46
|
-
fetch(method_name)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def ==(other)
|
51
|
-
[@creds, @environment] == [
|
52
|
-
other.instance_variable_get(:@creds),
|
53
|
-
other.instance_variable_get(:@environment)
|
54
|
-
]
|
55
|
-
end
|
56
|
-
|
57
|
-
def username
|
58
|
-
creds['username']
|
59
|
-
end
|
60
|
-
|
61
|
-
def password
|
62
|
-
creds['password']
|
63
|
-
end
|
64
|
-
|
65
|
-
def download_archive_before_push?
|
66
|
-
production?
|
67
|
-
end
|
68
|
-
|
69
|
-
def push_warning
|
70
|
-
if production?
|
71
|
-
'Warning: You are pushing to CF Docs production. Be careful.'
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
def routes
|
76
|
-
fetch(host_key) if correctly_formatted_domain_and_routes?(host_key)
|
77
|
-
end
|
78
|
-
|
79
|
-
def flat_routes
|
80
|
-
routes.reduce([]) do |all_routes, domain_apps|
|
81
|
-
domain, apps = domain_apps
|
82
|
-
all_routes + apps.map { |app| [domain, app] }
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
def space
|
87
|
-
fetch(space_key)
|
88
|
-
end
|
89
|
-
|
90
|
-
private
|
91
|
-
|
92
|
-
attr_reader :creds, :environment
|
93
|
-
|
94
|
-
def production?
|
95
|
-
environment == 'production'
|
96
|
-
end
|
97
|
-
|
98
|
-
def fetch(key)
|
99
|
-
creds.fetch(key)
|
100
|
-
rescue KeyError => e
|
101
|
-
raise CredentialKeyError, e
|
102
|
-
end
|
103
|
-
|
104
|
-
def correctly_formatted_domain_and_routes?(deploy_environment)
|
105
|
-
routes_hash = fetch(deploy_environment)
|
106
|
-
domains = routes_hash.keys
|
107
|
-
domains.each { |domain| correctly_formatted_domain?(domain, routes_hash) }
|
108
|
-
end
|
109
|
-
|
110
|
-
def correctly_formatted_domain?(domain, routes_hash)
|
111
|
-
raise 'Each domain in credentials must be a single string.' unless domain.is_a? String
|
112
|
-
raise "Domain #{domain} in credentials must contain a web extension, e.g. '.com'." unless domain.include?('.')
|
113
|
-
raise "Did you mean to add a list of hosts for domain #{domain}? Check your credentials.yml." unless routes_hash[domain]
|
114
|
-
raise "Hosts in credentials must be nested as an array under the desired domain #{domain}." unless routes_hash[domain].is_a? Array
|
115
|
-
raise "Did you mean to provide a hostname for the domain #{domain}? Check your credentials.yml." if routes_hash[domain].any?(&:nil?)
|
116
|
-
end
|
117
|
-
|
118
|
-
def host_key
|
119
|
-
"#{environment}_host"
|
120
|
-
end
|
121
|
-
|
122
|
-
def space_key
|
123
|
-
"#{environment}_space"
|
124
|
-
end
|
125
|
-
end
|
7
|
+
ConfigSchemaUnsupportedError = Class.new(RuntimeError)
|
126
8
|
|
127
9
|
attr_reader :schema_version, :schema_major_version, :schema_minor_version, :schema_patch_version
|
128
10
|
|
@@ -132,7 +14,7 @@ module Bookbinder
|
|
132
14
|
end
|
133
15
|
|
134
16
|
CONFIG_REQUIRED_KEYS = %w(book_repo public_host)
|
135
|
-
CONFIG_OPTIONAL_KEYS = %w(archive_menu layout_repo versions
|
17
|
+
CONFIG_OPTIONAL_KEYS = %w(archive_menu layout_repo versions cred_repo)
|
136
18
|
|
137
19
|
CONFIG_REQUIRED_KEYS.each do |method_name|
|
138
20
|
define_method(method_name) do
|
@@ -162,32 +44,14 @@ module Bookbinder
|
|
162
44
|
config.fetch('template_variables', {})
|
163
45
|
end
|
164
46
|
|
165
|
-
def aws_credentials
|
166
|
-
@aws_creds ||= AwsCredentials.new(credentials.fetch('aws'))
|
167
|
-
end
|
168
|
-
|
169
|
-
def cf_credentials(environment)
|
170
|
-
CfCredentials.new(credentials.fetch('cloud_foundry'), environment)
|
171
|
-
end
|
172
|
-
|
173
47
|
def ==(o)
|
174
|
-
|
48
|
+
o.class == self.class && o.instance_variable_get(:@config) == @config
|
175
49
|
end
|
176
50
|
|
177
51
|
alias_method :eql?, :==
|
178
52
|
|
179
|
-
protected
|
180
|
-
|
181
|
-
attr_reader :config
|
182
|
-
|
183
53
|
private
|
184
54
|
|
185
|
-
|
186
|
-
@credentials ||= RemoteYamlCredentialProvider.new(@logger, credentials_repository).credentials
|
187
|
-
end
|
188
|
-
|
189
|
-
def credentials_repository
|
190
|
-
@credentials_repository ||= GitHubRepository.new(logger: @logger, full_name: cred_repo, git_accessor: Git)
|
191
|
-
end
|
55
|
+
attr_reader :config
|
192
56
|
end
|
193
57
|
end
|