bookbindery 3.0.1 → 3.1.0

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