bookbindery 3.0.1 → 3.1.0

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 (53) hide show
  1. checksums.yaml +4 -4
  2. data/lib/bookbinder.rb +0 -4
  3. data/lib/bookbinder/archive.rb +12 -5
  4. data/lib/bookbinder/archive_menu_configuration.rb +4 -4
  5. data/lib/bookbinder/commands/bind.rb +29 -97
  6. data/lib/bookbinder/commands/bind/bind_options.rb +50 -0
  7. data/lib/bookbinder/commands/bind/directory_preparer.rb +13 -12
  8. data/lib/bookbinder/commands/build_and_push_tarball.rb +1 -8
  9. data/lib/bookbinder/commands/help.rb +1 -1
  10. data/lib/bookbinder/commands/run_publish_ci.rb +1 -3
  11. data/lib/bookbinder/commands/tag.rb +12 -9
  12. data/lib/bookbinder/commands/update_local_doc_repos.rb +23 -7
  13. data/lib/bookbinder/config/bind_config_factory.rb +5 -7
  14. data/lib/bookbinder/config/remote_bind_configuration.rb +23 -31
  15. data/lib/bookbinder/config/section_config.rb +56 -0
  16. data/lib/bookbinder/configuration.rb +58 -18
  17. data/lib/bookbinder/configuration_fetcher.rb +3 -5
  18. data/lib/bookbinder/configuration_validator.rb +1 -8
  19. data/lib/bookbinder/distributor.rb +1 -1
  20. data/lib/bookbinder/dita_command_creator.rb +60 -16
  21. data/lib/bookbinder/dita_html_to_middleman_formatter.rb +3 -2
  22. data/lib/bookbinder/errors/programmer_mistake.rb +5 -0
  23. data/lib/bookbinder/git_accessor.rb +36 -2
  24. data/lib/bookbinder/ingest/cloner_factory.rb +3 -3
  25. data/lib/bookbinder/ingest/destination_directory.rb +7 -1
  26. data/lib/bookbinder/ingest/{git_hub_repository_cloner.rb → git_cloner.rb} +3 -2
  27. data/lib/bookbinder/ingest/repo_identifier.rb +45 -0
  28. data/lib/bookbinder/local_file_system_accessor.rb +4 -9
  29. data/lib/bookbinder/middleman_runner.rb +5 -6
  30. data/lib/bookbinder/preprocessing/copy_to_site_gen_dir.rb +27 -0
  31. data/lib/bookbinder/preprocessing/dita_preprocessor.rb +103 -0
  32. data/lib/bookbinder/preprocessing/preprocessor.rb +26 -0
  33. data/lib/bookbinder/repositories/command_repository.rb +17 -21
  34. data/lib/bookbinder/repositories/section_repository.rb +24 -16
  35. data/lib/bookbinder/repositories/section_repository_factory.rb +19 -0
  36. data/lib/bookbinder/streams/{switchable_stdout_and_red_stderr.rb → colorized_stream.rb} +0 -17
  37. data/lib/bookbinder/time_fetcher.rb +7 -0
  38. data/lib/bookbinder/validation_checkers/dita_section_checker.rb +2 -2
  39. data/lib/bookbinder/values/output_locations.rb +13 -12
  40. data/lib/bookbinder/values/section.rb +22 -5
  41. data/master_middleman/bookbinder_helpers.rb +4 -11
  42. metadata +59 -75
  43. data/lib/bookbinder/book.rb +0 -59
  44. data/lib/bookbinder/config/local_bind_configuration.rb +0 -23
  45. data/lib/bookbinder/dita_preprocessor.rb +0 -68
  46. data/lib/bookbinder/dita_section_gatherer_factory.rb +0 -23
  47. data/lib/bookbinder/git_client.rb +0 -66
  48. data/lib/bookbinder/git_hub_repository.rb +0 -101
  49. data/lib/bookbinder/local_dita_section_gatherer.rb +0 -32
  50. data/lib/bookbinder/remote_dita_section_gatherer.rb +0 -35
  51. data/lib/bookbinder/validation_checkers/config_version_checker.rb +0 -91
  52. data/lib/bookbinder/values/code_example.rb +0 -7
  53. data/lib/bookbinder/values/dita_section.rb +0 -39
