bookbindery 8.5.0 → 9.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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/bookbinder.gemspec +1 -1
  3. data/lib/bookbinder/cli.rb +36 -55
  4. data/lib/bookbinder/commands/bind.rb +3 -19
  5. data/lib/bookbinder/commands/collection.rb +33 -73
  6. data/lib/bookbinder/commands/components/command_options.rb +3 -22
  7. data/lib/bookbinder/commands/generate.rb +0 -11
  8. data/lib/bookbinder/commands/imprint.rb +3 -10
  9. data/lib/bookbinder/commands/punch.rb +0 -11
  10. data/lib/bookbinder/commands/update_local_doc_repos.rb +1 -9
  11. data/lib/bookbinder/commands/watch.rb +1 -10
  12. data/lib/bookbinder/config/fetcher.rb +2 -18
  13. data/lib/bookbinder/preprocessing/dita_html_preprocessor.rb +3 -6
  14. data/lib/bookbinder/preprocessing/dita_pdf_preprocessor.rb +3 -5
  15. data/lib/bookbinder/terminal.rb +0 -1
  16. metadata +3 -31
  17. data/lib/bookbinder/cf_command_runner.rb +0 -123
  18. data/lib/bookbinder/command_runner.rb +0 -23
  19. data/lib/bookbinder/command_validator.rb +0 -51
  20. data/lib/bookbinder/commands/build_and_push_tarball.rb +0 -38
  21. data/lib/bookbinder/commands/chain.rb +0 -11
  22. data/lib/bookbinder/commands/help.rb +0 -70
  23. data/lib/bookbinder/commands/naming.rb +0 -29
  24. data/lib/bookbinder/commands/push_from_local.rb +0 -132
  25. data/lib/bookbinder/commands/push_to_prod.rb +0 -66
  26. data/lib/bookbinder/commands/run_publish_ci.rb +0 -37
  27. data/lib/bookbinder/commands/version.rb +0 -29
  28. data/lib/bookbinder/config/aws_credentials.rb +0 -21
  29. data/lib/bookbinder/config/cf_credentials.rb +0 -62
  30. data/lib/bookbinder/config/remote_yaml_credential_provider.rb +0 -22
  31. data/lib/bookbinder/deploy/app_fetcher.rb +0 -36
  32. data/lib/bookbinder/deploy/archive.rb +0 -102
  33. data/lib/bookbinder/deploy/artifact.rb +0 -26
  34. data/lib/bookbinder/deploy/blue_green_app.rb +0 -29
  35. data/lib/bookbinder/deploy/cf_routes.rb +0 -32
  36. data/lib/bookbinder/deploy/deployment.rb +0 -55
  37. data/lib/bookbinder/deploy/distributor.rb +0 -76
  38. data/lib/bookbinder/deploy/failure.rb +0 -15
  39. data/lib/bookbinder/deploy/pusher.rb +0 -34
  40. data/lib/bookbinder/deploy/success.rb +0 -16
  41. data/lib/bookbinder/deprecated_logger.rb +0 -33
  42. data/lib/bookbinder/errors/cli_error.rb +0 -6
  43. data/lib/bookbinder/legacy/cli.rb +0 -71
  44. data/lib/bookbinder/preprocessing/dita_preprocessor.rb +0 -17
