bookbindery 2.1.5 → 3.0.1

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 (54) hide show
  1. checksums.yaml +4 -4
  2. data/lib/bookbinder.rb +0 -4
  3. data/lib/bookbinder/cf_command_runner.rb +11 -5
  4. data/lib/bookbinder/cli.rb +8 -12
  5. data/lib/bookbinder/colorizer.rb +1 -2
  6. data/lib/bookbinder/command_runner.rb +0 -2
  7. data/lib/bookbinder/commands/bind.rb +96 -99
  8. data/lib/bookbinder/commands/bind/directory_preparer.rb +60 -0
  9. data/lib/bookbinder/commands/build_and_push_tarball.rb +5 -4
  10. data/lib/bookbinder/commands/push_from_local.rb +56 -2
  11. data/lib/bookbinder/commands/push_to_prod.rb +6 -2
  12. data/lib/bookbinder/commands/tag.rb +15 -3
  13. data/lib/bookbinder/config/aws_credentials.rb +21 -0
  14. data/lib/bookbinder/config/cf_credentials.rb +87 -0
  15. data/lib/bookbinder/configuration.rb +4 -140
  16. data/lib/bookbinder/configuration_fetcher.rb +28 -4
  17. data/lib/bookbinder/configuration_validator.rb +11 -164
  18. data/lib/bookbinder/distributor.rb +16 -12
  19. data/lib/bookbinder/{dita_to_html_converter.rb → dita_command_creator.rb} +5 -17
  20. data/lib/bookbinder/dita_preprocessor.rb +14 -12
  21. data/lib/bookbinder/git_accessor.rb +21 -2
  22. data/lib/bookbinder/git_hub_repository.rb +0 -43
  23. data/lib/bookbinder/ingest/cloner_factory.rb +5 -4
  24. data/lib/bookbinder/ingest/destination_directory.rb +15 -0
  25. data/lib/bookbinder/ingest/git_hub_repository_cloner.rb +22 -13
  26. data/lib/bookbinder/ingest/local_filesystem_cloner.rb +38 -14
  27. data/lib/bookbinder/ingest/working_copy.rb +31 -0
  28. data/lib/bookbinder/local_dita_section_gatherer.rb +4 -3
  29. data/lib/bookbinder/local_file_system_accessor.rb +1 -4
  30. data/lib/bookbinder/middleman_runner.rb +22 -26
  31. data/lib/bookbinder/remote_yaml_credential_provider.rb +10 -10
  32. data/lib/bookbinder/repositories/command_repository.rb +18 -12
  33. data/lib/bookbinder/repositories/section_repository.rb +8 -8
  34. data/lib/bookbinder/server_director.rb +16 -33
  35. data/lib/bookbinder/sheller.rb +33 -7
  36. data/lib/bookbinder/spider.rb +3 -0
  37. data/lib/bookbinder/streams/switchable_stdout_and_red_stderr.rb +38 -0
  38. data/lib/bookbinder/terminal.rb +11 -1
  39. data/lib/bookbinder/validation_checkers/archive_menu_checker.rb +31 -0
  40. data/lib/bookbinder/validation_checkers/config_version_checker.rb +91 -0
  41. data/lib/bookbinder/validation_checkers/dita_section_checker.rb +20 -0
  42. data/lib/bookbinder/validation_checkers/duplicate_section_name_checker.rb +25 -0
  43. data/lib/bookbinder/validation_checkers/repository_name_presence_checker.rb +33 -0
  44. data/lib/bookbinder/validation_checkers/required_keys_checker.rb +43 -0
  45. data/lib/bookbinder/values/dita_section.rb +5 -1
  46. data/lib/bookbinder/values/output_locations.rb +25 -2
  47. data/lib/bookbinder/values/user_message.rb +2 -2
  48. data/master_middleman/bookbinder_helpers.rb +5 -15
  49. data/template_app/Gemfile.lock +1 -1
  50. metadata +60 -80
  51. data/lib/bookbinder/commands/generate_pdf.rb +0 -141
  52. data/lib/bookbinder/pdf_generator.rb +0 -73
  53. data/lib/bookbinder/publisher.rb +0 -58
  54. data/lib/bookbinder/user_message_presenter.rb +0 -21