@@ -44,7 +44,7 @@ module Bookbinder
44
44
  end
45
45
 
46
46
  def chars_for_usage_definition
47
- 33
47
+ 72
48
48
  end
49
49
 
50
50
  def flags
@@ -22,10 +22,8 @@ module Bookbinder
22
22
  end
23
23
 
24
24
  def run(cli_args)
25
- raise BuildAndPushTarball::MissingBuildNumber unless ENV['BUILD_NUMBER']
26
-
27
25
  command_chain(
28
- ->{publish_command.run(['github'] + cli_args)},
26
+ ->{publish_command.run(['remote'] + cli_args)},
29
27
  ->{push_local_to_staging_command.run([])},
30
28
  ->{build_and_push_tarball_command.run([])}
31
29
  )
@@ -1,4 +1,3 @@
1
- require_relative '../book'
2
1
  require_relative '../deprecated_logger'
3
2
  require_relative '../errors/cli_error'
4
3
  require_relative 'naming'
@@ -8,31 +7,35 @@ module Bookbinder
8
7
  class Tag
9
8
  include Commands::Naming
10
9
 
11
- def initialize(logger, configuration_fetcher)
10
+ def initialize(logger, configuration_fetcher, version_control_system)
12
11
  @logger = logger
13
12
  @configuration_fetcher = configuration_fetcher
13
+ @version_control_system = version_control_system
14
14
  end
15
15
 
16
16
  def usage
17
17
  ["tag <git tag>", "Apply the specified <git tag> to your book and all sections of your book"]
18
18
  end
19
19
 
20
- def run(params)
21
- tag = params.first
20
+ def run((tag, *))
22
21
  raise CliError::InvalidArguments unless tag
23
22
 
24
- book = Book.new(logger: @logger, full_name: config.book_repo, sections: config.sections)
25
-
26
- book.tag_self_and_sections_with tag
23
+ urls(config).each do |url|
24
+ version_control_system.remote_tag(url, tag, 'HEAD')
25
+ end
27
26
 
28
27
  @logger.log 'Success!'.green
29
- @logger.log " #{book.full_name.yellow} and its sections were tagged with #{tag.blue}"
28
+ @logger.log " #{config.book_repo.yellow} and its sections were tagged with #{tag.blue}"
30
29
  0
31
30
  end
32
31
 
33
32
  private
34
33
 
35
- attr_reader :configuration_fetcher
34
+ attr_reader :configuration_fetcher, :version_control_system
35
+
36
+ def urls(config)
37
+ [config.book_repo_url] + config.sections.map(&:repo_url).uniq
38
+ end
36
39
 
37
40
  def config
38
41
  @config ||= configuration_fetcher.fetch_config
@@ -1,27 +1,43 @@
1
- require_relative 'bookbinder_command'
1
+ require_relative '../deprecated_logger'
2
+ require_relative '../ingest/destination_directory'
2
3
  require_relative 'naming'
3
4
 
4
5
  module Bookbinder
5
6
  module Commands
6
- class UpdateLocalDocRepos < BookbinderCommand
7
+ class UpdateLocalDocRepos
7
8
  include Commands::Naming
8
9
 
10
+ def initialize(logger, configuration_fetcher, version_control_system, filesystem)
11
+ @logger = logger
12
+ @configuration_fetcher = configuration_fetcher
13
+ @version_control_system = version_control_system
14
+ @filesystem = filesystem
15
+ end
16
+
9
17
  def usage
10
18
  [command_name,
11
19
  "Run `git pull` on all sections that exist at the same directory level as your book directory"]
12
20
  end
13
21
 
14
22
  def run(_)
