bookbindery 1.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 +7 -0
- data/bin/bookbinder +6 -0
- data/lib/bookbinder.rb +59 -0
- data/lib/bookbinder/app_fetcher.rb +40 -0
- data/lib/bookbinder/archive.rb +95 -0
- data/lib/bookbinder/artifact_namer.rb +22 -0
- data/lib/bookbinder/blue_green_app.rb +27 -0
- data/lib/bookbinder/book.rb +54 -0
- data/lib/bookbinder/bookbinder_logger.rb +33 -0
- data/lib/bookbinder/cf_command_runner.rb +114 -0
- data/lib/bookbinder/cf_routes.rb +19 -0
- data/lib/bookbinder/cli.rb +68 -0
- data/lib/bookbinder/cli_error.rb +6 -0
- data/lib/bookbinder/code_example.rb +40 -0
- data/lib/bookbinder/command_runner.rb +32 -0
- data/lib/bookbinder/command_validator.rb +24 -0
- data/lib/bookbinder/commands/bookbinder_command.rb +18 -0
- data/lib/bookbinder/commands/build_and_push_tarball.rb +31 -0
- data/lib/bookbinder/commands/generate_pdf.rb +140 -0
- data/lib/bookbinder/commands/help.rb +31 -0
- data/lib/bookbinder/commands/naming.rb +9 -0
- data/lib/bookbinder/commands/publish.rb +138 -0
- data/lib/bookbinder/commands/push_local_to_staging.rb +35 -0
- data/lib/bookbinder/commands/push_to_prod.rb +35 -0
- data/lib/bookbinder/commands/run_publish_ci.rb +42 -0
- data/lib/bookbinder/commands/tag.rb +31 -0
- data/lib/bookbinder/commands/update_local_doc_repos.rb +27 -0
- data/lib/bookbinder/commands/version.rb +25 -0
- data/lib/bookbinder/configuration.rb +163 -0
- data/lib/bookbinder/configuration_fetcher.rb +55 -0
- data/lib/bookbinder/configuration_validator.rb +162 -0
- data/lib/bookbinder/css_link_checker.rb +64 -0
- data/lib/bookbinder/directory_helpers.rb +15 -0
- data/lib/bookbinder/distributor.rb +69 -0
- data/lib/bookbinder/git_client.rb +63 -0
- data/lib/bookbinder/git_hub_repository.rb +151 -0
- data/lib/bookbinder/local_file_system_accessor.rb +9 -0
- data/lib/bookbinder/middleman_runner.rb +86 -0
- data/lib/bookbinder/pdf_generator.rb +73 -0
- data/lib/bookbinder/publisher.rb +125 -0
- data/lib/bookbinder/pusher.rb +34 -0
- data/lib/bookbinder/remote_yaml_credential_provider.rb +21 -0
- data/lib/bookbinder/section.rb +78 -0
- data/lib/bookbinder/server_director.rb +53 -0
- data/lib/bookbinder/shell_out.rb +19 -0
- data/lib/bookbinder/sieve.rb +62 -0
- data/lib/bookbinder/sitemap_generator.rb +19 -0
- data/lib/bookbinder/spider.rb +91 -0
- data/lib/bookbinder/stabilimentum.rb +59 -0
- data/lib/bookbinder/usage_messenger.rb +33 -0
- data/lib/bookbinder/yaml_loader.rb +22 -0
- data/master_middleman/bookbinder_helpers.rb +133 -0
- data/master_middleman/config.rb +23 -0
- data/master_middleman/quicklinks_renderer.rb +78 -0
- data/master_middleman/submodule_aware_assets.rb +45 -0
- data/template_app/Gemfile +7 -0
- data/template_app/Gemfile.lock +20 -0
- data/template_app/app.rb +3 -0
- data/template_app/config.ru +9 -0
- data/template_app/lib/rack_static.rb +19 -0
- data/template_app/lib/vienna_application.rb +26 -0
- metadata +462 -0
@@ -0,0 +1,19 @@
|
|
1
|
+
module Bookbinder
|
2
|
+
class CfRoutes
|
3
|
+
def initialize(raw_routes)
|
4
|
+
@raw_routes = raw_routes
|
5
|
+
end
|
6
|
+
|
7
|
+
def apps_by_host_and_domain
|
8
|
+
@apps_by_host_and_domain ||= Hash[
|
9
|
+
raw_routes.lines[3..-1].
|
10
|
+
map { |line| line.split(/\s+/, 3) }.
|
11
|
+
map { |item| [item[0..1], item[2].split(',').map(&:strip)] }
|
12
|
+
]
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
attr_reader :raw_routes
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require_relative 'command_runner'
|
2
|
+
require_relative 'local_file_system_accessor'
|
3
|
+
require_relative 'command_validator'
|
4
|
+
|
5
|
+
require_relative 'commands/build_and_push_tarball'
|
6
|
+
require_relative 'commands/generate_pdf'
|
7
|
+
require_relative 'commands/publish'
|
8
|
+
require_relative 'commands/version'
|
9
|
+
require_relative 'commands/help'
|
10
|
+
|
11
|
+
module Bookbinder
|
12
|
+
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
|
+
def run(args)
|
30
|
+
command_name = args[0]
|
31
|
+
command_arguments = args[1..-1]
|
32
|
+
|
33
|
+
logger = BookbinderLogger.new
|
34
|
+
yaml_loader = YAMLLoader.new
|
35
|
+
local_file_system_accessor = LocalFileSystemAccessor.new
|
36
|
+
configuration_validator = ConfigurationValidator.new(logger, local_file_system_accessor)
|
37
|
+
configuration_fetcher = ConfigurationFetcher.new(logger, configuration_validator, yaml_loader)
|
38
|
+
configuration_fetcher.set_config_file_path './config.yml'
|
39
|
+
usage_messenger = UsageMessenger.new
|
40
|
+
usage_message = usage_messenger.construct_for(COMMANDS, FLAGS)
|
41
|
+
command_validator = CommandValidator.new usage_messenger, COMMANDS + FLAGS, usage_message
|
42
|
+
|
43
|
+
command_runner = CommandRunner.new(configuration_fetcher, usage_message, logger, COMMANDS + FLAGS)
|
44
|
+
|
45
|
+
begin
|
46
|
+
command_name ? command_validator.validate!(command_name) : command_name = '--help'
|
47
|
+
|
48
|
+
command_runner.run command_name, command_arguments
|
49
|
+
|
50
|
+
rescue Commands::Publish::VersionUnsupportedError => e
|
51
|
+
logger.error "config.yml at version '#{e.message}' has an unsupported API."
|
52
|
+
1
|
53
|
+
rescue Configuration::CredentialKeyError => e
|
54
|
+
logger.error "#{e.message}, in credentials.yml"
|
55
|
+
1
|
56
|
+
rescue KeyError => e
|
57
|
+
logger.error "#{e.message} from your configuration."
|
58
|
+
1
|
59
|
+
rescue CliError::UnknownCommand => e
|
60
|
+
logger.log e.message
|
61
|
+
1
|
62
|
+
rescue RuntimeError => e
|
63
|
+
logger.error e.message
|
64
|
+
1
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require_relative 'section'
|
2
|
+
|
3
|
+
module Bookbinder
|
4
|
+
class CodeExample < Section
|
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 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
|
40
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require_relative 'cli_error'
|
2
|
+
|
3
|
+
module Bookbinder
|
4
|
+
class CommandRunner
|
5
|
+
def initialize(configuration_fetcher, usage_message, logger, commands)
|
6
|
+
@configuration_fetcher = configuration_fetcher
|
7
|
+
@usage_message = usage_message
|
8
|
+
@logger = logger
|
9
|
+
@commands = commands
|
10
|
+
end
|
11
|
+
|
12
|
+
def run(command_name, command_arguments)
|
13
|
+
command = commands.detect { |known_command| known_command.command_name == command_name }
|
14
|
+
begin
|
15
|
+
if command_name == '--help'
|
16
|
+
command.new(logger, usage_message).run command_arguments
|
17
|
+
else
|
18
|
+
command.new(logger, @configuration_fetcher).run command_arguments
|
19
|
+
end
|
20
|
+
rescue CliError::InvalidArguments
|
21
|
+
logger.log command.usage
|
22
|
+
1
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
attr_reader :logger, :usage_message, :commands
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require_relative 'cli_error'
|
2
|
+
|
3
|
+
module Bookbinder
|
4
|
+
class CommandValidator
|
5
|
+
def initialize(usage_messenger, commands, usage_text)
|
6
|
+
@usage_messenger = usage_messenger
|
7
|
+
@commands = commands
|
8
|
+
@usage_text = usage_text
|
9
|
+
end
|
10
|
+
|
11
|
+
def validate! command_name
|
12
|
+
known_command_names = commands.map(&:command_name)
|
13
|
+
command_type = "#{command_name}".match(/^--/) ? 'flag' : 'command'
|
14
|
+
if !known_command_names.include?(command_name)
|
15
|
+
raise CliError::UnknownCommand.new "Unrecognized #{command_type} '#{command_name}'\n" + usage_text
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
attr_reader :usage_messenger, :commands, :usage_text
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Bookbinder
|
2
|
+
module Commands
|
3
|
+
class BookbinderCommand
|
4
|
+
def initialize(logger, configuration_fetcher)
|
5
|
+
@logger = logger
|
6
|
+
@configuration_fetcher = configuration_fetcher
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def config
|
12
|
+
@config ||= configuration_fetcher.fetch_config
|
13
|
+
end
|
14
|
+
|
15
|
+
attr_reader :configuration_fetcher
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require_relative 'naming'
|
2
|
+
require_relative 'bookbinder_command'
|
3
|
+
require_relative '../archive'
|
4
|
+
|
5
|
+
module Bookbinder
|
6
|
+
module Commands
|
7
|
+
class BuildAndPushTarball < BookbinderCommand
|
8
|
+
extend Commands::Naming
|
9
|
+
|
10
|
+
class MissingBuildNumber < StandardError
|
11
|
+
def initialize
|
12
|
+
super 'You must set $BUILD_NUMBER to push an identifiable build.'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.usage
|
17
|
+
"build_and_push_tarball \t \t \t Create a tarball from the final_app directory and push to the S3 bucket specified in your credentials.yml"
|
18
|
+
end
|
19
|
+
|
20
|
+
def run(_)
|
21
|
+
raise MissingBuildNumber unless ENV['BUILD_NUMBER']
|
22
|
+
config = configuration_fetcher.fetch_config
|
23
|
+
aws_credentials = config.aws_credentials
|
24
|
+
repository = Archive.new(logger: @logger, key: aws_credentials.access_key, secret: aws_credentials.secret_key)
|
25
|
+
repository.create_and_upload_tarball(build_number: ENV['BUILD_NUMBER'], bucket: aws_credentials.green_builds_bucket,
|
26
|
+
namespace: GitHubRepository.new(logger: @logger, full_name: config.book_repo).short_name)
|
27
|
+
0
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
require_relative '../pdf_generator'
|
2
|
+
require_relative '../server_director'
|
3
|
+
require_relative 'bookbinder_command'
|
4
|
+
require_relative 'naming'
|
5
|
+
|
6
|
+
module Bookbinder
|
7
|
+
module Commands
|
8
|
+
class GeneratePDF < BookbinderCommand
|
9
|
+
extend Commands::Naming
|
10
|
+
|
11
|
+
class AppNotPublished < StandardError
|
12
|
+
def initialize(msg='You must publish locally before you generate a PDF.')
|
13
|
+
super(msg)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class PDFConfigMissing < StandardError
|
18
|
+
def initialize(file)
|
19
|
+
super("PDF config file '#{file}' does not exist.")
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class PDFOptionMissing < StandardError
|
24
|
+
def initialize(msg='No PDF options provided in config.yml')
|
25
|
+
super(msg)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class IncompletePDFConfig < StandardError
|
30
|
+
def initialize(file:nil, key:nil)
|
31
|
+
super("#{file} is missing required key '#{key}'")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.usage
|
36
|
+
"generate_pdf [<file_name>.yml] \t \t Generate a PDF from the files specified in <file_name.yml>"
|
37
|
+
end
|
38
|
+
|
39
|
+
def run(params)
|
40
|
+
raise AppNotPublished unless Dir.exists?('final_app')
|
41
|
+
|
42
|
+
@pdf_config_file = find_pdf_config_file(params)
|
43
|
+
|
44
|
+
ServerDirector.new(@logger, directory: 'final_app').use_server { |port| capture_pages_into_pdf_at(port) }
|
45
|
+
0
|
46
|
+
end
|
47
|
+
|
48
|
+
def find_pdf_config_file(params)
|
49
|
+
if params.first
|
50
|
+
pdf_config_file = File.expand_path(params.first)
|
51
|
+
raise PDFConfigMissing, File.basename(pdf_config_file) unless File.exists?(pdf_config_file)
|
52
|
+
pdf_config_file
|
53
|
+
else
|
54
|
+
@logger.warn "Declaring PDF options in config.yml is deprecated.\nDeclare them in a PDF config file, instead, and target that file when you re-invoke bookbinder.\ne.g. bookbinder generate_pdf theGoodParts.yml"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def capture_pages_into_pdf_at(port)
|
61
|
+
local_host = "localhost:#{port}"
|
62
|
+
header = pdf_options.fetch('header') { raise IncompletePDFConfig, {file: @pdf_config_file, key: :header} }
|
63
|
+
|
64
|
+
output_filename = get_output_file_name
|
65
|
+
urls_to_capture = get_urls_to_capture(local_host)
|
66
|
+
|
67
|
+
PdfGenerator.new(@logger).generate(urls_to_capture, output_filename, "http://#{local_host}/#{header}", pdf_options['copyright_notice'])
|
68
|
+
end
|
69
|
+
|
70
|
+
def pdf_options
|
71
|
+
@pdf_options ||= @pdf_config_file ? YAML.load(File.read(@pdf_config_file)) : main_config_pdf_options
|
72
|
+
end
|
73
|
+
|
74
|
+
def main_config_pdf_options
|
75
|
+
raise PDFOptionMissing unless config.has_option?('pdf')
|
76
|
+
{
|
77
|
+
'filename' => config.pdf.fetch('filename'),
|
78
|
+
'header' => config.pdf.fetch('header')
|
79
|
+
}
|
80
|
+
end
|
81
|
+
|
82
|
+
def get_output_file_name
|
83
|
+
if @pdf_config_file
|
84
|
+
File.basename(@pdf_config_file).gsub(/yml/, 'pdf')
|
85
|
+
else
|
86
|
+
pdf_options.fetch('filename')
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def get_urls_to_capture(local_host)
|
91
|
+
if @pdf_config_file
|
92
|
+
pages = pdf_options.fetch('pages')
|
93
|
+
return expand_urls(pages, local_host) if any_include_wildcard?(pages)
|
94
|
+
pages.map { |l| "http://#{local_host}/#{l}" }
|
95
|
+
else
|
96
|
+
sitemap_links(local_host)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def any_include_wildcard?(pages)
|
101
|
+
pages.each do |page|
|
102
|
+
return true if page.include?('*')
|
103
|
+
end
|
104
|
+
false
|
105
|
+
end
|
106
|
+
|
107
|
+
def expand_urls(pages, local_host)
|
108
|
+
final_pages = []
|
109
|
+
pages.each do |page|
|
110
|
+
if page.include?('*')
|
111
|
+
matching_pages = find_matching_files_in_directory(page, local_host)
|
112
|
+
final_pages += matching_pages
|
113
|
+
else
|
114
|
+
final_pages << "http://#{local_host}/#{page}"
|
115
|
+
end
|
116
|
+
end
|
117
|
+
final_pages
|
118
|
+
end
|
119
|
+
|
120
|
+
def find_matching_files_in_directory(wildcard_page, local_host)
|
121
|
+
wildcard_path = wildcard_page.gsub('*','')
|
122
|
+
possible_links = sitemap_links(local_host)
|
123
|
+
possible_links.select { |link| URI(link).path.match(/^\/#{Regexp.escape(wildcard_path)}/)}
|
124
|
+
end
|
125
|
+
|
126
|
+
def sitemap_links(local_host)
|
127
|
+
raw_links = Nokogiri::XML(sitemap).css('loc').map &:inner_html
|
128
|
+
deployed_host = URI(raw_links[0]).host
|
129
|
+
|
130
|
+
deployed_host ?
|
131
|
+
raw_links.map { |l| l.gsub(/#{Regexp.escape(deployed_host)}/, local_host) } :
|
132
|
+
raw_links.map { |l| "http://#{local_host}/#{l}" }
|
133
|
+
end
|
134
|
+
|
135
|
+
def sitemap
|
136
|
+
File.read File.join('public', 'sitemap.xml')
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Bookbinder
|
2
|
+
module Commands
|
3
|
+
class Help
|
4
|
+
def initialize(logger, usage_message)
|
5
|
+
@logger = logger
|
6
|
+
@usage_message = usage_message
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.to_s
|
10
|
+
'help'
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.command_name
|
14
|
+
'--help'
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.usage
|
18
|
+
"--help \t \t \t \t \t Print this message"
|
19
|
+
end
|
20
|
+
|
21
|
+
def run(*)
|
22
|
+
logger.log(usage_message)
|
23
|
+
0
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
attr_reader :logger, :usage_message
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
require_relative '../book'
|
2
|
+
require_relative '../cli_error'
|
3
|
+
require_relative '../configuration'
|
4
|
+
require_relative '../directory_helpers'
|
5
|
+
require_relative '../middleman_runner'
|
6
|
+
require_relative '../publisher'
|
7
|
+
require_relative '../spider'
|
8
|
+
require_relative 'bookbinder_command'
|
9
|
+
require_relative 'naming'
|
10
|
+
|
11
|
+
module Bookbinder
|
12
|
+
module Commands
|
13
|
+
class Publish < BookbinderCommand
|
14
|
+
VersionUnsupportedError = Class.new(StandardError)
|
15
|
+
|
16
|
+
include Bookbinder::DirectoryHelperMethods
|
17
|
+
extend Commands::Naming
|
18
|
+
|
19
|
+
def self.usage
|
20
|
+
"publish <local|github> [--verbose] \t Bind the sections specified in config.yml from <local> or <github> into the final_app directory"
|
21
|
+
end
|
22
|
+
|
23
|
+
def run(cli_arguments, git_accessor=Git)
|
24
|
+
raise CliError::InvalidArguments unless arguments_are_valid?(cli_arguments)
|
25
|
+
@git_accessor = git_accessor
|
26
|
+
|
27
|
+
final_app_dir = File.absolute_path('final_app')
|
28
|
+
bind_book(cli_arguments, final_app_dir)
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def bind_book(cli_arguments, final_app_dir)
|
34
|
+
generate_site_etc(cli_arguments, final_app_dir)
|
35
|
+
end
|
36
|
+
|
37
|
+
def generate_site_etc(cli_args, final_app_dir, target_tag=nil)
|
38
|
+
# TODO: general solution to turn all string keys to symbols
|
39
|
+
verbosity = cli_args.include?('--verbose')
|
40
|
+
location = cli_args[0]
|
41
|
+
|
42
|
+
cli_options = { verbose: verbosity, target_tag: target_tag }
|
43
|
+
output_paths = output_directory_paths(location, final_app_dir)
|
44
|
+
publish_config = publish_config(location)
|
45
|
+
spider = Spider.new(@logger, app_dir: final_app_dir)
|
46
|
+
static_site_generator = MiddlemanRunner.new(@logger)
|
47
|
+
|
48
|
+
success = Publisher.new(@logger, spider, static_site_generator).publish(cli_options, output_paths, publish_config, @git_accessor)
|
49
|
+
success ? 0 : 1
|
50
|
+
end
|
51
|
+
|
52
|
+
def output_directory_paths(location, final_app_dir)
|
53
|
+
local_repo_dir = (location == 'local') ? File.absolute_path('..') : nil
|
54
|
+
|
55
|
+
{
|
56
|
+
final_app_dir: final_app_dir,
|
57
|
+
local_repo_dir: local_repo_dir,
|
58
|
+
output_dir: File.absolute_path(output_dir_name),
|
59
|
+
master_middleman_dir: layout_repo_path(local_repo_dir)
|
60
|
+
}
|
61
|
+
end
|
62
|
+
|
63
|
+
def publish_config(location)
|
64
|
+
arguments = {
|
65
|
+
sections: config.sections,
|
66
|
+
book_repo: config.book_repo,
|
67
|
+
host_for_sitemap: config.public_host,
|
68
|
+
archive_menu: config.archive_menu
|
69
|
+
}
|
70
|
+
|
71
|
+
optional_arguments = {}
|
72
|
+
optional_arguments.merge!(template_variables: config.template_variables) if config.respond_to?(:template_variables)
|
73
|
+
if publishing_to_github? location
|
74
|
+
config.versions.each { |version| arguments[:sections].concat sections_from version, @git_accessor }
|
75
|
+
optional_arguments.merge!(versions: config.versions)
|
76
|
+
end
|
77
|
+
|
78
|
+
arguments.merge! optional_arguments
|
79
|
+
end
|
80
|
+
|
81
|
+
def sections_from(version, git_accessor)
|
82
|
+
config_file = File.join book_checkout(version, git_accessor), 'config.yml'
|
83
|
+
attrs = YAML.load(File.read(config_file))['sections']
|
84
|
+
raise VersionUnsupportedError.new(version) if attrs.nil?
|
85
|
+
|
86
|
+
attrs.map do |section_hash|
|
87
|
+
section_hash['repository']['ref'] = version
|
88
|
+
section_hash['directory'] = File.join(version, section_hash['directory'])
|
89
|
+
section_hash
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def book_checkout(ref, git_accessor=Git)
|
94
|
+
temp_workspace = Dir.mktmpdir('book_checkout')
|
95
|
+
book = Book.from_remote(logger: @logger,
|
96
|
+
full_name: config.book_repo,
|
97
|
+
destination_dir: temp_workspace,
|
98
|
+
ref: ref,
|
99
|
+
git_accessor: git_accessor,
|
100
|
+
)
|
101
|
+
|
102
|
+
File.join temp_workspace, book.directory
|
103
|
+
end
|
104
|
+
|
105
|
+
def layout_repo_path(local_repo_dir)
|
106
|
+
if config.has_option?('layout_repo')
|
107
|
+
if local_repo_dir
|
108
|
+
File.join(local_repo_dir, config.layout_repo.split('/').last)
|
109
|
+
else
|
110
|
+
section = {'repository' => {'name' => config.layout_repo}}
|
111
|
+
destination_dir = Dir.mktmpdir
|
112
|
+
repository = GitHubRepository.build_from_remote(@logger, section, destination_dir, 'master', @git_accessor)
|
113
|
+
if repository
|
114
|
+
File.join(destination_dir, repository.directory)
|
115
|
+
else
|
116
|
+
raise 'failed to fetch repository'
|
117
|
+
end
|
118
|
+
end
|
119
|
+
else
|
120
|
+
File.absolute_path('master_middleman')
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def arguments_are_valid?(arguments)
|
125
|
+
return false unless arguments.any?
|
126
|
+
verbose = arguments[1] && arguments[1..-1].include?('--verbose')
|
127
|
+
tag_provided = arguments[1] && (arguments[1..-1] - ['--verbose']).any?
|
128
|
+
nothing_special = arguments[1..-1].empty?
|
129
|
+
|
130
|
+
%w(local github).include?(arguments[0]) && (tag_provided || verbose || nothing_special)
|
131
|
+
end
|
132
|
+
|
133
|
+
def publishing_to_github?(publish_location)
|
134
|
+
config.has_option?('versions') && publish_location != 'local'
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|