bookbindery 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 19c1ec695ede30996441a72bccd9617f0802d6d1
|
4
|
+
data.tar.gz: e711b4cfe5f5af59d1e4ec68d0c98975295eab60
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1ab45230d391a2aac4d84ff67015bd48d44e82fbfb55188bbf03db798efada981a635a6d7d15e71e763eff98b45e1798850f85f0e41f1ffc346785782f683abb
|
7
|
+
data.tar.gz: 04f5b2b527d2c90a99b47942e6b440054d47e4e6ac74712cdb4c4fd8b80d0efb67a5a263fd7ea6cc615e6262554f0cb3824f9783259eeee5fc4025809a26a78b
|
data/bin/bookbinder
ADDED
data/lib/bookbinder.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'fog'
|
2
|
+
require 'tmpdir'
|
3
|
+
require 'ansi'
|
4
|
+
require 'faraday'
|
5
|
+
require 'faraday_middleware'
|
6
|
+
require 'octokit'
|
7
|
+
require 'padrino-contrib'
|
8
|
+
require 'middleman-syntax'
|
9
|
+
require 'middleman-core/cli'
|
10
|
+
require 'middleman-core/profiling'
|
11
|
+
require 'anemone'
|
12
|
+
require 'css_parser'
|
13
|
+
require 'vienna'
|
14
|
+
require 'popen4'
|
15
|
+
require 'puma'
|
16
|
+
|
17
|
+
#require_relative 'bookbinder/shell_out'
|
18
|
+
require_relative 'bookbinder/bookbinder_logger'
|
19
|
+
require_relative 'bookbinder/git_client'
|
20
|
+
#require_relative 'bookbinder/repository'
|
21
|
+
require_relative 'bookbinder/section'
|
22
|
+
require_relative 'bookbinder/book'
|
23
|
+
require_relative 'bookbinder/code_example'
|
24
|
+
require_relative 'bookbinder/remote_yaml_credential_provider'
|
25
|
+
require_relative 'bookbinder/configuration'
|
26
|
+
require_relative 'bookbinder/configuration_fetcher'
|
27
|
+
require_relative 'bookbinder/configuration_validator'
|
28
|
+
require_relative 'bookbinder/css_link_checker'
|
29
|
+
require_relative 'bookbinder/sitemap_generator'
|
30
|
+
require_relative 'bookbinder/sieve'
|
31
|
+
require_relative 'bookbinder/stabilimentum'
|
32
|
+
require_relative 'bookbinder/server_director'
|
33
|
+
require_relative 'bookbinder/spider'
|
34
|
+
|
35
|
+
require_relative 'bookbinder/archive'
|
36
|
+
require_relative 'bookbinder/pdf_generator'
|
37
|
+
require_relative 'bookbinder/middleman_runner'
|
38
|
+
require_relative 'bookbinder/publisher'
|
39
|
+
require_relative 'bookbinder/cf_command_runner'
|
40
|
+
require_relative 'bookbinder/pusher'
|
41
|
+
require_relative 'bookbinder/artifact_namer'
|
42
|
+
require_relative 'bookbinder/distributor'
|
43
|
+
|
44
|
+
require_relative 'bookbinder/commands/bookbinder_command'
|
45
|
+
require_relative 'bookbinder/commands/build_and_push_tarball'
|
46
|
+
require_relative 'bookbinder/commands/publish'
|
47
|
+
require_relative 'bookbinder/commands/push_local_to_staging'
|
48
|
+
require_relative 'bookbinder/commands/push_to_prod'
|
49
|
+
require_relative 'bookbinder/commands/run_publish_ci'
|
50
|
+
require_relative 'bookbinder/commands/update_local_doc_repos'
|
51
|
+
require_relative 'bookbinder/commands/tag'
|
52
|
+
require_relative 'bookbinder/commands/generate_pdf'
|
53
|
+
|
54
|
+
require_relative 'bookbinder/usage_messenger'
|
55
|
+
|
56
|
+
require_relative 'bookbinder/cli'
|
57
|
+
|
58
|
+
# Finds the project root for both spec & production
|
59
|
+
GEM_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require_relative "blue_green_app"
|
2
|
+
require_relative "cf_routes"
|
3
|
+
|
4
|
+
module Bookbinder
|
5
|
+
|
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
|
+
app_groups =
|
21
|
+
if existing_hosts.any?
|
22
|
+
existing_hosts.map { |domain, host| apps_for_host(cf_routes, domain, host) }
|
23
|
+
else
|
24
|
+
raise "cannot find currently deployed app."
|
25
|
+
end
|
26
|
+
apps_for_existing_routes = app_groups.first
|
27
|
+
apps_for_existing_routes.first
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
attr_reader :routes_to_search, :cf_command_runner
|
33
|
+
|
34
|
+
def apps_for_host(routes_from_cf, domain, host)
|
35
|
+
routes_from_cf.apps_by_host_and_domain.fetch([host, domain], []).
|
36
|
+
map &BlueGreenApp.method(:new)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'fog'
|
2
|
+
require 'tmpdir'
|
3
|
+
require_relative 'bookbinder_logger'
|
4
|
+
require_relative 'artifact_namer'
|
5
|
+
|
6
|
+
module Bookbinder
|
7
|
+
class Archive
|
8
|
+
class FileDoesNotExist < StandardError; end
|
9
|
+
class NoNamespaceGiven < StandardError; end
|
10
|
+
|
11
|
+
def initialize(logger: nil, key: '', secret: '')
|
12
|
+
@logger = logger
|
13
|
+
@aws_key = key
|
14
|
+
@aws_secret_key = secret
|
15
|
+
end
|
16
|
+
|
17
|
+
def create_and_upload_tarball(build_number: nil, app_dir: 'final_app', bucket: '', namespace: nil)
|
18
|
+
raise 'You must provide a build_number to push an identifiable build.' unless build_number
|
19
|
+
raise 'You must provide a namespace to push an identifiable build.' unless namespace
|
20
|
+
|
21
|
+
tarball_filename, tarball_path = create_tarball(app_dir, build_number, namespace)
|
22
|
+
|
23
|
+
upload_file(bucket, tarball_filename, tarball_path)
|
24
|
+
@logger.log "Green build ##{build_number.to_s.green} has been uploaded to S3 for #{namespace.to_s.cyan}"
|
25
|
+
end
|
26
|
+
|
27
|
+
def upload_file(bucket, name, source_path)
|
28
|
+
find_or_create_directory(bucket).
|
29
|
+
files.create(key: name,
|
30
|
+
body: File.read(source_path),
|
31
|
+
public: true)
|
32
|
+
end
|
33
|
+
|
34
|
+
def download(download_dir: nil, bucket: nil, build_number: nil, namespace: nil)
|
35
|
+
raise NoNamespaceGiven, 'One must specify a namespace to find files in this bucket' unless namespace
|
36
|
+
|
37
|
+
directory = connection.directories.get bucket
|
38
|
+
build_number ||= latest_build_number_for_namespace(directory, namespace)
|
39
|
+
filename = ArtifactNamer.new(namespace, build_number, 'tgz').filename
|
40
|
+
|
41
|
+
s3_file = directory.files.get(filename)
|
42
|
+
raise FileDoesNotExist, "Unable to find tarball on AWS for book '#{namespace}', build number: #{build_number}" unless s3_file
|
43
|
+
|
44
|
+
downloaded_file = File.join(Dir.mktmpdir, 'downloaded.tgz')
|
45
|
+
File.open(downloaded_file, 'wb') { |f| f.write(s3_file.body) }
|
46
|
+
Dir.chdir(download_dir) { `tar xzf #{downloaded_file}` }
|
47
|
+
|
48
|
+
@logger.log "Green build ##{build_number.to_s.green} has been downloaded from S3 and untarred into #{download_dir.to_s.cyan}"
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def find_or_create_directory(name)
|
54
|
+
connection.directories.create(key: name)
|
55
|
+
rescue Excon::Errors::Conflict
|
56
|
+
connection.directories.get(name)
|
57
|
+
end
|
58
|
+
|
59
|
+
def create_tarball(app_dir, build_number, namespace)
|
60
|
+
tarball_filename = ArtifactNamer.new(namespace, build_number, 'tgz').filename
|
61
|
+
tarball_path = File.join(Dir.mktmpdir, tarball_filename)
|
62
|
+
|
63
|
+
Dir.chdir(app_dir) { `tar czf #{tarball_path} *` }
|
64
|
+
return tarball_filename, tarball_path
|
65
|
+
end
|
66
|
+
|
67
|
+
def latest_build_number_for_namespace(directory, namespace)
|
68
|
+
all_files = all_files_workaround_for_fog_map_limitation(directory.files)
|
69
|
+
|
70
|
+
all_files_with_namespace = all_files.map do |file|
|
71
|
+
filename = file.key
|
72
|
+
matches = /^#{namespace}-([\d]+)\.tgz/.match(filename)
|
73
|
+
file if matches
|
74
|
+
end.compact
|
75
|
+
|
76
|
+
return nil if all_files_with_namespace.empty?
|
77
|
+
most_recent_file = all_files_with_namespace.sort_by { |file| file.last_modified }.last
|
78
|
+
|
79
|
+
most_recent_filename = most_recent_file.key
|
80
|
+
most_recent_build_number = /^#{namespace}-([\d]+)\.tgz/.match(most_recent_filename)[1]
|
81
|
+
end
|
82
|
+
|
83
|
+
def connection
|
84
|
+
@connection ||= Fog::Storage.new :provider => 'AWS',
|
85
|
+
:aws_access_key_id => @aws_key,
|
86
|
+
:aws_secret_access_key => @aws_secret_key
|
87
|
+
end
|
88
|
+
|
89
|
+
def all_files_workaround_for_fog_map_limitation(files)
|
90
|
+
all_files = []
|
91
|
+
files.each { |f| all_files << f }
|
92
|
+
all_files
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Bookbinder
|
2
|
+
class ArtifactNamer
|
3
|
+
def initialize(namespace, build_number, extension, path = '.')
|
4
|
+
@namespace = namespace
|
5
|
+
@build_number = build_number
|
6
|
+
@path = path
|
7
|
+
@extension = extension
|
8
|
+
end
|
9
|
+
|
10
|
+
def full_path
|
11
|
+
File.join(path, filename)
|
12
|
+
end
|
13
|
+
|
14
|
+
def filename
|
15
|
+
"#{namespace}-#{build_number}.#{extension}"
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
attr_reader :namespace, :build_number, :path, :extension
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Bookbinder
|
2
|
+
class BlueGreenApp
|
3
|
+
def initialize(name)
|
4
|
+
@name = name.strip
|
5
|
+
end
|
6
|
+
|
7
|
+
def ==(other)
|
8
|
+
to_s == other.to_s
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_s
|
12
|
+
name
|
13
|
+
end
|
14
|
+
|
15
|
+
def with_flipped_name
|
16
|
+
if name.match(/green$/)
|
17
|
+
BlueGreenApp.new(name.sub(/green$/, 'blue'))
|
18
|
+
else
|
19
|
+
BlueGreenApp.new(name.sub(/blue$/, 'green'))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
attr_reader :name
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require_relative 'git_hub_repository'
|
2
|
+
require_relative 'directory_helpers'
|
3
|
+
|
4
|
+
module Bookbinder
|
5
|
+
class Book
|
6
|
+
include DirectoryHelperMethods
|
7
|
+
attr_reader :sections
|
8
|
+
|
9
|
+
def self.from_remote(logger: nil, full_name: nil, destination_dir: nil, ref: nil, git_accessor: Git)
|
10
|
+
book = new(logger: logger, full_name: full_name, target_ref: ref, git_accessor: git_accessor)
|
11
|
+
book.copy_from_remote(destination_dir) if destination_dir
|
12
|
+
book
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(logger: nil, full_name: nil, target_ref: nil, github_token: nil, sections: [], git_accessor: Git)
|
16
|
+
@sections = sections.map do |section|
|
17
|
+
GitHubRepository.new logger: logger, full_name: section['repository']['name']
|
18
|
+
end
|
19
|
+
|
20
|
+
@repository = GitHubRepository.new(logger: logger, full_name: full_name, target_ref: target_ref, github_token: github_token)
|
21
|
+
@git_accessor = git_accessor
|
22
|
+
end
|
23
|
+
|
24
|
+
def full_name
|
25
|
+
@repository.full_name
|
26
|
+
end
|
27
|
+
|
28
|
+
def head_sha
|
29
|
+
@repository.head_sha
|
30
|
+
end
|
31
|
+
|
32
|
+
def directory
|
33
|
+
@repository.directory
|
34
|
+
end
|
35
|
+
|
36
|
+
def get_modification_date_for(file: nil, full_path: nil)
|
37
|
+
git_directory, file_relative_path = full_path.split(output_dir_name+'/')
|
38
|
+
begin
|
39
|
+
git_base_object = Git.open(git_directory)
|
40
|
+
rescue => e
|
41
|
+
raise "Invalid git repository! #{git_directory} is not a .git directory"
|
42
|
+
end
|
43
|
+
@repository.get_modification_date_for(file: file_relative_path, git: git_base_object)
|
44
|
+
end
|
45
|
+
|
46
|
+
def copy_from_remote(destination_dir)
|
47
|
+
@repository.copy_from_remote(destination_dir, @git_accessor)
|
48
|
+
end
|
49
|
+
|
50
|
+
def tag_self_and_sections_with(tag)
|
51
|
+
(@sections + [@repository]).each { |repo| repo.tag_with tag }
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'ansi'
|
2
|
+
|
3
|
+
class String
|
4
|
+
include ANSI::Mixin
|
5
|
+
end
|
6
|
+
|
7
|
+
module Bookbinder
|
8
|
+
class BookbinderLogger
|
9
|
+
def log(message)
|
10
|
+
puts message
|
11
|
+
end
|
12
|
+
|
13
|
+
def log_print(message)
|
14
|
+
print message
|
15
|
+
end
|
16
|
+
|
17
|
+
def error(message)
|
18
|
+
puts message.red
|
19
|
+
end
|
20
|
+
|
21
|
+
def success(message)
|
22
|
+
puts message.green
|
23
|
+
end
|
24
|
+
|
25
|
+
def warn(message)
|
26
|
+
puts message.yellow
|
27
|
+
end
|
28
|
+
|
29
|
+
def notify(message)
|
30
|
+
puts message.blue
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require 'open3'
|
2
|
+
require_relative 'blue_green_app'
|
3
|
+
|
4
|
+
module Bookbinder
|
5
|
+
class CfCommandRunner
|
6
|
+
def initialize(logger, cf_credentials, trace_file)
|
7
|
+
@logger = logger
|
8
|
+
@creds = cf_credentials
|
9
|
+
@trace_file = trace_file
|
10
|
+
end
|
11
|
+
|
12
|
+
def login
|
13
|
+
username = creds.username
|
14
|
+
password = creds.password
|
15
|
+
api_endpoint = creds.api_endpoint
|
16
|
+
organization = creds.organization
|
17
|
+
space = creds.space
|
18
|
+
creds_string = (username && password) ? "-u '#{username}' -p '#{password}'" : ''
|
19
|
+
|
20
|
+
success = Kernel.system("#{cf_binary_path} login #{creds_string} -a '#{api_endpoint}' -o '#{organization}' -s '#{space}'")
|
21
|
+
raise "Could not log in to #{creds.api_endpoint}" unless success
|
22
|
+
end
|
23
|
+
|
24
|
+
def cf_routes_output
|
25
|
+
output, status = Open3.capture2("CF_COLOR=false #{cf_binary_path} routes")
|
26
|
+
raise 'failure executing cf routes' unless status.success?
|
27
|
+
output
|
28
|
+
end
|
29
|
+
|
30
|
+
def new_app
|
31
|
+
BlueGreenApp.new([creds.app_name, 'blue'].join('-'))
|
32
|
+
end
|
33
|
+
|
34
|
+
def start(deploy_target_app)
|
35
|
+
# Theoretically we shouldn't need this (and corresponding "stop" below), but we've seen CF pull files from both
|
36
|
+
# green and blue when a DNS redirect points to HOST.cfapps.io
|
37
|
+
# Also, shutting down the unused app saves $$
|
38
|
+
Kernel.system("#{cf_binary_path} start #{deploy_target_app} ")
|
39
|
+
end
|
40
|
+
|
41
|
+
def push(deploy_target_app)
|
42
|
+
# Currently --no-routes is used to blow away all existing routes from a newly deployed app.
|
43
|
+
# The routes will then be recreated from the creds repo.
|
44
|
+
success = Kernel.system(environment_variables, "#{cf_binary_path} push #{deploy_target_app} --no-route -m 256M -i 3")
|
45
|
+
raise "Could not deploy app to #{deploy_target_app}" unless success
|
46
|
+
end
|
47
|
+
|
48
|
+
def unmap_routes(app)
|
49
|
+
creds.flat_routes.each do |domain, host|
|
50
|
+
unmap_route(app, domain, host)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def map_routes(app)
|
55
|
+
succeeded = []
|
56
|
+
|
57
|
+
creds.flat_routes.each do |domain, name|
|
58
|
+
begin
|
59
|
+
map_route(app, domain, name)
|
60
|
+
succeeded << [app, domain, name]
|
61
|
+
rescue RuntimeError
|
62
|
+
succeeded.each { |app, domain, host| unmap_route(app, domain, host) }
|
63
|
+
raise
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def takedown_old_target_app(app)
|
69
|
+
# Routers flush every 10 seconds (but not guaranteed), so wait a bit longer than that.
|
70
|
+
@logger.log "waiting 15 seconds for routes to remap...\n\n"
|
71
|
+
(1..15).to_a.reverse.each do |seconds|
|
72
|
+
@logger.log_print "\r\r#{seconds}... "
|
73
|
+
Kernel.sleep 1
|
74
|
+
end
|
75
|
+
stop(app)
|
76
|
+
unmap_routes(app)
|
77
|
+
end
|
78
|
+
|
79
|
+
private
|
80
|
+
|
81
|
+
attr_reader :creds
|
82
|
+
|
83
|
+
def stop(app)
|
84
|
+
success = Kernel.system("#{cf_binary_path} stop #{app}")
|
85
|
+
raise "Failed to stop application #{app}" unless success
|
86
|
+
end
|
87
|
+
|
88
|
+
def map_route(deploy_target_app, domain, host)
|
89
|
+
map_route_command = "#{cf_binary_path} map-route #{deploy_target_app} #{domain}"
|
90
|
+
map_route_command += " -n #{host}" unless host.empty?
|
91
|
+
|
92
|
+
success = Kernel.system(map_route_command)
|
93
|
+
raise "Deployed app to #{deploy_target_app} but failed to map hostname #{host}.#{domain} to it." unless success
|
94
|
+
end
|
95
|
+
|
96
|
+
def unmap_route(deploy_target_app, domain, host)
|
97
|
+
unmap_route_command = "#{cf_binary_path} unmap-route #{deploy_target_app} #{domain}"
|
98
|
+
unmap_route_command += " -n #{host}" unless host.empty?
|
99
|
+
|
100
|
+
success = Kernel.system(unmap_route_command)
|
101
|
+
raise "Failed to unmap route #{host} on #{deploy_target_app}." unless success
|
102
|
+
end
|
103
|
+
|
104
|
+
def cf_binary_path
|
105
|
+
@cf_binary_path ||= `which cf`.chomp!
|
106
|
+
raise "CF CLI could not be found in your PATH. Please make sure cf cli is in your PATH." if @cf_binary_path.nil?
|
107
|
+
@cf_binary_path
|
108
|
+
end
|
109
|
+
|
110
|
+
def environment_variables
|
111
|
+
{'CF_TRACE' => @trace_file}
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|