bookbindery 1.0.0 → 2.0.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.
- checksums.yaml +4 -4
- data/lib/bookbinder/archive.rb +1 -1
- data/lib/bookbinder/archive_menu_configuration.rb +34 -0
- data/lib/bookbinder/book.rb +17 -17
- data/lib/bookbinder/cli.rb +25 -36
- data/lib/bookbinder/code_example.rb +5 -38
- data/lib/bookbinder/code_example_reader.rb +40 -0
- data/lib/bookbinder/colorizer.rb +14 -0
- data/lib/bookbinder/command_runner.rb +9 -16
- data/lib/bookbinder/command_validator.rb +14 -7
- data/lib/bookbinder/commands/bind.rb +321 -0
- data/lib/bookbinder/commands/build_and_push_tarball.rb +7 -6
- data/lib/bookbinder/commands/chain.rb +11 -0
- data/lib/bookbinder/commands/generate_pdf.rb +4 -3
- data/lib/bookbinder/commands/help.rb +49 -10
- data/lib/bookbinder/commands/naming.rb +9 -1
- data/lib/bookbinder/commands/push_local_to_staging.rb +4 -3
- data/lib/bookbinder/commands/push_to_prod.rb +36 -4
- data/lib/bookbinder/commands/run_publish_ci.rb +21 -24
- data/lib/bookbinder/commands/tag.rb +3 -3
- data/lib/bookbinder/commands/update_local_doc_repos.rb +5 -4
- data/lib/bookbinder/commands/version.rb +11 -8
- data/lib/bookbinder/configuration.rb +8 -3
- data/lib/bookbinder/configuration_fetcher.rb +7 -25
- data/lib/bookbinder/configuration_validator.rb +21 -0
- data/lib/bookbinder/distributor.rb +1 -1
- data/lib/bookbinder/dita_html_to_middleman_formatter.rb +37 -0
- data/lib/bookbinder/dita_section.rb +7 -0
- data/lib/bookbinder/dita_section_gatherer.rb +28 -0
- data/lib/bookbinder/git_accessor.rb +17 -0
- data/lib/bookbinder/git_client.rb +10 -7
- data/lib/bookbinder/git_hub_repository.rb +46 -41
- data/lib/bookbinder/local_dita_preprocessor.rb +27 -0
- data/lib/bookbinder/local_dita_to_html_converter.rb +49 -0
- data/lib/bookbinder/local_file_system_accessor.rb +68 -0
- data/lib/bookbinder/middleman_runner.rb +30 -17
- data/lib/bookbinder/pdf_generator.rb +1 -1
- data/lib/bookbinder/publisher.rb +16 -80
- data/lib/bookbinder/remote_yaml_credential_provider.rb +2 -3
- data/lib/bookbinder/repositories/command_repository.rb +156 -0
- data/lib/bookbinder/repositories/section_repository.rb +31 -0
- data/lib/bookbinder/section.rb +5 -67
- data/lib/bookbinder/shell_out.rb +1 -0
- data/lib/bookbinder/sheller.rb +19 -0
- data/lib/bookbinder/sieve.rb +6 -1
- data/lib/bookbinder/stabilimentum.rb +5 -1
- data/lib/bookbinder/terminal.rb +10 -0
- data/lib/bookbinder/user_message.rb +6 -0
- data/lib/bookbinder/user_message_presenter.rb +21 -0
- data/lib/bookbinder/yaml_loader.rb +18 -7
- data/lib/bookbinder.rb +2 -9
- data/master_middleman/archive_drop_down_menu.rb +46 -0
- data/master_middleman/bookbinder_helpers.rb +47 -40
- data/master_middleman/quicklinks_renderer.rb +1 -1
- metadata +33 -87
- data/lib/bookbinder/commands/publish.rb +0 -138
- data/lib/bookbinder/usage_messenger.rb +0 -33
- /data/{bin → install_bin}/bookbinder +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 56679c8bf251f348c3dd66d86317c0c848b35706
|
|
4
|
+
data.tar.gz: e6a280ed228236c2fa381393d5bdeb5f3710f8e1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b28159d61a3847f29100709af210253bc25e90ed5770273d4891ea928a24f643f7537832c36e8e3efe2780b5dfdab773b4dd3c41ab994a3ce4c8cddfcedc9cb9
|
|
7
|
+
data.tar.gz: 3463e88ed1b0044e735c0e0ffd25c572b4258cc0906985f0b74c6bfca47d1e2269895700f4ca07c694c83c2a4ee25268be1c9dd9be2e5c8284cb286564510097
|
data/lib/bookbinder/archive.rb
CHANGED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
module Bookbinder
|
|
2
|
+
class ArchiveMenuConfiguration
|
|
3
|
+
def initialize(loader: nil, config_filename: nil)
|
|
4
|
+
@loader = loader
|
|
5
|
+
@config_filename = config_filename
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def generate(base_config, sections)
|
|
9
|
+
base_config.merge(
|
|
10
|
+
archive_menu: root_config(base_config).merge(section_config(sections))
|
|
11
|
+
)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
attr_reader :loader, :config_filename
|
|
17
|
+
|
|
18
|
+
def root_config(base_config)
|
|
19
|
+
{ '.' => base_config[:archive_menu] }
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def section_config(sections)
|
|
23
|
+
sections.reduce({}) {|config, section|
|
|
24
|
+
config_path = section.path_to_repository.join(config_filename)
|
|
25
|
+
archive_config = loader.load_key(config_path, 'archive_menu')
|
|
26
|
+
if archive_config
|
|
27
|
+
config.merge(section.directory_name => archive_config)
|
|
28
|
+
else
|
|
29
|
+
config
|
|
30
|
+
end
|
|
31
|
+
}
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
data/lib/bookbinder/book.rb
CHANGED
|
@@ -4,7 +4,6 @@ require_relative 'directory_helpers'
|
|
|
4
4
|
module Bookbinder
|
|
5
5
|
class Book
|
|
6
6
|
include DirectoryHelperMethods
|
|
7
|
-
attr_reader :sections
|
|
8
7
|
|
|
9
8
|
def self.from_remote(logger: nil, full_name: nil, destination_dir: nil, ref: nil, git_accessor: Git)
|
|
10
9
|
book = new(logger: logger, full_name: full_name, target_ref: ref, git_accessor: git_accessor)
|
|
@@ -12,12 +11,23 @@ module Bookbinder
|
|
|
12
11
|
book
|
|
13
12
|
end
|
|
14
13
|
|
|
15
|
-
def initialize(logger: nil,
|
|
16
|
-
|
|
17
|
-
|
|
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)
|
|
18
24
|
end
|
|
19
25
|
|
|
20
|
-
@repository = GitHubRepository.new(logger: logger,
|
|
26
|
+
@repository = GitHubRepository.new(logger: logger,
|
|
27
|
+
full_name: full_name,
|
|
28
|
+
target_ref: target_ref,
|
|
29
|
+
github_token: github_token,
|
|
30
|
+
git_accessor: git_accessor)
|
|
21
31
|
@git_accessor = git_accessor
|
|
22
32
|
end
|
|
23
33
|
|
|
@@ -33,22 +43,12 @@ module Bookbinder
|
|
|
33
43
|
@repository.directory
|
|
34
44
|
end
|
|
35
45
|
|
|
36
|
-
def get_modification_date_for(file: nil, full_path: nil)
|
|
37
|
-
git_directory, file_relative_path = full_path.split(output_dir_name+'/')
|
|
38
|
-
begin
|
|
39
|
-
git_base_object = Git.open(git_directory)
|
|
40
|
-
rescue => e
|
|
41
|
-
raise "Invalid git repository! #{git_directory} is not a .git directory"
|
|
42
|
-
end
|
|
43
|
-
@repository.get_modification_date_for(file: file_relative_path, git: git_base_object)
|
|
44
|
-
end
|
|
45
|
-
|
|
46
46
|
def copy_from_remote(destination_dir)
|
|
47
|
-
@repository.copy_from_remote(destination_dir
|
|
47
|
+
@repository.copy_from_remote(destination_dir)
|
|
48
48
|
end
|
|
49
49
|
|
|
50
50
|
def tag_self_and_sections_with(tag)
|
|
51
|
-
(@
|
|
51
|
+
(@section_vcs_repos + [@repository]).each { |repo| repo.tag_with tag }
|
|
52
52
|
end
|
|
53
53
|
end
|
|
54
54
|
end
|
data/lib/bookbinder/cli.rb
CHANGED
|
@@ -1,53 +1,42 @@
|
|
|
1
|
+
require_relative 'colorizer'
|
|
1
2
|
require_relative 'command_runner'
|
|
2
|
-
require_relative 'local_file_system_accessor'
|
|
3
3
|
require_relative 'command_validator'
|
|
4
|
-
|
|
5
|
-
require_relative '
|
|
6
|
-
require_relative '
|
|
7
|
-
require_relative '
|
|
8
|
-
require_relative 'commands/version'
|
|
9
|
-
require_relative 'commands/help'
|
|
4
|
+
require_relative 'configuration'
|
|
5
|
+
require_relative 'repositories/command_repository'
|
|
6
|
+
require_relative 'terminal'
|
|
7
|
+
require_relative 'user_message_presenter'
|
|
10
8
|
|
|
11
9
|
module Bookbinder
|
|
12
10
|
class Cli
|
|
13
|
-
FLAGS = [
|
|
14
|
-
Commands::Version,
|
|
15
|
-
Commands::Help
|
|
16
|
-
]
|
|
17
|
-
|
|
18
|
-
COMMANDS = [
|
|
19
|
-
Commands::BuildAndPushTarball,
|
|
20
|
-
Commands::GeneratePDF,
|
|
21
|
-
Commands::Publish,
|
|
22
|
-
Commands::PushLocalToStaging,
|
|
23
|
-
Commands::PushToProd,
|
|
24
|
-
Commands::RunPublishCI,
|
|
25
|
-
Commands::Tag,
|
|
26
|
-
Commands::UpdateLocalDocRepos,
|
|
27
|
-
].freeze
|
|
28
|
-
|
|
29
11
|
def run(args)
|
|
30
12
|
command_name = args[0]
|
|
31
13
|
command_arguments = args[1..-1]
|
|
32
14
|
|
|
33
15
|
logger = BookbinderLogger.new
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
16
|
+
commands = Repositories::CommandRepository.new(logger)
|
|
17
|
+
|
|
18
|
+
command_validator = CommandValidator.new(commands, commands.help.usage_message)
|
|
19
|
+
command_runner = CommandRunner.new(logger, commands)
|
|
20
|
+
command_name = command_name ? command_name : '--help'
|
|
21
|
+
|
|
22
|
+
colorizer = Colorizer.new
|
|
23
|
+
user_message_presenter = UserMessagePresenter.new(colorizer)
|
|
24
|
+
terminal = Terminal.new
|
|
25
|
+
|
|
26
|
+
user_message = command_validator.validate(command_name)
|
|
27
|
+
if user_message.escalation_type == EscalationType.error
|
|
28
|
+
error_message = user_message_presenter.get_error(user_message)
|
|
29
|
+
terminal.update(error_message)
|
|
30
|
+
return 1
|
|
31
|
+
elsif user_message.escalation_type == EscalationType.warn
|
|
32
|
+
warning_message = user_message_presenter.get_warning(user_message)
|
|
33
|
+
terminal.update(warning_message)
|
|
34
|
+
end
|
|
44
35
|
|
|
45
36
|
begin
|
|
46
|
-
command_name ? command_validator.validate!(command_name) : command_name = '--help'
|
|
47
|
-
|
|
48
37
|
command_runner.run command_name, command_arguments
|
|
49
38
|
|
|
50
|
-
rescue Commands::
|
|
39
|
+
rescue Commands::Bind::VersionUnsupportedError => e
|
|
51
40
|
logger.error "config.yml at version '#{e.message}' has an unsupported API."
|
|
52
41
|
1
|
|
53
42
|
rescue Configuration::CredentialKeyError => e
|
|
@@ -1,40 +1,7 @@
|
|
|
1
|
-
require_relative 'section'
|
|
2
|
-
|
|
3
1
|
module Bookbinder
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def get_snippet_and_language_at(marker)
|
|
12
|
-
unless @repository.copied?
|
|
13
|
-
@repository.announce_skip
|
|
14
|
-
return ''
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
prepared_snippet_at(marker)
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
private
|
|
21
|
-
|
|
22
|
-
def prepared_snippet_at(marker)
|
|
23
|
-
snippet = ''
|
|
24
|
-
FileUtils.cd(@repository.copied_to) { snippet = scrape_for(marker) }
|
|
25
|
-
|
|
26
|
-
raise InvalidSnippet.new(full_name, marker) if snippet.empty?
|
|
27
|
-
lines = snippet.split("\n")
|
|
28
|
-
language_match = lines[0].match(/code_snippet #{Regexp.escape(marker)} start (\w+)/)
|
|
29
|
-
language = language_match[1] if language_match
|
|
30
|
-
[lines[1..-2].join("\n"), language]
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def scrape_for(marker)
|
|
34
|
-
locale = 'LC_CTYPE=C LANG=C' # Quiets 'sed: RE error: illegal byte sequence'
|
|
35
|
-
result = `#{locale} find . -exec sed -ne '/code_snippet #{marker} start/,/code_snippet #{marker} end/ p' {} \\; 2> /dev/null`
|
|
36
|
-
result = "" unless result.lines.last && result.lines.last.match(/code_snippet #{marker} end/)
|
|
37
|
-
result
|
|
38
|
-
end
|
|
39
|
-
end
|
|
2
|
+
CodeExample = Struct.new(:path_to_repository,
|
|
3
|
+
:full_name,
|
|
4
|
+
:copied,
|
|
5
|
+
:destination_dir,
|
|
6
|
+
:directory_name)
|
|
40
7
|
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
require_relative '../../lib/bookbinder/bookbinder_logger'
|
|
2
|
+
|
|
3
|
+
module Bookbinder
|
|
4
|
+
class CodeExampleReader
|
|
5
|
+
class InvalidSnippet < StandardError
|
|
6
|
+
def initialize(repo, marker)
|
|
7
|
+
super "Error with marker #{marker.cyan} #{'in'.red} #{repo.cyan}#{'.'.red}"
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def initialize(logger)
|
|
12
|
+
@logger = logger
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def get_snippet_and_language_at(marker, path_to_repository, copied, repo_name)
|
|
16
|
+
unless copied
|
|
17
|
+
logger.log ' skipping (not found) '.magenta + repo_name
|
|
18
|
+
return ''
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
snippet = ''
|
|
22
|
+
FileUtils.cd(path_to_repository) { locale = 'LC_CTYPE=C LANG=C' # Quiets 'sed: RE error: illegal byte sequence'
|
|
23
|
+
result = `#{locale} find . -exec sed -ne '/code_snippet #{marker} start/,/code_snippet #{marker} end/ p' {} \\; 2> /dev/null`
|
|
24
|
+
result = "" unless result.lines.last && result.lines.last.match(/code_snippet #{marker} end/)
|
|
25
|
+
scrape_for_value = result
|
|
26
|
+
snippet = scrape_for_value }
|
|
27
|
+
|
|
28
|
+
raise InvalidSnippet.new(repo_name, marker) if snippet.empty?
|
|
29
|
+
lines = snippet.split("\n")
|
|
30
|
+
language_match = lines[0].match(/code_snippet #{Regexp.escape(marker)} start (\w+)/)
|
|
31
|
+
language = language_match[1] if language_match
|
|
32
|
+
[lines[1..-2].join("\n"), language]
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
attr_reader :logger
|
|
38
|
+
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
require 'ansi/code'
|
|
2
|
+
require 'ostruct'
|
|
3
|
+
|
|
4
|
+
module Bookbinder
|
|
5
|
+
|
|
6
|
+
class Colorizer
|
|
7
|
+
Colors = OpenStruct.new(red: Proc.new { |msg| ANSI.red {msg} },
|
|
8
|
+
yellow: Proc.new { |msg| ANSI.yellow {msg} })
|
|
9
|
+
|
|
10
|
+
def colorize(string, color)
|
|
11
|
+
color.call string.to_s
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -1,32 +1,25 @@
|
|
|
1
1
|
require_relative 'cli_error'
|
|
2
|
+
require_relative 'local_dita_to_html_converter'
|
|
3
|
+
require_relative 'sheller'
|
|
2
4
|
|
|
3
5
|
module Bookbinder
|
|
4
6
|
class CommandRunner
|
|
5
|
-
def initialize(
|
|
6
|
-
@configuration_fetcher = configuration_fetcher
|
|
7
|
-
@usage_message = usage_message
|
|
7
|
+
def initialize(logger, commands)
|
|
8
8
|
@logger = logger
|
|
9
9
|
@commands = commands
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
def run(command_name, command_arguments)
|
|
13
|
-
command = commands.detect { |known_command| known_command.command_name
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
command.new(logger, @configuration_fetcher).run command_arguments
|
|
19
|
-
end
|
|
20
|
-
rescue CliError::InvalidArguments
|
|
21
|
-
logger.log command.usage
|
|
22
|
-
1
|
|
23
|
-
end
|
|
13
|
+
command = commands.detect { |known_command| known_command.command_for?(command_name) }
|
|
14
|
+
command.run(command_arguments)
|
|
15
|
+
rescue CliError::InvalidArguments
|
|
16
|
+
logger.log command.usage
|
|
17
|
+
1
|
|
24
18
|
end
|
|
25
19
|
|
|
26
20
|
private
|
|
27
21
|
|
|
28
|
-
attr_reader :logger, :
|
|
29
|
-
|
|
22
|
+
attr_reader :logger, :commands
|
|
30
23
|
end
|
|
31
24
|
end
|
|
32
25
|
|
|
@@ -1,24 +1,31 @@
|
|
|
1
1
|
require_relative 'cli_error'
|
|
2
|
+
require 'ostruct'
|
|
3
|
+
require_relative 'user_message'
|
|
2
4
|
|
|
3
5
|
module Bookbinder
|
|
4
6
|
class CommandValidator
|
|
5
|
-
def initialize(
|
|
6
|
-
@usage_messenger = usage_messenger
|
|
7
|
+
def initialize(commands, usage_text)
|
|
7
8
|
@commands = commands
|
|
8
9
|
@usage_text = usage_text
|
|
9
10
|
end
|
|
10
11
|
|
|
11
|
-
def validate
|
|
12
|
-
known_command_names = commands.map(&:command_name)
|
|
12
|
+
def validate command_name
|
|
13
13
|
command_type = "#{command_name}".match(/^--/) ? 'flag' : 'command'
|
|
14
|
-
if
|
|
15
|
-
|
|
14
|
+
if commands.none? { |command| command.command_for?(command_name) }
|
|
15
|
+
UserMessage.new "Unrecognized #{command_type} '#{command_name}'\n" + usage_text, EscalationType.error
|
|
16
|
+
elsif command = commands.find { |command| (command.respond_to? :deprecated_command_for?) &&
|
|
17
|
+
(command.deprecated_command_for? command_name) }
|
|
18
|
+
UserMessage.new "Use of #{command_name} is deprecated. " +
|
|
19
|
+
"The preferred usage is below: \n#{command.usage}",
|
|
20
|
+
EscalationType.warn
|
|
21
|
+
else
|
|
22
|
+
UserMessage.new "Success", EscalationType.success
|
|
16
23
|
end
|
|
17
24
|
end
|
|
18
25
|
|
|
19
26
|
private
|
|
20
27
|
|
|
21
|
-
attr_reader :
|
|
28
|
+
attr_reader :commands, :usage_text
|
|
22
29
|
end
|
|
23
30
|
end
|
|
24
31
|
|