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