conan_deploy 0.0.9 → 0.0.12
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/conan +39 -21
- data/lib/conan/application.rb +164 -0
- data/lib/conan/application_helper.rb +2 -1
- data/lib/conan/deploy.rb +12 -10
- data/lib/conan/deployment.rb +93 -0
- data/lib/conan/environment.rb +24 -0
- data/lib/conan/has_options.rb +15 -0
- data/lib/conan/jvm_app.rb +16 -0
- data/lib/conan/manifest.rb +120 -0
- data/lib/conan/manifest_builder.rb +3 -530
- data/lib/conan/output.rb +24 -24
- data/lib/conan/pipeline.rb +130 -0
- data/lib/conan/rails_zip_app.rb +10 -0
- data/lib/conan/stackato.rb +65 -11
- data/lib/conan/version.rb +2 -2
- metadata +18 -6
- checksums.yaml +0 -15
data/lib/conan/output.rb
CHANGED
@@ -10,15 +10,15 @@ class OutThingy
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def outputToFile(file, &block)
|
13
|
-
o = File.join(@output_dir, file)
|
14
|
-
puts "Write: #{o}"
|
13
|
+
o = File.join(@output_dir, file)
|
14
|
+
puts "Write: #{o}"
|
15
15
|
FileUtils.mkdir_p File.dirname(o)
|
16
16
|
File.open(o, 'w') { |f| yield f }
|
17
17
|
end
|
18
18
|
|
19
19
|
def loadAppMetadataFromDeploymentIfExists(app, deploy)
|
20
20
|
loadAppMetadataFromDeployment(app, deploy, true)
|
21
|
-
end
|
21
|
+
end
|
22
22
|
end
|
23
23
|
|
24
24
|
class StackatoOutThingy < OutThingy
|
@@ -39,15 +39,15 @@ class StackatoOutThingy < OutThingy
|
|
39
39
|
FileUtils.mkdir_p apps_dir
|
40
40
|
end
|
41
41
|
|
42
|
-
def clean(app, environment)
|
42
|
+
def clean(app, environment)
|
43
43
|
# TODO: cleanup
|
44
44
|
end
|
45
45
|
|
46
46
|
def provision(app)
|
47
|
-
app.download(@apps_dir)
|
47
|
+
app.download(@apps_dir)
|
48
48
|
end
|
49
49
|
|
50
|
-
def filePath(app, deploy)
|
50
|
+
def filePath(app, deploy)
|
51
51
|
"#{deploy.environment.id}/#{deploy.shipcloud}/#{app.id}"
|
52
52
|
end
|
53
53
|
|
@@ -56,9 +56,9 @@ class StackatoOutThingy < OutThingy
|
|
56
56
|
end
|
57
57
|
|
58
58
|
# TODO this needs a refactor, it's knoted up with App
|
59
|
-
def loadAppMetadataFromDeployment(app, deploy, fail_silent=false)
|
59
|
+
def loadAppMetadataFromDeployment(app, deploy, fail_silent=false)
|
60
60
|
p = filePath(app, deploy)
|
61
|
-
path = File.join(@environments_dir, p)
|
61
|
+
path = File.join(@environments_dir, p)
|
62
62
|
metadata_file = File.join(path, @@metadata_file_name)
|
63
63
|
|
64
64
|
if (File.exists? path)
|
@@ -66,7 +66,7 @@ class StackatoOutThingy < OutThingy
|
|
66
66
|
else
|
67
67
|
raise "Build meta-data was not found: #{path}" unless fail_silent
|
68
68
|
end
|
69
|
-
end
|
69
|
+
end
|
70
70
|
|
71
71
|
def writeArtifactMetadata(app, deploy)
|
72
72
|
if (deploy.enabled?)
|
@@ -76,15 +76,15 @@ class StackatoOutThingy < OutThingy
|
|
76
76
|
}
|
77
77
|
end
|
78
78
|
end
|
79
|
-
|
79
|
+
|
80
80
|
def writeConfiguration(app, deploy, bg=false)
|
81
|
-
if (deploy.enabled?)
|
81
|
+
if (deploy.enabled?)
|
82
82
|
target_dir = workingDir(app)
|
83
83
|
templates_dir = File.join(target_dir, "deploy-templates")
|
84
84
|
|
85
|
-
daphne_tokens = [ "#{app.id}", "#{deploy.environment.id}" ]
|
85
|
+
daphne_tokens = [ "#{app.id}", "#{deploy.environment.id}" ]
|
86
86
|
daphne_tokens = daphne_tokens << "facility-#{deploy.facility_id}" unless deploy.facility_id.nil?
|
87
|
-
|
87
|
+
|
88
88
|
n_changes = Templates.evaluate templates_dir, target_dir, {
|
89
89
|
:app => app,
|
90
90
|
:deploy => deploy,
|
@@ -95,10 +95,10 @@ class StackatoOutThingy < OutThingy
|
|
95
95
|
:oauth_secret => DaphneUtil.generate_secret(*daphne_tokens),
|
96
96
|
:api_key => DaphneUtil.generate_api_key(*daphne_tokens),
|
97
97
|
|
98
|
-
# short-cuts
|
98
|
+
# short-cuts
|
99
99
|
:app_id => app.id,
|
100
100
|
:deploy_base_name => deploy.name(app),
|
101
|
-
:deploy_name => bg ?
|
101
|
+
:deploy_name => bg ? app.unique_name : deploy.name(app),
|
102
102
|
:deploy_urls => bg ? deploy.inactive_urls(app) : deploy.active_urls(app),
|
103
103
|
:env => deploy.environment.id,
|
104
104
|
:org => deploy.org,
|
@@ -106,7 +106,7 @@ class StackatoOutThingy < OutThingy
|
|
106
106
|
:infra => deploy.shipcloud, # TODO: remove infra key, this is just to avoid breaking existing templates
|
107
107
|
:shipcloud => deploy.shipcloud,
|
108
108
|
:facility => deploy.facility_id,
|
109
|
-
:options => deploy.options
|
109
|
+
:options => deploy.options
|
110
110
|
}
|
111
111
|
end
|
112
112
|
#TODO: can this be used to provide idempotency for config-only deploymnent?
|
@@ -116,19 +116,19 @@ end
|
|
116
116
|
|
117
117
|
class PropertiesFileOutThingy < OutThingy
|
118
118
|
|
119
|
-
def clean(app, environment)
|
119
|
+
def clean(app, environment)
|
120
120
|
# cleanup current
|
121
|
-
FileUtils.rm Dir.glob("#{@output_dir}/#{app.id}-deploy-#{environment.id}-*.properties")
|
121
|
+
FileUtils.rm Dir.glob("#{@output_dir}/#{app.id}-deploy-#{environment.id}-*.properties")
|
122
122
|
end
|
123
123
|
|
124
|
-
def fileName(app, deploy)
|
124
|
+
def fileName(app, deploy)
|
125
125
|
"#{app.id}-deploy-#{deploy.environment.id}-#{deploy.shipcloud}.properties"
|
126
126
|
end
|
127
127
|
|
128
128
|
def loadAppMetadataFromDeployment(app, deploy, fail_silent=false)
|
129
129
|
path = File.join(@output_dir, fileName(app, deploy))
|
130
130
|
if (File.exists? path)
|
131
|
-
props = Utils::Properties.load_from_file(path, true)
|
131
|
+
props = Utils::Properties.load_from_file(path, true)
|
132
132
|
app.version = props.get(:DEPLOY_VERSION) # TODO: preserve SHA1
|
133
133
|
else
|
134
134
|
raise "File not found: #{path}" unless fail_silent
|
@@ -138,16 +138,16 @@ class PropertiesFileOutThingy < OutThingy
|
|
138
138
|
def writeArtifactMetadata(app, deploy)
|
139
139
|
file_name = fileName(app, deploy)
|
140
140
|
out_file = File.join(@output_dir, file_name)
|
141
|
-
if (!deploy.enabled?)
|
142
|
-
if (File.exists? out_file)
|
141
|
+
if (!deploy.enabled?)
|
142
|
+
if (File.exists? out_file)
|
143
143
|
File.delete(out_file)
|
144
144
|
end
|
145
|
-
out_file = File.join(@output_dir, "DISABLED-#{file_name}")
|
145
|
+
out_file = File.join(@output_dir, "DISABLED-#{file_name}")
|
146
146
|
end
|
147
147
|
puts "Write: #{out_file}"
|
148
148
|
File.open(out_file, 'w') { |f|
|
149
149
|
# TODO: would like @time in the manifest as audit field, but not sure it's such a good idea yet
|
150
|
-
# f << "\# #{file_name}\n\# #{@time}\n"
|
150
|
+
# f << "\# #{file_name}\n\# #{@time}\n"
|
151
151
|
f << "\# #{file_name}\n"
|
152
152
|
f << "DEPLOY_ENV=#{deploy.environment.id}\n"
|
153
153
|
f << "DEPLOY_INFRA=#{deploy.shipcloud}\n"
|
@@ -0,0 +1,130 @@
|
|
1
|
+
class Pipeline
|
2
|
+
include ApiHelper
|
3
|
+
|
4
|
+
attr_accessor :id, :apps
|
5
|
+
|
6
|
+
def initialize(id, artifact_repo, output, options)
|
7
|
+
@id = id
|
8
|
+
@artifact_repo = artifact_repo
|
9
|
+
@output = output
|
10
|
+
@apps = {}
|
11
|
+
@options = options
|
12
|
+
end
|
13
|
+
|
14
|
+
def app(app_id, project_name, platform_type, url_segment=nil)
|
15
|
+
if (@options[:'deploy-app-name'].nil?) || (@options[:'deploy-app-name'] == app_id.to_s)
|
16
|
+
puts "No app specified, or we matched the specified app: #{@options[:'deploy-app-name']}"
|
17
|
+
@apps[app_id] = case platform_type
|
18
|
+
when :jvm
|
19
|
+
JvmApp.new(app_id, project_name, @artifact_repo, @options, url_segment)
|
20
|
+
when :rails_zip
|
21
|
+
RailsZipApp.new(app_id, project_name, @artifact_repo, @options, url_segment)
|
22
|
+
else
|
23
|
+
raise "unknown platform type: #{platform_type}"
|
24
|
+
end
|
25
|
+
else
|
26
|
+
puts "App #{app_id} doesn't match specified app #{@options[:'deploy-app-name']}, skipping"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def appVersion(app_id)
|
31
|
+
@apps[app_id].version
|
32
|
+
end
|
33
|
+
|
34
|
+
def load!(environment, deploy_shipcloud)
|
35
|
+
eachAppDeployment(environment) { |app, deploy|
|
36
|
+
# load the persisted meta-data
|
37
|
+
@output.loadAppMetadataFromDeploymentIfExists(app, deploy)
|
38
|
+
}
|
39
|
+
@deploy_shipcloud = deploy_shipcloud
|
40
|
+
end
|
41
|
+
|
42
|
+
def update(environment, from_upstream_env)
|
43
|
+
@apps.values.each { |app|
|
44
|
+
puts ''
|
45
|
+
if !(@options[:'deploy-app-version'].nil?)
|
46
|
+
puts "Using version from options: #{@options[:'deploy-app-version']}"
|
47
|
+
app.findRequestedVersion(@options[:'deploy-app-version'])
|
48
|
+
elsif (from_upstream_env)
|
49
|
+
# promote versions from an upstream deploy
|
50
|
+
# TODO: this needs improving
|
51
|
+
puts "Promote #{app.id} from #{from_upstream_env.id} to #{environment.id}"
|
52
|
+
upstream_deploy = from_upstream_env.deployments.select { |d| d.app_ids.select {|x| x == app.id }.size > 0 }.first
|
53
|
+
@output.loadAppMetadataFromDeployment(app, upstream_deploy)
|
54
|
+
else
|
55
|
+
puts "Find latest #{app.artifact_id}"
|
56
|
+
# lookup most recent from repo
|
57
|
+
app.findRequestedVersion('LATEST')
|
58
|
+
end
|
59
|
+
@output.clean(app, environment)
|
60
|
+
# download artifacts
|
61
|
+
@output.provision(app)
|
62
|
+
}
|
63
|
+
|
64
|
+
# write out deployment artifact meta-data
|
65
|
+
eachAppDeployment(environment) { |app, deploy| @output.writeArtifactMetadata(app, deploy) }
|
66
|
+
end
|
67
|
+
|
68
|
+
def configure(environment, bg=false)
|
69
|
+
eachAppDeployment(environment) { |app, deploy| @output.writeConfiguration(app, deploy, bg) }
|
70
|
+
end
|
71
|
+
|
72
|
+
def deploy(environment, paas, force=false)
|
73
|
+
eachAppDeployment(environment) { |app, deploy|
|
74
|
+
work_dir = @output.workingDir(app)
|
75
|
+
if (force)
|
76
|
+
paas.deploy(work_dir, app, deploy, true)
|
77
|
+
else
|
78
|
+
paas.deploy(work_dir, app, deploy) unless app.isDeployedAt(deploy.manifest_url(app))
|
79
|
+
end
|
80
|
+
}
|
81
|
+
end
|
82
|
+
|
83
|
+
def bg_deploy(environment, paas, force=false)
|
84
|
+
apps = []
|
85
|
+
eachAppDeployment(environment) { |app, deploy|
|
86
|
+
if (force or !app.isDeployedAt(deploy.manifest_url(app)))
|
87
|
+
paas.bg_deploy(@output.workingDir(app), app, deploy)
|
88
|
+
apps << app
|
89
|
+
end
|
90
|
+
}
|
91
|
+
apps
|
92
|
+
end
|
93
|
+
|
94
|
+
def is_inactive_node_operational?(environment, paas)
|
95
|
+
eachAppDeployment(environment) { |app, deploy|
|
96
|
+
response = ApiHelper.smoke_test(deploy.inactive_smoke_test_url(app), 60)
|
97
|
+
|
98
|
+
if(response.code != 200)
|
99
|
+
puts "Smoke test failed for inactive (Blue) node. Here is the entire response: #{response.inspect}"
|
100
|
+
return false
|
101
|
+
else
|
102
|
+
return true
|
103
|
+
end
|
104
|
+
}
|
105
|
+
end
|
106
|
+
|
107
|
+
def bg_switch(environment, paas)
|
108
|
+
eachAppDeployment(environment) { |app, deploy| paas.bg_switch(app, deploy) }
|
109
|
+
end
|
110
|
+
|
111
|
+
def bg_clean(environment, paas)
|
112
|
+
eachAppDeployment(environment) { |app, deploy| paas.bg_clean(app, deploy) }
|
113
|
+
end
|
114
|
+
|
115
|
+
def eachAppDeployment(environment)
|
116
|
+
selected_deployments = environment.deployments.select{ |d| @deploy_shipcloud.nil? || d.shipcloud == @deploy_shipcloud }
|
117
|
+
puts "WARNING no deploys selected: #{@deploy_shipcloud}" if selected_deployments.empty?
|
118
|
+
selected_deployments.each do |d|
|
119
|
+
d.app_ids.each do |a|
|
120
|
+
unless @apps[a].nil?
|
121
|
+
app = @apps[a]
|
122
|
+
app.additional_mappings = d.additional_mappings
|
123
|
+
app.unique_name = d.unique_name(app)
|
124
|
+
app.smoke_test_path = d.smoke_test_path
|
125
|
+
yield app, d
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'conan/application'
|
2
|
+
class RailsZipApp < Application
|
3
|
+
attr_accessor :sha1, :artifact_repo
|
4
|
+
|
5
|
+
def initialize(id, project_name, artifact_repo, options, url_segment=nil)
|
6
|
+
super(id, project_name, :rails_zip, options, url_segment)
|
7
|
+
@sha1 = nil
|
8
|
+
@artifact_repo = artifact_repo
|
9
|
+
end
|
10
|
+
end
|
data/lib/conan/stackato.rb
CHANGED
@@ -3,13 +3,13 @@ require 'json'
|
|
3
3
|
|
4
4
|
class Stackato
|
5
5
|
|
6
|
+
@@paas_token_file = File.join(Dir.tmpdir(), "token_#{Time.now.to_i}")
|
7
|
+
|
6
8
|
def initialize(paas_user, paas_password, trace=false, dry_run=false)
|
7
9
|
@paas_user = paas_user
|
8
10
|
@paas_password = paas_password
|
9
11
|
@doit = dry_run ? "echo " : ""
|
10
12
|
@trace = trace ? "--trace" : ""
|
11
|
-
random_str = (0...8).map { ('a'..'z').to_a[rand(26)] }.join
|
12
|
-
@paas_token_file = File.join(Dir.tmpdir(), "token_#{random_str}")
|
13
13
|
@paas_manifest = "stackato.yml"
|
14
14
|
end
|
15
15
|
|
@@ -17,16 +17,67 @@ class Stackato
|
|
17
17
|
# login only one time per target, and only one target at a time
|
18
18
|
if (@session != paas_target)
|
19
19
|
@session = paas_target
|
20
|
-
@paas_cmd = "stackato #{@trace} --target #{paas_target} --token-file #{
|
20
|
+
@paas_cmd = "stackato #{@trace} --target #{paas_target} --token-file #{@@paas_token_file}"
|
21
21
|
unless @paas_user.nil?
|
22
22
|
system( "#{@paas_cmd} login --user #{@paas_user} --password #{@paas_password}" ) or raise "Stackato login failed on #{paas_target}"
|
23
23
|
end
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
-
def
|
28
|
-
|
29
|
-
|
27
|
+
def self.static_login(options)
|
28
|
+
org = options[:'deploy-shipcloud'].split('-')[0]
|
29
|
+
infra = options[:'deploy-shipcloud'].split('-')[1]
|
30
|
+
`stackato --target https://api.paas.#{infra}.#{org}.mtnsatcloud.com --token-file #{@@paas_token_file}`
|
31
|
+
`stackato login --user #{options[:'paas-user']} --password #{options[:'paas-password']} --token-file #{@@paas_token_file}`
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.unmap(app, domain)
|
35
|
+
puts "[#{app.unique_name}] Unmapping #{domain}"
|
36
|
+
`stackato unmap #{app.unique_name} #{domain} --token-file #{@@paas_token_file}`
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.map(app, domain)
|
40
|
+
puts "[#{app.unique_name}] Mapping #{domain}"
|
41
|
+
`stackato map #{app.unique_name} #{domain} --token-file #{@@paas_token_file}`
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.stop(app)
|
45
|
+
puts "[#{app.unique_name}] Stopping"
|
46
|
+
`stackato stop #{app.unique_name} --token-file #{@@paas_token_file}`
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.delete(app)
|
50
|
+
puts "[#{app.unique_name}] Deleting"
|
51
|
+
`stackato delete #{app.unique_name} --token-file #{@@paas_token_file}`
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.bg_switch(app)
|
55
|
+
app.active_domains.each{ |domain| Stackato.map(app, domain) }
|
56
|
+
app.inactive_domains.each{ |domain| Stackato.unmap(app, domain) }
|
57
|
+
app.old_versions.each{ |old_app| old_app.active_domains.each { |domain| Stackato.unmap(old_app, domain) } }
|
58
|
+
app.old_versions.each{ |old_app| old_app.inactive_domains.each { |domain| Stackato.map(old_app, domain) } }
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.bg_clean(app)
|
62
|
+
app.old_versions.each { |old_app| Stackato.stop(old_app) }
|
63
|
+
app.old_versions.each { |old_app| Stackato.delete(old_app) }
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.find_old_versions(newly_deployed_app)
|
67
|
+
old_apps = []
|
68
|
+
JSON.parse(`stackato apps --json --token-file #{@@paas_token_file}`).map do |app|
|
69
|
+
if /#{Regexp.escape(newly_deployed_app.stackato_base_name)}/ =~ app["name"] and app["name"] != newly_deployed_app.unique_name
|
70
|
+
old_app = newly_deployed_app.clone
|
71
|
+
old_app.unique_name = app["name"]
|
72
|
+
old_apps << old_app
|
73
|
+
end
|
74
|
+
end
|
75
|
+
old_apps
|
76
|
+
end
|
77
|
+
|
78
|
+
def deploy(work_dir, app, deployment, force=false)
|
79
|
+
puts ''
|
80
|
+
Dir.chdir(work_dir){
|
30
81
|
login(deployment.paas_target)
|
31
82
|
|
32
83
|
paas_app_name = deployment.name(app)
|
@@ -44,7 +95,7 @@ class Stackato
|
|
44
95
|
stats_status = `#{@paas_cmd} stats #{paas_app_name} 2>&1 >/dev/null`
|
45
96
|
puts stats_status
|
46
97
|
raise ScriptError, "Stackato authorization failure. Provide user and password" if (stats_status =~ /Not Authorized/)
|
47
|
-
|
98
|
+
|
48
99
|
# print out the stackato.yml for posterity
|
49
100
|
puts '------------------------------------------------------------------------------'
|
50
101
|
|
@@ -82,19 +133,22 @@ class Stackato
|
|
82
133
|
login(deployment.paas_target)
|
83
134
|
|
84
135
|
app_info = application_info(app, deployment)
|
85
|
-
|
136
|
+
unless app_info.inactive_app_name.nil?
|
137
|
+
puts "inactive app [#{deployment.name(app)}]. Deleting it."
|
138
|
+
`stackato delete #{deployment.name(app)}`
|
139
|
+
end
|
86
140
|
|
87
|
-
puts "Deploying inactive app #{deployment.name(app)}"
|
141
|
+
puts "Deploying inactive app #{deployment.name(app)}"
|
88
142
|
c = "#{@doit} #{@paas_cmd} --manifest #{@paas_manifest} --no-prompt push"
|
89
143
|
system(c) or raise "Stackato push failed: #{c}"
|
90
144
|
}
|
91
|
-
end
|
145
|
+
end
|
92
146
|
|
93
147
|
def bg_switch(app, deployment)
|
94
148
|
login(deployment.paas_target)
|
95
149
|
|
96
150
|
app_info = application_info(app, deployment)
|
97
|
-
|
151
|
+
|
98
152
|
if app_info.inactive_app_name.nil?
|
99
153
|
puts "No inactive app to switch to."
|
100
154
|
return
|
data/lib/conan/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
module Conan
|
2
|
-
VERSION = "0.0.
|
3
|
-
end
|
2
|
+
VERSION = "0.0.12"
|
3
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: conan_deploy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.12
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
7
|
authors:
|
7
8
|
- Mike Reardon
|
@@ -9,11 +10,12 @@ authors:
|
|
9
10
|
autorequire:
|
10
11
|
bindir: bin
|
11
12
|
cert_chain: []
|
12
|
-
date: 2014-
|
13
|
+
date: 2014-06-06 00:00:00.000000000 Z
|
13
14
|
dependencies:
|
14
15
|
- !ruby/object:Gem::Dependency
|
15
16
|
name: daphne_util
|
16
17
|
requirement: !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
17
19
|
requirements:
|
18
20
|
- - '='
|
19
21
|
- !ruby/object:Gem::Version
|
@@ -21,6 +23,7 @@ dependencies:
|
|
21
23
|
type: :runtime
|
22
24
|
prerelease: false
|
23
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
24
27
|
requirements:
|
25
28
|
- - '='
|
26
29
|
- !ruby/object:Gem::Version
|
@@ -32,39 +35,48 @@ executables:
|
|
32
35
|
extensions: []
|
33
36
|
extra_rdoc_files: []
|
34
37
|
files:
|
35
|
-
- README.md
|
36
38
|
- bin/conan
|
39
|
+
- lib/conan/application.rb
|
37
40
|
- lib/conan/application_helper.rb
|
38
41
|
- lib/conan/deploy.rb
|
42
|
+
- lib/conan/deployment.rb
|
43
|
+
- lib/conan/environment.rb
|
44
|
+
- lib/conan/has_options.rb
|
45
|
+
- lib/conan/jvm_app.rb
|
46
|
+
- lib/conan/manifest.rb
|
39
47
|
- lib/conan/manifest_builder.rb
|
40
48
|
- lib/conan/newrelic.rb
|
41
49
|
- lib/conan/options.rb
|
42
50
|
- lib/conan/output.rb
|
51
|
+
- lib/conan/pipeline.rb
|
52
|
+
- lib/conan/rails_zip_app.rb
|
43
53
|
- lib/conan/repository.rb
|
44
54
|
- lib/conan/stackato.rb
|
45
55
|
- lib/conan/templates.rb
|
46
56
|
- lib/conan/version.rb
|
57
|
+
- README.md
|
47
58
|
homepage: http://github.com/MTNSatelliteComm/conan/README.md
|
48
59
|
licenses: []
|
49
|
-
metadata: {}
|
50
60
|
post_install_message:
|
51
61
|
rdoc_options: []
|
52
62
|
require_paths:
|
53
63
|
- lib
|
54
64
|
required_ruby_version: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
55
66
|
requirements:
|
56
67
|
- - ! '>='
|
57
68
|
- !ruby/object:Gem::Version
|
58
69
|
version: '0'
|
59
70
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
71
|
+
none: false
|
60
72
|
requirements:
|
61
73
|
- - ! '>='
|
62
74
|
- !ruby/object:Gem::Version
|
63
75
|
version: '0'
|
64
76
|
requirements: []
|
65
77
|
rubyforge_project:
|
66
|
-
rubygems_version:
|
78
|
+
rubygems_version: 1.8.23
|
67
79
|
signing_key:
|
68
|
-
specification_version:
|
80
|
+
specification_version: 3
|
69
81
|
summary: Conan da Deployer
|
70
82
|
test_files: []
|