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
@@ -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