@@ -1,141 +0,0 @@
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
- include 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 usage
36
- ["generate_pdf [<file_name>.yml]",
37
- "Generate a PDF from the files specified in <file_name.yml>"]
38
- end
39
-
40
- def run(params)
41
- raise AppNotPublished unless Dir.exists?('final_app')
42
-
43
- @pdf_config_file = find_pdf_config_file(params)
44
-
45
- ServerDirector.new(@logger, directory: 'final_app').use_server { |port| capture_pages_into_pdf_at(port) }
46
- 0
47
- end
48
-
49
- def find_pdf_config_file(params)
50
- if params.first
51
- pdf_config_file = File.expand_path(params.first)
52
- raise PDFConfigMissing, File.basename(pdf_config_file) unless File.exists?(pdf_config_file)
53
- pdf_config_file
54
- else
55
- @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"
56
- end
57
- end
58
-
59
- private
60
-
61
- def capture_pages_into_pdf_at(port)
62
- local_host = "localhost:#{port}"
63
- header = pdf_options.fetch('header') { raise IncompletePDFConfig, {file: @pdf_config_file, key: :header} }
64
-
65
- output_filename = get_output_file_name
66
- urls_to_capture = get_urls_to_capture(local_host)
67
-
68
- PdfGenerator.new(@logger).generate(urls_to_capture, output_filename, "http://#{local_host}/#{header}", pdf_options['copyright_notice'])
69
- end
70
-
71
- def pdf_options
72
- @pdf_options ||= @pdf_config_file ? YAML.load(File.read(@pdf_config_file)) : main_config_pdf_options
73
- end
74
-
75
- def main_config_pdf_options
76
- raise PDFOptionMissing unless config.has_option?('pdf')
77
- {
78
- 'filename' => config.pdf.fetch('filename'),
79
- 'header' => config.pdf.fetch('header')
80
- }
81
- end
82
-
83
- def get_output_file_name
84
- if @pdf_config_file
85
- File.basename(@pdf_config_file).gsub(/yml/, 'pdf')
86
- else
87
- pdf_options.fetch('filename')
88
- end
89
- end
90
-
91
- def get_urls_to_capture(local_host)
92
- if @pdf_config_file
93
- pages = pdf_options.fetch('pages')
94
- return expand_urls(pages, local_host) if any_include_wildcard?(pages)
95
- pages.map { |l| "http://#{local_host}/#{l}" }
96
- else
97
- sitemap_links(local_host)
98
- end
99
- end
100
-
101
- def any_include_wildcard?(pages)
102
- pages.each do |page|
103
- return true if page.include?('*')
104
- end
105
- false
106
- end
107
-
108
- def expand_urls(pages, local_host)
109
- final_pages = []
110
- pages.each do |page|
111
- if page.include?('*')
112
- matching_pages = find_matching_files_in_directory(page, local_host)
113
- final_pages += matching_pages
114
- else
115
- final_pages << "http://#{local_host}/#{page}"
116
- end
117
- end
118
- final_pages
119
- end
120
-
121
- def find_matching_files_in_directory(wildcard_page, local_host)
122
- wildcard_path = wildcard_page.gsub('*','')
123
- possible_links = sitemap_links(local_host)
124
- possible_links.select { |link| URI(link).path.match(/^\/#{Regexp.escape(wildcard_path)}/)}
125
- end
126
-
127
- def sitemap_links(local_host)
128
- raw_links = Nokogiri::XML(sitemap).css('loc').map &:inner_html
129
- deployed_host = URI(raw_links[0]).host
130
-
131
- deployed_host ?
132
- raw_links.map { |l| l.gsub(/#{Regexp.escape(deployed_host)}/, local_host) } :
133
- raw_links.map { |l| "http://#{local_host}/#{l}" }
134
- end
135
-
136
- def sitemap
137
- File.read File.join('public', 'sitemap.xml')
138
- end
139
- end
140
- end
141
- end
@@ -1,73 +0,0 @@
1
- require 'net/http'
2
-
3
- module Bookbinder
4
- class PdfGenerator
5
- class MissingSource < StandardError
6
- def initialize(required_file)
7
- super "Could not find file #{required_file}"
8
- end
9
- end
10
-
11
- def initialize(logger)
12
- @logger = logger
13
- end
14
-
15
- def generate(sources, target, header, left_footer=nil)
16
- sources.each { |s| check_destination_exists s }
17
- check_destination_exists header
18
-
19
- left_footer ||= " © Copyright 2013-#{Time.now.year}, Pivotal"
20
-
21
- toc_xslt_path = File.expand_path('../../../toc.xslt', __FILE__)
22
-
23
- command = <<-CMD
24
- wkhtmltopdf \
25
- --enable-external-links \
26
- --disable-javascript \
27
- --load-error-handling ignore \
28
- --margin-top 26mm \
29
- --margin-bottom 13mm \
30
- --header-spacing 10 \
31
- --header-html #{header} \
32
- --footer-spacing 5 \
33
- --footer-font-size 10 \
34
- --footer-left '#{left_footer}' \
35
- --footer-center '[page] of [toPage]' \
36
- --print-media-type \
37
- toc --xsl-style-sheet #{toc_xslt_path} \
38
- #{sources.join(' ')} \
39
- #{target}
40
- CMD
41
-
42
- `#{command}`
43
-
44
- raise "'wkhtmltopdf' appears to have failed" unless $?.success? && File.exist?(target)
45
-
46
- @logger.log "\nYour PDF file was generated to #{target.green}"
47
-
48
- end
49
-
50
- def check_file_exists(required_file)
51
- unless File.exist? required_file
52
- @logger.error "\nPDF Generation failed (could not find file)!"
53
- raise MissingSource, required_file
54
- end
55
- end
56
-
57
- def check_destination_exists(url)
58
- uri = URI(url)
59
- if uri.class == URI::Generic
60
- check_file_exists url
61
- elsif uri.class == URI::HTTP
62
- check_url_exists url
63
- else
64
- @logger.error "Malformed destination provided for PDF generation source: #{url}"
65
- end
66
- end
67
-
68
- def check_url_exists(url)
69
- res = Net::HTTP.get_response(URI(url))
70
- raise MissingSource, url if res.code == '404'
71
- end
72
- end
73
- end
@@ -1,58 +0,0 @@
1
- require 'middleman-syntax'
2
- require_relative 'deprecated_logger'
3
- require_relative 'directory_helpers'
4
- require_relative 'repositories/section_repository'
5
-
6
- module Bookbinder
7
- class Publisher
8
- include DirectoryHelperMethods
9
-
10
- def initialize(logger, sitemap_writer, static_site_generator, file_system_accessor)
11
- @logger = logger
12
- @sitemap_writer = sitemap_writer
13
- @static_site_generator = static_site_generator
14
- @file_system_accessor = file_system_accessor
15
- end
16
-
17
- def publish(subnavs, cli_options, output_paths, publish_config)
18
- intermediate_directory = output_paths.output_dir
19
- final_app_dir = output_paths.final_app_dir
20
- master_dir = File.join intermediate_directory, 'master_middleman'
21
- workspace_dir = File.join master_dir, 'source'
22
- build_directory = File.join master_dir, 'build/.'
23
- public_directory = File.join final_app_dir, 'public'
24
-
25
- FileUtils.cp 'redirects.rb', final_app_dir if File.exists?('redirects.rb')
26
-
27
- host_for_sitemap = publish_config.fetch(:host_for_sitemap)
28
-
29
- generate_site(cli_options, output_paths, publish_config, master_dir, workspace_dir, subnavs, build_directory, public_directory)
30
- result = generate_sitemap(host_for_sitemap)
31
-
32
- @logger.log "Bookbinder bound your book into #{final_app_dir.to_s.green}"
33
-
34
- !result.has_broken_links?
35
- end
36
-
37
- private
38
-
39
- attr_reader :section_repository, :logger, :file_system_accessor, :sitemap_writer
40
-
41
- def generate_sitemap(host_for_sitemap)
42
- raise "Your public host must be a single String." unless host_for_sitemap.is_a?(String)
43
- sitemap_writer.write(host_for_sitemap)
44
- end
45
-
46
- def generate_site(cli_options, output_paths, publish_config, middleman_dir, workspace_dir, subnavs, build_dir, public_dir)
47
- @static_site_generator.run(middleman_dir,
48
- workspace_dir,
49
- publish_config.fetch(:template_variables, {}),
50
- output_paths.local_repo_dir,
51
- cli_options[:verbose],
52
- subnavs,
53
- publish_config[:host_for_sitemap],
54
- publish_config[:archive_menu])
55
- file_system_accessor.copy build_dir, public_dir
56
- end
57
- end
58
- end
@@ -1,21 +0,0 @@
1
- require_relative 'colorizer'
2
-
3
- module Bookbinder
4
- class UserMessagePresenter
5
- def initialize(colorizer)
6
- @colorizer = colorizer
7
- end
8
-
9
- def get_error(user_message)
10
- colorizer.colorize(user_message.message, Colorizer::Colors.red)
11
- end
12
-
13
- def get_warning(user_message)
14
- colorizer.colorize(user_message.message, Colorizer::Colors.yellow)
15
- end
16
-
17
- private
18
-
19
- attr_reader :colorizer
20
- end
21
- end