15
- config.sections.map { |conf| repo_for(conf) }.each(&:update_local_copy)
23
+ urls = configuration_fetcher.fetch_config.sections.map(&:repo_url)
24
+ paths(urls).each do |path|
25
+ if filesystem.file_exist?(path)
26
+ logger.log 'Updating ' + path.cyan
27
+ version_control_system.update(path)
28
+ else
29
+ logger.log ' skipping (not found) '.magenta + path
30
+ end
31
+ end
16
32
  0
17
33
  end
18
34
 
19
35
  private
20
36
 
21
- def repo_for(section_config)
22
- local_repo_dir = File.absolute_path('../')
23
- GitHubRepository.new(logger: @logger, full_name: section_config['repository']['name'],
24
- local_repo_dir: local_repo_dir, git_accessor: Git)
37
+ attr_reader :logger, :configuration_fetcher, :version_control_system, :filesystem
38
+
39
+ def paths(urls)
40
+ urls.map {|url| File.absolute_path("../#{Ingest::DestinationDirectory.new(url)}")}
25
41
  end
26
42
  end
27
43
  end
@@ -1,20 +1,18 @@
1
- require_relative 'local_bind_configuration'
2
1
  require_relative 'remote_bind_configuration'
3
2
 
4
3
  module Bookbinder
5
4
  module Config
6
5
  class BindConfigFactory
7
- def initialize(logger, version_control_system, config_fetcher)
8
- @logger = logger
6
+ def initialize(version_control_system, config_fetcher)
9
7
  @version_control_system = version_control_system
10
8
  @config_fetcher = config_fetcher
11
9
  end
12
10
 
13
11
  def produce(bind_source)
14
- if bind_source == 'github' && config.has_option?('versions')
15
- RemoteBindConfiguration.new(logger, version_control_system, config).to_h
12
+ if %w(remote github).include?(bind_source) && config.has_option?('versions')
13
+ RemoteBindConfiguration.new(version_control_system, config).fetch
16
14
  else
17
- LocalBindConfiguration.new(config).to_h
15
+ config
18
16
  end
19
17
  end
20
18
 
@@ -24,7 +22,7 @@ module Bookbinder
24
22
  config_fetcher.fetch_config
25
23
  end
26
24
 
27
- attr_reader :logger, :version_control_system, :config_fetcher
25
+ attr_reader :version_control_system, :config_fetcher
28
26
  end
29
27
  end
30
28
  end
@@ -1,50 +1,42 @@
1
+ require 'yaml'
2
+ require_relative '../ingest/destination_directory'
3
+
1
4
  module Bookbinder
2
5
  module Config
3
6
  class RemoteBindConfiguration
4
7
  VersionUnsupportedError = Class.new(RuntimeError)
5
8
 
6
- def initialize(logger, version_control_system, base_config)
7
- @logger = logger
9
+ def initialize(version_control_system, base_config)
8
10
  @version_control_system = version_control_system
9
11
  @base_config = base_config
10
12
  end
11
13
 
12
- def to_h
13
- sections = base_config.sections
14
- base = {
15
- sections: sections,
16
- book_repo: base_config.book_repo,
17
- host_for_sitemap: base_config.public_host,
18
- archive_menu: base_config.archive_menu,
19
- versions: base_config.versions,
20
- template_variables: base_config.template_variables
21
- }
22
- base_config.versions.each { |version| sections.concat(sections_from(version)) }
23
- base
14
+ def fetch
15
+ base_config.merge_sections(base_config.versions.flat_map { |version| sections_from(version) })
24
16
  end
25
17
 
26
18
  private
27
19
 
28
- attr_reader :logger, :version_control_system, :base_config
20
+ attr_reader :version_control_system, :base_config
29
21
 
30
22
  def sections_from(version)
