bookbindery 8.5.0 → 9.0.0

Sign up to get free protection for your applications and to get access to all the features.
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
-