epc 1.0.2
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.
- data/CHANGELOG +1 -0
- data/Gemfile +22 -0
- data/Rakefile +67 -0
- data/Rakefile.gem +1 -0
- data/bin/epc +10 -0
- data/lib/epc.rb +126 -0
- data/lib/epc/client/base_client.rb +80 -0
- data/lib/epc/client/http_client.rb +19 -0
- data/lib/epc/client/json_client.rb +48 -0
- data/lib/epc/command/archive_project_command.rb +24 -0
- data/lib/epc/command/archive_solution_command.rb +21 -0
- data/lib/epc/command/attach_library_command.rb +82 -0
- data/lib/epc/command/attach_libraryset_command.rb +32 -0
- data/lib/epc/command/attach_runtime_command.rb +27 -0
- data/lib/epc/command/base_command.rb +451 -0
- data/lib/epc/command/bind_service_command.rb +35 -0
- data/lib/epc/command/build_command.rb +83 -0
- data/lib/epc/command/config/create_config_command.rb +55 -0
- data/lib/epc/command/copy_deployment_command.rb +21 -0
- data/lib/epc/command/create_command.rb +13 -0
- data/lib/epc/command/create_dependency_command.rb +43 -0
- data/lib/epc/command/define_service_command.rb +37 -0
- data/lib/epc/command/delete_config_command.rb +63 -0
- data/lib/epc/command/delete_dependency_command.rb +40 -0
- data/lib/epc/command/delete_group_command.rb +40 -0
- data/lib/epc/command/delete_library_command.rb +30 -0
- data/lib/epc/command/delete_librarylanguage_command.rb +40 -0
- data/lib/epc/command/delete_libraryset_command.rb +40 -0
- data/lib/epc/command/delete_project_command.rb +54 -0
- data/lib/epc/command/delete_role_command.rb +25 -0
- data/lib/epc/command/delete_serviceversion_command.rb +52 -0
- data/lib/epc/command/delete_solution_command.rb +39 -0
- data/lib/epc/command/delete_user_command.rb +31 -0
- data/lib/epc/command/deploy_command.rb +142 -0
- data/lib/epc/command/deployment/create_deployment_command.rb +82 -0
- data/lib/epc/command/detach_library_command.rb +35 -0
- data/lib/epc/command/detach_libraryset_command.rb +8 -0
- data/lib/epc/command/group/create_group_command.rb +21 -0
- data/lib/epc/command/info_command.rb +11 -0
- data/lib/epc/command/library/create_library_command.rb +45 -0
- data/lib/epc/command/librarylanguage/create_librarylanguage_command.rb +24 -0
- data/lib/epc/command/libraryset/create_libraryset_command.rb +54 -0
- data/lib/epc/command/list_approvals_command.rb +27 -0
- data/lib/epc/command/list_attachedlibraries_command.rb +42 -0
- data/lib/epc/command/list_boundservices_command.rb +40 -0
- data/lib/epc/command/list_config_command.rb +60 -0
- data/lib/epc/command/list_dependencies_command.rb +43 -0
- data/lib/epc/command/list_deployments_command.rb +68 -0
- data/lib/epc/command/list_groups_command.rb +19 -0
- data/lib/epc/command/list_libraries_command.rb +19 -0
- data/lib/epc/command/list_librarylanguages_command.rb +19 -0
- data/lib/epc/command/list_librarysets_command.rb +26 -0
- data/lib/epc/command/list_objectroles_command.rb +25 -0
- data/lib/epc/command/list_objecttypes_command.rb +20 -0
- data/lib/epc/command/list_permissiongroups_command.rb +20 -0
- data/lib/epc/command/list_projects_command.rb +36 -0
- data/lib/epc/command/list_projecttypes_command.rb +20 -0
- data/lib/epc/command/list_rolepermissions_command.rb +21 -0
- data/lib/epc/command/list_roles_command.rb +26 -0
- data/lib/epc/command/list_runtimes_command.rb +16 -0
- data/lib/epc/command/list_service_types_command.rb +19 -0
- data/lib/epc/command/list_servicedefinitions_command.rb +19 -0
- data/lib/epc/command/list_serviceversions_command.rb +21 -0
- data/lib/epc/command/list_solutions_command.rb +25 -0
- data/lib/epc/command/list_stages_command.rb +21 -0
- data/lib/epc/command/list_users_command.rb +26 -0
- data/lib/epc/command/list_versions_command.rb +39 -0
- data/lib/epc/command/login_command.rb +32 -0
- data/lib/epc/command/logout_command.rb +20 -0
- data/lib/epc/command/objectrole/create_objectrole_command.rb +19 -0
- data/lib/epc/command/project/create_project_command.rb +78 -0
- data/lib/epc/command/pull_command.rb +209 -0
- data/lib/epc/command/push_command.rb +194 -0
- data/lib/epc/command/refresh_solution_command.rb +71 -0
- data/lib/epc/command/renew_command.rb +19 -0
- data/lib/epc/command/request_passwordchange_command.rb +23 -0
- data/lib/epc/command/role/create_role_command.rb +17 -0
- data/lib/epc/command/serviceversion/create_serviceversion_command.rb +33 -0
- data/lib/epc/command/show_deployment_command.rb +57 -0
- data/lib/epc/command/show_group_command.rb +35 -0
- data/lib/epc/command/show_libraryset_command.rb +54 -0
- data/lib/epc/command/show_project_command.rb +74 -0
- data/lib/epc/command/show_projecttype_command.rb +18 -0
- data/lib/epc/command/show_role_command.rb +46 -0
- data/lib/epc/command/show_solution_command.rb +54 -0
- data/lib/epc/command/show_user_command.rb +42 -0
- data/lib/epc/command/solution/create_solution_command.rb +34 -0
- data/lib/epc/command/solution/list_solutions_command.rb +25 -0
- data/lib/epc/command/solution/update_solution_command.rb +43 -0
- data/lib/epc/command/submit_deployment_command.rb +19 -0
- data/lib/epc/command/target_command.rb +26 -0
- data/lib/epc/command/unarchive_project_command.rb +23 -0
- data/lib/epc/command/unarchive_solution_command.rb +21 -0
- data/lib/epc/command/unbind_service_command.rb +42 -0
- data/lib/epc/command/undefine_service_command.rb +33 -0
- data/lib/epc/command/undeploy_command.rb +106 -0
- data/lib/epc/command/update_config_command.rb +62 -0
- data/lib/epc/command/update_deploymentproject_command.rb +54 -0
- data/lib/epc/command/update_group_command.rb +43 -0
- data/lib/epc/command/update_librarylanguage_command.rb +28 -0
- data/lib/epc/command/update_libraryset_command.rb +80 -0
- data/lib/epc/command/update_project_command.rb +49 -0
- data/lib/epc/command/update_role_command.rb +47 -0
- data/lib/epc/command/update_rolepermissions_command.rb +83 -0
- data/lib/epc/command/update_solution_command.rb +45 -0
- data/lib/epc/command/update_user_command.rb +57 -0
- data/lib/epc/command/user/create_user_command.rb +27 -0
- data/lib/epc/command/vote_deployment_command.rb +29 -0
- data/lib/epc/config.rb +245 -0
- data/lib/epc/error/basic_error.rb +6 -0
- data/lib/epc/error/fatal_error.rb +6 -0
- data/lib/epc/error/input_error.rb +6 -0
- data/lib/epc/error/internal_error.rb +6 -0
- data/lib/epc/help.rb +292 -0
- data/lib/epc/persistent_attributes.rb +18 -0
- data/lib/epc/runner.rb +177 -0
- data/lib/epc/tabular_outputter.rb +161 -0
- data/lib/epc/version.rb +3 -0
- data/lib/fixnum.rb +9 -0
- data/lib/object.rb +13 -0
- data/test/command/archive_project_command_test.rb +41 -0
- data/test/command/archive_solution_command_test.rb +40 -0
- data/test/command/attach_library_command_test.rb +124 -0
- data/test/command/attach_libraryset_command_test.rb +49 -0
- data/test/command/attach_runtime_command_test.rb +44 -0
- data/test/command/base_command_test.rb +276 -0
- data/test/command/bind_service_command_test.rb +46 -0
- data/test/command/build_command_test.rb +103 -0
- data/test/command/copy_deployment_command_test.rb +38 -0
- data/test/command/create_config_command_test.rb +124 -0
- data/test/command/create_dependency_command_test.rb +55 -0
- data/test/command/create_deployment_command_test.rb +136 -0
- data/test/command/create_group_command_test.rb +34 -0
- data/test/command/create_library_command_test.rb +61 -0
- data/test/command/create_librarylanguage_command_test.rb +51 -0
- data/test/command/create_libraryset_command_test.rb +81 -0
- data/test/command/create_objectrole_command_test.rb +37 -0
- data/test/command/create_project_command_test.rb +102 -0
- data/test/command/create_role_command_test.rb +31 -0
- data/test/command/create_serviceversion_command_test.rb +60 -0
- data/test/command/create_solution_command_test.rb +70 -0
- data/test/command/create_user_command_test.rb +54 -0
- data/test/command/define_service_command_test.rb +55 -0
- data/test/command/delete_config_command_test.rb +82 -0
- data/test/command/delete_dependency_command_test.rb +50 -0
- data/test/command/delete_group_command_test.rb +56 -0
- data/test/command/delete_library_command_test.rb +43 -0
- data/test/command/delete_librarylanguage_command_test.rb +55 -0
- data/test/command/delete_libraryset_command_test.rb +55 -0
- data/test/command/delete_project_command_test.rb +76 -0
- data/test/command/delete_role_command_test.rb +41 -0
- data/test/command/delete_serviceversion_command_test.rb +53 -0
- data/test/command/delete_solution_command_test.rb +79 -0
- data/test/command/delete_user_command_test.rb +56 -0
- data/test/command/deploy_command_test.rb +185 -0
- data/test/command/detach_library_command_test.rb +53 -0
- data/test/command/info_command_test.rb +17 -0
- data/test/command/list_approvals_command_test.rb +41 -0
- data/test/command/list_boundservices_command_test.rb +46 -0
- data/test/command/list_config_command_test.rb +72 -0
- data/test/command/list_dependencies_command_test.rb +46 -0
- data/test/command/list_deployments_command_test.rb +112 -0
- data/test/command/list_deploymentstages_command_test.rb +44 -0
- data/test/command/list_libraries_command_test.rb +42 -0
- data/test/command/list_librarylanguages_command_test.rb +34 -0
- data/test/command/list_librarysets_command_test.rb +33 -0
- data/test/command/list_objectroles_command_test.rb +41 -0
- data/test/command/list_objecttypes_command_test.rb +25 -0
- data/test/command/list_permissiongroups_command_test.rb +25 -0
- data/test/command/list_projects_command_test.rb +63 -0
- data/test/command/list_projecttypes_command_test.rb +39 -0
- data/test/command/list_rolepermissions_command_test.rb +39 -0
- data/test/command/list_roles_command_test.rb +46 -0
- data/test/command/list_runtimes_command_test.rb +30 -0
- data/test/command/list_service_types_command_test.rb +44 -0
- data/test/command/list_servicedefinitions_command_test.rb +44 -0
- data/test/command/list_serviceversions_command_test.rb +47 -0
- data/test/command/list_solutions_command_test.rb +48 -0
- data/test/command/list_users_command_test.rb +33 -0
- data/test/command/login_command_test.rb +83 -0
- data/test/command/logout_command_test.rb +30 -0
- data/test/command/pull_command_test.rb +229 -0
- data/test/command/push_command_test.rb +246 -0
- data/test/command/refresh_solution_command_test.rb +35 -0
- data/test/command/renew_command_test.rb +43 -0
- data/test/command/request_passwordchange_command_test.rb +31 -0
- data/test/command/show_group_command_test.rb +50 -0
- data/test/command/show_libraryset_command_test.rb +51 -0
- data/test/command/show_project_command_test.rb +57 -0
- data/test/command/show_projecttype_command_test.rb +46 -0
- data/test/command/show_role_command_test.rb +37 -0
- data/test/command/show_solution_command_test.rb +59 -0
- data/test/command/show_user_command_test.rb +50 -0
- data/test/command/submit_deployment_command_test.rb +37 -0
- data/test/command/target_command_test.rb +58 -0
- data/test/command/unarchive_project_command_test.rb +45 -0
- data/test/command/unarchive_solution_command_test.rb +43 -0
- data/test/command/unbind_service_command_test.rb +48 -0
- data/test/command/undefine_service_command_test.rb +49 -0
- data/test/command/update_config_command_test.rb +74 -0
- data/test/command/update_deploymentproject_command_test.rb +77 -0
- data/test/command/update_group_command_test.rb +69 -0
- data/test/command/update_librarylanguage_command_test.rb +43 -0
- data/test/command/update_libraryset_command_test.rb +113 -0
- data/test/command/update_project_command_test.rb +56 -0
- data/test/command/update_role_command_test.rb +42 -0
- data/test/command/update_rolepermissions_command_test.rb +54 -0
- data/test/command/update_solution_command_test.rb +58 -0
- data/test/command/update_user_command_test.rb +76 -0
- data/test/command/vote_deployment_command_test.rb +33 -0
- data/test/config_test.rb +70 -0
- data/test/successful_test.rb +21 -0
- data/test/test_files/pom.xml +273 -0
- data/test/test_helper.rb +25 -0
- metadata +470 -0
@@ -0,0 +1,32 @@
|
|
1
|
+
module EPC::Command
|
2
|
+
class LoginCommand < BaseCommand
|
3
|
+
|
4
|
+
dont_require_login
|
5
|
+
|
6
|
+
def execute(email = nil)
|
7
|
+
if blank?(email)
|
8
|
+
say("You must supply an email address")
|
9
|
+
return 1
|
10
|
+
end
|
11
|
+
|
12
|
+
password = options[:password]
|
13
|
+
password = ask("Password: ") { |q| q.echo = '*' } unless password
|
14
|
+
|
15
|
+
begin
|
16
|
+
status, response, headers = client.post("#{EPC::Config::TOKENS_PATH}/retrieve", { :email => email, :password => password }, true)
|
17
|
+
if status.successful? && response
|
18
|
+
EPC::Config.store_caller_id(response[:caller_id])
|
19
|
+
EPC::Config.store_auth_token(response[:authentication_token])
|
20
|
+
EPC::Config.store_username(email)
|
21
|
+
say("Successfully logged into [#{target_url}]")
|
22
|
+
elsif response
|
23
|
+
say("Login failed [#{response[:message]}]. Please make sure you entered the correct email and password.")
|
24
|
+
end
|
25
|
+
return status
|
26
|
+
rescue Exception => ex
|
27
|
+
say("Login failed [#{ex}].")
|
28
|
+
return 1
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module EPC::Command
|
2
|
+
class LogoutCommand < BaseCommand
|
3
|
+
def execute
|
4
|
+
|
5
|
+
begin
|
6
|
+
if EPC::Config.remove_auth_token
|
7
|
+
EPC::Config.remove_username
|
8
|
+
say("Successfully logged out of [#{target_url}]")
|
9
|
+
return 0
|
10
|
+
else
|
11
|
+
say("Logout failed [#{response[:message]}]. Please try again later.")
|
12
|
+
return 1
|
13
|
+
end
|
14
|
+
rescue Exception => ex
|
15
|
+
say("Logout failed [#{ex}].")
|
16
|
+
return 1
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module EPC::Command
|
2
|
+
class CreateObjectroleCommand < BaseCommand
|
3
|
+
def execute(*params)
|
4
|
+
obj_type, obj_id = params[0].split(":") rescue [nil, nil]
|
5
|
+
name = params[1]
|
6
|
+
|
7
|
+
raise FatalError, "Parameters incorrectly specified" if obj_type.blank? || obj_id.blank? || name.blank?
|
8
|
+
|
9
|
+
status, response, headers = client.post(EPC::Config::ROLES_PATH, {:name => name, :owner_type => obj_type, :owner_id => obj_id})
|
10
|
+
|
11
|
+
if status.successful?
|
12
|
+
say("Role [#{name}] created")
|
13
|
+
else
|
14
|
+
say("Request failed: [#{response[:message]}]")
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module EPC::Command
|
2
|
+
class CreateProjectCommand < BaseCommand
|
3
|
+
def execute(*params)
|
4
|
+
|
5
|
+
target_type, target_id = params.first.split(":") rescue [nil, nil]
|
6
|
+
project_name = params[1]
|
7
|
+
uri_name = params[2]
|
8
|
+
|
9
|
+
raise FatalError, "You have to specify a project name to run this command" if project_name.blank?
|
10
|
+
raise InputError, "Target type must be: [Solution]" if target_type.present? && target_type.downcase != "solution"
|
11
|
+
|
12
|
+
if numeric?(@options[:type])
|
13
|
+
type_id = @options[:type].to_i
|
14
|
+
elsif @options[:type].present?
|
15
|
+
type_id = get_resource_id(EPC::Config::PROJECT_TYPES_PATH, :name, @options[:type], :case_sensitivity => false)
|
16
|
+
end
|
17
|
+
|
18
|
+
if type_id.blank? || type_id == 0
|
19
|
+
choose do |menu|
|
20
|
+
menu.prompt = "Please choose the project type: "
|
21
|
+
|
22
|
+
status, response, headers = client.get(EPC::Config::PROJECT_TYPES_PATH)
|
23
|
+
if status.failure?
|
24
|
+
say("Request failed: [#{response[:message]}")
|
25
|
+
return status
|
26
|
+
end
|
27
|
+
|
28
|
+
if response.empty?
|
29
|
+
say("No project types defined yet")
|
30
|
+
return status
|
31
|
+
end
|
32
|
+
|
33
|
+
response.each do |type|
|
34
|
+
menu.choice(type[:name]) { type_id = type[:id]}
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
path = File.expand_path(".")
|
41
|
+
|
42
|
+
solution_id, solution_name = infer_solution_context(target_id, path, :get_solution_name => true)
|
43
|
+
|
44
|
+
raise InputError, "Request failed: [Solution not found]" if solution_name.nil?
|
45
|
+
|
46
|
+
uri_name = project_name if uri_name.nil?
|
47
|
+
|
48
|
+
proceed = ask_yn("You are creating the '#{project_name}' project as part of the '#{solution_name}' solution. Correct? [Yn]: ")
|
49
|
+
if proceed.upcase == 'N'
|
50
|
+
return 1
|
51
|
+
end
|
52
|
+
|
53
|
+
begin
|
54
|
+
status, response, headers = client.post("#{EPC::Config::PROJECTS_PATH}",
|
55
|
+
{ :project_name => project_name, :solution_name => solution_name, :uri_name => uri_name, :project_type_id => type_id})
|
56
|
+
if status.successful?
|
57
|
+
if options[:nodir]
|
58
|
+
say("Successfully created the project with [#{target_url}]")
|
59
|
+
return status
|
60
|
+
end
|
61
|
+
result = mkdir(project_name)
|
62
|
+
if result == :ok
|
63
|
+
EPC::Config.write_project_metadata(response[:id], client)
|
64
|
+
say("Successfully created the project with [#{target_url}] and created your local directory.")
|
65
|
+
else
|
66
|
+
say("Successfully created the project with [#{target_url}], but FAILED to create your local directory.")
|
67
|
+
end
|
68
|
+
else
|
69
|
+
say("Project creation failed [#{response[:message]}].")
|
70
|
+
end
|
71
|
+
rescue Exception => ex
|
72
|
+
say("Project creation failed [#{ex}].")
|
73
|
+
return 1
|
74
|
+
end
|
75
|
+
return status
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,209 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'zip/zipfilesystem'
|
4
|
+
|
5
|
+
module EPC::Command
|
6
|
+
class PullCommand < BaseCommand
|
7
|
+
SLEEP_TIME = 1
|
8
|
+
|
9
|
+
# Numerators are in secs
|
10
|
+
TICKER_TICKS = 25/SLEEP_TIME
|
11
|
+
GIVEUP_TICKS = 120/SLEEP_TIME
|
12
|
+
|
13
|
+
def execute(solution_name = nil)
|
14
|
+
first_time_pull = false
|
15
|
+
|
16
|
+
path = File.expand_path(".")
|
17
|
+
create_dir = false
|
18
|
+
|
19
|
+
if numeric?(solution_name)
|
20
|
+
solution_name = get_resource_name(EPC::Config::SOLUTIONS_PATH, :id, solution_name)
|
21
|
+
end
|
22
|
+
|
23
|
+
if !EPC::Config.is_solution_dir?(path) && !EPC::Config.is_project_dir?(path)
|
24
|
+
if solution_name.nil?
|
25
|
+
raise FatalError, "Solution could not be inferred"
|
26
|
+
else
|
27
|
+
create_dir = true
|
28
|
+
first_time_pull = true
|
29
|
+
end
|
30
|
+
elsif EPC::Config.is_project_dir?(path)
|
31
|
+
path = File.join(path, "..")
|
32
|
+
end
|
33
|
+
|
34
|
+
return unless check_pull_directory(project_solution_path(path))
|
35
|
+
|
36
|
+
solution_name = EPC::Config.get_solution_value(project_solution_path(path), "name") if solution_name.nil?
|
37
|
+
|
38
|
+
proceed = ask_yn("You are pulling the '#{solution_name}' solution. Correct? [Yn]: ")
|
39
|
+
if proceed.upcase == 'N'
|
40
|
+
return 1
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
begin
|
45
|
+
status, id = create_pull(solution_name)
|
46
|
+
if status.successful?
|
47
|
+
say("Pulling - ")
|
48
|
+
shown, url = poll_for_pull_url(id)
|
49
|
+
if shown
|
50
|
+
tmpdir = Dir.tmpdir
|
51
|
+
pulled, zip_path = pull_zip(url, tmpdir)
|
52
|
+
if pulled
|
53
|
+
if create_dir
|
54
|
+
return 1 unless prep_solution_directory(path, solution_name)
|
55
|
+
path = File.join(path, solution_name)
|
56
|
+
end
|
57
|
+
unzip_solution(zip_path, path)
|
58
|
+
confirm_pull(id)
|
59
|
+
refresh_command = EPC::Command::RefreshSolutionCommand.new(client, @options)
|
60
|
+
refresh_command.options[:prompt_refresh] = false if first_time_pull
|
61
|
+
refresh_command.execute(path)
|
62
|
+
return 0
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
rescue Exception => ex
|
67
|
+
say("Pull failed [#{ex.to_s}].")
|
68
|
+
end
|
69
|
+
return 1
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def create_pull(solution_name)
|
75
|
+
status, response, headers = client.post("#{EPC::Config::PULLS_PATH}", { :solution_name => solution_name })
|
76
|
+
if status.successful?
|
77
|
+
say("Successfully created a pull with [#{target_url}]")
|
78
|
+
return status, response[:id]
|
79
|
+
else
|
80
|
+
raise Exception, response[:message]
|
81
|
+
return status
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def confirm_pull(id)
|
86
|
+
status, response, headers = client.put("#{EPC::Config::PULLS_PATH}/#{id}/confirm", { :pulled => 'yes' })
|
87
|
+
if status.successful?
|
88
|
+
say("Successfully confirmed the pull with [#{target_url}]")
|
89
|
+
true
|
90
|
+
else
|
91
|
+
say("Pull confirmation failed [#{response[:message]}].")
|
92
|
+
false
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def sign_pull(id)
|
97
|
+
status, response, headers = client.put("#{EPC::Config::PULLS_PATH}/#{id}/sign")
|
98
|
+
if status.successful?
|
99
|
+
return status, nil, response[:signed_url]
|
100
|
+
else
|
101
|
+
return status, response[:error_code], nil
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def prep_solution_directory(path, solution_name)
|
106
|
+
solution_id = get_resource_id(EPC::Config::SOLUTIONS_PATH, :name, solution_name)
|
107
|
+
if solution_id.nil?
|
108
|
+
say("Solution not found")
|
109
|
+
return false
|
110
|
+
end
|
111
|
+
|
112
|
+
begin
|
113
|
+
Dir.mkdir(File.join(path, solution_name))
|
114
|
+
rescue Exception => ex
|
115
|
+
say(ex.to_s)
|
116
|
+
return false
|
117
|
+
end
|
118
|
+
|
119
|
+
begin
|
120
|
+
File.open(File.join(path, solution_name, ".epc_solution"), 'w') do |f|
|
121
|
+
f.write({:id => solution_id, :name => solution_name}.to_json)
|
122
|
+
end
|
123
|
+
rescue Exception => ex
|
124
|
+
say(ex.to_s)
|
125
|
+
return false
|
126
|
+
end
|
127
|
+
return true
|
128
|
+
end
|
129
|
+
|
130
|
+
def poll_for_pull_url(id)
|
131
|
+
count = 0
|
132
|
+
failed = false
|
133
|
+
|
134
|
+
while count <= GIVEUP_TICKS
|
135
|
+
unless count > TICKER_TICKS
|
136
|
+
STDOUT.print('.')
|
137
|
+
STDOUT.flush
|
138
|
+
end
|
139
|
+
sleep(SLEEP_TIME)
|
140
|
+
|
141
|
+
status, code, url = sign_pull(id)
|
142
|
+
if status.successful? || (status == 404 && code == 801)
|
143
|
+
count += 1
|
144
|
+
next if url.nil? || url.empty?
|
145
|
+
break
|
146
|
+
else
|
147
|
+
say("Poller failed to get the pull URL. Aborting.")
|
148
|
+
failed = true
|
149
|
+
break
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
|
154
|
+
if url
|
155
|
+
[true, url]
|
156
|
+
elsif failed
|
157
|
+
[false, nil]
|
158
|
+
else
|
159
|
+
if count > GIVEUP_TICKS
|
160
|
+
say("\nServer is taking too long to update the pull URL. Please contact the AgileMethods support team.")
|
161
|
+
end
|
162
|
+
[false, nil]
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def check_pull_directory(path)
|
167
|
+
unless File.exists?(path)
|
168
|
+
say("Pull path does not exist")
|
169
|
+
return false
|
170
|
+
end
|
171
|
+
|
172
|
+
unless File.directory?(path)
|
173
|
+
say("Pull path is not a directory")
|
174
|
+
return false
|
175
|
+
end
|
176
|
+
return true
|
177
|
+
end
|
178
|
+
|
179
|
+
def pull_zip(url, path)
|
180
|
+
status, response, headers = http_client.get(url)
|
181
|
+
if status.successful?
|
182
|
+
say("Successfully pulled the zip file from the build repository")
|
183
|
+
|
184
|
+
zip_path = File.join(path, "pulled#{rand(9999)}.zip")
|
185
|
+
open(zip_path, "wb") { |io| io.write(response) }
|
186
|
+
[true, zip_path]
|
187
|
+
else
|
188
|
+
say("Failed to pull the zip file from the build repository [status = #{status}]. Aborting pull command.")
|
189
|
+
[false, nil]
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
def unzip_solution(zip_path, solution_path)
|
194
|
+
Zip::ZipFile.foreach(zip_path) do |entry|
|
195
|
+
file_path = File.join(solution_path, entry.to_s)
|
196
|
+
FileUtils.mkdir_p File.dirname(file_path)
|
197
|
+
if entry.file?
|
198
|
+
FileUtils.rm(file_path) if File.exists?(file_path)
|
199
|
+
entry.extract(file_path)
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
say("Solution skeleton has been extracted to #{solution_path}")
|
204
|
+
|
205
|
+
ensure File.delete zip_path if File.exists? zip_path
|
206
|
+
end
|
207
|
+
|
208
|
+
end
|
209
|
+
end
|
@@ -0,0 +1,194 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'digest/sha1'
|
3
|
+
require 'fileutils'
|
4
|
+
require 'find'
|
5
|
+
require 'pathname'
|
6
|
+
require 'zip/zipfilesystem'
|
7
|
+
|
8
|
+
module EPC::Command
|
9
|
+
class PushCommand < BaseCommand
|
10
|
+
ZIP_DIR_EXCLUDES = %w(target)
|
11
|
+
ZIP_FILE_EXCLUDES = %w(pom.xml)
|
12
|
+
ZIP_EXT_EXCLUDES = ['.class', '.jar']
|
13
|
+
|
14
|
+
def execute(project_name = nil)
|
15
|
+
path = "."
|
16
|
+
path = File.expand_path(path)
|
17
|
+
|
18
|
+
|
19
|
+
if @options[:no_poll].present? && @options[:timeout].present?
|
20
|
+
raise InputError, "You cannot specify both --nopoll and --timeout options at the same time"
|
21
|
+
end
|
22
|
+
|
23
|
+
@timeout = GIVEUP_TICKS
|
24
|
+
parse_timeout_value
|
25
|
+
|
26
|
+
solution_id, solution_name = infer_solution_context(nil, path)
|
27
|
+
|
28
|
+
raise FatalError, "Solution could not be inferred" if solution_id.nil?
|
29
|
+
|
30
|
+
if EPC::Config.is_solution_dir?(path)
|
31
|
+
if project_name.nil?
|
32
|
+
proceed = ask_yn("You are pushing the [#{solution_name}] solution. Correct: [Yn]? ")
|
33
|
+
paths = Dir.glob(path +"/*/").select{|dir| EPC::Config.is_project_dir?(dir)}
|
34
|
+
else
|
35
|
+
project_id, p_name = infer_project_context(project_name, path, solution_id, {:get_project_name => true})
|
36
|
+
raise FatalError, "Project not found. Please run this command with the correct project name." if !project_name.nil? && (p_name.nil? || p_name.empty?)
|
37
|
+
proceed = ask_yn("You are pushing the [#{p_name}] project belonging to the [#{solution_name}] solution. Correct: [Yn]? ")
|
38
|
+
paths = [path + "/#{project_name}"]
|
39
|
+
end
|
40
|
+
elsif EPC::Config.is_project_dir?(path)
|
41
|
+
project_id, project_name = infer_project_context(p_name, path, solution_id, false)
|
42
|
+
raise FatalError if project_id.nil?
|
43
|
+
proceed = ask_yn("You are pushing the [#{project_name}] project belonging to the [#{solution_name}] solution. Correct: [Yn]? ")
|
44
|
+
paths = [path]
|
45
|
+
else
|
46
|
+
say("This command must be run from a solution/project directory")
|
47
|
+
return 1
|
48
|
+
end
|
49
|
+
|
50
|
+
if (proceed.upcase == "N" rescue true )
|
51
|
+
return 1
|
52
|
+
end
|
53
|
+
|
54
|
+
raise FatalError, "Nothing to push" if paths.empty?
|
55
|
+
|
56
|
+
@versions = []
|
57
|
+
paths.each do |path|
|
58
|
+
project_id, project_name = infer_project_context(nil, path, solution_id, {:get_project_name => true})
|
59
|
+
say("\nPushing #{project_name}...")
|
60
|
+
begin
|
61
|
+
zip_path = zip_source(path)
|
62
|
+
return 1 unless zip_path
|
63
|
+
sha1 = sha1(zip_path)
|
64
|
+
status, url, signature, id = create_push(project_name, solution_name, sha1, @options[:note])
|
65
|
+
if status.successful?
|
66
|
+
pushed = push_zip(zip_path, url, signature)
|
67
|
+
resp = confirm_push(id)
|
68
|
+
if resp[:build_id].present? && !@options[:skip_build]
|
69
|
+
poll_for_build_status(resp[:build_id]) unless @options[:no_poll].present?
|
70
|
+
end
|
71
|
+
@versions << {project_name => resp[:project_version]} if pushed
|
72
|
+
else
|
73
|
+
return 1
|
74
|
+
end
|
75
|
+
rescue Exception => ex
|
76
|
+
say("Push failed [#{ex}].")
|
77
|
+
return 1
|
78
|
+
end
|
79
|
+
end
|
80
|
+
return 0
|
81
|
+
end
|
82
|
+
|
83
|
+
def execute_internal
|
84
|
+
code = execute
|
85
|
+
return code, @versions
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
def create_push(project_name, solution_name, sha1, note = nil)
|
91
|
+
status, response, headers = client.post("#{EPC::Config::PUSHES_PATH}",
|
92
|
+
{ :project_name => project_name, :solution_name => solution_name, :sha1 => sha1, :note => note})
|
93
|
+
if status.successful?
|
94
|
+
say("Successfully created a push with [#{target_url}]")
|
95
|
+
return status, response[:url], response[:signature], response[:id]
|
96
|
+
else
|
97
|
+
raise BasicError, "Push creation failed [#{response[:message]}]. Aborting push command."
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def confirm_push(id)
|
102
|
+
status, response, headers = client.put("#{EPC::Config::PUSHES_PATH}/#{id}/confirm", { :pushed => 'yes' })
|
103
|
+
if status.successful?
|
104
|
+
say("Successfully confirmed the push with [#{target_url}]")
|
105
|
+
response
|
106
|
+
else
|
107
|
+
say("Push confirmation failed [#{response[:message]}].")
|
108
|
+
nil
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def zip_source(path)
|
113
|
+
if check_push_directory(path)
|
114
|
+
tmpdir = Dir.tmpdir
|
115
|
+
zip_path = File.join(tmpdir, "#{rand(9999)}pushed.zip")
|
116
|
+
FileUtils.rm_f(zip_path) if File.exists?(zip_path)
|
117
|
+
Zip::ZipFile.open(zip_path, Zip::ZipFile::CREATE) { |zf|
|
118
|
+
full_paths, relative_paths = recurse_project_directory(path)
|
119
|
+
full_paths.each_index do |i|
|
120
|
+
zf.add(relative_paths[i], full_paths[i])
|
121
|
+
end
|
122
|
+
}
|
123
|
+
end
|
124
|
+
|
125
|
+
zip_path
|
126
|
+
end
|
127
|
+
|
128
|
+
def recurse_project_directory(projdir)
|
129
|
+
full_paths = Array.new
|
130
|
+
relative_paths = Array.new
|
131
|
+
toplevel = Pathname(projdir)
|
132
|
+
|
133
|
+
|
134
|
+
Find.find(projdir) { |path|
|
135
|
+
if File.directory?(path)
|
136
|
+
if ZIP_DIR_EXCLUDES.include?(File.basename(path.downcase))
|
137
|
+
Find.prune # skip this dir
|
138
|
+
else
|
139
|
+
full_paths << path
|
140
|
+
|
141
|
+
current = Pathname.new(path)
|
142
|
+
relative_paths << current.relative_path_from(toplevel)
|
143
|
+
end
|
144
|
+
else
|
145
|
+
current = Pathname.new(path)
|
146
|
+
relative_path = current.relative_path_from(toplevel)
|
147
|
+
|
148
|
+
unless ZIP_FILE_EXCLUDES.include?(File.basename(relative_path.to_s.downcase)) ||
|
149
|
+
(ZIP_EXT_EXCLUDES.include?(File.extname(relative_path.to_s.downcase)) && relative_path.to_s !~ /^lib/)
|
150
|
+
full_paths << path
|
151
|
+
relative_paths << relative_path.to_s
|
152
|
+
end
|
153
|
+
end
|
154
|
+
}
|
155
|
+
|
156
|
+
return full_paths, relative_paths
|
157
|
+
end
|
158
|
+
|
159
|
+
def push_zip(zip_path, url, signature)
|
160
|
+
# create API returns a URL that includes protocol://host/solution_name/project_name/version
|
161
|
+
|
162
|
+
status, response, headers = http_client.post(url,
|
163
|
+
{ :file => File.new(zip_path, "rb") }, nil, { 'X-AGILEMETHODS-SIGNATURE' => signature }, true)
|
164
|
+
if status.successful?
|
165
|
+
say("Successfully pushed the zip file to the build area")
|
166
|
+
true
|
167
|
+
else
|
168
|
+
raise BasicError, "Failed to push the zip file to the build area [status = #{status}]. Aborting push command."
|
169
|
+
end
|
170
|
+
|
171
|
+
ensure File.delete zip_path if File.exists? zip_path
|
172
|
+
end
|
173
|
+
|
174
|
+
def check_push_directory(path)
|
175
|
+
project_type = EPC::Config.get_project_value(path, "project_type")["name"] rescue ""
|
176
|
+
unless File.exists?(path)
|
177
|
+
say("#{path} does not exist")
|
178
|
+
return false
|
179
|
+
end
|
180
|
+
|
181
|
+
unless File.directory?(path)
|
182
|
+
say("#{path} is not a directory")
|
183
|
+
return false
|
184
|
+
end
|
185
|
+
|
186
|
+
if project_type == "Java Web Archive" || project_type == "Java Library"
|
187
|
+
src_path = File.join(path, "src")
|
188
|
+
raise BasicError, "#{path} does not include a src directory" if !File.exists?(src_path) && !File.directory?(src_path)
|
189
|
+
end
|
190
|
+
|
191
|
+
return true
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|