31
- Dir.mktmpdir('book_checkout') do |temp_workspace|
32
- book = Book.from_remote(logger: logger,
33
- full_name: base_config.book_repo,
34
- destination_dir: temp_workspace,
35
- ref: version,
36
- git_accessor: version_control_system)
37
-
38
- book_checkout_value = File.join temp_workspace, book.directory
39
- config_file = File.join book_checkout_value, 'config.yml'
40
- attrs = YAML.load(File.read(config_file))['sections']
41
- raise VersionUnsupportedError.new(version) if attrs.nil?
23
+ sections = Configuration.parse(
24
+ YAML.load(
25
+ version_control_system.read_file(
26
+ 'config.yml',
27
+ from_repo: base_config.book_repo_url,
28
+ checkout: version
29
+ )
30
+ )).sections
31
+ raise VersionUnsupportedError.new(version) if sections.empty?
42
32
 
43
- attrs.map do |section_hash|
44
- section_hash['repository']['ref'] = version
45
- section_hash['directory'] = File.join(version, section_hash['directory'])
46
- section_hash
47
- end
33
+ sections.map do |section|
34
+ section.merge(
35
+ Config::SectionConfig.new(
36
+ 'repository' => { 'name' => section.repo_name, 'ref' => version },
37
+ 'directory' => File.join(version, section.desired_directory_name)
38
+ )
39
+ )
48
40
  end
49
41
  end
50
42
  end
@@ -0,0 +1,56 @@
1
+ require_relative '../ingest/repo_identifier'
2
+
3
+ module Bookbinder
4
+ module Config
5
+ class SectionConfig
6
+ def initialize(config)
7
+ @config = config
8
+ end
9
+
10
+ def subnav_template
11
+ config['subnav_template']
12
+ end
13
+
14
+ def desired_directory_name
15
+ config['directory']
16
+ end
17
+
18
+ def repo_name
19
+ repo['name']
20
+ end
21
+
22
+ def repo_url
23
+ Ingest::RepoIdentifier.new(repo['name'])
24
+ end
25
+
26
+ def repo_ref
27
+ repo['ref'] || 'master'
28
+ end
29
+
30
+ def preprocessor_config
31
+ config['preprocessor_config']
32
+ end
33
+
34
+ def ==(other)
35
+ config == other.instance_variable_get(:@config)
36
+ end
37
+
38
+ def merge(other_section_config)
39
+ SectionConfig.new(config.merge(other_section_config.instance_variable_get(:@config)))
40
+ end
41
+
42
+ def inspect
43
+ config.inspect
44
+ end
45
+
46
+ private
47
+
48
+ def repo
49
+ config['repository']
50
+ end
51
+
52
+ attr_reader :config
53
+ end
54
+ end
55
+ end
56
+
@@ -1,47 +1,87 @@
1
+ require_relative 'ingest/repo_identifier'
2
+ require_relative 'config/section_config'
3
+
1
4
  module Bookbinder
2
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
3
12
 
4
- CURRENT_SCHEMA_VERSION = '1.0.0'
5
- STARTING_SCHEMA_VERSION = '1.0.0'
13
+ private
6
14
 
7
- ConfigSchemaUnsupportedError = Class.new(RuntimeError)
15
+ def symbolize_keys(h)
16
+ h.reduce({}) {|acc, (k, v)| acc.merge(k.to_sym => v) }
17
+ end
8
18
 
9
- attr_reader :schema_version, :schema_major_version, :schema_minor_version, :schema_patch_version
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
10
23
 
11
- def initialize(logger, config_hash)
12
- @logger = logger
13
- @config = config_hash
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
14
50
  end
15
51
 
16
52
  CONFIG_REQUIRED_KEYS = %w(book_repo public_host)
17
- CONFIG_OPTIONAL_KEYS = %w(archive_menu layout_repo versions cred_repo)
53
+ CONFIG_OPTIONAL_KEYS = %w(archive_menu book_repo_url cred_repo cred_repo_url layout_repo layout_repo_url sections)
18
54
 
19
55
  CONFIG_REQUIRED_KEYS.each do |method_name|
20
56
  define_method(method_name) do
21
- config.fetch(method_name)
57
+ config.fetch(method_name.to_sym)
22
58
  end
