pantograph 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (202) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +1 -0
  3. data/LICENSE +21 -0
  4. data/README.md +197 -0
  5. data/bin/bin-proxy +19 -0
  6. data/bin/pantograph +23 -0
  7. data/pantograph/README.md +11 -0
  8. data/pantograph/lib/assets/ActionDetails.md.erb +106 -0
  9. data/pantograph/lib/assets/Actions.md.erb +43 -0
  10. data/pantograph/lib/assets/DefaultPantfileTemplate +20 -0
  11. data/pantograph/lib/assets/completions/completion.bash +23 -0
  12. data/pantograph/lib/assets/completions/completion.fish +39 -0
  13. data/pantograph/lib/assets/completions/completion.sh +12 -0
  14. data/pantograph/lib/assets/completions/completion.zsh +23 -0
  15. data/pantograph/lib/assets/custom_action_template.rb +80 -0
  16. data/pantograph/lib/assets/report_template.xml.erb +15 -0
  17. data/pantograph/lib/pantograph/action.rb +194 -0
  18. data/pantograph/lib/pantograph/action_collector.rb +35 -0
  19. data/pantograph/lib/pantograph/actions/README.md +3 -0
  20. data/pantograph/lib/pantograph/actions/actions_helper.rb +166 -0
  21. data/pantograph/lib/pantograph/actions/add_extra_platforms.rb +45 -0
  22. data/pantograph/lib/pantograph/actions/artifactory.rb +157 -0
  23. data/pantograph/lib/pantograph/actions/bundle_install.rb +156 -0
  24. data/pantograph/lib/pantograph/actions/changelog_from_git_commits.rb +197 -0
  25. data/pantograph/lib/pantograph/actions/clipboard.rb +52 -0
  26. data/pantograph/lib/pantograph/actions/cloc.rb +89 -0
  27. data/pantograph/lib/pantograph/actions/create_pull_request.rb +190 -0
  28. data/pantograph/lib/pantograph/actions/danger.rb +131 -0
  29. data/pantograph/lib/pantograph/actions/debug.rb +32 -0
  30. data/pantograph/lib/pantograph/actions/default_platform.rb +47 -0
  31. data/pantograph/lib/pantograph/actions/download.rb +76 -0
  32. data/pantograph/lib/pantograph/actions/echo.rb +14 -0
  33. data/pantograph/lib/pantograph/actions/ensure_bundle_exec.rb +59 -0
  34. data/pantograph/lib/pantograph/actions/ensure_env_vars.rb +58 -0
  35. data/pantograph/lib/pantograph/actions/ensure_git_branch.rb +69 -0
  36. data/pantograph/lib/pantograph/actions/ensure_git_status_clean.rb +81 -0
  37. data/pantograph/lib/pantograph/actions/erb.rb +88 -0
  38. data/pantograph/lib/pantograph/actions/get_build_number_repository.rb +120 -0
  39. data/pantograph/lib/pantograph/actions/get_github_release.rb +163 -0
  40. data/pantograph/lib/pantograph/actions/git_add.rb +93 -0
  41. data/pantograph/lib/pantograph/actions/git_branch.rb +58 -0
  42. data/pantograph/lib/pantograph/actions/git_commit.rb +80 -0
  43. data/pantograph/lib/pantograph/actions/git_pull.rb +53 -0
  44. data/pantograph/lib/pantograph/actions/git_submodule_update.rb +52 -0
  45. data/pantograph/lib/pantograph/actions/git_tag_exists.rb +74 -0
  46. data/pantograph/lib/pantograph/actions/github_api.rb +262 -0
  47. data/pantograph/lib/pantograph/actions/gradle.rb +278 -0
  48. data/pantograph/lib/pantograph/actions/import.rb +49 -0
  49. data/pantograph/lib/pantograph/actions/import_from_git.rb +71 -0
  50. data/pantograph/lib/pantograph/actions/is_ci.rb +51 -0
  51. data/pantograph/lib/pantograph/actions/jira.rb +115 -0
  52. data/pantograph/lib/pantograph/actions/lane_context.rb +60 -0
  53. data/pantograph/lib/pantograph/actions/last_git_commit.rb +58 -0
  54. data/pantograph/lib/pantograph/actions/last_git_tag.rb +51 -0
  55. data/pantograph/lib/pantograph/actions/make_changelog_from_jenkins.rb +81 -0
  56. data/pantograph/lib/pantograph/actions/min_pantograph_version.rb +57 -0
  57. data/pantograph/lib/pantograph/actions/nexus_upload.rb +230 -0
  58. data/pantograph/lib/pantograph/actions/notification.rb +75 -0
  59. data/pantograph/lib/pantograph/actions/number_of_commits.rb +75 -0
  60. data/pantograph/lib/pantograph/actions/opt_out_usage.rb +40 -0
  61. data/pantograph/lib/pantograph/actions/pantograph_version.rb +15 -0
  62. data/pantograph/lib/pantograph/actions/println.rb +14 -0
  63. data/pantograph/lib/pantograph/actions/prompt.rb +119 -0
  64. data/pantograph/lib/pantograph/actions/push_git_tags.rb +76 -0
  65. data/pantograph/lib/pantograph/actions/push_to_git_remote.rb +127 -0
  66. data/pantograph/lib/pantograph/actions/puts.rb +68 -0
  67. data/pantograph/lib/pantograph/actions/reset_git_repo.rb +121 -0
  68. data/pantograph/lib/pantograph/actions/rocket.rb +83 -0
  69. data/pantograph/lib/pantograph/actions/rsync.rb +74 -0
  70. data/pantograph/lib/pantograph/actions/ruby_version.rb +56 -0
  71. data/pantograph/lib/pantograph/actions/say.rb +56 -0
  72. data/pantograph/lib/pantograph/actions/scp.rb +114 -0
  73. data/pantograph/lib/pantograph/actions/set_github_release.rb +274 -0
  74. data/pantograph/lib/pantograph/actions/sh.rb +71 -0
  75. data/pantograph/lib/pantograph/actions/skip_docs.rb +52 -0
  76. data/pantograph/lib/pantograph/actions/slack.rb +288 -0
  77. data/pantograph/lib/pantograph/actions/sonar.rb +156 -0
  78. data/pantograph/lib/pantograph/actions/ssh.rb +162 -0
  79. data/pantograph/lib/pantograph/actions/twitter.rb +89 -0
  80. data/pantograph/lib/pantograph/actions/update_pantograph.rb +177 -0
  81. data/pantograph/lib/pantograph/actions/zip.rb +120 -0
  82. data/pantograph/lib/pantograph/auto_complete.rb +82 -0
  83. data/pantograph/lib/pantograph/boolean.rb +5 -0
  84. data/pantograph/lib/pantograph/cli_tools_distributor.rb +183 -0
  85. data/pantograph/lib/pantograph/command_line_handler.rb +43 -0
  86. data/pantograph/lib/pantograph/commands_generator.rb +344 -0
  87. data/pantograph/lib/pantograph/configuration_helper.rb +26 -0
  88. data/pantograph/lib/pantograph/core_ext/bundler_monkey_patch.rb +14 -0
  89. data/pantograph/lib/pantograph/documentation/actions_list.rb +214 -0
  90. data/pantograph/lib/pantograph/documentation/docs_generator.rb +95 -0
  91. data/pantograph/lib/pantograph/documentation/markdown_docs_generator.rb +221 -0
  92. data/pantograph/lib/pantograph/environment_printer.rb +282 -0
  93. data/pantograph/lib/pantograph/erb_template_helper.rb +30 -0
  94. data/pantograph/lib/pantograph/features.rb +4 -0
  95. data/pantograph/lib/pantograph/helper/README.md +29 -0
  96. data/pantograph/lib/pantograph/helper/dotenv_helper.rb +50 -0
  97. data/pantograph/lib/pantograph/helper/gem_helper.rb +26 -0
  98. data/pantograph/lib/pantograph/helper/git_helper.rb +135 -0
  99. data/pantograph/lib/pantograph/helper/gradle_helper.rb +62 -0
  100. data/pantograph/lib/pantograph/helper/sh_helper.rb +134 -0
  101. data/pantograph/lib/pantograph/junit_generator.rb +27 -0
  102. data/pantograph/lib/pantograph/lane.rb +97 -0
  103. data/pantograph/lib/pantograph/lane_list.rb +77 -0
  104. data/pantograph/lib/pantograph/lane_manager.rb +140 -0
  105. data/pantograph/lib/pantograph/lane_manager_base.rb +92 -0
  106. data/pantograph/lib/pantograph/markdown_table_formatter.rb +62 -0
  107. data/pantograph/lib/pantograph/new_action.rb +47 -0
  108. data/pantograph/lib/pantograph/one_off.rb +45 -0
  109. data/pantograph/lib/pantograph/other_action.rb +29 -0
  110. data/pantograph/lib/pantograph/pant_file.rb +377 -0
  111. data/pantograph/lib/pantograph/pantograph_require.rb +75 -0
  112. data/pantograph/lib/pantograph/plugins/plugin_fetcher.rb +55 -0
  113. data/pantograph/lib/pantograph/plugins/plugin_generator.rb +86 -0
  114. data/pantograph/lib/pantograph/plugins/plugin_generator_ui.rb +19 -0
  115. data/pantograph/lib/pantograph/plugins/plugin_info.rb +49 -0
  116. data/pantograph/lib/pantograph/plugins/plugin_info_collector.rb +159 -0
  117. data/pantograph/lib/pantograph/plugins/plugin_manager.rb +387 -0
  118. data/pantograph/lib/pantograph/plugins/plugin_search.rb +46 -0
  119. data/pantograph/lib/pantograph/plugins/plugin_update_manager.rb +70 -0
  120. data/pantograph/lib/pantograph/plugins/plugins.rb +12 -0
  121. data/pantograph/lib/pantograph/plugins/template/%gem_name%.gemspec.erb +35 -0
  122. data/pantograph/lib/pantograph/plugins/template/.circleci/config.yml +43 -0
  123. data/pantograph/lib/pantograph/plugins/template/.gitignore +12 -0
  124. data/pantograph/lib/pantograph/plugins/template/.rspec +5 -0
  125. data/pantograph/lib/pantograph/plugins/template/.rubocop.yml +179 -0
  126. data/pantograph/lib/pantograph/plugins/template/.travis.yml +4 -0
  127. data/pantograph/lib/pantograph/plugins/template/Gemfile +6 -0
  128. data/pantograph/lib/pantograph/plugins/template/LICENSE.erb +21 -0
  129. data/pantograph/lib/pantograph/plugins/template/README.md.erb +52 -0
  130. data/pantograph/lib/pantograph/plugins/template/Rakefile +9 -0
  131. data/pantograph/lib/pantograph/plugins/template/lib/pantograph/plugin/%plugin_name%/actions/%plugin_name%_action.rb.erb +47 -0
  132. data/pantograph/lib/pantograph/plugins/template/lib/pantograph/plugin/%plugin_name%/helper/%plugin_name%_helper.rb.erb +16 -0
  133. data/pantograph/lib/pantograph/plugins/template/lib/pantograph/plugin/%plugin_name%/version.rb.erb +5 -0
  134. data/pantograph/lib/pantograph/plugins/template/lib/pantograph/plugin/%plugin_name%.rb.erb +16 -0
  135. data/pantograph/lib/pantograph/plugins/template/pantograph/Pantfile.erb +3 -0
  136. data/pantograph/lib/pantograph/plugins/template/pantograph/Pluginfile.erb +1 -0
  137. data/pantograph/lib/pantograph/plugins/template/spec/%plugin_name%_action_spec.rb.erb +9 -0
  138. data/pantograph/lib/pantograph/plugins/template/spec/spec_helper.rb.erb +15 -0
  139. data/pantograph/lib/pantograph/runner.rb +371 -0
  140. data/pantograph/lib/pantograph/server/action_command.rb +61 -0
  141. data/pantograph/lib/pantograph/server/action_command_return.rb +14 -0
  142. data/pantograph/lib/pantograph/server/command_executor.rb +7 -0
  143. data/pantograph/lib/pantograph/server/command_parser.rb +36 -0
  144. data/pantograph/lib/pantograph/server/control_command.rb +23 -0
  145. data/pantograph/lib/pantograph/server/json_return_value_processor.rb +72 -0
  146. data/pantograph/lib/pantograph/server/socket_server.rb +232 -0
  147. data/pantograph/lib/pantograph/server/socket_server_action_command_executor.rb +101 -0
  148. data/pantograph/lib/pantograph/setup/setup.rb +290 -0
  149. data/pantograph/lib/pantograph/setup/setup_android.rb +64 -0
  150. data/pantograph/lib/pantograph/setup/setup_ios.rb +412 -0
  151. data/pantograph/lib/pantograph/shells.rb +6 -0
  152. data/pantograph/lib/pantograph/supported_platforms.rb +28 -0
  153. data/pantograph/lib/pantograph/tools.rb +10 -0
  154. data/pantograph/lib/pantograph/version.rb +5 -0
  155. data/pantograph/lib/pantograph.rb +51 -0
  156. data/pantograph_core/README.md +79 -0
  157. data/pantograph_core/lib/assets/XMLTemplate.xml.erb +12 -0
  158. data/pantograph_core/lib/pantograph_core/analytics/action_completion_context.rb +34 -0
  159. data/pantograph_core/lib/pantograph_core/analytics/action_launch_context.rb +38 -0
  160. data/pantograph_core/lib/pantograph_core/analytics/analytics_event_builder.rb +23 -0
  161. data/pantograph_core/lib/pantograph_core/analytics/analytics_ingester_client.rb +54 -0
  162. data/pantograph_core/lib/pantograph_core/analytics/analytics_session.rb +71 -0
  163. data/pantograph_core/lib/pantograph_core/cert_checker.rb +116 -0
  164. data/pantograph_core/lib/pantograph_core/command_executor.rb +99 -0
  165. data/pantograph_core/lib/pantograph_core/configuration/commander_generator.rb +103 -0
  166. data/pantograph_core/lib/pantograph_core/configuration/config_item.rb +314 -0
  167. data/pantograph_core/lib/pantograph_core/configuration/configuration.rb +332 -0
  168. data/pantograph_core/lib/pantograph_core/configuration/configuration_file.rb +182 -0
  169. data/pantograph_core/lib/pantograph_core/core_ext/shellwords.rb +63 -0
  170. data/pantograph_core/lib/pantograph_core/core_ext/string.rb +17 -0
  171. data/pantograph_core/lib/pantograph_core/env.rb +9 -0
  172. data/pantograph_core/lib/pantograph_core/feature/feature.rb +51 -0
  173. data/pantograph_core/lib/pantograph_core/features.rb +4 -0
  174. data/pantograph_core/lib/pantograph_core/globals.rb +27 -0
  175. data/pantograph_core/lib/pantograph_core/helper.rb +409 -0
  176. data/pantograph_core/lib/pantograph_core/keychain_importer.rb +74 -0
  177. data/pantograph_core/lib/pantograph_core/languages.rb +14 -0
  178. data/pantograph_core/lib/pantograph_core/module.rb +29 -0
  179. data/pantograph_core/lib/pantograph_core/pantograph_folder.rb +39 -0
  180. data/pantograph_core/lib/pantograph_core/pantograph_pty.rb +57 -0
  181. data/pantograph_core/lib/pantograph_core/pkg_file_analyser.rb +44 -0
  182. data/pantograph_core/lib/pantograph_core/print_table.rb +131 -0
  183. data/pantograph_core/lib/pantograph_core/string_filters.rb +51 -0
  184. data/pantograph_core/lib/pantograph_core/swag.rb +85 -0
  185. data/pantograph_core/lib/pantograph_core/tag_version.rb +31 -0
  186. data/pantograph_core/lib/pantograph_core/test_parser.rb +107 -0
  187. data/pantograph_core/lib/pantograph_core/ui/disable_colors.rb +17 -0
  188. data/pantograph_core/lib/pantograph_core/ui/errors/pantograph_common_error.rb +19 -0
  189. data/pantograph_core/lib/pantograph_core/ui/errors/pantograph_crash.rb +11 -0
  190. data/pantograph_core/lib/pantograph_core/ui/errors/pantograph_error.rb +25 -0
  191. data/pantograph_core/lib/pantograph_core/ui/errors/pantograph_exception.rb +19 -0
  192. data/pantograph_core/lib/pantograph_core/ui/errors/pantograph_shell_error.rb +11 -0
  193. data/pantograph_core/lib/pantograph_core/ui/errors.rb +1 -0
  194. data/pantograph_core/lib/pantograph_core/ui/github_issue_inspector_reporter.rb +62 -0
  195. data/pantograph_core/lib/pantograph_core/ui/implementations/shell.rb +159 -0
  196. data/pantograph_core/lib/pantograph_core/ui/interface.rb +205 -0
  197. data/pantograph_core/lib/pantograph_core/ui/pantograph_runner.rb +276 -0
  198. data/pantograph_core/lib/pantograph_core/ui/ui.rb +26 -0
  199. data/pantograph_core/lib/pantograph_core/update_checker/changelog.rb +37 -0
  200. data/pantograph_core/lib/pantograph_core/update_checker/update_checker.rb +107 -0
  201. data/pantograph_core/lib/pantograph_core.rb +45 -0
  202. metadata +987 -0
