bookbindery 8.5.0 → 9.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bookbinder.gemspec +1 -1
- data/lib/bookbinder/cli.rb +36 -55
- data/lib/bookbinder/commands/bind.rb +3 -19
- data/lib/bookbinder/commands/collection.rb +33 -73
- data/lib/bookbinder/commands/components/command_options.rb +3 -22
- data/lib/bookbinder/commands/generate.rb +0 -11
- data/lib/bookbinder/commands/imprint.rb +3 -10
- data/lib/bookbinder/commands/punch.rb +0 -11
- data/lib/bookbinder/commands/update_local_doc_repos.rb +1 -9
- data/lib/bookbinder/commands/watch.rb +1 -10
- data/lib/bookbinder/config/fetcher.rb +2 -18
- data/lib/bookbinder/preprocessing/dita_html_preprocessor.rb +3 -6
- data/lib/bookbinder/preprocessing/dita_pdf_preprocessor.rb +3 -5
- data/lib/bookbinder/terminal.rb +0 -1
- metadata +3 -31
- data/lib/bookbinder/cf_command_runner.rb +0 -123
- data/lib/bookbinder/command_runner.rb +0 -23
- data/lib/bookbinder/command_validator.rb +0 -51
- data/lib/bookbinder/commands/build_and_push_tarball.rb +0 -38
- data/lib/bookbinder/commands/chain.rb +0 -11
- data/lib/bookbinder/commands/help.rb +0 -70
- data/lib/bookbinder/commands/naming.rb +0 -29
- data/lib/bookbinder/commands/push_from_local.rb +0 -132
- data/lib/bookbinder/commands/push_to_prod.rb +0 -66
- data/lib/bookbinder/commands/run_publish_ci.rb +0 -37
- data/lib/bookbinder/commands/version.rb +0 -29
- data/lib/bookbinder/config/aws_credentials.rb +0 -21
- data/lib/bookbinder/config/cf_credentials.rb +0 -62
- data/lib/bookbinder/config/remote_yaml_credential_provider.rb +0 -22
- data/lib/bookbinder/deploy/app_fetcher.rb +0 -36
- data/lib/bookbinder/deploy/archive.rb +0 -102
- data/lib/bookbinder/deploy/artifact.rb +0 -26
- data/lib/bookbinder/deploy/blue_green_app.rb +0 -29
- data/lib/bookbinder/deploy/cf_routes.rb +0 -32
- data/lib/bookbinder/deploy/deployment.rb +0 -55
- data/lib/bookbinder/deploy/distributor.rb +0 -76
- data/lib/bookbinder/deploy/failure.rb +0 -15
- data/lib/bookbinder/deploy/pusher.rb +0 -34
- data/lib/bookbinder/deploy/success.rb +0 -16
- data/lib/bookbinder/deprecated_logger.rb +0 -33
- data/lib/bookbinder/errors/cli_error.rb +0 -6
- data/lib/bookbinder/legacy/cli.rb +0 -71
- data/lib/bookbinder/preprocessing/dita_preprocessor.rb +0 -17
@@ -1,38 +0,0 @@
|
|
1
|
-
require_relative '../deploy/archive'
|
2
|
-
require_relative '../ingest/destination_directory'
|
3
|
-
require_relative 'naming'
|
4
|
-
|
5
|
-
module Bookbinder
|
6
|
-
module Commands
|
7
|
-
class BuildAndPushTarball
|
8
|
-
def initialize(streams, configuration_fetcher)
|
9
|
-
@success = streams[:success]
|
10
|
-
@configuration_fetcher = configuration_fetcher
|
11
|
-
end
|
12
|
-
|
13
|
-
include Commands::Naming
|
14
|
-
|
15
|
-
def usage
|
16
|
-
[command_name,
|
17
|
-
"Create a tarball from the final_app directory and push to the S3 bucket specified in your credentials.yml"]
|
18
|
-
end
|
19
|
-
|
20
|
-
def run(_)
|
21
|
-
config = configuration_fetcher.fetch_config
|
22
|
-
aws_credentials = configuration_fetcher.fetch_credentials[:aws]
|
23
|
-
archive = Deploy::Archive.new(key: aws_credentials.access_key, secret: aws_credentials.secret_key)
|
24
|
-
result = archive.create_and_upload_tarball(
|
25
|
-
build_number: ENV.fetch('BUILD_NUMBER', Time.now.strftime("%Y%m%d_%H%M")),
|
26
|
-
bucket: aws_credentials.green_builds_bucket,
|
27
|
-
namespace: Ingest::DestinationDirectory.new(config.book_repo)
|
28
|
-
)
|
29
|
-
success.puts(result.reason)
|
30
|
-
0
|
31
|
-
end
|
32
|
-
|
33
|
-
private
|
34
|
-
|
35
|
-
attr_reader :configuration_fetcher, :success
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
@@ -1,70 +0,0 @@
|
|
1
|
-
require_relative 'naming'
|
2
|
-
|
3
|
-
module Bookbinder
|
4
|
-
module Commands
|
5
|
-
class Help
|
6
|
-
include Commands::Naming
|
7
|
-
|
8
|
-
def initialize(logger, other_commands)
|
9
|
-
@logger = logger
|
10
|
-
@other_commands = other_commands
|
11
|
-
end
|
12
|
-
|
13
|
-
def usage
|
14
|
-
[command_name, "Print this message"]
|
15
|
-
end
|
16
|
-
|
17
|
-
def run(*)
|
18
|
-
logger.log(usage_message)
|
19
|
-
0
|
20
|
-
end
|
21
|
-
|
22
|
-
def usage_message
|
23
|
-
[usage_header, command_usage_messages].join("\n")
|
24
|
-
end
|
25
|
-
|
26
|
-
private
|
27
|
-
|
28
|
-
def command_name
|
29
|
-
'--help'
|
30
|
-
end
|
31
|
-
|
32
|
-
def command_usage_messages
|
33
|
-
(flags + standard_commands).reduce('') { |message, command|
|
34
|
-
"#{message}#{usage_indent}#{formatted_usage(command)}\n"
|
35
|
-
}
|
36
|
-
end
|
37
|
-
|
38
|
-
def formatted_usage(command)
|
39
|
-
"#{command.usage[0].ljust(chars_for_usage_definition)}#{command.usage[1]}"
|
40
|
-
end
|
41
|
-
|
42
|
-
def usage_indent
|
43
|
-
" " * 4
|
44
|
-
end
|
45
|
-
|
46
|
-
def chars_for_usage_definition
|
47
|
-
72
|
48
|
-
end
|
49
|
-
|
50
|
-
def flags
|
51
|
-
other_commands.select(&:flag?) + [self]
|
52
|
-
end
|
53
|
-
|
54
|
-
def standard_commands
|
55
|
-
other_commands.reject(&:flag?)
|
56
|
-
end
|
57
|
-
|
58
|
-
def usage_header
|
59
|
-
<<TEXT
|
60
|
-
|
61
|
-
\e[1;39;49mDocumentation\e[0m: https://github.com/pivotal-cf/docs-bookbinder
|
62
|
-
|
63
|
-
\e[1;39;49mUsage\e[0m: bookbinder <command|flag> [args]
|
64
|
-
TEXT
|
65
|
-
end
|
66
|
-
|
67
|
-
attr_reader :logger, :other_commands
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
require 'active_support/inflector'
|
2
|
-
|
3
|
-
module Bookbinder
|
4
|
-
module Commands
|
5
|
-
module Naming
|
6
|
-
def command_for?(test_command_name)
|
7
|
-
command_name == test_command_name
|
8
|
-
end
|
9
|
-
|
10
|
-
def flag?
|
11
|
-
command_name.match(/^--/)
|
12
|
-
end
|
13
|
-
|
14
|
-
def command_type
|
15
|
-
if flag?
|
16
|
-
'flag'
|
17
|
-
else
|
18
|
-
'command'
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
private
|
23
|
-
|
24
|
-
def command_name
|
25
|
-
self.class.name.demodulize.underscore
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
@@ -1,132 +0,0 @@
|
|
1
|
-
require_relative '../deploy/deployment'
|
2
|
-
require_relative '../deploy/distributor'
|
3
|
-
require_relative 'naming'
|
4
|
-
|
5
|
-
module Bookbinder
|
6
|
-
module Commands
|
7
|
-
class PushFromLocal
|
8
|
-
include Commands::Naming
|
9
|
-
|
10
|
-
CredentialKeyError = Class.new(RuntimeError)
|
11
|
-
FeedbackConfigError = Class.new(RuntimeError)
|
12
|
-
REQUIRED_AWS_KEYS = %w(access_key secret_key green_builds_bucket)
|
13
|
-
REQUIRED_CF_KEYS = %w(username password api_endpoint organization app_name)
|
14
|
-
|
15
|
-
def initialize(streams, logger, configuration_fetcher)
|
16
|
-
@streams = streams
|
17
|
-
@logger = logger
|
18
|
-
@configuration_fetcher = configuration_fetcher
|
19
|
-
end
|
20
|
-
|
21
|
-
def usage
|
22
|
-
["push_local_to <environment>",
|
23
|
-
"Push the contents of final_app to the specified environment using the credentials.yml"]
|
24
|
-
end
|
25
|
-
|
26
|
-
def run(cli_arguments)
|
27
|
-
@environment = cli_arguments.first
|
28
|
-
validate
|
29
|
-
deployment = Deploy::Deployment.new(
|
30
|
-
app_dir: './final_app',
|
31
|
-
aws_credentials: credentials[:aws],
|
32
|
-
book_repo: config.book_repo,
|
33
|
-
build_number: ENV['BUILD_NUMBER'],
|
34
|
-
cf_credentials: credentials[:cloud_foundry]
|
35
|
-
)
|
36
|
-
archive = Deploy::Archive.new(
|
37
|
-
logger: @logger,
|
38
|
-
key: deployment.aws_access_key,
|
39
|
-
secret: deployment.aws_secret_key
|
40
|
-
)
|
41
|
-
Deploy::Distributor.build(
|
42
|
-
streams,
|
43
|
-
archive,
|
44
|
-
deployment
|
45
|
-
).distribute
|
46
|
-
0
|
47
|
-
end
|
48
|
-
|
49
|
-
private
|
50
|
-
|
51
|
-
attr_reader :configuration_fetcher, :environment, :streams
|
52
|
-
|
53
|
-
def command_name
|
54
|
-
'push_local_to'
|
55
|
-
end
|
56
|
-
|
57
|
-
def config
|
58
|
-
configuration_fetcher.fetch_config
|
59
|
-
end
|
60
|
-
|
61
|
-
def credentials
|
62
|
-
configuration_fetcher.fetch_credentials(environment)
|
63
|
-
end
|
64
|
-
|
65
|
-
def creds_error_message
|
66
|
-
<<-ERROR
|
67
|
-
Cannot locate a specific key in credentials.yml.
|
68
|
-
Your credentials file should follow this format:
|
69
|
-
|
70
|
-
aws:
|
71
|
-
access_key: <your_AWS_access_key>
|
72
|
-
secret_key: <your_AWS_secret_key>
|
73
|
-
green_builds_bucket: <your_AWS_bucket>
|
74
|
-
|
75
|
-
cloud_foundry:
|
76
|
-
username: <your_CF_account>
|
77
|
-
password: <your_CF_password>
|
78
|
-
staging_space: <your_CF_staging_space_name>
|
79
|
-
staging_host: <your_CF_staging_host_name>
|
80
|
-
<your-domain.com>:
|
81
|
-
- <your_hostname>
|
82
|
-
production_space: <your_CF_production_space_name>
|
83
|
-
production_host: <your_CF_production_host_name>
|
84
|
-
<your-domain.com>:
|
85
|
-
- <your_hostname>
|
86
|
-
app_name: <your_app_name>
|
87
|
-
api_endpoint: <your_api_endpoint>
|
88
|
-
organization: <your_organization>
|
89
|
-
ERROR
|
90
|
-
end
|
91
|
-
|
92
|
-
def mail_error_message
|
93
|
-
<<-ERROR
|
94
|
-
Your environment variables for sending feedback are not set.
|
95
|
-
|
96
|
-
To enable feedback, you must set the following variables in your environment:
|
97
|
-
|
98
|
-
export SENDGRID_USERNAME=<your-username>
|
99
|
-
export SENDGRID_API_KEY=<your-api-key>
|
100
|
-
export FEEDBACK_TO=<email-to-receive-feedback>
|
101
|
-
export FEEDBACK_FROM=<email-to-send-feedback>
|
102
|
-
ERROR
|
103
|
-
end
|
104
|
-
|
105
|
-
def validate
|
106
|
-
missing_keys = []
|
107
|
-
|
108
|
-
creds = configuration_fetcher.fetch_credentials(environment)
|
109
|
-
aws_creds = creds[:aws]
|
110
|
-
cf_creds = creds[:cloud_foundry]
|
111
|
-
|
112
|
-
missing_keys << 'aws' unless aws_creds
|
113
|
-
missing_keys << 'cloud_foundry' unless cf_creds
|
114
|
-
|
115
|
-
REQUIRED_AWS_KEYS.map do |key|
|
116
|
-
missing_keys << key unless aws_creds.send(key)
|
117
|
-
end
|
118
|
-
|
119
|
-
REQUIRED_CF_KEYS.each do |key|
|
120
|
-
missing_keys << key unless cf_creds.send(key)
|
121
|
-
end
|
122
|
-
|
123
|
-
raise CredentialKeyError.new(creds_error_message) if missing_keys.any?
|
124
|
-
raise FeedbackConfigError.new(mail_error_message) if config.feedback_enabled && mail_vars_absent?
|
125
|
-
end
|
126
|
-
|
127
|
-
def mail_vars_absent?
|
128
|
-
!(ENV['SENDGRID_USERNAME'] && ENV['SENDGRID_API_KEY'] && ENV['FEEDBACK_TO'] && ENV['FEEDBACK_FROM'])
|
129
|
-
end
|
130
|
-
end
|
131
|
-
end
|
132
|
-
end
|
@@ -1,66 +0,0 @@
|
|
1
|
-
require_relative '../deploy/archive'
|
2
|
-
require_relative '../deploy/deployment'
|
3
|
-
require_relative '../deploy/distributor'
|
4
|
-
require_relative 'naming'
|
5
|
-
|
6
|
-
module Bookbinder
|
7
|
-
module Commands
|
8
|
-
class PushToProd
|
9
|
-
include Commands::Naming
|
10
|
-
MissingRequiredKeyError = Class.new(RuntimeError)
|
11
|
-
|
12
|
-
def initialize(streams, logger, configuration_fetcher, app_dir)
|
13
|
-
@streams = streams
|
14
|
-
@logger = logger
|
15
|
-
@configuration_fetcher = configuration_fetcher
|
16
|
-
@app_dir = app_dir
|
17
|
-
end
|
18
|
-
|
19
|
-
def usage
|
20
|
-
["push_to_prod [build_#]",
|
21
|
-
"Push latest or <build_#> from your S3 bucket to the production host specified in credentials.yml"]
|
22
|
-
end
|
23
|
-
|
24
|
-
def run((build_number))
|
25
|
-
streams[:warn].puts "Warning: You are pushing to production."
|
26
|
-
validate
|
27
|
-
deployment = Deploy::Deployment.new(
|
28
|
-
app_dir: app_dir,
|
29
|
-
build_number: build_number,
|
30
|
-
aws_credentials: credentials[:aws],
|
31
|
-
cf_credentials: credentials[:cloud_foundry],
|
32
|
-
book_repo: config.book_repo,
|
33
|
-
)
|
34
|
-
archive = Deploy::Archive.new(
|
35
|
-
logger: @logger,
|
36
|
-
key: deployment.aws_access_key,
|
37
|
-
secret: deployment.aws_secret_key
|
38
|
-
)
|
39
|
-
archive.download(download_dir: deployment.app_dir,
|
40
|
-
bucket: deployment.green_builds_bucket,
|
41
|
-
build_number: deployment.build_number,
|
42
|
-
namespace: deployment.namespace)
|
43
|
-
Deploy::Distributor.build(streams, archive, deployment).distribute
|
44
|
-
0
|
45
|
-
end
|
46
|
-
|
47
|
-
private
|
48
|
-
|
49
|
-
attr_reader :app_dir, :configuration_fetcher, :streams
|
50
|
-
|
51
|
-
def credentials
|
52
|
-
configuration_fetcher.fetch_credentials('production')
|
53
|
-
end
|
54
|
-
|
55
|
-
def config
|
56
|
-
configuration_fetcher.fetch_config
|
57
|
-
end
|
58
|
-
|
59
|
-
def validate
|
60
|
-
unless config.has_option?('cred_repo')
|
61
|
-
raise MissingRequiredKeyError.new "Your config.yml is missing required key(s). The require keys for this commands are cred_repo"
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
require_relative 'bind'
|
2
|
-
require_relative 'build_and_push_tarball'
|
3
|
-
require_relative 'chain'
|
4
|
-
require_relative 'naming'
|
5
|
-
require_relative 'push_from_local'
|
6
|
-
|
7
|
-
module Bookbinder
|
8
|
-
module Commands
|
9
|
-
class RunPublishCI
|
10
|
-
include Commands::Naming
|
11
|
-
include Commands::Chain
|
12
|
-
|
13
|
-
def usage
|
14
|
-
[command_name,
|
15
|
-
"Run publish, push_local_to staging, and build_and_push_tarball for CI purposes"]
|
16
|
-
end
|
17
|
-
|
18
|
-
def initialize(publish_command, push_local_to_command, build_and_push_tarball_command)
|
19
|
-
@publish_command = publish_command
|
20
|
-
@push_local_to_command = push_local_to_command
|
21
|
-
@build_and_push_tarball_command = build_and_push_tarball_command
|
22
|
-
end
|
23
|
-
|
24
|
-
def run(cli_args)
|
25
|
-
command_chain(
|
26
|
-
->{publish_command.run(['remote'] + cli_args)},
|
27
|
-
->{push_local_to_command.run(['staging'])},
|
28
|
-
->{build_and_push_tarball_command.run([])}
|
29
|
-
)
|
30
|
-
end
|
31
|
-
|
32
|
-
private
|
33
|
-
|
34
|
-
attr_reader :publish_command, :push_local_to_command, :build_and_push_tarball_command
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
require_relative 'naming'
|
2
|
-
|
3
|
-
module Bookbinder
|
4
|
-
module Commands
|
5
|
-
class Version
|
6
|
-
include Commands::Naming
|
7
|
-
|
8
|
-
def initialize(logger)
|
9
|
-
@logger = logger
|
10
|
-
end
|
11
|
-
|
12
|
-
def usage
|
13
|
-
[command_name, "Print the version of bookbinder"]
|
14
|
-
end
|
15
|
-
|
16
|
-
def run(*)
|
17
|
-
root = File.expand_path('../../../../', __FILE__)
|
18
|
-
@logger.log "bookbinder #{Gem::Specification::load(File.join root, "bookbinder.gemspec").version}"
|
19
|
-
0
|
20
|
-
end
|
21
|
-
|
22
|
-
private
|
23
|
-
|
24
|
-
def command_name
|
25
|
-
'--version'
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
@@ -1,21 +0,0 @@
|
|
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
|
@@ -1,62 +0,0 @@
|
|
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 routes
|
26
|
-
fetch('host') if correctly_formatted_domain_and_routes?
|
27
|
-
end
|
28
|
-
|
29
|
-
def flat_routes
|
30
|
-
routes.flat_map { |(domain, apps)| apps.map { |app| [domain, app] } }
|
31
|
-
end
|
32
|
-
|
33
|
-
def space
|
34
|
-
fetch('space')
|
35
|
-
end
|
36
|
-
|
37
|
-
private
|
38
|
-
|
39
|
-
attr_reader :creds, :environment
|
40
|
-
|
41
|
-
def fetch(key)
|
42
|
-
creds.fetch('env').fetch(environment).fetch(key)
|
43
|
-
rescue KeyError => e
|
44
|
-
raise CredentialKeyError, e
|
45
|
-
end
|
46
|
-
|
47
|
-
def correctly_formatted_domain_and_routes?
|
48
|
-
routes_hash = fetch('host')
|
49
|
-
domains = routes_hash.keys
|
50
|
-
domains.each { |domain| correctly_formatted_domain?(domain, routes_hash) }
|
51
|
-
end
|
52
|
-
|
53
|
-
def correctly_formatted_domain?(domain, routes_hash)
|
54
|
-
raise 'Each domain in credentials must be a single string.' unless domain.is_a? String
|
55
|
-
raise "Domain #{domain} in credentials must contain a web extension, e.g. '.com'." unless domain.include?('.')
|
56
|
-
raise "Did you mean to add a list of hosts for domain #{domain}? Check your credentials.yml." unless routes_hash[domain]
|
57
|
-
raise "Hosts in credentials must be nested as an array under the desired domain #{domain}." unless routes_hash[domain].is_a? Array
|
58
|
-
raise "Did you mean to provide a hostname for the domain #{domain}? Check your credentials.yml." if routes_hash[domain].any?(&:nil?)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|