@@ -1,22 +0,0 @@
1
- require 'yaml'
2
- require 'ansi/code'
3
-
4
- module Bookbinder
5
- module Config
6
- class RemoteYamlCredentialProvider
7
- def initialize(logger, version_control_system)
8
- @logger = logger
9
- @version_control_system = version_control_system
10
- end
11
-
12
- def credentials(repo_url)
13
- logger.log "Processing #{ANSI.cyan{repo_url}}"
14
- YAML.load(version_control_system.read_file("credentials.yml", from_repo: repo_url))
15
- end
16
-
17
- private
18
-
19
- attr_reader :logger, :version_control_system
20
- end
21
- end
22
- end
@@ -1,36 +0,0 @@
1
- require_relative 'blue_green_app'
2
- require_relative 'cf_routes'
3
-
4
- module Bookbinder
5
- module Deploy
6
- class AppFetcher
7
- def initialize(routes_to_search, cf_command_runner)
8
- @routes_to_search = routes_to_search
9
- @cf_command_runner = cf_command_runner
10
- end
11
-
12
- def fetch_current_app
13
- raw_cf_routes = cf_command_runner.cf_routes_output
14
- cf_routes = CfRoutes.new(raw_cf_routes)
15
-
16
- existing_hosts = routes_to_search.select do |domain, host|
17
- cf_routes.apps_by_host_and_domain.has_key?([host, domain])
18
- end
19
-
20
- return nil if existing_hosts.empty?
21
- app_groups = existing_hosts.map { |domain, host| apps_for_host(cf_routes, domain, host) }
22
- apps_for_existing_routes = app_groups.first
23
- apps_for_existing_routes.first
24
- end
25
-
26
- private
27
-
28
- attr_reader :routes_to_search, :cf_command_runner
29
-
30
- def apps_for_host(routes_from_cf, domain, host)
31
- routes_from_cf.apps_by_host_and_domain.fetch([host, domain], []).
32
- map &BlueGreenApp.method(:new)
33
- end
34
- end
35
- end
36
- end
@@ -1,102 +0,0 @@
1
- require 'fog/aws'
2
- require 'tmpdir'
3
- require_relative '../deprecated_logger'
4
- require_relative 'artifact'
5
- require_relative 'success'
6
-
7
- module Bookbinder
8
- module Deploy
9
- class Archive
10
- class FileDoesNotExist < StandardError; end
11
- class NoNamespaceGiven < StandardError; end
12
-
13
- def initialize(logger: nil, key: '', secret: '')
14
- @logger = logger
15
- @aws_key = key
16
- @aws_secret_key = secret
17
- end
18
-
19
- def create_and_upload_tarball(
20
- app_dir: 'final_app',
21
- bucket: '',
22
- build_number: nil,
23
- namespace: nil
24
- )
25
- tarball_filename, tarball_path = create_tarball(app_dir, build_number, namespace)
26
- upload_file(bucket, tarball_filename, tarball_path)
27
- Success.new("Green build ##{build_number} has been uploaded to S3 for #{namespace}")
28
- end
29
-
30
- def upload_file(bucket, name, source_path)
31
- find_or_create_directory(bucket).
32
- files.create(key: name,
33
- body: File.read(source_path),
34
- public: true)
35
- end
36
-
37
- def download(download_dir: nil, bucket: nil, build_number: nil, namespace: nil)
38
- raise NoNamespaceGiven, 'One must specify a namespace to find files in this bucket' unless namespace
39
-
40
- directory = connection.directories.get bucket
41
- build_number ||= latest_build_number_for_namespace(directory, namespace)
42
- filename = Artifact.new(namespace, build_number, 'tgz').filename
43
-
44
- s3_file = directory.files.get(filename)
45
- raise FileDoesNotExist, "Unable to find tarball on AWS for book '#{namespace}', build number: #{build_number}" unless s3_file
46
-
47
- downloaded_file = File.join(Dir.mktmpdir, 'downloaded.tgz')
48
- File.open(downloaded_file, 'wb') { |f| f.write(s3_file.body) }
49
- Dir.chdir(download_dir) { `tar xzf #{downloaded_file}` }
50
-
51
- @logger.log "Green build ##{build_number.to_s.green} has been downloaded from S3 and untarred into #{download_dir.to_s.cyan}"
52
- end
53
-
54
- def tarball_name_regex(namespace)
55
- /^#{namespace}-(\d+_?\d*)\.tgz/
56
- end
57
-
58
- private
59
-
60
- def find_or_create_directory(name)
61
- connection.directories.create(key: name)
62
- rescue Excon::Errors::Conflict
63
- connection.directories.get(name)
64
- end
65
-
66
- def create_tarball(app_dir, build_number, namespace)
67
- tarball_filename = Artifact.new(namespace, build_number, 'tgz').filename
68
- tarball_path = File.join(Dir.mktmpdir, tarball_filename)
69
-
70
- Dir.chdir(app_dir) { `tar czf #{tarball_path} *` }
71
- return tarball_filename, tarball_path
72
- end
73
-
74
- def latest_build_number_for_namespace(directory, namespace)
75
- all_files = all_files_workaround_for_fog_map_limitation(directory.files)
76
-
77
- all_files_with_namespace = all_files.map do |file|
78
- filename = file.key
79
- file if filename[tarball_name_regex(namespace)]
80
- end.compact
81
-
82
- return nil if all_files_with_namespace.empty?
83
- most_recent_file = all_files_with_namespace.sort_by { |file| file.last_modified }.last
84
-
85
- most_recent_filename = most_recent_file.key
86
- most_recent_filename[tarball_name_regex(namespace), 1]
87
- end
88
-
89
- def connection
90
- @connection ||= Fog::Storage.new :provider => 'AWS',
91
- :aws_access_key_id => @aws_key,
92
- :aws_secret_access_key => @aws_secret_key
93
- end
94
-
95
- def all_files_workaround_for_fog_map_limitation(files)
96
- all_files = []
97
- files.each { |f| all_files << f }
98
- all_files
99
- end
100
- end
101
- end
102
- end
@@ -1,26 +0,0 @@
1
- module Bookbinder
2
- module Deploy
3
- class Artifact
4
- attr_reader :namespace
5
-
6
- def initialize(namespace, build_number, extension, path = '.')
7
- @namespace = namespace
8
- @build_number = build_number
9
- @path = path
10
- @extension = extension
11
- end
12
-
13
- def full_path
14
- File.join(path, filename)
15
- end
16
-
17
- def filename
18
- "#{namespace}-#{build_number}.#{extension}"
19
- end
20
-
21
- private
22
-
23
- attr_reader :build_number, :path, :extension
24
- end
25
- end
26
- end
@@ -1,29 +0,0 @@
1
- module Bookbinder
2
- module Deploy
3
- class BlueGreenApp
4
- def initialize(name)
5
- @name = name.strip
6
- end
7
-
8
- def ==(other)
9
- to_s == other.to_s
10
- end
11
-
12
- def to_s
13
- name
14
- end
15
-
16
- def with_flipped_name
17
- if name.match(/green$/)
18
- BlueGreenApp.new(name.sub(/green$/, 'blue'))
19
- else
20
- BlueGreenApp.new(name.sub(/blue$/, 'green'))
21
- end
22
- end
23
-
24
- private
25
-
26
- attr_reader :name
27
- end
28
- end
29
- end
@@ -1,32 +0,0 @@
1
- module Bookbinder
2
- module Deploy
3
- class CfRoutes
4
- def initialize(raw_routes)
5
- @raw_routes = raw_routes
6
- end
7
-
8
- def apps_by_host_and_domain
9
- @apps_by_host_and_domain ||= data(raw_routes).reduce({}) {|acc, row|
10
- parsed_row = Hash[headers(raw_routes).zip(row)]
11
- acc.merge(parsed_row.values_at('host', 'domain') => parse_apps(parsed_row['apps']))
12
- }
13
- end
14
-
15
- private
16
-
17
- attr_reader :raw_routes
18
-
19
- def parse_apps(apps)
20
- apps.split(',').map(&:strip) unless apps.nil?
21
- end
22
-
23
- def headers(raw)
24
- raw.lines[2].split(/\s+/)
25
- end
26
-
27
- def data(raw)
28
- raw.lines[3..-1].map {|line| line.split(/\s+/, headers(raw).size)}
29
- end
30
- end
31
- end
32
- end
@@ -1,55 +0,0 @@
1
- module Bookbinder
2
- module Deploy
3
- class Deployment
4
- attr_reader :app_dir, :build_number, :cf_credentials
5
-
6
- def initialize(app_dir: nil,
7
- aws_credentials: nil,
8
- book_repo: nil,
9
- build_number: nil,
10
- cf_credentials: nil)
11
- @app_dir = app_dir
12
- @aws_credentials = aws_credentials
13
- @book_repo = book_repo
14
- @build_number = build_number
15
- @cf_credentials = cf_credentials
16
- end
17
-
18
- def artifact_filename
19
- artifact.filename
20
- end
21
-
22
- def artifact_full_path
23
- artifact.full_path
24
- end
25
-
26
- def aws_access_key
27
- aws_credentials.access_key
28
- end
29
-
30
- def aws_secret_key
31
- aws_credentials.secret_key
32
- end
33
-
34
- def flat_routes
35
- cf_credentials.flat_routes
36
- end
37
-
38
- def green_builds_bucket
39
- aws_credentials.green_builds_bucket
40
- end
41
-
42
- def namespace
43
- Ingest::DestinationDirectory.new(book_repo)
44
- end
45
-
46
- private
47
-
48
- attr_reader :aws_credentials, :book_repo
49
-
50
- def artifact
51
- Artifact.new(namespace, build_number, 'log', '/tmp')
52
- end
53
- end
54
- end
55
- end
@@ -1,76 +0,0 @@
1
- require_relative '../cf_command_runner'
2
- require_relative '../ingest/destination_directory'
3
- require_relative '../sheller'
4
- require_relative 'app_fetcher'
5
- require_relative 'archive'
6
- require_relative 'artifact'
7
- require_relative 'pusher'
8
-
9
- module Bookbinder
10
- module Deploy
11
- class Distributor
12
- EXPIRATION_HOURS = 2
13
-
14
- def self.build(streams, archive, deployment)
15
- cf_command_runner = CfCommandRunner.new(streams, Sheller.new, deployment.cf_credentials, deployment.artifact_full_path)
16
- cf_app_fetcher = AppFetcher.new(deployment.flat_routes, cf_command_runner)
17
- pusher = Pusher.new(cf_command_runner, cf_app_fetcher)
18
- new(streams, archive, pusher, deployment)
19
- end
20
-
21
- def initialize(streams, archive, pusher, deployment)
22
- @streams = streams
23
- @archive = archive
24
- @pusher = pusher
25
- @deployment = deployment
26
- end
27
-
28
- def distribute
29
- push_app
30
- nil
31
- rescue => e
32
- streams[:err].puts(<<-ERROR.chomp)
33
- [ERROR] #{e.message}
34
- [DEBUG INFO]
35
- CF organization: #{cf_credentials.organization}
36
- CF space: #{cf_credentials.space}
37
- CF account: #{cf_credentials.username}
38
- routes: #{cf_credentials.routes}
39
- ERROR
40
- raise
41
- ensure
42
- upload_trace
43
- end
44
-
45
- private
46
-
47
- attr_reader :archive, :deployment, :pusher, :streams
48
-
49
- def push_app
50
- pusher.push(deployment.app_dir)
51
- end
52
-
53
- def upload_trace
54
- uploaded_file = archive.upload_file(deployment.green_builds_bucket, deployment.artifact_filename, deployment.artifact_full_path)
55
- log_success(
56
- ["Your cf trace file is available at: #{uploaded_file.url(Time.now.to_i + EXPIRATION_HOURS*60*60)}",
57
- "This URL will expire in #{EXPIRATION_HOURS} hours, so if you need to share it, make sure to save a copy now."]
58
- )
59
- rescue Errno::ENOENT
60
- log_error("Could not find CF trace file: #{deployment.artifact_full_path}")
61
- end
62
-
63
- def cf_credentials
64
- deployment.cf_credentials
65
- end
66
-
67
- def log_success(message)
68
- streams[:success].puts(message)
69
- end
70
-
71
- def log_error(message)
72
- streams[:err].puts(message)
73
- end
74
- end
75
- end
76
- end
@@ -1,15 +0,0 @@
1
- module Bookbinder
2
- module Deploy
3
- class Failure
4
- attr_reader :reason
5
-
6
- def initialize(reason)
7
- @reason = reason
8
- end
9
-
10
- def success?
11
- false
12
- end
13
- end
14
- end
15
- end
@@ -1,34 +0,0 @@
1
- module Bookbinder
2
- module Deploy
3
- class Pusher
4
- def initialize(cf_cli, app_fetcher)
5
- @cf_cli = cf_cli
6
- @app_fetcher = app_fetcher
7
- end
8
-
9
- def push(app_dir)
10
- Dir.chdir(app_dir) do
11
- cf_cli.login
12
-
13
- old_app = app_fetcher.fetch_current_app
14
-
15
- if old_app
16
- new_app = old_app.with_flipped_name
17
- cf_cli.start(new_app)
18
- cf_cli.push(new_app)
19
- cf_cli.map_routes(new_app)
20
- cf_cli.takedown_old_target_app(old_app)
21
- else
22
- new_app = cf_cli.new_app
23
- cf_cli.push(new_app)
24
- cf_cli.map_routes(new_app)
25
- end
26
- end
27
- end
28
-
29
- private
30
-
31
- attr_reader :cf_cli, :app_fetcher
32
- end
33
- end
34
- end
@@ -1,16 +0,0 @@
1
- module Bookbinder
2
- module Deploy
3
- class Success
4
- attr_reader :reason
5
-
6
- def initialize(reason)
7
- @reason = reason
8
- end
9
-
10
- def success?
11
- true
12
- end
13
- end
14
- end
15
- end
16
-