bookbindery 1.0.3 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/{bin → install_bin}/bookbinder +0 -0
- data/lib/bookbinder.rb +2 -9
- 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/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/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/master_middleman/archive_drop_down_menu.rb +46 -0
- data/master_middleman/bookbinder_helpers.rb +47 -40
- metadata +33 -87
- data/lib/bookbinder/commands/publish.rb +0 -138
- data/lib/bookbinder/usage_messenger.rb +0 -33
@@ -5,7 +5,7 @@ require_relative '../archive'
|
|
5
5
|
module Bookbinder
|
6
6
|
module Commands
|
7
7
|
class BuildAndPushTarball < BookbinderCommand
|
8
|
-
|
8
|
+
include Commands::Naming
|
9
9
|
|
10
10
|
class MissingBuildNumber < StandardError
|
11
11
|
def initialize
|
@@ -13,17 +13,18 @@ module Bookbinder
|
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
-
def
|
17
|
-
|
16
|
+
def usage
|
17
|
+
[command_name,
|
18
|
+
"Create a tarball from the final_app directory and push to the S3 bucket specified in your credentials.yml"]
|
18
19
|
end
|
19
20
|
|
20
21
|
def run(_)
|
21
22
|
raise MissingBuildNumber unless ENV['BUILD_NUMBER']
|
22
23
|
config = configuration_fetcher.fetch_config
|
23
24
|
aws_credentials = config.aws_credentials
|
24
|
-
|
25
|
-
|
26
|
-
|
25
|
+
archive = Archive.new(logger: @logger, key: aws_credentials.access_key, secret: aws_credentials.secret_key)
|
26
|
+
archive.create_and_upload_tarball(build_number: ENV['BUILD_NUMBER'], bucket: aws_credentials.green_builds_bucket,
|
27
|
+
namespace: GitHubRepository.new(logger: @logger, full_name: config.book_repo, git_accessor: Git).short_name)
|
27
28
|
0
|
28
29
|
end
|
29
30
|
end
|
@@ -6,7 +6,7 @@ require_relative 'naming'
|
|
6
6
|
module Bookbinder
|
7
7
|
module Commands
|
8
8
|
class GeneratePDF < BookbinderCommand
|
9
|
-
|
9
|
+
include Commands::Naming
|
10
10
|
|
11
11
|
class AppNotPublished < StandardError
|
12
12
|
def initialize(msg='You must publish locally before you generate a PDF.')
|
@@ -32,8 +32,9 @@ module Bookbinder
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
-
def
|
36
|
-
"generate_pdf [<file_name>.yml]
|
35
|
+
def usage
|
36
|
+
["generate_pdf [<file_name>.yml]",
|
37
|
+
"Generate a PDF from the files specified in <file_name.yml>"]
|
37
38
|
end
|
38
39
|
|
39
40
|
def run(params)
|
@@ -1,21 +1,21 @@
|
|
1
|
+
require_relative 'naming'
|
2
|
+
|
1
3
|
module Bookbinder
|
2
4
|
module Commands
|
3
5
|
class Help
|
4
|
-
|
5
|
-
@logger = logger
|
6
|
-
@usage_message = usage_message
|
7
|
-
end
|
6
|
+
include Commands::Naming
|
8
7
|
|
9
|
-
def
|
10
|
-
|
8
|
+
def initialize(logger, other_commands)
|
9
|
+
@logger = logger
|
10
|
+
@other_commands = other_commands
|
11
11
|
end
|
12
12
|
|
13
|
-
def
|
13
|
+
def command_name
|
14
14
|
'--help'
|
15
15
|
end
|
16
16
|
|
17
|
-
def
|
18
|
-
"
|
17
|
+
def usage
|
18
|
+
[command_name, "Print this message"]
|
19
19
|
end
|
20
20
|
|
21
21
|
def run(*)
|
@@ -23,9 +23,48 @@ module Bookbinder
|
|
23
23
|
0
|
24
24
|
end
|
25
25
|
|
26
|
+
def usage_message
|
27
|
+
[usage_header, command_usage_messages].join("\n")
|
28
|
+
end
|
29
|
+
|
26
30
|
private
|
27
31
|
|
28
|
-
|
32
|
+
def command_usage_messages
|
33
|
+
(flags + standard_commands).reduce('') { |message, command|
|
34
|
+
"#{message}#{usage_indent}#{formatted_usage(command)}\n"
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
def formatted_usage(command)
|
39
|
+
"#{command.usage[0].ljust(chars_for_usage_definition)}#{command.usage[1]}"
|
40
|
+
end
|
41
|
+
|
42
|
+
def usage_indent
|
43
|
+
" " * 4
|
44
|
+
end
|
45
|
+
|
46
|
+
def chars_for_usage_definition
|
47
|
+
33
|
48
|
+
end
|
49
|
+
|
50
|
+
def flags
|
51
|
+
other_commands.select(&:flag?) + [self]
|
52
|
+
end
|
53
|
+
|
54
|
+
def standard_commands
|
55
|
+
other_commands.reject(&:flag?)
|
56
|
+
end
|
57
|
+
|
58
|
+
def usage_header
|
59
|
+
<<TEXT
|
60
|
+
|
61
|
+
\e[1;39;49mDocumentation\e[0m: https://github.com/pivotal-cf/docs-bookbinder
|
62
|
+
|
63
|
+
\e[1;39;49mUsage\e[0m: bookbinder <command|flag> [args]
|
64
|
+
TEXT
|
65
|
+
end
|
66
|
+
|
67
|
+
attr_reader :logger, :other_commands
|
29
68
|
end
|
30
69
|
end
|
31
70
|
end
|
@@ -2,7 +2,15 @@ module Bookbinder
|
|
2
2
|
module Commands
|
3
3
|
module Naming
|
4
4
|
def command_name
|
5
|
-
name.demodulize.underscore
|
5
|
+
self.class.name.demodulize.underscore
|
6
|
+
end
|
7
|
+
|
8
|
+
def command_for?(test_command_name)
|
9
|
+
command_name == test_command_name
|
10
|
+
end
|
11
|
+
|
12
|
+
def flag?
|
13
|
+
command_name.match(/^--/)
|
6
14
|
end
|
7
15
|
end
|
8
16
|
end
|
@@ -5,10 +5,11 @@ require_relative 'naming'
|
|
5
5
|
module Bookbinder
|
6
6
|
module Commands
|
7
7
|
class PushLocalToStaging < BookbinderCommand
|
8
|
-
|
8
|
+
include Commands::Naming
|
9
9
|
|
10
|
-
def
|
11
|
-
|
10
|
+
def usage
|
11
|
+
[command_name,
|
12
|
+
"Push the contents of final_app to the staging host specified in credentials.yml"]
|
12
13
|
end
|
13
14
|
|
14
15
|
def run(_)
|
@@ -3,21 +3,35 @@ require_relative 'bookbinder_command'
|
|
3
3
|
require_relative 'naming'
|
4
4
|
|
5
5
|
module Bookbinder
|
6
|
+
class PushToProdValidator
|
7
|
+
MissingRequiredKeyError = Class.new(RuntimeError)
|
8
|
+
end
|
9
|
+
|
6
10
|
module Commands
|
7
|
-
class PushToProd
|
8
|
-
|
11
|
+
class PushToProd
|
12
|
+
include Commands::Naming
|
13
|
+
CONFIG_REQUIRED_KEYS = %w(cred_repo)
|
14
|
+
|
15
|
+
def initialize(logger, configuration_fetcher)
|
16
|
+
@logger = logger
|
17
|
+
@configuration_fetcher = configuration_fetcher
|
18
|
+
end
|
9
19
|
|
10
|
-
def
|
11
|
-
"push_to_prod [build_#]
|
20
|
+
def usage
|
21
|
+
["push_to_prod [build_#]",
|
22
|
+
"Push latest or <build_#> from your S3 bucket to the production host specified in credentials.yml"]
|
12
23
|
end
|
13
24
|
|
14
25
|
def run(arguments)
|
26
|
+
validate
|
15
27
|
Distributor.build(@logger, options(arguments)).distribute
|
16
28
|
0
|
17
29
|
end
|
18
30
|
|
19
31
|
private
|
20
32
|
|
33
|
+
attr_reader :configuration_fetcher
|
34
|
+
|
21
35
|
def options(arguments)
|
22
36
|
{
|
23
37
|
app_dir: Dir.mktmpdir,
|
@@ -30,6 +44,24 @@ module Bookbinder
|
|
30
44
|
production: true
|
31
45
|
}
|
32
46
|
end
|
47
|
+
|
48
|
+
def config
|
49
|
+
@config ||= configuration_fetcher.fetch_config
|
50
|
+
end
|
51
|
+
|
52
|
+
def validate
|
53
|
+
missing_keys = []
|
54
|
+
CONFIG_REQUIRED_KEYS.map do |required_key|
|
55
|
+
unless config.has_option?(required_key)
|
56
|
+
missing_keys.push(required_key)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
if missing_keys.length > 0
|
61
|
+
raise PushToProdValidator::MissingRequiredKeyError.new "Your config.yml is missing required key(s). The require keys for this commands are " + missing_keys.join(", ")
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
33
65
|
end
|
34
66
|
end
|
35
67
|
end
|
@@ -1,42 +1,39 @@
|
|
1
|
-
require_relative '
|
1
|
+
require_relative 'bind'
|
2
|
+
require_relative 'build_and_push_tarball'
|
3
|
+
require_relative 'chain'
|
2
4
|
require_relative 'naming'
|
3
|
-
require_relative 'publish'
|
4
5
|
require_relative 'push_local_to_staging'
|
5
|
-
require_relative 'build_and_push_tarball'
|
6
6
|
|
7
7
|
module Bookbinder
|
8
8
|
module Commands
|
9
|
-
class RunPublishCI
|
10
|
-
|
9
|
+
class RunPublishCI
|
10
|
+
include Commands::Naming
|
11
|
+
include Commands::Chain
|
11
12
|
|
12
|
-
def
|
13
|
-
|
13
|
+
def usage
|
14
|
+
[command_name,
|
15
|
+
"Run publish, push_local_to_staging, and build_and_push_tarball for CI purposes"]
|
14
16
|
end
|
15
17
|
|
16
|
-
def
|
17
|
-
|
18
|
-
|
19
|
-
|
18
|
+
def initialize(publish_command, push_local_to_staging_command, build_and_push_tarball_command)
|
19
|
+
@publish_command = publish_command
|
20
|
+
@push_local_to_staging_command = push_local_to_staging_command
|
21
|
+
@build_and_push_tarball_command = build_and_push_tarball_command
|
20
22
|
end
|
21
23
|
|
22
|
-
|
23
|
-
|
24
|
-
def check_params
|
24
|
+
def run(cli_args)
|
25
25
|
raise BuildAndPushTarball::MissingBuildNumber unless ENV['BUILD_NUMBER']
|
26
|
-
config.book_repo
|
27
|
-
end
|
28
26
|
|
29
|
-
|
30
|
-
|
27
|
+
command_chain(
|
28
|
+
->{publish_command.run(['github'] + cli_args)},
|
29
|
+
->{push_local_to_staging_command.run([])},
|
30
|
+
->{build_and_push_tarball_command.run([])}
|
31
|
+
)
|
31
32
|
end
|
32
33
|
|
33
|
-
|
34
|
-
PushLocalToStaging.new(@logger, @configuration_fetcher).run []
|
35
|
-
end
|
34
|
+
private
|
36
35
|
|
37
|
-
|
38
|
-
BuildAndPushTarball.new(@logger, @configuration_fetcher).run []
|
39
|
-
end
|
36
|
+
attr_reader :publish_command, :push_local_to_staging_command, :build_and_push_tarball_command
|
40
37
|
end
|
41
38
|
end
|
42
39
|
end
|
@@ -8,10 +8,10 @@ require_relative 'naming'
|
|
8
8
|
module Bookbinder
|
9
9
|
module Commands
|
10
10
|
class Tag < BookbinderCommand
|
11
|
-
|
11
|
+
include Commands::Naming
|
12
12
|
|
13
|
-
def
|
14
|
-
"tag <git tag>
|
13
|
+
def usage
|
14
|
+
["tag <git tag>", "Apply the specified <git tag> to your book and all sections of your book"]
|
15
15
|
end
|
16
16
|
|
17
17
|
def run(params)
|
@@ -4,10 +4,11 @@ require_relative 'naming'
|
|
4
4
|
module Bookbinder
|
5
5
|
module Commands
|
6
6
|
class UpdateLocalDocRepos < BookbinderCommand
|
7
|
-
|
7
|
+
include Commands::Naming
|
8
8
|
|
9
|
-
def
|
10
|
-
|
9
|
+
def usage
|
10
|
+
[command_name,
|
11
|
+
"Run `git pull` on all sections that exist at the same directory level as your book directory"]
|
11
12
|
end
|
12
13
|
|
13
14
|
def run(_)
|
@@ -20,7 +21,7 @@ module Bookbinder
|
|
20
21
|
def repo_for(section_config)
|
21
22
|
local_repo_dir = File.absolute_path('../')
|
22
23
|
GitHubRepository.new(logger: @logger, full_name: section_config['repository']['name'],
|
23
|
-
local_repo_dir: local_repo_dir)
|
24
|
+
local_repo_dir: local_repo_dir, git_accessor: Git)
|
24
25
|
end
|
25
26
|
end
|
26
27
|
end
|
@@ -1,22 +1,25 @@
|
|
1
|
-
require_relative '
|
1
|
+
require_relative 'naming'
|
2
2
|
|
3
3
|
module Bookbinder
|
4
4
|
module Commands
|
5
|
-
class Version
|
6
|
-
|
7
|
-
|
5
|
+
class Version
|
6
|
+
include Commands::Naming
|
7
|
+
|
8
|
+
def initialize(logger)
|
9
|
+
@logger = logger
|
8
10
|
end
|
9
11
|
|
10
|
-
def
|
12
|
+
def command_name
|
11
13
|
'--version'
|
12
14
|
end
|
13
15
|
|
14
|
-
def
|
15
|
-
"
|
16
|
+
def usage
|
17
|
+
[command_name, "Print the version of bookbinder"]
|
16
18
|
end
|
17
19
|
|
18
20
|
def run(*)
|
19
|
-
|
21
|
+
root = File.expand_path('../../../../', __FILE__)
|
22
|
+
@logger.log "bookbinder #{Gem::Specification::load(File.join root, "bookbinder.gemspec").version}"
|
20
23
|
0
|
21
24
|
end
|
22
25
|
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require_relative 'remote_yaml_credential_provider'
|
2
2
|
require_relative 'git_hub_repository'
|
3
|
+
require 'git'
|
3
4
|
|
4
5
|
module Bookbinder
|
5
6
|
class Configuration
|
@@ -105,8 +106,8 @@ module Bookbinder
|
|
105
106
|
@config = config_hash
|
106
107
|
end
|
107
108
|
|
108
|
-
CONFIG_REQUIRED_KEYS = %w(book_repo
|
109
|
-
CONFIG_OPTIONAL_KEYS = %w(archive_menu)
|
109
|
+
CONFIG_REQUIRED_KEYS = %w(book_repo public_host pdf)
|
110
|
+
CONFIG_OPTIONAL_KEYS = %w(archive_menu dita_sections layout_repo versions pdf_index cred_repo)
|
110
111
|
|
111
112
|
CONFIG_REQUIRED_KEYS.each do |method_name|
|
112
113
|
define_method(method_name) do
|
@@ -120,6 +121,10 @@ module Bookbinder
|
|
120
121
|
end
|
121
122
|
end
|
122
123
|
|
124
|
+
def sections
|
125
|
+
config.fetch('sections', [])
|
126
|
+
end
|
127
|
+
|
123
128
|
def has_option?(key)
|
124
129
|
@config.has_key?(key)
|
125
130
|
end
|
@@ -157,7 +162,7 @@ module Bookbinder
|
|
157
162
|
end
|
158
163
|
|
159
164
|
def credentials_repository
|
160
|
-
@credentials_repository ||= GitHubRepository.new(logger: @logger, full_name: cred_repo)
|
165
|
+
@credentials_repository ||= GitHubRepository.new(logger: @logger, full_name: cred_repo, git_accessor: Git)
|
161
166
|
end
|
162
167
|
end
|
163
168
|
end
|
@@ -1,13 +1,8 @@
|
|
1
|
+
require_relative 'configuration'
|
1
2
|
require_relative 'yaml_loader'
|
2
3
|
|
3
4
|
module Bookbinder
|
4
|
-
|
5
5
|
class ConfigurationFetcher
|
6
|
-
attr_reader :logger,
|
7
|
-
:configuration_validator,
|
8
|
-
:config,
|
9
|
-
:config_file_path
|
10
|
-
|
11
6
|
def initialize(logger, configuration_validator, loader)
|
12
7
|
@loader = loader
|
13
8
|
@logger = logger
|
@@ -22,30 +17,17 @@ module Bookbinder
|
|
22
17
|
@config_file_path = config_file_path
|
23
18
|
end
|
24
19
|
|
25
|
-
|
26
20
|
private
|
27
21
|
|
28
|
-
attr_reader :
|
22
|
+
attr_reader(:loader, :logger, :configuration_validator, :config, :config_file_path)
|
29
23
|
|
30
24
|
def read_config_file
|
25
|
+
loader.load(config_file_path).merge('pdf_index' => nil)
|
31
26
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
rescue InvalidSyntaxError => e
|
37
|
-
raise "There is a syntax error in your config file: \n #{e}"
|
38
|
-
end
|
39
|
-
|
40
|
-
if config_hash
|
41
|
-
if File.exists?('./pdf_index.yml')
|
42
|
-
config_hash['pdf_index'] = loader.load(config_file_path)
|
43
|
-
else
|
44
|
-
config_hash['pdf_index'] = nil
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
config_hash
|
27
|
+
rescue FileNotFoundError => e
|
28
|
+
raise "The configuration file specified does not exist. Please create a config #{e} file at #{config_file_path} and try again."
|
29
|
+
rescue InvalidSyntaxError => e
|
30
|
+
raise "There is a syntax error in your config file: \n #{e}"
|
49
31
|
end
|
50
32
|
|
51
33
|
def validate(config_hash)
|