bookbindery 4.2.0 → 5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 23596356b5d99dfb4817501ce2347d9169249aac
4
- data.tar.gz: 8a6c4f16b9d084462385d5e91c8639a0b64994f5
3
+ metadata.gz: 621e97dd76f614e82790228cfe022f204df2f3f3
4
+ data.tar.gz: 1555c3fe96a2231e0b850abfe6b7d98a7ca4b28e
5
5
  SHA512:
6
- metadata.gz: 11458b7bd0d835303c8b32d61a692dbb72b8a39b724b05e32b75d07f77394f45520a47aa3f0aaa7c7797638388e527c2a78e358a0ae75b678ae2bdf217fcc1f4
7
- data.tar.gz: f9f09e56be8ebef88f596f862c3652c803f036f83b1c50aada789ec099ffe8381aaffbe855836519116b2a5576b06ccbc2690ad4eeb7b2429e593b425b9446c4
6
+ metadata.gz: 1b22cdca4d39c048af425c48d3de76bfab47c923913d00b40f9212a59d37d60ad01a36c15932d13e9c4e7555ab65e91b5a0e0cad5b252513c3b7fc60c173f502
7
+ data.tar.gz: 49b94f81e1f08e00047e5ce6be496565ca39a34f6816cf11681795f055a25590418e80d313d493a888252aa6e82ef977e8786992b25a2cd5366fc68b9127b61d
@@ -38,9 +38,6 @@ module Bookbinder
38
38
  begin
39
39
  command_runner.run command_name, command_arguments
40
40
 
41
- rescue Config::RemoteBindConfiguration::VersionUnsupportedError => e
42
- colorized_streams[:err].puts "config.yml at version '#{e.message}' has an unsupported API."
43
- 1
44
41
  rescue Config::CfCredentials::CredentialKeyError => e
45
42
  colorized_streams[:err].puts "#{e.message}, in credentials.yml"
46
43
  1
@@ -6,16 +6,14 @@ module Bookbinder
6
6
  end
7
7
  end
8
8
 
9
- def initialize(out: out)
10
- @out = out
9
+ def initialize(streams, fs)
10
+ @out = streams[:out]
11
+ @fs = fs
11
12
  end
12
13
 
13
14
  def get_snippet_and_language_at(marker, working_copy)
14
- snippet = Snippet.new(marker, working_copy)
15
- if snippet.available? && !snippet.valid?
16
- raise InvalidSnippet.new(working_copy.full_name, marker)
17
- elsif snippet.available?
18
- [snippet.content, snippet.language]
15
+ if working_copy.available?
16
+ process_snippet(marker, working_copy)
19
17
  else
20
18
  out << " skipping (not found) #{working_copy.full_name}"
21
19
  ''
@@ -23,54 +21,74 @@ module Bookbinder
23
21
  end
24
22
 
25
23
  class Snippet
26
- def initialize(marker, working_copy)
27
- @marker = marker
28
- @working_copy = working_copy
29
- end
30
-
31
- def available?
32
- working_copy.available?
24
+ def initialize(text, language_pattern)
25
+ @text = text
26
+ @language_pattern = language_pattern
33
27
  end
34
28
 
35
29
  def valid?
36
- ! get_snippet(marker, working_copy).empty?
30
+ ! text.empty?
37
31
  end
38
32
 
39
33
  def language
