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.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/lib/bookbinder.rb +0 -4
  3. data/lib/bookbinder/cf_command_runner.rb +11 -5
  4. data/lib/bookbinder/cli.rb +8 -12
  5. data/lib/bookbinder/colorizer.rb +1 -2
  6. data/lib/bookbinder/command_runner.rb +0 -2
  7. data/lib/bookbinder/commands/bind.rb +96 -99
  8. data/lib/bookbinder/commands/bind/directory_preparer.rb +60 -0
  9. data/lib/bookbinder/commands/build_and_push_tarball.rb +5 -4
  10. data/lib/bookbinder/commands/push_from_local.rb +56 -2
  11. data/lib/bookbinder/commands/push_to_prod.rb +6 -2
  12. data/lib/bookbinder/commands/tag.rb +15 -3
  13. data/lib/bookbinder/config/aws_credentials.rb +21 -0
  14. data/lib/bookbinder/config/cf_credentials.rb +87 -0
  15. data/lib/bookbinder/configuration.rb +4 -140
  16. data/lib/bookbinder/configuration_fetcher.rb +28 -4
  17. data/lib/bookbinder/configuration_validator.rb +11 -164
  18. data/lib/bookbinder/distributor.rb +16 -12
  19. data/lib/bookbinder/{dita_to_html_converter.rb → dita_command_creator.rb} +5 -17
  20. data/lib/bookbinder/dita_preprocessor.rb +14 -12
  21. data/lib/bookbinder/git_accessor.rb +21 -2
  22. data/lib/bookbinder/git_hub_repository.rb +0 -43
  23. data/lib/bookbinder/ingest/cloner_factory.rb +5 -4
  24. data/lib/bookbinder/ingest/destination_directory.rb +15 -0
  25. data/lib/bookbinder/ingest/git_hub_repository_cloner.rb +22 -13
  26. data/lib/bookbinder/ingest/local_filesystem_cloner.rb +38 -14
  27. data/lib/bookbinder/ingest/working_copy.rb +31 -0
  28. data/lib/bookbinder/local_dita_section_gatherer.rb +4 -3
  29. data/lib/bookbinder/local_file_system_accessor.rb +1 -4
  30. data/lib/bookbinder/middleman_runner.rb +22 -26
  31. data/lib/bookbinder/remote_yaml_credential_provider.rb +10 -10
  32. data/lib/bookbinder/repositories/command_repository.rb +18 -12
  33. data/lib/bookbinder/repositories/section_repository.rb +8 -8
  34. data/lib/bookbinder/server_director.rb +16 -33
  35. data/lib/bookbinder/sheller.rb +33 -7
  36. data/lib/bookbinder/spider.rb +3 -0
  37. data/lib/bookbinder/streams/switchable_stdout_and_red_stderr.rb +38 -0
  38. data/lib/bookbinder/terminal.rb +11 -1
  39. data/lib/bookbinder/validation_checkers/archive_menu_checker.rb +31 -0
  40. data/lib/bookbinder/validation_checkers/config_version_checker.rb +91 -0
  41. data/lib/bookbinder/validation_checkers/dita_section_checker.rb +20 -0
  42. data/lib/bookbinder/validation_checkers/duplicate_section_name_checker.rb +25 -0
  43. data/lib/bookbinder/validation_checkers/repository_name_presence_checker.rb +33 -0
  44. data/lib/bookbinder/validation_checkers/required_keys_checker.rb +43 -0
  45. data/lib/bookbinder/values/dita_section.rb +5 -1
  46. data/lib/bookbinder/values/output_locations.rb +25 -2
  47. data/lib/bookbinder/values/user_message.rb +2 -2
  48. data/master_middleman/bookbinder_helpers.rb +5 -15
  49. data/template_app/Gemfile.lock +1 -1
  50. metadata +60 -80
  51. data/lib/bookbinder/commands/generate_pdf.rb +0 -141
  52. data/lib/bookbinder/pdf_generator.rb +0 -73
  53. data/lib/bookbinder/publisher.rb +0 -58
  54. 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 = config.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: GitHubRepository.new(logger: @logger, full_name: config.book_repo, git_accessor: Git).short_name)
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: config.aws_credentials,
44
- cf_credentials: config.cf_credentials(environment),
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: config.aws_credentials,
41
- cf_credentials: config.cf_credentials('production'),
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 'bookbinder_command'
3
+ require_relative '../errors/cli_error'
5
4
  require_relative 'naming'
6
5
 
7
6
  module Bookbinder
8
7
  module Commands
9
- class Tag < BookbinderCommand
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
- CredentialKeyError = Class.new(StandardError)
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 pdf_index cred_repo pdf)
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
- (o.class == self.class) && (o.config == self.config)
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
- def credentials
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