pantograph 0.1.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.
- checksums.yaml +7 -0
- data/.yardopts +1 -0
- data/LICENSE +21 -0
- data/README.md +197 -0
- data/bin/bin-proxy +19 -0
- data/bin/pantograph +23 -0
- data/pantograph/README.md +11 -0
- data/pantograph/lib/assets/ActionDetails.md.erb +106 -0
- data/pantograph/lib/assets/Actions.md.erb +43 -0
- data/pantograph/lib/assets/DefaultPantfileTemplate +20 -0
- data/pantograph/lib/assets/completions/completion.bash +23 -0
- data/pantograph/lib/assets/completions/completion.fish +39 -0
- data/pantograph/lib/assets/completions/completion.sh +12 -0
- data/pantograph/lib/assets/completions/completion.zsh +23 -0
- data/pantograph/lib/assets/custom_action_template.rb +80 -0
- data/pantograph/lib/assets/report_template.xml.erb +15 -0
- data/pantograph/lib/pantograph/action.rb +194 -0
- data/pantograph/lib/pantograph/action_collector.rb +35 -0
- data/pantograph/lib/pantograph/actions/README.md +3 -0
- data/pantograph/lib/pantograph/actions/actions_helper.rb +166 -0
- data/pantograph/lib/pantograph/actions/add_extra_platforms.rb +45 -0
- data/pantograph/lib/pantograph/actions/artifactory.rb +157 -0
- data/pantograph/lib/pantograph/actions/bundle_install.rb +156 -0
- data/pantograph/lib/pantograph/actions/changelog_from_git_commits.rb +197 -0
- data/pantograph/lib/pantograph/actions/clipboard.rb +52 -0
- data/pantograph/lib/pantograph/actions/cloc.rb +89 -0
- data/pantograph/lib/pantograph/actions/create_pull_request.rb +190 -0
- data/pantograph/lib/pantograph/actions/danger.rb +131 -0
- data/pantograph/lib/pantograph/actions/debug.rb +32 -0
- data/pantograph/lib/pantograph/actions/default_platform.rb +47 -0
- data/pantograph/lib/pantograph/actions/download.rb +76 -0
- data/pantograph/lib/pantograph/actions/echo.rb +14 -0
- data/pantograph/lib/pantograph/actions/ensure_bundle_exec.rb +59 -0
- data/pantograph/lib/pantograph/actions/ensure_env_vars.rb +58 -0
- data/pantograph/lib/pantograph/actions/ensure_git_branch.rb +69 -0
- data/pantograph/lib/pantograph/actions/ensure_git_status_clean.rb +81 -0
- data/pantograph/lib/pantograph/actions/erb.rb +88 -0
- data/pantograph/lib/pantograph/actions/get_build_number_repository.rb +120 -0
- data/pantograph/lib/pantograph/actions/get_github_release.rb +163 -0
- data/pantograph/lib/pantograph/actions/git_add.rb +93 -0
- data/pantograph/lib/pantograph/actions/git_branch.rb +58 -0
- data/pantograph/lib/pantograph/actions/git_commit.rb +80 -0
- data/pantograph/lib/pantograph/actions/git_pull.rb +53 -0
- data/pantograph/lib/pantograph/actions/git_submodule_update.rb +52 -0
- data/pantograph/lib/pantograph/actions/git_tag_exists.rb +74 -0
- data/pantograph/lib/pantograph/actions/github_api.rb +262 -0
- data/pantograph/lib/pantograph/actions/gradle.rb +278 -0
- data/pantograph/lib/pantograph/actions/import.rb +49 -0
- data/pantograph/lib/pantograph/actions/import_from_git.rb +71 -0
- data/pantograph/lib/pantograph/actions/is_ci.rb +51 -0
- data/pantograph/lib/pantograph/actions/jira.rb +115 -0
- data/pantograph/lib/pantograph/actions/lane_context.rb +60 -0
- data/pantograph/lib/pantograph/actions/last_git_commit.rb +58 -0
- data/pantograph/lib/pantograph/actions/last_git_tag.rb +51 -0
- data/pantograph/lib/pantograph/actions/make_changelog_from_jenkins.rb +81 -0
- data/pantograph/lib/pantograph/actions/min_pantograph_version.rb +57 -0
- data/pantograph/lib/pantograph/actions/nexus_upload.rb +230 -0
- data/pantograph/lib/pantograph/actions/notification.rb +75 -0
- data/pantograph/lib/pantograph/actions/number_of_commits.rb +75 -0
- data/pantograph/lib/pantograph/actions/opt_out_usage.rb +40 -0
- data/pantograph/lib/pantograph/actions/pantograph_version.rb +15 -0
- data/pantograph/lib/pantograph/actions/println.rb +14 -0
- data/pantograph/lib/pantograph/actions/prompt.rb +119 -0
- data/pantograph/lib/pantograph/actions/push_git_tags.rb +76 -0
- data/pantograph/lib/pantograph/actions/push_to_git_remote.rb +127 -0
- data/pantograph/lib/pantograph/actions/puts.rb +68 -0
- data/pantograph/lib/pantograph/actions/reset_git_repo.rb +121 -0
- data/pantograph/lib/pantograph/actions/rocket.rb +83 -0
- data/pantograph/lib/pantograph/actions/rsync.rb +74 -0
- data/pantograph/lib/pantograph/actions/ruby_version.rb +56 -0
- data/pantograph/lib/pantograph/actions/say.rb +56 -0
- data/pantograph/lib/pantograph/actions/scp.rb +114 -0
- data/pantograph/lib/pantograph/actions/set_github_release.rb +274 -0
- data/pantograph/lib/pantograph/actions/sh.rb +71 -0
- data/pantograph/lib/pantograph/actions/skip_docs.rb +52 -0
- data/pantograph/lib/pantograph/actions/slack.rb +288 -0
- data/pantograph/lib/pantograph/actions/sonar.rb +156 -0
- data/pantograph/lib/pantograph/actions/ssh.rb +162 -0
- data/pantograph/lib/pantograph/actions/twitter.rb +89 -0
- data/pantograph/lib/pantograph/actions/update_pantograph.rb +177 -0
- data/pantograph/lib/pantograph/actions/zip.rb +120 -0
- data/pantograph/lib/pantograph/auto_complete.rb +82 -0
- data/pantograph/lib/pantograph/boolean.rb +5 -0
- data/pantograph/lib/pantograph/cli_tools_distributor.rb +183 -0
- data/pantograph/lib/pantograph/command_line_handler.rb +43 -0
- data/pantograph/lib/pantograph/commands_generator.rb +344 -0
- data/pantograph/lib/pantograph/configuration_helper.rb +26 -0
- data/pantograph/lib/pantograph/core_ext/bundler_monkey_patch.rb +14 -0
- data/pantograph/lib/pantograph/documentation/actions_list.rb +214 -0
- data/pantograph/lib/pantograph/documentation/docs_generator.rb +95 -0
- data/pantograph/lib/pantograph/documentation/markdown_docs_generator.rb +221 -0
- data/pantograph/lib/pantograph/environment_printer.rb +282 -0
- data/pantograph/lib/pantograph/erb_template_helper.rb +30 -0
- data/pantograph/lib/pantograph/features.rb +4 -0
- data/pantograph/lib/pantograph/helper/README.md +29 -0
- data/pantograph/lib/pantograph/helper/dotenv_helper.rb +50 -0
- data/pantograph/lib/pantograph/helper/gem_helper.rb +26 -0
- data/pantograph/lib/pantograph/helper/git_helper.rb +135 -0
- data/pantograph/lib/pantograph/helper/gradle_helper.rb +62 -0
- data/pantograph/lib/pantograph/helper/sh_helper.rb +134 -0
- data/pantograph/lib/pantograph/junit_generator.rb +27 -0
- data/pantograph/lib/pantograph/lane.rb +97 -0
- data/pantograph/lib/pantograph/lane_list.rb +77 -0
- data/pantograph/lib/pantograph/lane_manager.rb +140 -0
- data/pantograph/lib/pantograph/lane_manager_base.rb +92 -0
- data/pantograph/lib/pantograph/markdown_table_formatter.rb +62 -0
- data/pantograph/lib/pantograph/new_action.rb +47 -0
- data/pantograph/lib/pantograph/one_off.rb +45 -0
- data/pantograph/lib/pantograph/other_action.rb +29 -0
- data/pantograph/lib/pantograph/pant_file.rb +377 -0
- data/pantograph/lib/pantograph/pantograph_require.rb +75 -0
- data/pantograph/lib/pantograph/plugins/plugin_fetcher.rb +55 -0
- data/pantograph/lib/pantograph/plugins/plugin_generator.rb +86 -0
- data/pantograph/lib/pantograph/plugins/plugin_generator_ui.rb +19 -0
- data/pantograph/lib/pantograph/plugins/plugin_info.rb +49 -0
- data/pantograph/lib/pantograph/plugins/plugin_info_collector.rb +159 -0
- data/pantograph/lib/pantograph/plugins/plugin_manager.rb +387 -0
- data/pantograph/lib/pantograph/plugins/plugin_search.rb +46 -0
- data/pantograph/lib/pantograph/plugins/plugin_update_manager.rb +70 -0
- data/pantograph/lib/pantograph/plugins/plugins.rb +12 -0
- data/pantograph/lib/pantograph/plugins/template/%gem_name%.gemspec.erb +35 -0
- data/pantograph/lib/pantograph/plugins/template/.circleci/config.yml +43 -0
- data/pantograph/lib/pantograph/plugins/template/.gitignore +12 -0
- data/pantograph/lib/pantograph/plugins/template/.rspec +5 -0
- data/pantograph/lib/pantograph/plugins/template/.rubocop.yml +179 -0
- data/pantograph/lib/pantograph/plugins/template/.travis.yml +4 -0
- data/pantograph/lib/pantograph/plugins/template/Gemfile +6 -0
- data/pantograph/lib/pantograph/plugins/template/LICENSE.erb +21 -0
- data/pantograph/lib/pantograph/plugins/template/README.md.erb +52 -0
- data/pantograph/lib/pantograph/plugins/template/Rakefile +9 -0
- data/pantograph/lib/pantograph/plugins/template/lib/pantograph/plugin/%plugin_name%/actions/%plugin_name%_action.rb.erb +47 -0
- data/pantograph/lib/pantograph/plugins/template/lib/pantograph/plugin/%plugin_name%/helper/%plugin_name%_helper.rb.erb +16 -0
- data/pantograph/lib/pantograph/plugins/template/lib/pantograph/plugin/%plugin_name%/version.rb.erb +5 -0
- data/pantograph/lib/pantograph/plugins/template/lib/pantograph/plugin/%plugin_name%.rb.erb +16 -0
- data/pantograph/lib/pantograph/plugins/template/pantograph/Pantfile.erb +3 -0
- data/pantograph/lib/pantograph/plugins/template/pantograph/Pluginfile.erb +1 -0
- data/pantograph/lib/pantograph/plugins/template/spec/%plugin_name%_action_spec.rb.erb +9 -0
- data/pantograph/lib/pantograph/plugins/template/spec/spec_helper.rb.erb +15 -0
- data/pantograph/lib/pantograph/runner.rb +371 -0
- data/pantograph/lib/pantograph/server/action_command.rb +61 -0
- data/pantograph/lib/pantograph/server/action_command_return.rb +14 -0
- data/pantograph/lib/pantograph/server/command_executor.rb +7 -0
- data/pantograph/lib/pantograph/server/command_parser.rb +36 -0
- data/pantograph/lib/pantograph/server/control_command.rb +23 -0
- data/pantograph/lib/pantograph/server/json_return_value_processor.rb +72 -0
- data/pantograph/lib/pantograph/server/socket_server.rb +232 -0
- data/pantograph/lib/pantograph/server/socket_server_action_command_executor.rb +101 -0
- data/pantograph/lib/pantograph/setup/setup.rb +290 -0
- data/pantograph/lib/pantograph/setup/setup_android.rb +64 -0
- data/pantograph/lib/pantograph/setup/setup_ios.rb +412 -0
- data/pantograph/lib/pantograph/shells.rb +6 -0
- data/pantograph/lib/pantograph/supported_platforms.rb +28 -0
- data/pantograph/lib/pantograph/tools.rb +10 -0
- data/pantograph/lib/pantograph/version.rb +5 -0
- data/pantograph/lib/pantograph.rb +51 -0
- data/pantograph_core/README.md +79 -0
- data/pantograph_core/lib/assets/XMLTemplate.xml.erb +12 -0
- data/pantograph_core/lib/pantograph_core/analytics/action_completion_context.rb +34 -0
- data/pantograph_core/lib/pantograph_core/analytics/action_launch_context.rb +38 -0
- data/pantograph_core/lib/pantograph_core/analytics/analytics_event_builder.rb +23 -0
- data/pantograph_core/lib/pantograph_core/analytics/analytics_ingester_client.rb +54 -0
- data/pantograph_core/lib/pantograph_core/analytics/analytics_session.rb +71 -0
- data/pantograph_core/lib/pantograph_core/cert_checker.rb +116 -0
- data/pantograph_core/lib/pantograph_core/command_executor.rb +99 -0
- data/pantograph_core/lib/pantograph_core/configuration/commander_generator.rb +103 -0
- data/pantograph_core/lib/pantograph_core/configuration/config_item.rb +314 -0
- data/pantograph_core/lib/pantograph_core/configuration/configuration.rb +332 -0
- data/pantograph_core/lib/pantograph_core/configuration/configuration_file.rb +182 -0
- data/pantograph_core/lib/pantograph_core/core_ext/shellwords.rb +63 -0
- data/pantograph_core/lib/pantograph_core/core_ext/string.rb +17 -0
- data/pantograph_core/lib/pantograph_core/env.rb +9 -0
- data/pantograph_core/lib/pantograph_core/feature/feature.rb +51 -0
- data/pantograph_core/lib/pantograph_core/features.rb +4 -0
- data/pantograph_core/lib/pantograph_core/globals.rb +27 -0
- data/pantograph_core/lib/pantograph_core/helper.rb +409 -0
- data/pantograph_core/lib/pantograph_core/keychain_importer.rb +74 -0
- data/pantograph_core/lib/pantograph_core/languages.rb +14 -0
- data/pantograph_core/lib/pantograph_core/module.rb +29 -0
- data/pantograph_core/lib/pantograph_core/pantograph_folder.rb +39 -0
- data/pantograph_core/lib/pantograph_core/pantograph_pty.rb +57 -0
- data/pantograph_core/lib/pantograph_core/pkg_file_analyser.rb +44 -0
- data/pantograph_core/lib/pantograph_core/print_table.rb +131 -0
- data/pantograph_core/lib/pantograph_core/string_filters.rb +51 -0
- data/pantograph_core/lib/pantograph_core/swag.rb +85 -0
- data/pantograph_core/lib/pantograph_core/tag_version.rb +31 -0
- data/pantograph_core/lib/pantograph_core/test_parser.rb +107 -0
- data/pantograph_core/lib/pantograph_core/ui/disable_colors.rb +17 -0
- data/pantograph_core/lib/pantograph_core/ui/errors/pantograph_common_error.rb +19 -0
- data/pantograph_core/lib/pantograph_core/ui/errors/pantograph_crash.rb +11 -0
- data/pantograph_core/lib/pantograph_core/ui/errors/pantograph_error.rb +25 -0
- data/pantograph_core/lib/pantograph_core/ui/errors/pantograph_exception.rb +19 -0
- data/pantograph_core/lib/pantograph_core/ui/errors/pantograph_shell_error.rb +11 -0
- data/pantograph_core/lib/pantograph_core/ui/errors.rb +1 -0
- data/pantograph_core/lib/pantograph_core/ui/github_issue_inspector_reporter.rb +62 -0
- data/pantograph_core/lib/pantograph_core/ui/implementations/shell.rb +159 -0
- data/pantograph_core/lib/pantograph_core/ui/interface.rb +205 -0
- data/pantograph_core/lib/pantograph_core/ui/pantograph_runner.rb +276 -0
- data/pantograph_core/lib/pantograph_core/ui/ui.rb +26 -0
- data/pantograph_core/lib/pantograph_core/update_checker/changelog.rb +37 -0
- data/pantograph_core/lib/pantograph_core/update_checker/update_checker.rb +107 -0
- data/pantograph_core/lib/pantograph_core.rb +45 -0
- metadata +987 -0
@@ -0,0 +1,23 @@
|
|
1
|
+
module PantographCore
|
2
|
+
class AnalyticsEventBuilder
|
3
|
+
attr_accessor :action_name
|
4
|
+
|
5
|
+
# pantograph_client_language valid options are :ruby
|
6
|
+
def initialize(p_hash: nil, session_id: nil, action_name: nil, pantograph_client_language: :ruby)
|
7
|
+
@p_hash = p_hash
|
8
|
+
@session_id = session_id
|
9
|
+
@action_name = action_name
|
10
|
+
@pantograph_client_language = pantograph_client_language
|
11
|
+
end
|
12
|
+
|
13
|
+
def new_event(action_stage)
|
14
|
+
{
|
15
|
+
client_id: @p_hash,
|
16
|
+
category: "pantograph Client Language - #{@pantograph_client_language}",
|
17
|
+
action: action_stage,
|
18
|
+
label: action_name,
|
19
|
+
value: nil
|
20
|
+
}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'openssl'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
require_relative '../helper'
|
6
|
+
|
7
|
+
module PantographCore
|
8
|
+
class AnalyticsIngesterClient
|
9
|
+
GA_URL = "https://www.google-analytics.com"
|
10
|
+
|
11
|
+
private_constant :GA_URL
|
12
|
+
|
13
|
+
def initialize(ga_tracking)
|
14
|
+
@ga_tracking = ga_tracking
|
15
|
+
end
|
16
|
+
|
17
|
+
def post_event(event)
|
18
|
+
# If our users want to opt out of usage metrics, don't post the events.
|
19
|
+
# Learn more at https://docs.pantograph.tools/#metrics
|
20
|
+
if Helper.test? || PantographCore::Env.truthy?("PANTOGRAPH_OPT_OUT_USAGE")
|
21
|
+
return nil
|
22
|
+
end
|
23
|
+
return Thread.new do
|
24
|
+
send_request(event)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def send_request(event, retries: 2)
|
29
|
+
post_request(event)
|
30
|
+
rescue
|
31
|
+
retries -= 1
|
32
|
+
retry if retries >= 0
|
33
|
+
end
|
34
|
+
|
35
|
+
def post_request(event)
|
36
|
+
connection = Faraday.new(GA_URL) do |conn|
|
37
|
+
conn.request(:url_encoded)
|
38
|
+
conn.adapter(Faraday.default_adapter)
|
39
|
+
end
|
40
|
+
connection.headers[:user_agent] = 'pantograph/' + Pantograph::VERSION
|
41
|
+
connection.post("/collect", {
|
42
|
+
v: "1", # API Version
|
43
|
+
tid: @ga_tracking, # Tracking ID / Property ID
|
44
|
+
cid: event[:client_id], # Client ID
|
45
|
+
t: "event", # Event hit type
|
46
|
+
ec: event[:category], # Event category
|
47
|
+
ea: event[:action], # Event action
|
48
|
+
el: event[:label] || "na", # Event label
|
49
|
+
ev: event[:value] || "0", # Event value
|
50
|
+
aip: "1" # IP anonymization
|
51
|
+
})
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require_relative 'analytics_ingester_client'
|
2
|
+
require_relative 'action_launch_context'
|
3
|
+
require_relative 'analytics_event_builder'
|
4
|
+
|
5
|
+
module PantographCore
|
6
|
+
class AnalyticsSession
|
7
|
+
GA_TRACKING = "UA-121171860-1"
|
8
|
+
|
9
|
+
private_constant :GA_TRACKING
|
10
|
+
attr_accessor :session_id
|
11
|
+
attr_accessor :client
|
12
|
+
|
13
|
+
def initialize(analytics_ingester_client: AnalyticsIngesterClient.new(GA_TRACKING))
|
14
|
+
require 'securerandom'
|
15
|
+
@session_id = SecureRandom.uuid
|
16
|
+
@client = analytics_ingester_client
|
17
|
+
@threads = []
|
18
|
+
@launch_event_sent = false
|
19
|
+
end
|
20
|
+
|
21
|
+
def action_launched(launch_context: nil)
|
22
|
+
unless did_show_message?
|
23
|
+
show_message
|
24
|
+
end
|
25
|
+
|
26
|
+
if @launch_event_sent || launch_context.p_hash.nil?
|
27
|
+
return
|
28
|
+
end
|
29
|
+
|
30
|
+
@launch_event_sent = true
|
31
|
+
builder = AnalyticsEventBuilder.new(
|
32
|
+
p_hash: launch_context.p_hash,
|
33
|
+
session_id: session_id,
|
34
|
+
action_name: nil,
|
35
|
+
pantograph_client_language: launch_context.pantograph_client_language
|
36
|
+
)
|
37
|
+
|
38
|
+
launch_event = builder.new_event(:launch)
|
39
|
+
post_thread = client.post_event(launch_event)
|
40
|
+
unless post_thread.nil?
|
41
|
+
@threads << post_thread
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def action_completed(completion_context: nil)
|
46
|
+
end
|
47
|
+
|
48
|
+
def show_message
|
49
|
+
UI.message("Sending anonymous analytics information")
|
50
|
+
UI.message("Learn more at https://docs.pantograph.tools/#metrics")
|
51
|
+
UI.message("No personal or sensitive data is sent.")
|
52
|
+
UI.message("You can disable this by adding `opt_out_usage` at the top of your Pantfile")
|
53
|
+
end
|
54
|
+
|
55
|
+
def did_show_message?
|
56
|
+
file_name = ".did_show_opt_info"
|
57
|
+
|
58
|
+
new_path = File.join(PantographCore.pantograph_user_dir, file_name)
|
59
|
+
did_show = File.exist?(new_path)
|
60
|
+
|
61
|
+
return did_show if did_show
|
62
|
+
|
63
|
+
File.write(new_path, '1')
|
64
|
+
false
|
65
|
+
end
|
66
|
+
|
67
|
+
def finalize_session
|
68
|
+
@threads.map(&:join)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
require 'tempfile'
|
2
|
+
require 'openssl'
|
3
|
+
|
4
|
+
require_relative 'helper'
|
5
|
+
|
6
|
+
module PantographCore
|
7
|
+
# This class checks if a specific certificate is installed on the current mac
|
8
|
+
class CertChecker
|
9
|
+
def self.installed?(path, in_keychain: nil)
|
10
|
+
UI.user_error!("Could not find file '#{path}'") unless File.exist?(path)
|
11
|
+
|
12
|
+
ids = installed_identies(in_keychain: in_keychain)
|
13
|
+
finger_print = sha1_fingerprint(path)
|
14
|
+
|
15
|
+
return ids.include?(finger_print)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Legacy Method, use `installed?` instead
|
19
|
+
def self.is_installed?(path)
|
20
|
+
installed?(path)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.installed_identies(in_keychain: nil)
|
24
|
+
install_wwdr_certificate unless wwdr_certificate_installed?
|
25
|
+
|
26
|
+
available = list_available_identities(in_keychain: in_keychain)
|
27
|
+
# Match for this text against word boundaries to avoid edge cases around multiples of 10 identities!
|
28
|
+
if /\b0 valid identities found\b/ =~ available
|
29
|
+
UI.error([
|
30
|
+
"There are no local code signing identities found.",
|
31
|
+
"You can run" << " `security find-identity -v -p codesigning #{in_keychain}".rstrip << "` to get this output.",
|
32
|
+
"This Stack Overflow thread has more information: https://stackoverflow.com/q/35390072/774.",
|
33
|
+
"(Check in Keychain Access for an expired WWDR certificate: https://stackoverflow.com/a/35409835/774 has more info.)"
|
34
|
+
].join("\n"))
|
35
|
+
end
|
36
|
+
|
37
|
+
ids = []
|
38
|
+
available.split("\n").each do |current|
|
39
|
+
next if current.include?("REVOKED")
|
40
|
+
begin
|
41
|
+
(ids << current.match(/.*\) ([[:xdigit:]]*) \".*/)[1])
|
42
|
+
rescue
|
43
|
+
# the last line does not match
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
return ids
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.list_available_identities(in_keychain: nil)
|
51
|
+
commands = ['security find-identity -v -p codesigning']
|
52
|
+
commands << in_keychain if in_keychain
|
53
|
+
`#{commands.join(' ')}`
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.wwdr_certificate_installed?
|
57
|
+
certificate_name = "Apple Worldwide Developer Relations Certification Authority"
|
58
|
+
keychain = wwdr_keychain
|
59
|
+
response = Helper.backticks("security find-certificate -c '#{certificate_name}' #{keychain.shellescape}", print: PantographCore::Globals.verbose?)
|
60
|
+
return response.include?("attributes:")
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.install_wwdr_certificate
|
64
|
+
url = 'https://developer.apple.com/certificationauthority/AppleWWDRCA.cer'
|
65
|
+
file = Tempfile.new('AppleWWDRCA')
|
66
|
+
filename = file.path
|
67
|
+
keychain = wwdr_keychain
|
68
|
+
keychain = "-k #{keychain.shellescape}" unless keychain.empty?
|
69
|
+
|
70
|
+
require 'open3'
|
71
|
+
|
72
|
+
import_command = "curl -f -o #{filename} #{url} && security import #{filename} #{keychain}"
|
73
|
+
UI.verbose("Installing WWDR Cert: #{import_command}")
|
74
|
+
|
75
|
+
stdout, stderr, _status = Open3.capture3(import_command)
|
76
|
+
if PantographCore::Globals.verbose?
|
77
|
+
UI.command_output(stdout)
|
78
|
+
UI.command_output(stderr)
|
79
|
+
end
|
80
|
+
|
81
|
+
unless $?.success?
|
82
|
+
UI.verbose("Failed to install WWDR Certificate, checking output to see why")
|
83
|
+
# Check the command output, WWDR might already exist
|
84
|
+
unless /The specified item already exists in the keychain./ =~ stderr
|
85
|
+
UI.user_error!("Could not install WWDR certificate")
|
86
|
+
end
|
87
|
+
UI.verbose("WWDR Certificate was already installed")
|
88
|
+
end
|
89
|
+
return true
|
90
|
+
end
|
91
|
+
|
92
|
+
def self.wwdr_keychain
|
93
|
+
priority = [
|
94
|
+
"security list-keychains -d user",
|
95
|
+
"security default-keychain -d user"
|
96
|
+
]
|
97
|
+
priority.each do |command|
|
98
|
+
keychains = Helper.backticks(command, print: PantographCore::Globals.verbose?).split("\n")
|
99
|
+
unless keychains.empty?
|
100
|
+
# Select first keychain name from returned keychains list
|
101
|
+
return keychains[0].strip.tr('"', '')
|
102
|
+
end
|
103
|
+
end
|
104
|
+
return ""
|
105
|
+
end
|
106
|
+
|
107
|
+
def self.sha1_fingerprint(path)
|
108
|
+
file_data = File.read(path.to_s)
|
109
|
+
cert = OpenSSL::X509::Certificate.new(file_data)
|
110
|
+
return OpenSSL::Digest::SHA1.new(cert.to_der).to_s.upcase
|
111
|
+
rescue => error
|
112
|
+
UI.error(error)
|
113
|
+
UI.user_error!("Error parsing certificate '#{path}'")
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require_relative 'ui/ui'
|
2
|
+
require_relative 'globals'
|
3
|
+
require_relative 'pantograph_pty'
|
4
|
+
|
5
|
+
module PantographCore
|
6
|
+
# Executes commands and takes care of error handling and more
|
7
|
+
class CommandExecutor
|
8
|
+
class << self
|
9
|
+
# Cross-platform way of finding an executable in the $PATH. Respects the $PATHEXT, which lists
|
10
|
+
# valid file extensions for executables on Windows.
|
11
|
+
#
|
12
|
+
# which('ruby') #=> /usr/bin/ruby
|
13
|
+
#
|
14
|
+
# Derived from https://stackoverflow.com/a/5471032/3005
|
15
|
+
def which(cmd)
|
16
|
+
# PATHEXT contains the list of file extensions that Windows considers executable, semicolon separated.
|
17
|
+
# e.g. ".COM;.EXE;.BAT;.CMD"
|
18
|
+
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : []
|
19
|
+
exts << '' # Always have an empty string (= no file extension)
|
20
|
+
|
21
|
+
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
|
22
|
+
exts.each do |ext|
|
23
|
+
cmd_path = File.join(path, "#{cmd}#{ext}")
|
24
|
+
return cmd_path if Helper.executable?(cmd_path)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
return nil
|
29
|
+
end
|
30
|
+
|
31
|
+
# @param command [String] The command to be executed
|
32
|
+
# @param print_all [Boolean] Do we want to print out the command output while running?
|
33
|
+
# @param print_command [Boolean] Should we print the command that's being executed
|
34
|
+
# @param error [Block] A block that's called if an error occurs
|
35
|
+
# @param prefix [Array] An array containing a prefix + block which might get applied to the output
|
36
|
+
# @param loading [String] A loading string that is shown before the first output
|
37
|
+
# @param suppress_output [Boolean] Should we print the command's output?
|
38
|
+
# @return [String] All the output as string
|
39
|
+
def execute(command: nil, print_all: false, print_command: true, error: nil, prefix: nil, loading: nil, suppress_output: false)
|
40
|
+
print_all = true if PantographCore::Globals.verbose?
|
41
|
+
prefix ||= {}
|
42
|
+
|
43
|
+
output = []
|
44
|
+
command = command.join(" ") if command.kind_of?(Array)
|
45
|
+
UI.command(command) if print_command
|
46
|
+
|
47
|
+
if print_all && loading # this is only used to show the "Loading text"...
|
48
|
+
UI.command_output(loading)
|
49
|
+
end
|
50
|
+
|
51
|
+
begin
|
52
|
+
status = PantographCore::PantographPty.spawn(command) do |command_stdout, command_stdin, pid|
|
53
|
+
command_stdout.each do |l|
|
54
|
+
line = l.chomp
|
55
|
+
output << line
|
56
|
+
|
57
|
+
next unless print_all
|
58
|
+
|
59
|
+
# Prefix the current line with a string
|
60
|
+
prefix.each do |element|
|
61
|
+
line = element[:prefix] + line if element[:block] && element[:block].call(line)
|
62
|
+
end
|
63
|
+
|
64
|
+
UI.command_output(line) unless suppress_output
|
65
|
+
end
|
66
|
+
end
|
67
|
+
rescue => ex
|
68
|
+
# PantographPty adds exit_status on to StandardError so every error will have a status code
|
69
|
+
status = ex.exit_status
|
70
|
+
|
71
|
+
# This could happen when the environment is wrong:
|
72
|
+
# > invalid byte sequence in US-ASCII (ArgumentError)
|
73
|
+
output << ex.to_s
|
74
|
+
o = output.join("\n")
|
75
|
+
puts(o)
|
76
|
+
if error
|
77
|
+
error.call(o, nil)
|
78
|
+
else
|
79
|
+
raise ex
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# Exit status for build command, should be 0 if build succeeded
|
84
|
+
if status != 0
|
85
|
+
o = output.join("\n")
|
86
|
+
puts(o) unless suppress_output # the user has the right to see the raw output
|
87
|
+
UI.error("Exit status: #{status}")
|
88
|
+
if error
|
89
|
+
error.call(o, status)
|
90
|
+
else
|
91
|
+
UI.user_error!("Exit status: #{status}")
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
return output.join("\n")
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'commander'
|
2
|
+
|
3
|
+
require_relative '../module'
|
4
|
+
require_relative '../ui/ui'
|
5
|
+
|
6
|
+
module PantographCore
|
7
|
+
class CommanderGenerator
|
8
|
+
include Commander::Methods
|
9
|
+
|
10
|
+
# Calls the appropriate methods for commander to show the available parameters
|
11
|
+
def generate(options, command: nil)
|
12
|
+
# First, enable `always_trace`, to show the stack trace
|
13
|
+
always_trace!
|
14
|
+
|
15
|
+
used_switches = []
|
16
|
+
options.each do |option|
|
17
|
+
next if option.description.to_s.empty? # "private" options
|
18
|
+
next unless option.display_in_shell
|
19
|
+
|
20
|
+
short_switch = option.short_option
|
21
|
+
key = option.key
|
22
|
+
validate_short_switch(used_switches, short_switch, key)
|
23
|
+
|
24
|
+
type = option.data_type
|
25
|
+
|
26
|
+
# We added type: Hash to code generation, but Ruby's OptionParser doesn't like that
|
27
|
+
# so we need to switch that to something that is supported, luckily, we have an `is_string`
|
28
|
+
# property and if that is false, we'll default to nil
|
29
|
+
if type == Hash
|
30
|
+
type = option.is_string ? String : nil
|
31
|
+
end
|
32
|
+
|
33
|
+
# Boolean is a pantograph thing, it's either TrueClass, or FalseClass, but we won't know
|
34
|
+
# that until runtime, so nil is the best we get
|
35
|
+
if type == Pantograph::Boolean
|
36
|
+
type = nil
|
37
|
+
end
|
38
|
+
|
39
|
+
# This is an important bit of trickery to solve the boolean option situation.
|
40
|
+
#
|
41
|
+
# Typically, boolean command line flags do not accept trailing values. If the flag
|
42
|
+
# is present, the value is true, if it is missing, the value is false. pantograph
|
43
|
+
# supports this style of flag. For example, you can specify a flag like `--clean`,
|
44
|
+
# and the :clean option will be true.
|
45
|
+
#
|
46
|
+
# However, pantograph also supports another boolean flag style that accepts trailing
|
47
|
+
# values much like options for Strings and other value types. That looks like
|
48
|
+
# `--include_bitcode false` The problem is that this does not work out of the box
|
49
|
+
# for Commander and OptionsParser. So, we need to get tricky.
|
50
|
+
#
|
51
|
+
# The value_appendix below acts as a placeholder in the switch definition that
|
52
|
+
# states that we expect to have a trailing value for our options. When an option
|
53
|
+
# declares a data type, we use the name of that data type in all caps like:
|
54
|
+
# "--devices ARRAY". When the data type is nil, this implies that we're going
|
55
|
+
# to be doing some special handling on that value. One special thing we do
|
56
|
+
# automatically in Configuration is to coerce special Strings into boolean values.
|
57
|
+
#
|
58
|
+
# If the data type is nil, the trick we do is to specify a value placeholder, but
|
59
|
+
# we wrap it in [] brackets to mark it as optional. That means that the trailing
|
60
|
+
# value may or may not be present for this flag. If the flag is present, but the
|
61
|
+
# value is not, we get a value of `true`. Perfect for the boolean flag base-case!
|
62
|
+
# If the value is there, we'll actually get it back as a String, which we can
|
63
|
+
# later coerce into a boolean.
|
64
|
+
#
|
65
|
+
# In this way we support handling boolean flags with or without trailing values.
|
66
|
+
value_appendix = (type || '[VALUE]').to_s.upcase
|
67
|
+
long_switch = "--#{option.key} #{value_appendix}"
|
68
|
+
|
69
|
+
description = option.description
|
70
|
+
description += " (#{option.env_name})" unless option.env_name.to_s.empty?
|
71
|
+
|
72
|
+
# We compact this array here to remove the short_switch variable if it is nil.
|
73
|
+
# Passing a nil value to global_option has been shown to create problems with
|
74
|
+
# option parsing!
|
75
|
+
#
|
76
|
+
# See: https://github.com/pantograph/pantograph_core/pull/89
|
77
|
+
#
|
78
|
+
# If we don't have a data type for this option, we tell it to act like a String.
|
79
|
+
# This allows us to get a reasonable value for boolean options that can be
|
80
|
+
# automatically coerced or otherwise handled by the ConfigItem for others.
|
81
|
+
args = [short_switch, long_switch, (type || String), description].compact
|
82
|
+
|
83
|
+
if command
|
84
|
+
command.option(*args)
|
85
|
+
else
|
86
|
+
# This is the call to Commander to set up the option we've been building.
|
87
|
+
global_option(*args)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def validate_short_switch(used_switches, short_switch, key)
|
93
|
+
return if short_switch.nil?
|
94
|
+
|
95
|
+
UI.user_error!("Short option #{short_switch} already taken for key #{key}") if used_switches.include?(short_switch)
|
96
|
+
UI.user_error!("-v is already used for the version (key #{key})") if short_switch == "-v"
|
97
|
+
UI.user_error!("-h is already used for the help screen (key #{key})") if short_switch == "-h"
|
98
|
+
UI.user_error!("-t is already used for the trace screen (key #{key})") if short_switch == "-t"
|
99
|
+
|
100
|
+
used_switches << short_switch
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|