40
- lines = get_snippet(marker, working_copy).split("\n")
41
- language_match = lines[0].match(/code_snippet #{Regexp.escape(marker)} start (\w+)/)
34
+ language_match = lines[0].match(language_pattern)
42
35
  Array(language_match)[1]
43
36
  end
44
37
 
45
38
  def content
46
- lines = get_snippet(marker, working_copy).split("\n")
47
- lines[1..-2].join("\n")
39
+ lines[1..-2].join("\n").strip
48
40
  end
49
41
 
50
42
  private
51
43
 
52
- attr_reader :marker, :working_copy
44
+ attr_reader :text, :language_pattern
53
45
 
54
- def get_snippet(marker, working_copy)
55
- @snippet ||=
56
- begin
57
- snippet = ''
58
- FileUtils.cd(working_copy.path) {
59
- locale = 'LC_CTYPE=C LANG=C' # Quiets 'sed: RE error: illegal byte sequence'
60
- result = `#{locale} find . -exec sed -ne '/code_snippet #{marker} start/,/code_snippet #{marker} end/ p' {} \\; 2> /dev/null`
61
- snippet = if result.lines.last && result.lines.last.match(/code_snippet #{marker} end/)
62
- result
63
- else
64
- ""
65
- end
66
- }
67
- snippet
68
- end
46
+ def lines
47
+ text.split("\n")
69
48
  end
70
49
  end
71
50
 
72
51
  private
73
52
 
74
- attr_reader :out
53
+ attr_reader :out, :fs
54
+
55
+ def process_snippet(marker, working_copy)
56
+ snippet = Snippet.new(
57
+ find_text(working_copy.path, pattern_for(marker)),
58
+ language_pattern_for(marker)
59
+ )
60
+ if snippet.valid?
61
+ [snippet.content, snippet.language]
62
+ else
63
+ raise InvalidSnippet.new(working_copy.full_name, marker)
64
+ end
65
+ end
66
+
67
+ def find_text(start_path, pattern)
68
+ fs.find_files_recursively(start_path).
69
+ lazy.
70
+ map {|path| fs.read(path)}.
71
+ map {|contents|
72
+ begin
73
+ contents.scan(pattern)
74
+ rescue ArgumentError => e
75
+ cannot_scan
76
+ end
77
+ }.
78
+ map(&:first).
79
+ detect ->{""} {|text| text}
80
+ end
81
+
82
+ def pattern_for(marker)
83
+ /code_snippet #{Regexp.escape(marker)} start.*code_snippet #{Regexp.escape(marker)} end/m
84
+ end
85
+
86
+ def language_pattern_for(marker)
87
+ /code_snippet #{Regexp.escape(marker)} start (\w+)/
88
+ end
89
+
90
+ def cannot_scan
91
+ []
92
+ end
75
93
  end
76
94
  end
@@ -1,6 +1,5 @@
1
1
  require 'middleman-syntax'
2
2
 
3
- require_relative '../config/archive_menu_configuration'
4
3
  require_relative '../errors/cli_error'
5
4
  require_relative 'bind/bind_options'
6
5
  require_relative 'naming'
@@ -12,25 +11,25 @@ module Bookbinder
12
11
 
13
12
  def initialize(base_streams,
14
13
  output_locations,
15
- config_factory,
16
- archive_menu_config,
14
+ config_fetcher,
15
+ config_decorator,
17
16
  file_system_accessor,
18
17
  static_site_generator,
19
18
  sitemap_writer,
20
19
  preprocessor,
21
20
  cloner_factory,
22
- section_repository_factory,
21
+ section_repository,
23
22
  directory_preparer)
24
23
  @base_streams = base_streams
25
24
  @output_locations = output_locations
26
- @config_factory = config_factory
27
- @archive_menu_config = archive_menu_config
25
+ @config_fetcher = config_fetcher
26
+ @config_decorator = config_decorator
28
27
  @file_system_accessor = file_system_accessor
29
28
  @static_site_generator = static_site_generator
30
29
  @sitemap_writer = sitemap_writer
31
30
  @preprocessor = preprocessor
32
31
  @cloner_factory = cloner_factory
33
- @section_repository_factory = section_repository_factory
32
+ @section_repository = section_repository
34
33
  @directory_preparer = directory_preparer
35
34
  end
36
35
 
@@ -48,101 +47,75 @@ module Bookbinder
48
47
  end
49
48
 
50
49
  def run(cli_arguments)
51
- bind_options = BindComponents::BindOptions.new(cli_arguments, base_streams)
52
- bind_options.validate!
53
-
54
- bind_source, *options = cli_arguments
55
- bind_config = config_factory.produce(bind_source)
56
-
57
- local_repo_dir = generate_local_repo_dir(context_dir, bind_source)
58
- cloner = cloner_factory.produce(local_repo_dir)
59
- section_repository = section_repository_factory.produce(cloner)
50
+ bind_options = BindComponents::BindOptions.new(cli_arguments, base_streams).tap(&:validate!)
51
+ bind_config = config_fetcher.fetch_config
52
+ cloner = cloner_factory.produce(bind_options.local_repo_dir)
60
53
 
61
54
  directory_preparer.prepare_directories(
62
55
  bind_config,
63
56
  File.expand_path('../../../../', __FILE__),
64
57
  output_locations,
65
- layout_repo_path(bind_config, cloner)
58
+ cloner
66
59
  )
67
-
68
60
  sections = section_repository.fetch(
69
61
  configured_sections: bind_config.sections,
70
62
  destination_dir: output_locations.cloned_preprocessing_dir,
71
- ref_override: bind_options.ref_override
63
+ ref_override: bind_options.ref_override,
64
+ cloner: cloner,
65
+ streams: base_streams
72
66
  )
73
-
74
67
  preprocessor.preprocess(
75
68
  sections,
76
69
  output_locations,
77
- options: options,
70
+ options: bind_options.options,
78
71
  output_streams: bind_options.streams
79
72
  )
80
-
81
- success = publish(
82
- sections.map(&:subnav).reduce({}, :merge),
83
- {verbose: options.include?('--verbose')},
84
- bind_options.streams,
85
- output_locations,
86
- archive_menu_config.generate(bind_config, sections),
87
- cloner
73
+ if file_system_accessor.file_exist?('redirects.rb')
74
+ file_system_accessor.copy('redirects.rb', output_locations.final_app_dir)
75
+ end
76
+ generation_result = static_site_generator.run(
77
+ ["build", bind_options.verbosity].compact.join(" "),
78
+ streams: bind_options.streams,
79
+ output_locations: output_locations,
80
+ config: config_decorator.generate(bind_config, sections),
81
+ local_repo_dir: bind_options.local_repo_dir,
82
+ subnavs: subnavs(sections)
88
83
  )
84
+ if generation_result.success?
85
+ file_system_accessor.copy(output_locations.build_dir, output_locations.public_dir)
86
+ result = sitemap_writer.write(
87
+ bind_config.public_host,
88
+ bind_options.streams,
89
+ bind_config.broken_link_exclusions
90
+ )
89
91
 
90
- success ? 0 : 1
92
+ bind_options.streams[:success].puts "Bookbinder bound your book into #{output_locations.final_app_dir}"
93
+
94
+ result.has_broken_links? ? 1 : 0
95
+ else
96
+ 1
97
+ end
91
98
  end
92
99
 
93
100
  private
94
101
 
95
102
  attr_reader(
96
- :archive_menu_config,
97
103
  :base_streams,
98
104
  :cloner_factory,
99
- :config_factory,
100
- :context_dir,
105
+ :config_decorator,
106
+ :config_fetcher,
101
107
  :directory_preparer,
102
108
  :file_system_accessor,
103
109
  :final_app_directory,
104
110
  :output_locations,
105
111
  :preprocessor,
106
- :section_repository_factory,
112
+ :section_repository,
107
113
  :sitemap_writer,
108
114
  :static_site_generator,
109
115
  )
110
116
 
111
- def publish(subnavs, cli_options, streams, output_locations, publish_config, cloner)
112
- FileUtils.cp 'redirects.rb', output_locations.final_app_dir if File.exists?('redirects.rb')
113
-
114
- host_for_sitemap = publish_config.public_host
115
-
116
- static_site_generator.run(output_locations,
117
- publish_config,
118
- cloner,
119
- cli_options[:verbose],
120
- subnavs)
121
- file_system_accessor.copy output_locations.build_dir, output_locations.public_dir
122
-
123
- result = sitemap_writer.write(
124
- host_for_sitemap,
125
- streams,
126
- publish_config.broken_link_exclusions
127
- )
128
-
129
- streams[:success].puts "Bookbinder bound your book into #{output_locations.final_app_dir}"
130
-
131
- !result.has_broken_links?
132
- end
133
-
134
- def generate_local_repo_dir(context_dir, bind_source)
135
- File.expand_path('..', context_dir) if bind_source == 'local'
136
- end
137
-
138
- def layout_repo_path(config, cloner)
139
- if config.has_option?('layout_repo')
140
- working_copy = cloner.call(source_repo_name: config.layout_repo,
141
- destination_parent_dir: Dir.mktmpdir)
142
- working_copy.path
143
- else
144
- File.absolute_path('master_middleman')
145
- end
117
+ def subnavs(sections)
118
+ sections.map(&:subnav).reduce({}, :merge)
146
119
  end
147
120
  end
148
121
  end
@@ -1,5 +1,4 @@
1
1
  require_relative '../../sheller'
2
- require_relative '../../streams/colorized_stream'
3
2
 
4
3
  module Bookbinder
5
4
  module Commands
@@ -14,35 +13,46 @@ module Bookbinder
14
13
  raise CliError::InvalidArguments unless arguments_are_valid?
15
14
  end
16
15
 
16
+ def bind_source
17
+ opts.first
18
+ end
19
+
20
+ def local_repo_dir
21
+ File.expand_path('..') if bind_source == 'local'
22
+ end
23
+
24
+ def options
25
+ opts[1..-1]
26
+ end
27
+
17
28
  def ref_override
18
- 'master' if opts.include?('--ignore-section-refs')
29
+ 'master' if options.include?('--ignore-section-refs')
19
30
  end
20
31
 
21
32
  def streams
22
33
  base_streams.merge(
23
- out: opts.include?('--verbose') ? base_streams[:out] : Sheller::DevNull.new,
34
+ out: verbosity ? base_streams[:out] : Sheller::DevNull.new,
24
35
  )
25
36
  end
26
37
 
38
+ def verbosity
39
+ options.detect {|arg| arg == '--verbose'}
40
+ end
41
+
27
42
  private
28
43
 
29
44
  attr_accessor :base_streams, :opts
30
45
 
31
46
  def arguments_are_valid?
32
- valid_options = %w(--verbose --ignore-section-refs --dita-flags).to_set
33
- %w(local remote github).include?(bind_source) && flag_names.to_set.subset?(valid_options)
34
- end
35
-
36
- def flag_names
37
- options.map {|o| o.split('=').first}
47
+ %w(local remote github).include?(bind_source) && flag_names.subset?(valid_options)
38
48
  end
39
49
 
40
- def bind_source
41
- opts.first
50
+ def valid_options
51
+ %w(--verbose --ignore-section-refs --dita-flags).to_set
42
52
  end
43
53
 
44
- def options
45
- opts[1..-1]
54
+ def flag_names
55
+ options.map {|o| o.split('=').first}.to_set
46
56
  end
47
57
  end
48
58
  end
@@ -1,54 +1,38 @@
1
- require_relative '../../directory_helpers'
2
- require_relative '../../ingest/destination_directory'
3
-
4
1
  module Bookbinder
5
2
  module Commands
6
3
  module BindComponents
7
4
  class DirectoryPreparer
8
- include Bookbinder::DirectoryHelperMethods
9
-
10
- def initialize(logger, file_system_accessor, version_control_system)
11
- @logger = logger
12
- @file_system_accessor = file_system_accessor
13
- @version_control_system = version_control_system
5
+ def initialize(fs)
6
+ @fs = fs
14
7
  end
15
8
 
16
- def prepare_directories(config, gem_root, output_locations, layout_repo_dir)
17
- file_system_accessor.remove_directory(output_locations.output_dir)
18
- file_system_accessor.empty_directory(output_locations.final_app_dir)
9
+ def prepare_directories(config, gem_root, output_locations, cloner)
10
+ fs.remove_directory(output_locations.output_dir)
11
+ fs.empty_directory(output_locations.final_app_dir)
19
12
 
20
13
  copy_directory_from_gem(gem_root, 'template_app', output_locations.final_app_dir)
21
14
  copy_directory_from_gem(gem_root, 'master_middleman', output_locations.site_generator_home)
22
- file_system_accessor.copy_contents(layout_repo_dir, output_locations.site_generator_home)
23
15
 
24
- config.versions.each do |version|
25
- copy_index_file_from_version_to_master_middleman(version, output_locations.source_for_site_generator, config.book_repo_url)
26
- end
16
+ layout_repo_path = fetch_layout_repo(config, cloner)
17
+ fs.copy_contents(layout_repo_path, output_locations.site_generator_home)
27
18
  end
28
19
 
29
20
  private
30
21
 
31
- attr_reader :logger, :file_system_accessor, :version_control_system
32
-
33
- def copy_index_file_from_version_to_master_middleman(version, dest_dir, url)
34
- clone_dir_name = Ingest::DestinationDirectory.new(url)
35
- Dir.mktmpdir(version) do |tmpdir|
36
- version_control_system.clone(url,
37
- clone_dir_name,
38
- path: tmpdir,
39
- checkout: version)
40
- index_source_dir = Pathname(tmpdir).join(clone_dir_name, 'master_middleman', source_dir_name)
41
- index_dest_dir = File.join(dest_dir, version)
42
- file_system_accessor.make_directory(index_dest_dir)
22
+ attr_reader :fs
43
23
 
44
- Dir.glob(index_source_dir.join('index.*')) do |f|
45
- file_system_accessor.copy(File.expand_path(f), index_dest_dir)
46
- end
47
- end
24
+ def copy_directory_from_gem(gem_root, dir, output_dir)
25
+ fs.copy_contents(File.join(gem_root, dir), output_dir)
48
26
  end
49
27
 
50
- def copy_directory_from_gem(gem_root, dir, output_dir)
51
- file_system_accessor.copy_contents(File.join(gem_root, dir), output_dir)
28
+ def fetch_layout_repo(config, cloner)
29
+ if config.has_option?('layout_repo')
30
+ cloned_repo = cloner.call(source_repo_name: config.layout_repo,
31
+ destination_parent_dir: Dir.mktmpdir)
32
+ cloned_repo.path
33
+ else
34
+ File.absolute_path('master_middleman')
35
+ end
52
36
  end
53
37
  end
54
38
  end