23
59
  end
24
60
 
25
61
  CONFIG_OPTIONAL_KEYS.each do |method_name|
26
62
  define_method(method_name) do
27
- config[method_name]
63
+ config[method_name.to_sym]
28
64
  end
29
65
  end
30
66
 
31
- def sections
32
- config.fetch('sections', [])
67
+ def template_variables
68
+ config.fetch(:template_variables, {})
33
69
  end
34
70
 
35
- def dita_sections
36
- config.fetch('dita_sections', {})
71
+ def versions
72
+ config.fetch(:versions, [])
37
73
  end
38
74
 
39
- def has_option?(key)
40
- @config.has_key?(key)
75
+ def merge(other_configuration)
76
+ Configuration.new(config.merge(other_configuration.instance_variable_get(:@config)))
41
77
  end
42
78
 
43
- def template_variables
44
- config.fetch('template_variables', {})
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]
45
85
  end
46
86
 
47
87
  def ==(o)
@@ -17,7 +17,7 @@ module Bookbinder
17
17
  end
18
18
 
19
19
  def fetch_credentials(environment = 'null-environment')
20
- @credentials ||= credentials_provider.credentials("git@github.com:#{fetch_config.cred_repo}")
20
+ @credentials ||= credentials_provider.credentials(fetch_config.cred_repo_url)
21
21
  {
22
22
  aws: Config::AwsCredentials.new(
23
23
  @credentials.fetch('aws', {})
@@ -50,12 +50,10 @@ module Bookbinder
50
50
  def validate(config_hash)
51
51
  raise 'Your config.yml appears to be empty. Please check and try again.' unless config_hash
52
52
 
53
- errors = configuration_validator.exceptions(config_hash,
54
- Configuration::CURRENT_SCHEMA_VERSION,
55
- Configuration::STARTING_SCHEMA_VERSION)
53
+ errors = configuration_validator.exceptions(config_hash)
56
54
  raise errors.first if errors.any?
57
55
 
58
- Configuration.new(logger, config_hash)
56
+ Configuration.parse(config_hash)
59
57
  end
60
58
  end
61
59
  end
@@ -1,6 +1,5 @@
1
1
  require_relative 'validation_checkers/duplicate_section_name_checker'
2
2
  require_relative 'validation_checkers/archive_menu_checker'
3
- require_relative 'validation_checkers/config_version_checker'
4
3
  require_relative 'validation_checkers/required_keys_checker'
5
4
  require_relative 'validation_checkers/repository_name_presence_checker'
6
5
  require_relative 'validation_checkers/dita_section_checker'
@@ -12,14 +11,8 @@ module Bookbinder
12
11
  @file_system_accessor = file_system_accessor
13
12
  end
14
13
 
15
- def exceptions(config_hash, bookbinder_schema_version, starting_schema_version)
16
- user_config_schema_version = config_hash['schema_version']
14
+ def exceptions(config_hash)
17
15
  exceptions = [
18
- ConfigVersionChecker.new(Version.parse(bookbinder_schema_version),
19
- Version.parse(starting_schema_version),
20
- VersionCheckerMessages.new(Version.parse(user_config_schema_version),
21
- bookbinder_schema_version),
22
- @logger),
23
16
  RequiredKeysChecker.new,
24
17
  DuplicateSectionNameChecker.new,
25
18
  RepositoryNamePresenceChecker.new,
@@ -11,7 +11,7 @@ module Bookbinder
11
11
  EXPIRATION_HOURS = 2
12
12
 
13
13
  def self.build(logger, options)
14
- namespace = Ingest::DestinationDirectory.new(options[:book_repo], nil)
14
+ namespace = Ingest::DestinationDirectory.new(options[:book_repo])
15
15
  namer = ArtifactNamer.new(namespace, options[:build_number], 'log', '/tmp')
16
16
 
17
17
  archive = Archive.new(logger: logger, key: options[:aws_credentials].access_key, secret: options[:aws_credentials].secret_key)