@@ -0,0 +1,140 @@
1
+ require_relative 'lane_manager_base.rb'
2
+
3
+ module Pantograph
4
+ class LaneManager < LaneManagerBase
5
+ # @param platform The name of the platform to execute
6
+ # @param lane_name The name of the lane to execute
7
+ # @param parameters [Hash] The parameters passed from the command line to the lane
8
+ # @param env Dot Env Information
9
+ # @param A custom Pantfile path, this is used by pantograph.ci
10
+ # rubocop:disable Metrics/PerceivedComplexity
11
+ def self.cruise_lane(platform, lane, parameters = nil, env = nil, pantfile_path = nil)
12
+ UI.user_error!('lane must be a string') unless lane.kind_of?(String) || lane.nil?
13
+ UI.user_error!('platform must be a string') unless platform.kind_of?(String) || platform.nil?
14
+ UI.user_error!('parameters must be a hash') unless parameters.kind_of?(Hash) || parameters.nil?
15
+
16
+ ff = Pantograph::PantFile.new(pantfile_path || PantographCore::PantographFolder.pantfile_path)
17
+
18
+ is_platform = false
19
+ begin
20
+ is_platform = ff.is_platform_block?(lane)
21
+ rescue # rescue, because this raises an exception if it can't be found at all
22
+ end
23
+
24
+ unless is_platform
25
+ # maybe the user specified a default platform
26
+ # We'll only do this, if the lane specified isn't a platform, as we want to list all platforms then
27
+
28
+ # Make sure that's not a lane without a platform
29
+ unless ff.runner.available_lanes.include?(lane)
30
+ platform ||= Actions.lane_context[Actions::SharedValues::DEFAULT_PLATFORM]
31
+ end
32
+ end
33
+
34
+ if !platform && lane
35
+ # Either, the user runs a specific lane in root or want to auto complete the available lanes for a platform
36
+ # e.g. `pantograph ios` should list all available iOS actions
37
+ if ff.is_platform_block?(lane)
38
+ platform = lane
39
+ lane = nil
40
+ end
41
+ end
42
+
43
+ platform, lane = choose_lane(ff, platform) unless lane
44
+
45
+ # xcodeproj has a bug in certain versions that causes it to change directories
46
+ # and not return to the original working directory
47
+ # https://github.com/CocoaPods/Xcodeproj/issues/426
48
+ # Setting this environment variable causes xcodeproj to work around the problem
49
+ ENV["FORK_XCODE_WRITING"] = "true" unless platform == 'android'
50
+
51
+ Pantograph::Helper::DotenvHelper.load_dot_env(env)
52
+
53
+ started = Time.now
54
+ e = nil
55
+ begin
56
+ ff.runner.execute(lane, platform, parameters)
57
+ rescue NameError => ex
58
+ print_lane_context
59
+ print_error_line(ex)
60
+ e = ex
61
+ rescue Exception => ex # rubocop:disable Lint/RescueException
62
+ # We also catch Exception, since the implemented action might send a SystemExit signal
63
+ # (or similar). We still want to catch that, since we want properly finish running pantograph
64
+ # Tested with `xcake`, which throws a `Xcake::Informative` object
65
+
66
+ print_lane_context
67
+ print_error_line(ex)
68
+ UI.error(ex.to_s) if ex.kind_of?(StandardError) # we don't want to print things like 'system exit'
69
+ e = ex
70
+ end
71
+
72
+ # After running the lanes, since skip_docs might be somewhere in-between
73
+ Pantograph::DocsGenerator.run(ff) unless skip_docs?
74
+
75
+ duration = ((Time.now - started) / 60.0).round
76
+ finish_pantograph(ff, duration, e)
77
+
78
+ return ff
79
+ end
80
+ # rubocop:enable Metrics/PerceivedComplexity
81
+
82
+ def self.skip_docs?
83
+ Helper.test? || PantographCore::Env.truthy?("PANTOGRAPH_SKIP_DOCS")
84
+ end
85
+
86
+ # Lane chooser if user didn't provide a lane
87
+ # @param platform: is probably nil, but user might have called `pantograph android`, and only wants to list those actions
88
+ def self.choose_lane(ff, platform)
89
+ available = []
90
+
91
+ # nil is the key for lanes that are not under a specific platform
92
+ lane_platforms = [nil] + Pantograph::SupportedPlatforms.all
93
+ lane_platforms.each do |p|
94
+ available += ff.runner.lanes[p].to_a.reject { |lane| lane.last.is_private }
95
+ end
96
+
97
+ if available.empty?
98
+ UI.user_error!("It looks like you don't have any lanes to run just yet. Check out how to get started here: https://github.com/pantograph/pantograph 🚀")
99
+ end
100
+
101
+ rows = []
102
+ available.each_with_index do |lane, index|
103
+ rows << [index + 1, lane.last.pretty_name, lane.last.description.join("\n")]
104
+ end
105
+
106
+ rows << [0, "cancel", "No selection, exit pantograph!"]
107
+
108
+ require 'terminal-table'
109
+
110
+ table = Terminal::Table.new(
111
+ title: "Available lanes to run",
112
+ headings: ['Number', 'Lane Name', 'Description'],
113
+ rows: PantographCore::PrintTable.transform_output(rows)
114
+ )
115
+
116
+ UI.message("Welcome to pantograph! Here's what your app is setup to do:")
117
+
118
+ puts(table)
119
+
120
+ i = UI.input("Which number would you like run?")
121
+
122
+ i = i.to_i - 1
123
+ if i >= 0 && available[i]
124
+ selection = available[i].last.pretty_name
125
+ UI.important("Running lane `#{selection}`. Next time you can do this by directly typing `pantograph #{selection}` 🚀.")
126
+ platform = selection.split(' ')[0]
127
+ lane_name = selection.split(' ')[1]
128
+
129
+ unless lane_name # no specific platform, just a root lane
130
+ lane_name = platform
131
+ platform = nil
132
+ end
133
+
134
+ return platform, lane_name # yeah
135
+ else
136
+ UI.user_error!("Run `pantograph` the next time you need to build, test or release your app 🚀")
137
+ end
138
+ end
139
+ end
140
+ end
@@ -0,0 +1,92 @@
1
+ module Pantograph
2
+ # Base class for all LaneManager classes
3
+ # Takes care of all common things like printing the lane description tables and loading .env files
4
+ class LaneManagerBase
5
+ def self.skip_docs?
6
+ Helper.test? || PantographCore::Env.truthy?("PANTOGRAPH_SKIP_DOCS")
7
+ end
8
+
9
+ # All the finishing up that needs to be done
10
+ def self.finish_pantograph(ff, duration, error, skip_message: false)
11
+ # Sometimes we don't have a pantfile
12
+ unless ff.nil?
13
+ ff.runner.did_finish
14
+ end
15
+
16
+ # Finished with all the lanes
17
+ Pantograph::JUnitGenerator.generate(Pantograph::Actions.executed_actions)
18
+ print_table(Pantograph::Actions.executed_actions)
19
+
20
+ Pantograph::PluginUpdateManager.show_update_status
21
+
22
+ if error
23
+ UI.error('pantograph finished with errors') unless skip_message
24
+ raise error
25
+ elsif duration > 5
26
+ UI.success("pantograph.tools just saved you #{duration} minutes! 🎉") unless skip_message
27
+ else
28
+ UI.success('pantograph.tools finished successfully 🎉') unless skip_message
29
+ end
30
+ end
31
+
32
+ # Print a table as summary of the executed actions
33
+ def self.print_table(actions)
34
+ return if actions.count == 0
35
+ return if PantographCore::Env.truthy?('PANTOGRAPH_SKIP_ACTION_SUMMARY') # User disabled table output
36
+
37
+ require 'terminal-table'
38
+
39
+ rows = []
40
+ actions.each_with_index do |current, i|
41
+ is_error_step = !current[:error].to_s.empty?
42
+
43
+ name = current[:name][0..60]
44
+ name = name.red if is_error_step
45
+ index = i + 1
46
+ index = "💥" if is_error_step
47
+ rows << [index, name, current[:time].to_i]
48
+ end
49
+
50
+ puts("")
51
+ puts(Terminal::Table.new(
52
+ title: "pantograph summary".green,
53
+ headings: ["Step", "Action", "Time (in s)"],
54
+ rows: PantographCore::PrintTable.transform_output(rows)
55
+ ))
56
+ puts("")
57
+ end
58
+
59
+ def self.print_lane_context
60
+ return if Actions.lane_context.empty?
61
+
62
+ if PantographCore::Globals.verbose?
63
+ UI.important('Lane Context:'.yellow)
64
+ UI.message(Actions.lane_context)
65
+ return
66
+ end
67
+
68
+ # Print a nice table unless in PantographCore::Globals.verbose? mode
69
+ rows = Actions.lane_context.collect do |key, content|
70
+ [key, content.to_s]
71
+ end
72
+
73
+ require 'terminal-table'
74
+ puts(Terminal::Table.new({
75
+ title: "Lane Context".yellow,
76
+ rows: PantographCore::PrintTable.transform_output(rows)
77
+ }))
78
+ end
79
+
80
+ def self.print_error_line(ex)
81
+ error_line = ex.backtrace.first
82
+ return if error_line.nil?
83
+
84
+ error_line = error_line.match("Pantfile:(\\d+):")
85
+ return unless error_line
86
+
87
+ line = error_line[1]
88
+ UI.error("Error in your Pantfile at line #{line}")
89
+ UI.content_error(File.read(PantographCore::PantographFolder.pantfile_path, encoding: "utf-8"), line)
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,62 @@
1
+ module Pantograph
2
+ class MarkdownTableFormatter
3
+ # taken from: https://github.com/benbalter/markdown-table-formatter
4
+ def initialize(string, header = true)
5
+ @doc = string
6
+ @header = header
7
+ end
8
+
9
+ # converts the markdown string into an array of arrays
10
+ def parse
11
+ @table = []
12
+ rows = @doc.split(/\r?\n/)
13
+ rows.each do |row|
14
+ row_array = row.split("|")
15
+ row_array.each(&:strip!)
16
+ @table.push(row_array)
17
+ end
18
+ @table.delete_at(1) if @header # strip header separator
19
+ @table
20
+ end
21
+
22
+ def table
23
+ @table ||= parse
24
+ end
25
+
26
+ def column_width(column)
27
+ width = 0
28
+ table.each do |row|
29
+ length = row[column].strip.length
30
+ width = length if length > width
31
+ end
32
+ width
33
+ end
34
+
35
+ def pad(string, length)
36
+ string.strip.ljust(length, ' ')
37
+ end
38
+
39
+ def separator(length)
40
+ "".ljust(length, '-')
41
+ end
42
+
43
+ def header_separator_row
44
+ output = []
45
+ [*0...table.first.length].each do |column|
46
+ output.push(separator(column_width(column)))
47
+ end
48
+ output
49
+ end
50
+
51
+ def to_md
52
+ output = ""
53
+ t = table.clone
54
+ t.insert(1, header_separator_row) if @header
55
+ t.each_with_index do |row, index|
56
+ row.map!.with_index { |cell_row, index_row| pad(cell_row, column_width(index_row)) }
57
+ output += "#{row.join(' | ').lstrip} |\n"
58
+ end
59
+ output
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,47 @@
1
+ module Pantograph
2
+ # Guides the new user through creating a new action
3
+ module NewAction
4
+ def self.run(new_action_name: nil)
5
+ name = new_action_name && check_action_name_from_args(new_action_name) ? new_action_name : fetch_name
6
+ generate_action(name)
7
+ end
8
+
9
+ def self.fetch_name
10
+ puts("Must be lower case, and use a '_' between words. Do not use '.'".green)
11
+ puts("examples: 'testflight', 'upload_to_s3'".green)
12
+ name = UI.input("Name of your action: ")
13
+ until name_valid?(name)
14
+ puts("Name is invalid. Please ensure the name is all lowercase, free of spaces and without special characters! Try again.")
15
+ name = UI.input("Name of your action: ")
16
+ end
17
+ name
18
+ end
19
+
20
+ def self.generate_action(name)
21
+ template = File.read("#{Pantograph::ROOT}/lib/assets/custom_action_template.rb")
22
+ template.gsub!('[[NAME]]', name)
23
+ template.gsub!('[[NAME_UP]]', name.upcase)
24
+ template.gsub!('[[NAME_CLASS]]', name.pantograph_class + 'Action')
25
+
26
+ actions_path = File.join((PantographCore::PantographFolder.path || Dir.pwd), 'actions')
27
+ FileUtils.mkdir_p(actions_path) unless File.directory?(actions_path)
28
+
29
+ path = File.join(actions_path, "#{name}.rb")
30
+ File.write(path, template)
31
+ UI.success("Created new action file '#{path}'. Edit it to implement your custom action.")
32
+ end
33
+
34
+ def self.check_action_name_from_args(new_action_name)
35
+ if name_valid?(new_action_name)
36
+ new_action_name
37
+ else
38
+ puts("Name is invalid. Please ensure the name is all lowercase, free of spaces and without special characters! Try again.")
39
+ end
40
+ end
41
+
42
+ def self.name_valid?(name)
43
+ name =~ /^[a-z0-9_]+$/
44
+ end
45
+ private_class_method :name_valid?
46
+ end
47
+ end
@@ -0,0 +1,45 @@
1
+ module Pantograph
2
+ # Call actions without triggering a full lane
3
+ class OneOff
4
+ def self.execute(args: nil)
5
+ action_parameters = {}
6
+ action_name = nil
7
+
8
+ args.each do |current|
9
+ if current.include?(":") # that's a key/value which we want to pass to the lane
10
+ key, value = current.split(":", 2)
11
+ UI.user_error!("Please pass values like this: key:value") unless key.length > 0
12
+ value = CommandLineHandler.convert_value(value)
13
+ UI.verbose("Using #{key}: #{value}")
14
+ action_parameters[key.to_sym] = value
15
+ else
16
+ action_name ||= current
17
+ end
18
+ end
19
+
20
+ UI.crash!("invalid syntax") unless action_name
21
+
22
+ run(action: action_name,
23
+ parameters: action_parameters)
24
+ end
25
+
26
+ def self.run(action: nil, parameters: nil)
27
+ Pantograph.load_actions
28
+
29
+ class_ref = Actions.action_class_ref(action)
30
+ unless class_ref
31
+ if Pantograph::Actions.formerly_bundled_actions.include?(action)
32
+ # This was a formerly bundled action which is now a plugin.
33
+ UI.verbose(caller.join("\n"))
34
+ UI.user_error!("The action '#{action}' is no longer bundled with pantograph. You can install it using `pantograph add_plugin #{action}`")
35
+ else
36
+ Pantograph::ActionsList.print_suggestions(action)
37
+ UI.user_error!("Action '#{action}' not available, run `pantograph actions` to get a full list")
38
+ end
39
+ end
40
+
41
+ r = Runner.new
42
+ r.execute_action(action, class_ref, [parameters], custom_dir: '.')
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,29 @@
1
+ module Pantograph
2
+ # This class is used to call other actions from within actions
3
+ # We use a separate class so that we can easily identify when
4
+ # we have dependencies between actions
5
+ class OtherAction
6
+ attr_accessor :runner
7
+
8
+ def initialize(runner)
9
+ self.runner = runner
10
+ end
11
+
12
+ # Allows the user to call an action from an action
13
+ def method_missing(method_sym, *arguments, &_block)
14
+ # We have to go inside the pantograph directory
15
+ # since in the pantograph runner.rb we do the following
16
+ # custom_dir = ".."
17
+ # Dir.chdir(custom_dir) do
18
+ # this goes one folder up, since we're inside the "pantograph"
19
+ # folder at that point
20
+ # Since we call an action from an action we need to go inside
21
+ # the pantograph folder too
22
+
23
+ self.runner.trigger_action_by_name(method_sym,
24
+ PantographCore::PantographFolder.path,
25
+ true,
26
+ *arguments)
27
+ end
28
+ end
29
+ end