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
@@ -1,59 +0,0 @@
1
- require_relative 'git_hub_repository'
2
- require_relative 'directory_helpers'
3
-
4
- module Bookbinder
5
- class Book
6
- include DirectoryHelperMethods
7
-
8
- def self.from_remote(logger: nil, full_name: nil, destination_dir: nil, ref: nil, git_accessor: Git)
9
- book = new(logger: logger, full_name: full_name, target_ref: ref, git_accessor: git_accessor)
10
- book.copy_from_remote(destination_dir) if destination_dir
11
- book
12
- end
13
-
14
- def initialize(logger: nil,
15
- full_name: nil,
16
- target_ref: nil,
17
- github_token: nil,
18
- sections: [],
19
- git_accessor: Git)
20
- @section_vcs_repos = sections.map do |section|
21
- GitHubRepository.new(logger: logger,
22
- full_name: section['repository']['name'],
23
- git_accessor: git_accessor)
24
- end
25
-
26
- @target_ref = target_ref || 'master'
27
-
28
- @repository = GitHubRepository.new(logger: logger,
29
- full_name: full_name,
30
- github_token: github_token,
31
- git_accessor: git_accessor)
32
- @git_accessor = git_accessor
33
- end
34
-
35
- def full_name
36
- @repository.full_name
37
- end
38
-
39
- def head_sha
40
- @repository.head_sha
41
- end
42
-
43
- def directory
44
- @repository.directory
45
- end
46
-
47
- def copy_from_remote(destination_dir)
48
- @repository.copy_from_remote(destination_dir, target_ref)
49
- end
50
-
51
- def tag_self_and_sections_with(tag)
52
- (@section_vcs_repos + [@repository]).each { |repo| repo.tag_with tag }
53
- end
54
-
55
- private
56
-
57
- attr_reader :target_ref
58
- end
59
- end
@@ -1,23 +0,0 @@
1
- module Bookbinder
2
- module Config
3
- class LocalBindConfiguration
4
- def initialize(base_config)
5
- @base_config = base_config
6
- end
7
-
8
- def to_h
9
- {
10
- sections: base_config.sections,
11
- book_repo: base_config.book_repo,
12
- host_for_sitemap: base_config.public_host,
13
- archive_menu: base_config.archive_menu,
14
- template_variables: base_config.template_variables
15
- }
16
- end
17
-
18
- private
19
-
20
- attr_reader :base_config
21
- end
22
- end
23
- end
@@ -1,68 +0,0 @@
1
- require_relative 'values/subnav'
2
-
3
- module Bookbinder
4
- class DitaPreprocessor
5
-
6
- ACCEPTED_IMAGE_FORMATS = %w(png jpeg jpg svg gif bmp tif tiff eps)
7
-
8
- def initialize(dita_formatter, local_fs_accessor)
9
- @dita_formatter = dita_formatter
10
- @local_fs_accessor = local_fs_accessor
11
- end
12
-
13
- def preprocess(dita_sections,
14
- subnavs_dir,
15
- dita_subnav_template_path,
16
- &block)
17
- ditamap_location_sections = dita_sections.select { |dita_section| dita_section.ditamap_location }
18
- ditamap_location_sections.each do |dita_section|
19
- block.call(dita_section)
20
- generate_subnav(dita_section, dita_subnav_template_path, subnavs_dir)
21
- end
22
-
23
- dita_sections.each do |dita_section|
24
- dita_formatter.format_html dita_section.html_from_dita_section_dir, dita_section.formatted_section_dir
25
-
26
- copy_images(dita_section.path_to_local_repo, dita_section.formatted_section_dir)
27
-
28
- local_fs_accessor.copy_contents(dita_section.formatted_section_dir,
29
- dita_section.section_source_for_site_generator)
30
- end
31
- end
32
-
33
- private
34
-
35
- attr_reader :dita_formatter, :local_fs_accessor
36
-
37
- def generate_subnav(dita_section, dita_subnav_template_path, subnavs_dir)
38
- dita_subnav_template_text = local_fs_accessor.read(dita_subnav_template_path)
39
-
40
- tocjs_text = local_fs_accessor.read(File.join dita_section.html_from_dita_section_dir, 'index.html')
41
- json_props_location = File.join('dita-subnav-props.json')
42
- props_file_location = File.join(subnavs_dir, json_props_location)
43
-
44
- subnav = dita_formatter.format_subnav(dita_section,
45
- dita_subnav_template_text,
46
- json_props_location,
47
- tocjs_text)
48
-
49
- local_fs_accessor.write text: subnav.json_links, to: props_file_location
50
-
51
- local_fs_accessor.write text: subnav.text,
52
- to: File.join(subnavs_dir, "dita_subnav.erb")
53
- end
54
-
55
- def copy_images(src, dest)
56
- image_paths = ACCEPTED_IMAGE_FORMATS.map do |format|
57
- local_fs_accessor.find_files_with_ext(format, src)
58
- end.flatten
59
-
60
- image_paths.each do |image_path|
61
- local_fs_accessor.copy_including_intermediate_dirs(image_path,
62
- src,
63
- dest)
64
- end
65
- end
66
-
67
- end
68
- end
@@ -1,23 +0,0 @@
1
- require_relative 'local_dita_section_gatherer'
2
- require_relative 'remote_dita_section_gatherer'
3
-
4
- module Bookbinder
5
- class DitaSectionGathererFactory
6
- def initialize(version_control_system, view_updater)
7
- @version_control_system = version_control_system
8
- @view_updater = view_updater
9
- end
10
-
11
- def produce(source_location, output_locations)
12
- if source_location == 'github'
13
- RemoteDitaSectionGatherer.new(version_control_system, view_updater, output_locations)
14
- else
15
- LocalDitaSectionGatherer.new(output_locations)
16
- end
17
- end
18
-
19
- private
20
-
21
- attr_reader :version_control_system, :view_updater
22
- end
23
- end
@@ -1,66 +0,0 @@
1
- require 'octokit'
2
-
3
- module Bookbinder
4
- class GitClient < Octokit::Client
5
- class GitClient::TokenException < StandardError;
6
- end
7
-
8
- def head_sha(full_name)
9
- commits(full_name).first.sha
10
- end
11
-
12
- def create_tag!(full_name, tagname, ref)
13
- tag_result = create_tag(
14
- full_name,
15
- "tags/#{tagname}",
16
- 'Tagged by Bookbinder',
17
- ref,
18
- 'commit',
19
- 'Bookbinder',
20
- 'bookbinder@cloudfoundry.org',
21
- Time.now.iso8601
22
- )
23
- create_ref(full_name, "tags/#{tagname}", tag_result.sha)
24
- rescue Octokit::Unauthorized, Octokit::NotFound
25
- raise_error_with_context
26
- end
27
-
28
- def archive_link(*args)
29
- super
30
- rescue Octokit::Unauthorized, Octokit::NotFound
31
- raise_error_with_context
32
- end
33
-
34
- def tags(*args)
35
- super
36
- rescue Octokit::Unauthorized, Octokit::NotFound
37
- raise_error_with_context
38
- end
39
-
40
- def refs(*args)
41
- super
42
- rescue Octokit::Unauthorized, Octokit::NotFound
43
- raise_error_with_context
44
- end
45
-
46
- def last_modified_date_of(full_name, target_ref, file)
47
- commits = commits(full_name, target_ref, path: file)
48
- commits.first[:commit][:author][:date]
49
- end
50
-
51
- private
52
-
53
- def commits(*args)
54
- super
55
- rescue Octokit::Unauthorized, Octokit::NotFound
56
- raise_error_with_context
57
- end
58
-
59
- def raise_error_with_context
60
- absent_token_message = ' Cannot access repository! You must set $GITHUB_API_TOKEN.'
61
- invalid_token_message = ' Cannot access repository! Does your $GITHUB_API_TOKEN have access to this repository? Does it exist?'
62
-
63
- ENV['GITHUB_API_TOKEN'] ? raise(TokenException.new(invalid_token_message)) : raise(TokenException.new(absent_token_message))
64
- end
65
- end
66
- end
@@ -1,101 +0,0 @@
1
- require 'git'
2
- require_relative 'deprecated_logger'
3
- require_relative 'git_client'
4
- require_relative 'shell_out'
5
-
6
- module Bookbinder
7
- class GitHubRepository
8
- RepositoryCloneError = Class.new(StandardError)
9
-
10
- include Bookbinder::ShellOut
11
-
12
- attr_reader :full_name, :copied_to
13
-
14
- def initialize(logger: nil,
15
- full_name: nil,
16
- github_token: nil,
17
- directory: nil,
18
- local_repo_dir: nil,
19
- git_accessor: nil)
20
- @logger = logger
21
- raise 'No full_name provided ' unless full_name
22
- @full_name = full_name
23
- @directory = directory
24
- @local_repo_dir = local_repo_dir
25
-
26
- @github = GitClient.new(access_token: github_token || ENV['GITHUB_API_TOKEN'])
27
- @git_accessor = git_accessor or raise ArgumentError.new("Must provide a git accessor")
28
- end
29
-
30
- def tag_with(tagname)
31
- @logger.log 'Tagging ' + full_name.cyan
32
- @github.create_tag! full_name, tagname, head_sha
33
- end
34
-
35
- def short_name
36
- full_name.split('/')[1]
37
- end
38
-
39
- def head_sha
40
- @head_sha ||= @github.head_sha(full_name)
41
- end
42
-
43
- def directory
44
- @directory || short_name
45
- end
46
-
47
- def copy_from_remote(destination_dir, target_ref)
48
- begin
49
- @git_base_object = git_accessor.clone("git@github.com:#{full_name}",
50
- directory,
51
- path: destination_dir)
52
- rescue => e
53
- if e.message.include? "Permission denied (publickey)"
54
- raise RepositoryCloneError.new "Unable to access repository #{full_name}. You do not have the correct access rights. Please either add the key to your SSH agent, or set the GIT_SSH environment variable to override default SSH key usage. For more information run: `man git`."
55
- elsif
56
- e.message.include? "Repository not found."
57
- raise RepositoryCloneError.new "Could not read from repository. Please make sure you have the correct access rights and the repository #{full_name} exists."
58
- else
59
- raise e
60
- end
61
- end
62
- @git_base_object.checkout(target_ref) unless target_ref == 'master'
63
- @copied_to = File.join(destination_dir, directory)
64
- end
65
-
66
- def copied?
67
- !@copied_to.nil?
68
- end
69
-
70
- def has_tag?(tagname)
71
- tags.any? { |tag| tag.name == tagname }
72
- end
73
-
74
- def update_local_copy
75
- if File.exist?(path_to_local_repo)
76
- @logger.log 'Updating ' + path_to_local_repo.cyan
77
- Kernel.system("cd #{path_to_local_repo} && git pull")
78
- else
79
- announce_skip
80
- end
81
- end
82
-
83
- def announce_skip
84
- @logger.log ' skipping (not found) '.magenta + path_to_local_repo
85
- end
86
-
87
- private
88
-
89
- attr_reader :git_accessor
90
-
91
- def path_to_local_repo
92
- if @local_repo_dir
93
- File.join(@local_repo_dir, short_name)
94
- end
95
- end
96
-
97
- def tags
98
- @github.tags @full_name
99
- end
100
- end
101
- end
@@ -1,32 +0,0 @@
1
- module Bookbinder
2
- class LocalDitaSectionGatherer
3
- def initialize(output_locations)
4
- @output_locations = output_locations
5
- end
6
-
7
- def gather(dita_section_config_hash)
8
- dita_section_config_hash.map do |dita_section_config|
9
- relative_path_to_dita_map = dita_section_config['ditamap_location']
10
- relative_path_to_dita_val = dita_section_config['ditaval_location']
11
- full_name = dita_section_config.fetch('repository', {}).fetch('name')
12
- target_ref = dita_section_config.fetch('repository', {})['ref']
13
- desired_destination_directory_name = dita_section_config['directory']
14
- local_source_directory_name = full_name.split('/').last
15
- path_to_local_copy = output_locations.local_repo_dir.join(local_source_directory_name)
16
-
17
- DitaSection.new(path_to_local_copy,
18
- relative_path_to_dita_map,
19
- relative_path_to_dita_val,
20
- full_name,
21
- target_ref,
22
- desired_destination_directory_name,
23
- output_locations)
24
- end
25
- end
26
-
27
- private
28
-
29
- attr_reader :output_locations
30
-
31
- end
32
- end
@@ -1,35 +0,0 @@
1
- require_relative '../../lib/bookbinder/deprecated_logger'
2
- require_relative '../../lib/bookbinder/values/dita_section'
3
-
4
- module Bookbinder
5
- class RemoteDitaSectionGatherer
6
- def initialize(version_control_system, view_updater, output_locations)
7
- @version_control_system = version_control_system
8
- @view_updater = view_updater
9
- @cloned_dita_dir = output_locations.cloned_dita_dir
10
- @output_locations = output_locations
11
- end
12
-
13
- def gather(dita_section_config_hash)
14
- dita_section_config_hash.map do |dita_section_config|
15
- view_updater.log "Gathering " + "#{dita_section_config.fetch('repository', {}).fetch('name')}".cyan
16
- version_control_system.clone("git@github.com:#{dita_section_config.fetch('repository', {}).fetch('name')}",
17
- dita_section_config['directory'],
18
- path: cloned_dita_dir)
19
-
20
- DitaSection.new(cloned_dita_dir.join(dita_section_config['directory']),
21
- dita_section_config['ditamap_location'],
22
- dita_section_config['ditaval_location'],
23
- dita_section_config.fetch('repository', {}).fetch('name'),
24
- dita_section_config.fetch('repository', {})['ref'],
25
- dita_section_config['directory'],
26
- output_locations)
27
- end
28
- end
29
-
30
- private
31
-
32
- attr_reader :version_control_system, :view_updater, :cloned_dita_dir, :output_locations
33
-
34
- end
35
- end
@@ -1,91 +0,0 @@
1
- require 'active_support/core_ext/object/blank'
2
- require_relative '../configuration'
3
-
4
- module Bookbinder
5
- class ConfigVersionChecker
6
- def initialize(bookbinder_schema_version, starting_schema_version, messages, view_updater)
7
- @bookbinder_schema_version = bookbinder_schema_version
8
- @starting_schema_version = starting_schema_version
9
- @messages = messages
10
- @view_updater = view_updater
11
- end
12
-
13
- def check(config)
14
- user_schema_version = Version.parse(config['schema_version'])
15
- if user_schema_version.valid?
16
- if user_schema_version.major > bookbinder_schema_version.major
17
- raise Configuration::ConfigSchemaUnsupportedError.new messages.unrecognized_schema_version_message
18
- elsif user_schema_version.minor > bookbinder_schema_version.minor
19
- raise Configuration::ConfigSchemaUnsupportedError.new messages.unrecognized_schema_version_message
20
- elsif user_schema_version.patch > bookbinder_schema_version.patch
21
- raise Configuration::ConfigSchemaUnsupportedError.new messages.unrecognized_schema_version_message
22
- elsif user_schema_version.major < bookbinder_schema_version.major
23
- raise Configuration::ConfigSchemaUnsupportedError.new messages.incompatible_schema_message
24
- elsif user_schema_version.minor < bookbinder_schema_version.minor
25
- view_updater.warn nonbreaking_schema_message_for("minor")
26
- elsif user_schema_version.patch < bookbinder_schema_version.patch
27
- view_updater.warn nonbreaking_schema_message_for("patch")
28
- end
29
- elsif bookbinder_schema_version != starting_schema_version
30
- raise Configuration::ConfigSchemaUnsupportedError.new messages.schema_now_required_message
31
- end
32
- end
33
-
34
- private
35
-
36
- attr_reader :bookbinder_schema_version, :starting_schema_version, :messages, :view_updater
37
-
38
- def nonbreaking_schema_message_for(version_level)
39
- "[WARNING] Your schema is valid, but there exists a new #{version_level} version. Consider updating your config.yml."
40
- end
41
- end
42
-
43
- Version = Struct.new(:major, :minor, :patch) do
44
- class << self
45
- def parse(raw_version)
46
- if raw_version
47
- new(*raw_version.split('.'))
48
- else
49
- new(nil, nil, nil)
50
- end
51
- end
52
- end
53
-
54
- def valid?
55
- [major, minor, patch].all?(&:present?)
56
- end
57
-
58
- def to_s
59
- [major, minor, patch].compact.join('.')
60
- end
61
- end
62
-
63
- class VersionCheckerMessages
64
- def initialize(user_schema_version, bookbinder_schema_version)
65
- @user_schema_version = user_schema_version
66
- @bookbinder_schema_version = bookbinder_schema_version
67
- end
68
-
69
- def schema_now_required_message
70
- "[ERROR] Bookbinder now requires a certain schema. Please see README " +
71
- "and provide a schema version."
72
- end
73
-
74
- def incompatible_schema_message
75
- "[ERROR] Your config.yml format, schema version #{user_schema_version}, " +
76
- "is older than this version of Bookbinder can support. Please update " +
77
- "your config.yml keys and format to version #{bookbinder_schema_version} " +
78
- "and try again."
79
- end
80
-
81
- def unrecognized_schema_version_message
82
- "[ERROR] The config schema version #{user_schema_version} is " +
83
- "unrecognized by this version of Bookbinder. The latest schema version " +
84
- "is #{bookbinder_schema_version}."
85
- end
86
-
87
- private
88
-
89
- attr_reader :user_schema_version, :bookbinder_schema_version
90
- end
91
- end