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,412 @@
1
+ module Pantograph
2
+ class SetupIos < Setup
3
+ # Reference to the iOS project `project.rb`
4
+ attr_accessor :project
5
+
6
+ # App Identifier of the current app
7
+ attr_accessor :app_identifier
8
+
9
+ # Scheme of the Xcode project
10
+ attr_accessor :scheme
11
+
12
+ # If the current setup requires a login, this is where we'll store the team ID
13
+ attr_accessor :itc_team_id
14
+ attr_accessor :adp_team_id
15
+
16
+ attr_accessor :app_exists_on_itc
17
+
18
+ attr_accessor :automatic_versioning_enabled
19
+
20
+ def setup_ios
21
+ require 'spaceship'
22
+
23
+ self.platform = :ios
24
+
25
+ welcome_to_pantograph
26
+
27
+ self.pantfile_content = pantfile_template_content
28
+
29
+ if preferred_setup_method
30
+ self.send(preferred_setup_method)
31
+
32
+ return
33
+ end
34
+
35
+ options = {
36
+ "📸 Automate screenshots" => :ios_screenshots,
37
+ "👩‍✈️ Automate beta distribution to TestFlight" => :ios_testflight,
38
+ "🚀 Automate App Store distribution" => :ios_app_store,
39
+ "🛠 Manual setup - manually setup your project to automate your tasks" => :ios_manual
40
+ }
41
+
42
+ selected = UI.select("What would you like to use pantograph for?", options.keys)
43
+ @method_to_use = options[selected]
44
+
45
+ begin
46
+ self.send(@method_to_use)
47
+ rescue => ex
48
+ # If it's already manual, and it has failed
49
+ # we need to re-raise the exception, as something definitely is wrong
50
+ raise ex if @method_to_use == :ios_manual
51
+
52
+ # If we're here, that means something else failed. We now show the
53
+ # error message and fallback to `:ios_manual`
54
+ UI.error("--------------------")
55
+ UI.error("pantograph init failed")
56
+ UI.error("--------------------")
57
+
58
+ UI.verbose(ex.backtrace.join("\n"))
59
+ if ex.kind_of?(Spaceship::Client::BasicPreferredInfoError) || ex.kind_of?(Spaceship::Client::UnexpectedResponse)
60
+ UI.error(ex.preferred_error_info)
61
+ else
62
+ UI.error(ex.to_s)
63
+ end
64
+
65
+ UI.important("Something failed while running `pantograph init`")
66
+ UI.important("Tried using Apple ID with email '#{self.user}'")
67
+ UI.important("You can either retry, or fallback to manual setup which will create a basic Pantfile")
68
+ if UI.confirm("Would you like to fallback to a manual Pantfile?")
69
+ self.ios_manual
70
+ else
71
+ self.send(@method_to_use)
72
+ end
73
+ # the second time, we're just failing, and don't use a `begin` `rescue` block any more
74
+ end
75
+ end
76
+
77
+ # Different iOS flows
78
+ def ios_testflight
79
+ UI.header("Setting up pantograph for iOS TestFlight distribution")
80
+ find_and_setup_xcode_project
81
+ apple_xcode_project_versioning_enabled
82
+ ask_for_credentials(adp: true, itc: true)
83
+ verify_app_exists_adp!
84
+ verify_app_exists_itc!
85
+
86
+ lane = ["desc \"Push a new beta build to TestFlight\"",
87
+ "lane :beta do",
88
+ increment_build_number_if_applicable,
89
+ " build_app(#{project_prefix}scheme: \"#{self.scheme}\")",
90
+ " upload_to_testflight",
91
+ "end"]
92
+
93
+ self.append_lane(lane)
94
+
95
+ self.lane_to_mention = "beta"
96
+ finish_up
97
+ end
98
+
99
+ def ios_app_store
100
+ UI.header("Setting up pantograph for iOS App Store distribution")
101
+ find_and_setup_xcode_project
102
+ apple_xcode_project_versioning_enabled
103
+ ask_for_credentials(adp: true, itc: true)
104
+ verify_app_exists_adp!
105
+ verify_app_exists_itc!
106
+
107
+ if self.app_exists_on_itc
108
+ UI.header("Manage app metadata?")
109
+ UI.message("Would you like to have pantograph manage your app's metadata?")
110
+ UI.message("If you enable this feature, pantograph will download your existing metadata and screenshots.")
111
+ UI.message("This way, you'll be able to edit your app's metadata in local `.txt` files.")
112
+ UI.message("After editing the local `.txt` files, just run pantograph and all changes will be pushed up.")
113
+ UI.message("If you don't want to use this feature, you can still use pantograph to upload and distribute new builds to the App Store")
114
+ end
115
+
116
+ lane = ["desc \"Push a new release build to the App Store\"",
117
+ "lane :release do",
118
+ increment_build_number_if_applicable,
119
+ " build_app(#{project_prefix}scheme: \"#{self.scheme}\")"]
120
+ if include_metadata
121
+ lane << " upload_to_app_store"
122
+ else
123
+ lane << " upload_to_app_store(skip_metadata: true, skip_screenshots: true)"
124
+ end
125
+ lane << "end"
126
+
127
+ append_lane(lane)
128
+ self.lane_to_mention = "release"
129
+ finish_up
130
+ end
131
+
132
+ def ios_screenshots
133
+ UI.header("Setting up pantograph to automate iOS screenshots")
134
+
135
+ UI.message("pantograph uses UI Tests to automate generating localized screenshots of your iOS app")
136
+ UI.message("pantograph will now create 2 helper files that are needed to get the setup running")
137
+ UI.message("For more information on how this works and best practices, check out")
138
+ UI.message("\thttps://docs.pantograph.tools/getting-started/ios/screenshots/".cyan)
139
+ continue_with_enter
140
+
141
+ begin
142
+ find_and_setup_xcode_project(ask_for_scheme: false) # to get the bundle identifier
143
+ rescue => ex
144
+ # If this fails, it's no big deal, since we really just want the bundle identifier
145
+ # so instead, we'll just ask the user
146
+ UI.verbose(ex.to_s)
147
+ end
148
+
149
+ continue_with_enter
150
+
151
+ available_schemes = self.project.schemes
152
+ ui_testing_scheme = UI.select("Which is your UI Testing scheme? If you can't find it in this list, make sure it's marked as `Shared` in the Xcode scheme list", available_schemes)
153
+
154
+ UI.header("Automatically upload to iTC?")
155
+ UI.message("Would you like pantograph to automatically upload all generated screenshots to App Store Connect")
156
+ UI.message("after generating them?")
157
+ UI.message("If you enable this feature you'll need to provide your App Store Connect credentials so pantograph can upload the screenshots to App Store Connect")
158
+ automatic_upload = UI.confirm("Enable automatic upload of localized screenshots to App Store Connect?")
159
+ if automatic_upload
160
+ ask_for_credentials(adp: true, itc: true)
161
+ verify_app_exists_itc!
162
+ end
163
+
164
+ lane = ["desc \"Generate new localized screenshots\"",
165
+ "lane :screenshots do",
166
+ " capture_screenshots(#{project_prefix}scheme: \"#{ui_testing_scheme}\")"]
167
+
168
+ if automatic_upload
169
+ lane << " upload_to_app_store(skip_binary_upload: true, skip_metadata: true)"
170
+ end
171
+ lane << "end"
172
+
173
+ append_lane(lane)
174
+
175
+ self.lane_to_mention = "screenshots"
176
+ finish_up
177
+ end
178
+
179
+ def ios_manual
180
+ UI.header("Setting up pantograph so you can manually configure it")
181
+
182
+ append_lane(["desc \"Description of what the lane does\"",
183
+ "lane :custom_lane do",
184
+ " # add actions here: https://docs.pantograph.tools/actions",
185
+ "end"])
186
+ self.lane_to_mention = "custom_lane"
187
+
188
+ finish_up
189
+ end
190
+
191
+ # Helpers
192
+
193
+ # Every installation setup that needs an Xcode project should
194
+ # call this method
195
+ def find_and_setup_xcode_project(ask_for_scheme: true)
196
+ UI.message("Parsing your local Xcode project to find the available schemes and the app identifier")
197
+ config = {} # this is needed as the first method call will store information in there
198
+ if self.project_path.end_with?("xcworkspace")
199
+ config[:workspace] = self.project_path
200
+ else
201
+ config[:project] = self.project_path
202
+ end
203
+
204
+ PantographCore::Project.detect_projects(config)
205
+ self.project = PantographCore::Project.new(config)
206
+
207
+ if ask_for_scheme
208
+ self.scheme = self.project.select_scheme(preferred_to_include: self.project.project_name)
209
+ end
210
+
211
+ self.app_identifier = self.project.default_app_identifier # These two vars need to be accessed in order to be set
212
+ if self.app_identifier.to_s.length == 0
213
+ ask_for_bundle_identifier
214
+ end
215
+ end
216
+
217
+ def ask_for_bundle_identifier
218
+ loop do
219
+ return if self.app_identifier.to_s.length > 0
220
+ self.app_identifier = UI.input("Bundle identifier of your app: ")
221
+ end
222
+ end
223
+
224
+ def ask_for_credentials(itc: true, adp: false)
225
+ UI.header("Login with your Apple ID")
226
+ UI.message("To use App Store Connect and Apple Developer Portal features as part of pantograph,")
227
+ UI.message("we will ask you for your Apple ID username and password")
228
+ UI.message("This is necessary for certain pantograph features, for example:")
229
+ UI.message("")
230
+ UI.message("- Create and manage your provisioning profiles on the Developer Portal")
231
+ UI.message("- Upload and manage TestFlight and App Store builds on App Store Connect")
232
+ UI.message("- Manage your App Store Connect app metadata and screenshots")
233
+ UI.message("")
234
+ UI.message("Your Apple ID credentials will only be stored in your Keychain, on your local machine")
235
+ UI.message("For more information, check out")
236
+ UI.message("\thttps://github.com/pantograph/pantograph/tree/master/credentials_manager".cyan)
237
+ UI.message("")
238
+
239
+ if self.user.to_s.length == 0
240
+ UI.important("Please enter your Apple ID developer credentials")
241
+ self.user = UI.input("Apple ID Username:")
242
+ end
243
+ UI.message("Logging in...")
244
+
245
+ # Disable the warning texts and information that's not relevant during onboarding
246
+ ENV["PANTOGRAPH_HIDE_LOGIN_INFORMATION"] = 1.to_s
247
+ ENV["PANTOGRAPH_HIDE_TEAM_INFORMATION"] = 1.to_s
248
+
249
+ if itc
250
+ Spaceship::Tunes.login(self.user)
251
+ Spaceship::Tunes.select_team
252
+ self.itc_team_id = Spaceship::Tunes.client.team_id
253
+
254
+ end
255
+
256
+ if adp
257
+ Spaceship::Portal.login(self.user)
258
+ Spaceship::Portal.select_team
259
+ self.adp_team_id = Spaceship::Portal.client.team_id
260
+
261
+ end
262
+
263
+ UI.success("✅ Logging in with your Apple ID was successful")
264
+ end
265
+
266
+ def apple_xcode_project_versioning_enabled
267
+ self.automatic_versioning_enabled = false
268
+
269
+ paths = self.project.project_paths
270
+ return false if paths.count == 0
271
+
272
+ result = Pantograph::Actions::GetBuildNumberAction.run({
273
+ project: paths.first, # most of the times, there will only be one project in there
274
+ hide_error_when_versioning_disabled: true
275
+ })
276
+
277
+ if result.kind_of?(String) && result.to_f > 0
278
+ self.automatic_versioning_enabled = true
279
+ end
280
+ return self.automatic_versioning_enabled
281
+ end
282
+
283
+ def show_information_about_version_bumps
284
+ UI.important("It looks like your project isn't set up to do automatic version incrementing")
285
+ UI.important("To enable pantograph to handle automatic version incrementing for you, please follow this guide:")
286
+ UI.message("\thttps://developer.apple.com/library/content/qa/qa1827/_index.html".cyan)
287
+ UI.important("Afterwards check out the pantograph docs on how to set up automatic build increments")
288
+ UI.message("\thttps://docs.pantograph.tools/getting-started/ios/beta-deployment/#best-practices".cyan)
289
+ end
290
+
291
+ def verify_app_exists_adp!
292
+ UI.user_error!("No app identifier provided") if self.app_identifier.to_s.length == 0
293
+ UI.message("Checking if the app '#{self.app_identifier}' exists in your Apple Developer Portal...")
294
+ app = Spaceship::Portal::App.find(self.app_identifier)
295
+ if app.nil?
296
+ UI.error("It looks like the app '#{self.app_identifier}' isn't available on the #{'Apple Developer Portal'.bold.underline}")
297
+ UI.error("for the team ID '#{self.adp_team_id}' on Apple ID '#{self.user}'")
298
+
299
+ if UI.confirm("Do you want pantograph to create the App ID for you on the Apple Developer Portal?")
300
+ create_app_online!(mode: :adp)
301
+ else
302
+ UI.important("Alright, we won't create the app for you. Be aware, the build is probably going to fail when you try it")
303
+ end
304
+ else
305
+ UI.success("✅ Your app '#{self.app_identifier}' is available in your Apple Developer Portal")
306
+ end
307
+ end
308
+
309
+ def verify_app_exists_itc!
310
+ UI.user_error!("No app identifier provided") if self.app_identifier.to_s.length == 0
311
+ UI.message("Checking if the app '#{self.app_identifier}' exists on App Store Connect...")
312
+ app = Spaceship::Tunes::Application.find(self.app_identifier)
313
+ if app.nil?
314
+ UI.error("Looks like the app '#{self.app_identifier}' isn't available on #{'App Store Connect'.bold.underline}")
315
+ UI.error("for the team ID '#{self.itc_team_id}' on Apple ID '#{self.user}'")
316
+ if UI.confirm("Would you like pantograph to create the App on App Store Connect for you?")
317
+ create_app_online!(mode: :itc)
318
+ self.app_exists_on_itc = true
319
+ else
320
+ UI.important("Alright, we won't create the app for you. Be aware, the build is probably going to fail when you try it")
321
+ end
322
+ else
323
+ UI.success("✅ Your app '#{self.app_identifier}' is available on App Store Connect")
324
+ self.app_exists_on_itc = true
325
+ end
326
+ end
327
+
328
+ def finish_up
329
+ # iOS specific things first
330
+ if !self.automatic_versioning_enabled && @method_to_use != :ios_manual
331
+ self.show_information_about_version_bumps
332
+ end
333
+
334
+ super
335
+ end
336
+
337
+ # Returns the `workspace` or `project` key/value pair for
338
+ # gym, but only if necessary
339
+ # (when there are multiple projects in the current directory)
340
+ # it's a prefix, and not a suffix, as Swift cares about the order of parameters
341
+ def project_prefix
342
+ return "" unless self.had_multiple_projects_to_choose_from
343
+
344
+ if self.project_path.end_with?(".xcworkspace")
345
+ return "workspace: \"#{self.project_path}\", "
346
+ else
347
+ return "project: \"#{self.project_path}\", "
348
+ end
349
+ end
350
+
351
+ def increment_build_number_if_applicable
352
+ return nil unless self.automatic_versioning_enabled
353
+ return nil if self.project.project_paths.first.to_s.length == 0
354
+
355
+ project_path = self.project.project_paths.first
356
+ # Convert the absolute path to a relative path
357
+ project_path_name = Pathname.new(project_path)
358
+ current_path_name = Pathname.new(File.expand_path("."))
359
+
360
+ relative_project_path = project_path_name.relative_path_from(current_path_name)
361
+
362
+ return " increment_build_number(xcodeproj: \"#{relative_project_path}\")"
363
+ end
364
+
365
+ def create_app_online!(mode: nil)
366
+ # mode is either :adp or :itc
367
+ require 'produce'
368
+ produce_options = {
369
+ username: self.user,
370
+ team_id: self.adp_team_id,
371
+ itc_team_id: self.itc_team_id,
372
+ platform: "ios",
373
+ app_identifier: self.app_identifier
374
+ }
375
+ if mode == :adp
376
+ produce_options[:skip_itc] = true
377
+ else
378
+ produce_options[:skip_devcenter] = true
379
+ end
380
+
381
+ # The retrying system allows people to correct invalid inputs
382
+ # e.g. the app's name is already taken
383
+ loop do
384
+ # Creating config in the loop so user will be reprompted
385
+ # for app name if app name is taken or too long
386
+ Produce.config = PantographCore::Configuration.create(
387
+ Produce::Options.available_options,
388
+ produce_options
389
+ )
390
+
391
+ begin
392
+ Produce::Manager.start_producing
393
+ UI.success("✅ Successfully created app")
394
+ return # success
395
+ rescue => ex
396
+ # show the user facing error, and inform them of what went wrong
397
+ if ex.kind_of?(Spaceship::Client::BasicPreferredInfoError) || ex.kind_of?(Spaceship::Client::UnexpectedResponse)
398
+ UI.error(ex.preferred_error_info)
399
+ else
400
+ UI.error(ex.to_s)
401
+ end
402
+ UI.error(ex.backtrace.join("\n")) if PantographCore::Globals.verbose?
403
+ UI.important("It looks like something went wrong when we tried to create your app on the Apple Developer Portal")
404
+ unless UI.confirm("Would you like to try again (y)? If you enter (n), pantograph will fall back to the manual setup")
405
+ raise ex
406
+ end
407
+ end
408
+ end
409
+ end
410
+ end
411
+ # rubocop:enable Metrics/ClassLength
412
+ end
@@ -0,0 +1,6 @@
1
+ module Pantograph
2
+ SHELLS = [
3
+ :bash,
4
+ :zsh
5
+ ]
6
+ end
@@ -0,0 +1,28 @@
1
+ module Pantograph
2
+ class SupportedPlatforms
3
+ class << self
4
+ attr_accessor :extra
5
+ attr_reader :default
6
+
7
+ def extra=(value)
8
+ value ||= []
9
+ UI.important("Setting '#{value}' as extra SupportedPlatforms")
10
+ @extra = value
11
+ end
12
+ end
13
+
14
+ @default = [:ios, :mac, :android]
15
+ @extra = []
16
+
17
+ def self.all
18
+ (@default + @extra).flatten
19
+ end
20
+
21
+ # this will log a warning if the passed platform is not supported
22
+ def self.verify!(platform)
23
+ unless all.include?(platform.to_s.to_sym)
24
+ UI.important("Platform '#{platform}' is not officially supported. Currently supported platforms are #{self.all}.")
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,10 @@
1
+ module Pantograph
2
+ TOOLS = [
3
+ :pantograph
4
+ ]
5
+
6
+ # a list of all the config files we currently expect
7
+ TOOL_CONFIG_FILES = [
8
+ "Pantfile"
9
+ ]
10
+ end
@@ -0,0 +1,5 @@
1
+ module Pantograph
2
+ VERSION = '0.1.0'.freeze
3
+ DESCRIPTION = 'The easiest way to automate your apps'.freeze
4
+ RUBOCOP_REQUIREMENT = '0.49.1'.freeze
5
+ end
@@ -0,0 +1,51 @@
1
+ require 'pantograph_core'
2
+
3
+ require 'pantograph/version'
4
+ require 'pantograph/features'
5
+ require 'pantograph/shells'
6
+ require 'pantograph/tools'
7
+ require 'pantograph/documentation/actions_list'
8
+ require 'pantograph/actions/actions_helper' # has to be before pant_file
9
+ require 'pantograph/pant_file'
10
+ require 'pantograph/runner'
11
+ require 'pantograph/setup/setup'
12
+ require 'pantograph/lane'
13
+ require 'pantograph/junit_generator'
14
+ require 'pantograph/lane_manager'
15
+ require 'pantograph/lane_manager_base'
16
+ require 'pantograph/action'
17
+ require 'pantograph/action_collector'
18
+ require 'pantograph/supported_platforms'
19
+ require 'pantograph/configuration_helper'
20
+ require 'pantograph/one_off'
21
+ require 'pantograph/server/socket_server_action_command_executor'
22
+ require 'pantograph/server/socket_server'
23
+ require 'pantograph/command_line_handler'
24
+ require 'pantograph/documentation/docs_generator'
25
+ require 'pantograph/other_action'
26
+ require 'pantograph/plugins/plugins'
27
+ require 'pantograph/pantograph_require'
28
+
29
+ module Pantograph
30
+ Helper = PantographCore::Helper # you gotta love Ruby: Helper.* should use the Helper class contained in PantographCore
31
+ UI = PantographCore::UI
32
+ ROOT = Pathname.new(File.expand_path('../..', __FILE__))
33
+
34
+ class << self
35
+ def load_actions
36
+ Pantograph::Actions.load_default_actions
37
+ Pantograph::Actions.load_helpers
38
+
39
+ if PantographCore::PantographFolder.path
40
+ actions_path = File.join(PantographCore::PantographFolder.path, 'actions')
41
+ @external_actions = Pantograph::Actions.load_external_actions(actions_path) if File.directory?(actions_path)
42
+ end
43
+ end
44
+
45
+ attr_reader :external_actions
46
+
47
+ def plugin_manager
48
+ @plugin_manager ||= Pantograph::PluginManager.new
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,79 @@
1
+ PantographCore
2
+ ============
3
+
4
+ [![Twitter: @PantographTools](https://img.shields.io/badge/contact-@PantographTools-blue.svg?style=flat)](https://twitter.com/PantographTools)
5
+ [![License](https://img.shields.io/badge/license-MIT-green.svg?style=flat)](https://github.com/pantograph/pantograph/blob/master/LICENSE)
6
+
7
+ All shared code of the pantograph tools is stored in this repository.
8
+
9
+ Get in contact with the developer on Twitter: [@PantographTools](https://twitter.com/PantographTools)
10
+
11
+ # Features
12
+
13
+ This gem contains all shared classes and code:
14
+
15
+ - Checking for updates for a specific gem and showing an update message
16
+ - All output of all tools with different logging levels
17
+ - Finding of the current Xcode and iTunes Transporter path
18
+ - More helper methods and classes
19
+
20
+ You can hide the inline changelog by setting the `PANTOGRAPH_HIDE_CHANGELOG` environment variable
21
+
22
+ ## Output environment variables
23
+
24
+ - To hide timestamps in each row, set the `PANTOGRAPH_HIDE_TIMESTAMP` environment variable to true.
25
+ - To disable output formatting, set the `PANTOGRAPH_DISABLE_OUTPUT_FORMAT` environment variable to true.
26
+
27
+ ## Interacting with the user
28
+
29
+ Instead of using `puts`, `raise` and `gets`, please use the helper class `UI` across all pantograph tools:
30
+
31
+ ```ruby
32
+ UI.message("Neutral message (usually white)")
33
+ UI.success("Successfully finished processing (usually green)")
34
+ UI.error("Wahaha, what's going on here! (usually red)")
35
+ UI.important("Make sure to use Windows (usually yellow)")
36
+
37
+ UI.header("Inputs") # a big box
38
+
39
+ name = UI.input("What's your name? ")
40
+ if UI.confirm("Are you '#{name}'?")
41
+ UI.success("Oh yeah")
42
+ else
43
+ UI.error("Wups, invalid")
44
+ end
45
+
46
+ UI.password("Your password please: ") # password inputs are hidden
47
+
48
+ ###### A "Dropdown" for the user
49
+ project = UI.select("Select your project: ", ["Test Project", "Test Workspace"])
50
+
51
+ UI.success("Okay #{name}, you selected '#{project}'")
52
+
53
+ ###### To run a command use
54
+ PantographCore::CommandExecutor.execute(command: "ls",
55
+ print_all: true,
56
+ error: proc do |error_output|
57
+ # handle error here
58
+ end)
59
+
60
+ ###### or if you just want to receive a simple value use this only if the command doesn't take long
61
+ diff = Helper.backticks("git diff")
62
+
63
+ ###### pantograph "crash" because of a user error everything that is caused by the user and is not unexpected
64
+ UI.user_error!("You don't have a project in the current directory")
65
+
66
+ ###### an actual crash when something unexpected happened
67
+ UI.crash!("Network timeout")
68
+
69
+ ###### a deprecation message
70
+ UI.deprecated("The '--key' parameter is deprecated")
71
+ ```
72
+
73
+ # Code of Conduct
74
+ Help us keep _pantograph_ open and inclusive. Please read and follow our [Code of Conduct](https://github.com/pantograph/pantograph/blob/master/CODE_OF_CONDUCT.md).
75
+
76
+ # License
77
+ This project is licensed under the terms of the MIT license. See the LICENSE file.
78
+
79
+ > This project and all pantograph tools are in no way affiliated with Apple Inc. This project is open source under the MIT license, which means you have full access to the source code and can modify it to fit your own needs. All pantograph tools run on your own computer or server, so your credentials or other sensitive information will never leave your own computer. You are responsible for how you use pantograph tools.
@@ -0,0 +1,12 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <package xmlns="http://apple.com/itunes/importer" version="software5.4">
3
+ <software_assets apple_id="<%= @data[:apple_id] %>" app_platform="<%= @data[:platform] %>">
4
+ <asset type="<%= @data[:archive_type] %>">
5
+ <data_file>
6
+ <size><%= @data[:file_size] %></size>
7
+ <file_name><%= @data[:ipa_path] %></file_name>
8
+ <checksum type="md5"><%= @data[:md5] %></checksum>
9
+ </data_file>
10
+ </asset>
11
+ </software_assets>
12
+ </package>
@@ -0,0 +1,34 @@
1
+ # require_relative 'app_identifier_guesser'
2
+
3
+ module PantographCore
4
+ class ActionCompletionStatus
5
+ SUCCESS = 'success'
6
+ FAILED = 'failed' # pantograph crashes unrelated to user_error!
7
+ USER_ERROR = 'user_error' # Anytime a user_error! is triggered
8
+ INTERRUPTED = 'interrupted'
9
+ end
10
+
11
+ class ActionCompletionContext
12
+ attr_accessor :p_hash
13
+ attr_accessor :action_name
14
+ attr_accessor :status
15
+ attr_accessor :pantograph_client_language
16
+
17
+ def initialize(p_hash: nil, action_name: nil, status: nil, pantograph_client_language: nil)
18
+ @p_hash = p_hash
19
+ @action_name = action_name
20
+ @status = status
21
+ @pantograph_client_language = pantograph_client_language
22
+ end
23
+
24
+ def self.context_for_action_name(action_name, pantograph_client_language: :ruby, args: nil, status: nil)
25
+ # app_id_guesser = PantographCore::AppIdentifierGuesser.new(args: args)
26
+ return self.new(
27
+ action_name: action_name,
28
+ p_hash: 'unknown',
29
+ status: status,
30
+ pantograph_client_language: pantograph_client_language
31
+ )
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,38 @@
1
+ require_relative '../helper'
2
+ # require_relative 'app_identifier_guesser'
3
+
4
+ module PantographCore
5
+ class ActionLaunchContext
6
+ UNKNOWN_P_HASH = 'unknown'
7
+
8
+ attr_accessor :action_name
9
+ attr_accessor :p_hash
10
+ attr_accessor :platform
11
+ attr_accessor :pantograph_client_language # example: ruby pantfile
12
+
13
+ def initialize(action_name: nil, p_hash: UNKNOWN_P_HASH, platform: nil, pantograph_client_language: nil)
14
+ @action_name = action_name
15
+ @p_hash = p_hash
16
+ @platform = platform
17
+ @pantograph_client_language = pantograph_client_language
18
+ end
19
+
20
+ def self.context_for_action_name(action_name, pantograph_client_language: :ruby, args: nil)
21
+ # app_id_guesser = PantographCore::AppIdentifierGuesser.new(args: args)
22
+ return self.new(
23
+ action_name: action_name,
24
+ p_hash: UNKNOWN_P_HASH,
25
+ # platform: nil,
26
+ pantograph_client_language: pantograph_client_language
27
+ )
28
+ end
29
+
30
+ def build_tool_version
31
+ if platform == :android
32
+ return 'android'
33
+ else
34
+ return "Xcode #{Helper.xcode_version}"
35
+ end
36
+ end
37
+ end
38
+ end