fastlane 1.111.0 → 2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +76 -111
- data/bin/bin-proxy +19 -0
- data/cert/README.md +163 -0
- data/cert/lib/cert.rb +18 -0
- data/cert/lib/cert/commands_generator.rb +51 -0
- data/cert/lib/cert/options.rb +67 -0
- data/cert/lib/cert/runner.rb +181 -0
- data/credentials_manager/README.md +62 -0
- data/credentials_manager/lib/credentials_manager.rb +12 -0
- data/credentials_manager/lib/credentials_manager/account_manager.rb +104 -0
- data/credentials_manager/lib/credentials_manager/appfile_config.rb +186 -0
- data/credentials_manager/lib/credentials_manager/cli.rb +65 -0
- data/deliver/README.md +271 -0
- data/deliver/lib/assets/DeliverfileDefault +10 -0
- data/deliver/lib/assets/ScreenshotsHelp +7 -0
- data/deliver/lib/assets/summary.html.erb +210 -0
- data/deliver/lib/deliver.rb +31 -0
- data/deliver/lib/deliver/app_screenshot.rb +226 -0
- data/deliver/lib/deliver/commands_generator.rb +150 -0
- data/deliver/lib/deliver/detect_values.rb +69 -0
- data/deliver/lib/deliver/download_screenshots.rb +46 -0
- data/deliver/lib/deliver/generate_summary.rb +9 -0
- data/deliver/lib/deliver/html_generator.rb +58 -0
- data/deliver/lib/deliver/loader.rb +18 -0
- data/deliver/lib/deliver/options.rb +269 -0
- data/deliver/lib/deliver/runner.rb +99 -0
- data/deliver/lib/deliver/setup.rb +78 -0
- data/deliver/lib/deliver/submit_for_review.rb +87 -0
- data/deliver/lib/deliver/upload_assets.rb +22 -0
- data/deliver/lib/deliver/upload_metadata.rb +191 -0
- data/deliver/lib/deliver/upload_price_tier.rb +21 -0
- data/deliver/lib/deliver/upload_screenshots.rb +110 -0
- data/fastlane/README.md +193 -0
- data/{lib → fastlane/lib}/assets/Actions.md.erb +0 -0
- data/{lib → fastlane/lib}/assets/AppfileTemplate +0 -0
- data/{lib → fastlane/lib}/assets/AppfileTemplateAndroid +0 -0
- data/{lib → fastlane/lib}/assets/AvailablePlugins.md.erb +0 -0
- data/{lib → fastlane/lib}/assets/DefaultFastfileTemplate +2 -2
- data/{lib → fastlane/lib}/assets/FastfileTemplateAndroid +2 -2
- data/{lib → fastlane/lib}/assets/completions/completion.bash +0 -0
- data/{lib → fastlane/lib}/assets/completions/completion.sh +0 -0
- data/{lib → fastlane/lib}/assets/completions/completion.zsh +0 -0
- data/{lib → fastlane/lib}/assets/custom_action_template.rb +0 -0
- data/{lib → fastlane/lib}/assets/mailgun_html_template.erb +0 -0
- data/{lib → fastlane/lib}/assets/report_template.xml.erb +0 -0
- data/{lib → fastlane/lib}/assets/s3_html_template.erb +0 -0
- data/{lib → fastlane/lib}/assets/s3_plist_template.erb +0 -0
- data/{lib → fastlane/lib}/assets/s3_version_template.erb +0 -0
- data/{lib → fastlane/lib}/fastlane.rb +3 -3
- data/{lib → fastlane/lib}/fastlane/action.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/action_collector.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/README.md +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/actions_helper.rb +16 -0
- data/{lib → fastlane/lib}/fastlane/actions/adb.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/adb_devices.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/add_git_tag.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/app_store_build_number.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/appaloosa.rb +1 -0
- data/{lib → fastlane/lib}/fastlane/actions/appetize.rb +1 -0
- data/{lib → fastlane/lib}/fastlane/actions/appetize_viewing_url_generator.rb +1 -0
- data/{lib → fastlane/lib}/fastlane/actions/appium.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/appledoc.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/appstore.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/apteligent.rb +1 -0
- data/{lib → fastlane/lib}/fastlane/actions/artifactory.rb +2 -0
- data/{lib → fastlane/lib}/fastlane/actions/backup_file.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/backup_xcarchive.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/badge.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/build_and_upload_to_appetize.rb +1 -0
- data/{lib → fastlane/lib}/fastlane/actions/bundle_install.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/carthage.rb +1 -1
- data/{lib → fastlane/lib}/fastlane/actions/cert.rb +0 -4
- data/{lib → fastlane/lib}/fastlane/actions/changelog_from_git_commits.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/chatwork.rb +1 -0
- data/{lib → fastlane/lib}/fastlane/actions/clean_build_artifacts.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/clean_cocoapods_cache.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/clear_derived_data.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/clipboard.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/cloc.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/cocoapods.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/commit_version_bump.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/copy_artifacts.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/crashlytics.rb +2 -0
- data/{lib → fastlane/lib}/fastlane/actions/create_keychain.rb +1 -0
- data/{lib → fastlane/lib}/fastlane/actions/create_pull_request.rb +1 -0
- data/{lib → fastlane/lib}/fastlane/actions/danger.rb +1 -0
- data/{lib → fastlane/lib}/fastlane/actions/debug.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/default_platform.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/delete_keychain.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/deliver.rb +0 -4
- data/{lib → fastlane/lib}/fastlane/actions/deploygate.rb +34 -19
- data/{lib → fastlane/lib}/fastlane/actions/device_grid/README.md +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/dotgpg_environment.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/download.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/download_dsyms.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/dsym_zip.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/ensure_git_branch.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/ensure_git_status_clean.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/ensure_no_debug_code.rb +10 -2
- data/{lib → fastlane/lib}/fastlane/actions/ensure_xcode_version.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/erb.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/fastlane_version.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/flock.rb +1 -0
- data/{lib → fastlane/lib}/fastlane/actions/frameit.rb +6 -10
- data/{lib → fastlane/lib}/fastlane/actions/gcovr.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/get_build_number.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/get_build_number_repository.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/get_github_release.rb +1 -0
- data/{lib → fastlane/lib}/fastlane/actions/get_info_plist_value.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/get_ipa_info_plist_value.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/get_version_number.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/git_add.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/git_branch.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/git_commit.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/git_pull.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/git_tag_exists.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/gradle.rb +0 -0
- data/fastlane/lib/fastlane/actions/gym.rb +84 -0
- data/{lib → fastlane/lib}/fastlane/actions/hg_add_tag.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/hg_commit_version_bump.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/hg_ensure_clean_status.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/hg_push.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/hipchat.rb +1 -0
- data/{lib → fastlane/lib}/fastlane/actions/hockey.rb +37 -11
- data/{lib → fastlane/lib}/fastlane/actions/ifttt.rb +1 -0
- data/{lib → fastlane/lib}/fastlane/actions/import.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/import_certificate.rb +2 -0
- data/{lib → fastlane/lib}/fastlane/actions/import_from_git.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/increment_build_number.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/increment_version_number.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/install_on_device.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/install_xcode_plugin.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/installr.rb +1 -0
- data/{lib → fastlane/lib}/fastlane/actions/ipa.rb +12 -4
- data/{lib → fastlane/lib}/fastlane/actions/is_ci.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/jazzy.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/jira.rb +1 -0
- data/{lib → fastlane/lib}/fastlane/actions/lane_context.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/last_git_commit.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/last_git_tag.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/latest_testflight_build_number.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/lcov.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/mailgun.rb +2 -0
- data/{lib → fastlane/lib}/fastlane/actions/make_changelog_from_jenkins.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/match.rb +3 -9
- data/{lib → fastlane/lib}/fastlane/actions/nexus_upload.rb +1 -0
- data/{lib → fastlane/lib}/fastlane/actions/notification.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/notify.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/number_of_commits.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/oclint.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/onesignal.rb +3 -0
- data/{lib → fastlane/lib}/fastlane/actions/opt_out_usage.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/pem.rb +9 -15
- data/{lib → fastlane/lib}/fastlane/actions/pilot.rb +6 -12
- data/{lib → fastlane/lib}/fastlane/actions/pod_lib_lint.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/pod_push.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/podio_item.rb +2 -0
- data/{lib → fastlane/lib}/fastlane/actions/produce.rb +7 -11
- data/{lib → fastlane/lib}/fastlane/actions/prompt.rb +5 -2
- data/{lib → fastlane/lib}/fastlane/actions/push_git_tags.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/push_to_git_remote.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/puts.rb +8 -0
- data/{lib → fastlane/lib}/fastlane/actions/read_podspec.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/recreate_schemes.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/register_devices.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/reset_git_repo.rb +0 -0
- data/fastlane/lib/fastlane/actions/reset_simulator_contents.rb +62 -0
- data/{lib → fastlane/lib}/fastlane/actions/resign.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/restore_file.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/rocket.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/rsync.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/s3.rb +2 -1
- data/{lib → fastlane/lib}/fastlane/actions/say.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/scan.rb +0 -4
- data/{lib → fastlane/lib}/fastlane/actions/scp.rb +1 -0
- data/{lib → fastlane/lib}/fastlane/actions/screengrab.rb +7 -13
- data/{lib → fastlane/lib}/fastlane/actions/set_build_number_repository.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/set_changelog.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/set_github_release.rb +1 -0
- data/{lib → fastlane/lib}/fastlane/actions/set_info_plist_value.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/set_pod_key.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/setup_jenkins.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/sigh.rb +9 -15
- data/{lib → fastlane/lib}/fastlane/actions/skip_docs.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/slack.rb +1 -0
- data/{lib → fastlane/lib}/fastlane/actions/slather.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/snapshot.rb +5 -11
- data/{lib → fastlane/lib}/fastlane/actions/sonar.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/splunkmint.rb +3 -0
- data/{lib → fastlane/lib}/fastlane/actions/ssh.rb +1 -0
- data/{lib → fastlane/lib}/fastlane/actions/supply.rb +9 -13
- data/{lib → fastlane/lib}/fastlane/actions/swiftlint.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/team_id.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/team_name.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/testfairy.rb +28 -9
- data/{lib → fastlane/lib}/fastlane/actions/testflight.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/tryouts.rb +1 -0
- data/{lib → fastlane/lib}/fastlane/actions/twitter.rb +4 -0
- data/{lib → fastlane/lib}/fastlane/actions/typetalk.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/unlock_keychain.rb +1 -0
- data/{lib → fastlane/lib}/fastlane/actions/update_app_group_identifiers.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/update_app_identifier.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/update_fastlane.rb +1 -20
- data/{lib → fastlane/lib}/fastlane/actions/update_icloud_container_identifiers.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/update_info_plist.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/update_project_code_signing.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/update_project_provisioning.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/update_project_team.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/update_urban_airship_configuration.rb +4 -0
- data/{lib → fastlane/lib}/fastlane/actions/update_url_schemes.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/upload_symbols_to_crashlytics.rb +1 -0
- data/{lib → fastlane/lib}/fastlane/actions/upload_symbols_to_sentry.rb +2 -0
- data/{lib → fastlane/lib}/fastlane/actions/verify_build.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/verify_pod_keys.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/verify_xcode.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/version_bump_podspec.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/version_get_podspec.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/xcode_install.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/xcode_select.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/xcode_server_get_assets.rb +1 -0
- data/{lib → fastlane/lib}/fastlane/actions/xcodebuild.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/xcov.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/xctool.rb +1 -1
- data/{lib → fastlane/lib}/fastlane/actions/xcversion.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/actions/zip.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/auto_complete.rb +0 -0
- data/fastlane/lib/fastlane/cli_tools_distributor.rb +125 -0
- data/{lib → fastlane/lib}/fastlane/command_line_handler.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/commands_generator.rb +5 -4
- data/{lib → fastlane/lib}/fastlane/configuration_helper.rb +0 -1
- data/{lib → fastlane/lib}/fastlane/core_ext/bundler_monkey_patch.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/documentation/actions_list.rb +1 -1
- data/{lib → fastlane/lib}/fastlane/documentation/docs_generator.rb +1 -1
- data/{lib → fastlane/lib}/fastlane/documentation/markdown_docs_generator.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/environment_printer.rb +1 -1
- data/{lib → fastlane/lib}/fastlane/erb_template_helper.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/fast_file.rb +1 -1
- data/{lib → fastlane/lib}/fastlane/fastlane_require.rb +27 -3
- data/{lib → fastlane/lib}/fastlane/features.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/helper/README.md +0 -0
- data/{lib → fastlane/lib}/fastlane/helper/adb_helper.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/helper/cocoapod_helper.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/helper/crashlytics_helper.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/helper/gem_helper.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/helper/git_helper.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/helper/gradle_helper.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/helper/podspec_helper.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/helper/sh_helper.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/helper/xcversion_helper.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/junit_generator.rb +1 -1
- data/{lib → fastlane/lib}/fastlane/lane.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/lane_list.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/lane_manager.rb +25 -6
- data/{lib → fastlane/lib}/fastlane/markdown_table_formatter.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/new_action.rb +1 -1
- data/{lib → fastlane/lib}/fastlane/one_off.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/other_action.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/plugins/plugin_fetcher.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/plugins/plugin_generator.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/plugins/plugin_generator_ui.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/plugins/plugin_info.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/plugins/plugin_info_collector.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/plugins/plugin_manager.rb +4 -4
- data/{lib → fastlane/lib}/fastlane/plugins/plugin_search.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/plugins/plugin_update_manager.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/plugins/plugins.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/plugins/template/%gem_name%.gemspec.erb +3 -0
- data/{lib → fastlane/lib}/fastlane/plugins/template/.gitignore +0 -0
- data/{lib → fastlane/lib}/fastlane/plugins/template/.rspec +0 -0
- data/{lib → fastlane/lib}/fastlane/plugins/template/.rubocop.yml +0 -0
- data/{lib → fastlane/lib}/fastlane/plugins/template/.travis.yml +0 -0
- data/{lib → fastlane/lib}/fastlane/plugins/template/Gemfile +0 -0
- data/{lib → fastlane/lib}/fastlane/plugins/template/LICENSE.erb +0 -0
- data/{lib → fastlane/lib}/fastlane/plugins/template/README.md.erb +2 -2
- data/{lib → fastlane/lib}/fastlane/plugins/template/Rakefile +0 -0
- data/{lib → fastlane/lib}/fastlane/plugins/template/circle.yml +0 -0
- data/{lib → fastlane/lib}/fastlane/plugins/template/fastlane/Fastfile.erb +0 -0
- data/{lib → fastlane/lib}/fastlane/plugins/template/fastlane/Pluginfile.erb +0 -0
- data/{lib → fastlane/lib}/fastlane/plugins/template/lib/fastlane/plugin/%plugin_name%.rb.erb +0 -0
- data/{lib → fastlane/lib}/fastlane/plugins/template/lib/fastlane/plugin/%plugin_name%/actions/%plugin_name%_action.rb.erb +0 -0
- data/{lib → fastlane/lib}/fastlane/plugins/template/lib/fastlane/plugin/%plugin_name%/helper/%plugin_name%_helper.rb.erb +0 -0
- data/{lib → fastlane/lib}/fastlane/plugins/template/lib/fastlane/plugin/%plugin_name%/version.rb.erb +0 -0
- data/{lib → fastlane/lib}/fastlane/plugins/template/spec/%plugin_name%_action_spec.rb.erb +0 -0
- data/{lib → fastlane/lib}/fastlane/plugins/template/spec/spec_helper.rb.erb +0 -0
- data/{lib → fastlane/lib}/fastlane/runner.rb +25 -2
- data/{lib → fastlane/lib}/fastlane/setup/crashlytics_beta.rb +1 -1
- data/{lib → fastlane/lib}/fastlane/setup/crashlytics_beta_command_line_handler.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/setup/crashlytics_beta_info.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/setup/crashlytics_beta_info_collector.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/setup/crashlytics_beta_ui.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/setup/crashlytics_beta_user_email_fetcher.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/setup/crashlytics_project_parser.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/setup/setup.rb +2 -2
- data/{lib → fastlane/lib}/fastlane/setup/setup_android.rb +2 -2
- data/{lib → fastlane/lib}/fastlane/setup/setup_ios.rb +3 -3
- data/{lib → fastlane/lib}/fastlane/supported_platforms.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/tools.rb +0 -0
- data/{lib → fastlane/lib}/fastlane/version.rb +2 -2
- data/fastlane_core/README.md +54 -0
- data/fastlane_core/lib/assets/XMLTemplate.xml.erb +12 -0
- data/fastlane_core/lib/fastlane_core.rb +48 -0
- data/fastlane_core/lib/fastlane_core/cert_checker.rb +94 -0
- data/fastlane_core/lib/fastlane_core/command_executor.rb +98 -0
- data/fastlane_core/lib/fastlane_core/configuration/commander_generator.rb +82 -0
- data/fastlane_core/lib/fastlane_core/configuration/config_item.rb +133 -0
- data/fastlane_core/lib/fastlane_core/configuration/configuration.rb +266 -0
- data/fastlane_core/lib/fastlane_core/configuration/configuration_file.rb +82 -0
- data/fastlane_core/lib/fastlane_core/core_ext/string.rb +17 -0
- data/fastlane_core/lib/fastlane_core/device_manager.rb +231 -0
- data/fastlane_core/lib/fastlane_core/env.rb +9 -0
- data/{lib/fastlane → fastlane_core/lib/fastlane_core}/fastlane_folder.rb +1 -11
- data/fastlane_core/lib/fastlane_core/feature/feature.rb +49 -0
- data/fastlane_core/lib/fastlane_core/features.rb +2 -0
- data/fastlane_core/lib/fastlane_core/helper.rb +240 -0
- data/fastlane_core/lib/fastlane_core/ipa_file_analyser.rb +55 -0
- data/fastlane_core/lib/fastlane_core/ipa_upload_package_builder.rb +44 -0
- data/fastlane_core/lib/fastlane_core/itunes_search_api.rb +48 -0
- data/fastlane_core/lib/fastlane_core/itunes_transporter.rb +409 -0
- data/fastlane_core/lib/fastlane_core/keychain_importer.rb +27 -0
- data/fastlane_core/lib/fastlane_core/languages.rb +11 -0
- data/fastlane_core/lib/fastlane_core/pkg_file_analyser.rb +42 -0
- data/fastlane_core/lib/fastlane_core/pkg_upload_package_builder.rb +44 -0
- data/fastlane_core/lib/fastlane_core/print_table.rb +63 -0
- data/fastlane_core/lib/fastlane_core/project.rb +450 -0
- data/fastlane_core/lib/fastlane_core/provisioning_profile.rb +69 -0
- data/fastlane_core/lib/fastlane_core/string_filters.rb +34 -0
- data/fastlane_core/lib/fastlane_core/tool_collector.rb +179 -0
- data/fastlane_core/lib/fastlane_core/ui/disable_colors.rb +17 -0
- data/fastlane_core/lib/fastlane_core/ui/fastlane_runner.rb +190 -0
- data/fastlane_core/lib/fastlane_core/ui/github_issue_inspector_reporter.rb +50 -0
- data/fastlane_core/lib/fastlane_core/ui/implementations/shell.rb +122 -0
- data/fastlane_core/lib/fastlane_core/ui/interface.rb +159 -0
- data/fastlane_core/lib/fastlane_core/ui/ui.rb +26 -0
- data/fastlane_core/lib/fastlane_core/update_checker/changelog.rb +37 -0
- data/fastlane_core/lib/fastlane_core/update_checker/update_checker.rb +198 -0
- data/fastlane_core/lib/fastlane_core/xcodebuild_list_output_parser.rb +28 -0
- data/frameit/README.md +284 -0
- data/frameit/lib/assets/empty.png +0 -0
- data/frameit/lib/frameit.rb +52 -0
- data/frameit/lib/frameit/commands_generator.rb +99 -0
- data/frameit/lib/frameit/config_parser.rb +98 -0
- data/frameit/lib/frameit/dependency_checker.rb +20 -0
- data/frameit/lib/frameit/device_types.rb +13 -0
- data/frameit/lib/frameit/editor.rb +351 -0
- data/frameit/lib/frameit/frame_downloader.rb +71 -0
- data/frameit/lib/frameit/mac_editor.rb +32 -0
- data/frameit/lib/frameit/offsets.rb +19 -0
- data/frameit/lib/frameit/options.rb +46 -0
- data/frameit/lib/frameit/runner.rb +45 -0
- data/frameit/lib/frameit/screenshot.rb +89 -0
- data/frameit/lib/frameit/strings_parser.rb +35 -0
- data/frameit/lib/frameit/template_finder.rb +36 -0
- data/gym/README.md +288 -0
- data/gym/lib/assets/GymfileTemplate +13 -0
- data/gym/lib/assets/package_application_patches/0001_codesign_args_patch.diff +38 -0
- data/gym/lib/assets/package_application_patches/0002_no_strict_parameter_patch.diff +42 -0
- data/gym/lib/assets/package_application_patches/PackageApplication_MD5 +2 -0
- data/gym/lib/assets/wrap_xcodebuild/xcbuild-safe.sh +58 -0
- data/gym/lib/gym.rb +49 -0
- data/gym/lib/gym/commands_generator.rb +62 -0
- data/gym/lib/gym/detect_values.rb +105 -0
- data/gym/lib/gym/error_handler.rb +186 -0
- data/gym/lib/gym/generators/README.md +1 -0
- data/gym/lib/gym/generators/build_command_generator.rb +136 -0
- data/gym/lib/gym/generators/package_command_generator.rb +58 -0
- data/gym/lib/gym/generators/package_command_generator_legacy.rb +102 -0
- data/gym/lib/gym/generators/package_command_generator_xcode7.rb +191 -0
- data/gym/lib/gym/manager.rb +17 -0
- data/gym/lib/gym/options.rb +254 -0
- data/gym/lib/gym/runner.rb +256 -0
- data/gym/lib/gym/xcode.rb +21 -0
- data/gym/lib/gym/xcodebuild_fixes/README.md +9 -0
- data/gym/lib/gym/xcodebuild_fixes/generic_archive_fix.rb +32 -0
- data/gym/lib/gym/xcodebuild_fixes/package_application_fix.rb +53 -0
- data/gym/lib/gym/xcodebuild_fixes/swift_fix.rb +99 -0
- data/gym/lib/gym/xcodebuild_fixes/watchkit2_fix.rb +35 -0
- data/gym/lib/gym/xcodebuild_fixes/watchkit_fix.rb +40 -0
- data/match/README.md +414 -0
- data/match/lib/assets/MatchfileTemplate +9 -0
- data/match/lib/assets/READMETemplate.md +49 -0
- data/match/lib/match.rb +57 -0
- data/match/lib/match/change_password.rb +30 -0
- data/match/lib/match/commands_generator.rb +120 -0
- data/match/lib/match/encrypt.rb +93 -0
- data/match/lib/match/generator.rb +74 -0
- data/match/lib/match/git_helper.rb +139 -0
- data/match/lib/match/nuke.rb +190 -0
- data/match/lib/match/options.rb +124 -0
- data/match/lib/match/runner.rb +172 -0
- data/match/lib/match/setup.rb +20 -0
- data/match/lib/match/spaceship_ensure.rb +78 -0
- data/match/lib/match/table_printer.rb +43 -0
- data/match/lib/match/utils.rb +59 -0
- data/pem/README.md +175 -0
- data/pem/lib/pem.rb +21 -0
- data/pem/lib/pem/commands_generator.rb +41 -0
- data/pem/lib/pem/manager.rb +93 -0
- data/pem/lib/pem/options.rb +79 -0
- data/pilot/README.md +285 -0
- data/pilot/lib/pilot.rb +22 -0
- data/pilot/lib/pilot/build_manager.rb +209 -0
- data/pilot/lib/pilot/commands_generator.rb +136 -0
- data/pilot/lib/pilot/features.rb +0 -0
- data/pilot/lib/pilot/manager.rb +71 -0
- data/pilot/lib/pilot/options.rb +161 -0
- data/pilot/lib/pilot/tester_exporter.rb +37 -0
- data/pilot/lib/pilot/tester_importer.rb +51 -0
- data/pilot/lib/pilot/tester_manager.rb +212 -0
- data/pilot/lib/pilot/tester_util.rb +23 -0
- data/produce/README.md +232 -0
- data/produce/lib/produce.rb +21 -0
- data/produce/lib/produce/available_default_languages.rb +36 -0
- data/produce/lib/produce/commands_generator.rb +134 -0
- data/produce/lib/produce/developer_center.rb +58 -0
- data/produce/lib/produce/group.rb +89 -0
- data/produce/lib/produce/itunes_connect.rb +87 -0
- data/produce/lib/produce/manager.rb +11 -0
- data/produce/lib/produce/options.rb +114 -0
- data/produce/lib/produce/service.rb +227 -0
- data/scan/README.md +219 -0
- data/scan/lib/assets/ScanfileTemplate +13 -0
- data/scan/lib/scan.rb +40 -0
- data/scan/lib/scan/commands_generator.rb +61 -0
- data/scan/lib/scan/detect_values.rb +184 -0
- data/scan/lib/scan/error_handler.rb +43 -0
- data/scan/lib/scan/manager.rb +17 -0
- data/scan/lib/scan/options.rb +189 -0
- data/scan/lib/scan/report_collector.rb +70 -0
- data/scan/lib/scan/runner.rb +103 -0
- data/scan/lib/scan/slack_poster.rb +59 -0
- data/scan/lib/scan/test_command_generator.rb +130 -0
- data/scan/lib/scan/test_result_parser.rb +21 -0
- data/screengrab/README.md +190 -0
- data/screengrab/lib/assets/ScreengrabfileTemplate +15 -0
- data/screengrab/lib/screengrab.rb +32 -0
- data/screengrab/lib/screengrab/android_environment.rb +88 -0
- data/screengrab/lib/screengrab/commands_generator.rb +60 -0
- data/screengrab/lib/screengrab/dependency_checker.rb +56 -0
- data/screengrab/lib/screengrab/detect_values.rb +16 -0
- data/screengrab/lib/screengrab/options.rb +109 -0
- data/screengrab/lib/screengrab/page.html.erb +206 -0
- data/screengrab/lib/screengrab/runner.rb +336 -0
- data/screengrab/lib/screengrab/setup.rb +16 -0
- data/sigh/README.md +256 -0
- data/sigh/lib/assets/resign.sh +774 -0
- data/sigh/lib/sigh.rb +19 -0
- data/sigh/lib/sigh/commands_generator.rb +133 -0
- data/sigh/lib/sigh/download_all.rb +36 -0
- data/sigh/lib/sigh/local_manage.rb +140 -0
- data/sigh/lib/sigh/manager.rb +44 -0
- data/sigh/lib/sigh/options.rb +117 -0
- data/sigh/lib/sigh/repair.rb +30 -0
- data/sigh/lib/sigh/resign.rb +201 -0
- data/sigh/lib/sigh/runner.rb +235 -0
- data/snapshot/README.md +400 -0
- data/snapshot/lib/assets/SnapfileTemplate +36 -0
- data/snapshot/lib/assets/SnapshotHelper.swift +138 -0
- data/snapshot/lib/assets/SnapshotHelper2-3.swift +140 -0
- data/snapshot/lib/snapshot.rb +59 -0
- data/snapshot/lib/snapshot/collector.rb +92 -0
- data/snapshot/lib/snapshot/commands_generator.rb +108 -0
- data/snapshot/lib/snapshot/dependency_checker.rb +50 -0
- data/snapshot/lib/snapshot/detect_values.rb +53 -0
- data/snapshot/lib/snapshot/error_handler.rb +22 -0
- data/snapshot/lib/snapshot/fixes/README.md +5 -0
- data/snapshot/lib/snapshot/fixes/hardware_keyboard_fix.rb +14 -0
- data/snapshot/lib/snapshot/fixes/simulator_zoom_fix.rb +25 -0
- data/snapshot/lib/snapshot/latest_os_version.rb +31 -0
- data/snapshot/lib/snapshot/options.rb +161 -0
- data/snapshot/lib/snapshot/page.html.erb +206 -0
- data/snapshot/lib/snapshot/reports_generator.rb +64 -0
- data/snapshot/lib/snapshot/reset_simulators.rb +88 -0
- data/snapshot/lib/snapshot/runner.rb +294 -0
- data/snapshot/lib/snapshot/screenshot_flatten.rb +18 -0
- data/snapshot/lib/snapshot/screenshot_rotate.rb +38 -0
- data/snapshot/lib/snapshot/setup.rb +35 -0
- data/snapshot/lib/snapshot/test_command_generator.rb +118 -0
- data/snapshot/lib/snapshot/update.rb +29 -0
- data/spaceship/README.md +191 -0
- data/spaceship/lib/assets/languageMapping.json +240 -0
- data/spaceship/lib/assets/languageMappingReadable.json +30 -0
- data/spaceship/lib/spaceship.rb +31 -0
- data/spaceship/lib/spaceship/babosa_fix.rb +30 -0
- data/spaceship/lib/spaceship/base.rb +236 -0
- data/spaceship/lib/spaceship/client.rb +487 -0
- data/spaceship/lib/spaceship/commands_generator.rb +48 -0
- data/spaceship/lib/spaceship/du/du_client.rb +122 -0
- data/spaceship/lib/spaceship/du/upload_file.rb +56 -0
- data/spaceship/lib/spaceship/du/utilities.rb +81 -0
- data/spaceship/lib/spaceship/helper/net_http_generic_request.rb +14 -0
- data/spaceship/lib/spaceship/helper/plist_middleware.rb +15 -0
- data/spaceship/lib/spaceship/launcher.rb +94 -0
- data/spaceship/lib/spaceship/playground.rb +72 -0
- data/spaceship/lib/spaceship/portal/app.rb +148 -0
- data/spaceship/lib/spaceship/portal/app_group.rb +77 -0
- data/spaceship/lib/spaceship/portal/app_service.rb +278 -0
- data/spaceship/lib/spaceship/portal/certificate.rb +333 -0
- data/spaceship/lib/spaceship/portal/device.rb +192 -0
- data/spaceship/lib/spaceship/portal/portal.rb +8 -0
- data/spaceship/lib/spaceship/portal/portal_base.rb +13 -0
- data/spaceship/lib/spaceship/portal/portal_client.rb +491 -0
- data/spaceship/lib/spaceship/portal/provisioning_profile.rb +467 -0
- data/spaceship/lib/spaceship/portal/spaceship.rb +112 -0
- data/spaceship/lib/spaceship/portal/ui/select_team.rb +83 -0
- data/spaceship/lib/spaceship/spaceauth_runner.rb +50 -0
- data/spaceship/lib/spaceship/tunes/app_details.rb +139 -0
- data/spaceship/lib/spaceship/tunes/app_image.rb +55 -0
- data/spaceship/lib/spaceship/tunes/app_ratings.rb +107 -0
- data/spaceship/lib/spaceship/tunes/app_screenshot.rb +17 -0
- data/spaceship/lib/spaceship/tunes/app_status.rb +60 -0
- data/spaceship/lib/spaceship/tunes/app_submission.rb +136 -0
- data/spaceship/lib/spaceship/tunes/app_trailer.rb +68 -0
- data/spaceship/lib/spaceship/tunes/app_version.rb +766 -0
- data/spaceship/lib/spaceship/tunes/app_version_common.rb +33 -0
- data/spaceship/lib/spaceship/tunes/app_version_generated_promocodes.rb +35 -0
- data/spaceship/lib/spaceship/tunes/app_version_history.rb +59 -0
- data/spaceship/lib/spaceship/tunes/app_version_promocodes.rb +34 -0
- data/spaceship/lib/spaceship/tunes/app_version_ref.rb +19 -0
- data/spaceship/lib/spaceship/tunes/app_version_states_history.rb +34 -0
- data/spaceship/lib/spaceship/tunes/application.rb +437 -0
- data/spaceship/lib/spaceship/tunes/build.rb +269 -0
- data/spaceship/lib/spaceship/tunes/build_details.rb +48 -0
- data/spaceship/lib/spaceship/tunes/build_train.rb +182 -0
- data/spaceship/lib/spaceship/tunes/device_type.rb +14 -0
- data/spaceship/lib/spaceship/tunes/language_converter.rb +63 -0
- data/spaceship/lib/spaceship/tunes/language_item.rb +56 -0
- data/spaceship/lib/spaceship/tunes/pricing_tier.rb +81 -0
- data/spaceship/lib/spaceship/tunes/recovery_device.rb +69 -0
- data/spaceship/lib/spaceship/tunes/spaceship.rb +34 -0
- data/spaceship/lib/spaceship/tunes/tester.rb +283 -0
- data/spaceship/lib/spaceship/tunes/transit_app_file.rb +27 -0
- data/spaceship/lib/spaceship/tunes/tunes.rb +35 -0
- data/spaceship/lib/spaceship/tunes/tunes_base.rb +15 -0
- data/spaceship/lib/spaceship/tunes/tunes_client.rb +1068 -0
- data/spaceship/lib/spaceship/tunes/user_detail.rb +19 -0
- data/spaceship/lib/spaceship/tunes/version_set.rb +35 -0
- data/spaceship/lib/spaceship/two_step_client.rb +195 -0
- data/spaceship/lib/spaceship/ui.rb +27 -0
- data/supply/README.md +214 -0
- data/supply/lib/supply.rb +29 -0
- data/supply/lib/supply/apk_listing.rb +14 -0
- data/supply/lib/supply/client.rb +345 -0
- data/supply/lib/supply/commands_generator.rb +62 -0
- data/supply/lib/supply/listing.rb +32 -0
- data/supply/lib/supply/options.rb +135 -0
- data/supply/lib/supply/setup.rb +102 -0
- data/supply/lib/supply/uploader.rb +221 -0
- metadata +699 -428
- data/bin//360/237/232/200 +0 -5
- data/lib/.DS_Store +0 -0
- data/lib/assets/.DS_Store +0 -0
- data/lib/assets/completions/.DS_Store +0 -0
- data/lib/fastlane/.DS_Store +0 -0
- data/lib/fastlane/actions/gym.rb +0 -90
- data/lib/fastlane/actions/reset_simulators.rb +0 -44
- data/lib/fastlane/cli_tools_distributor.rb +0 -100
- data/lib/fastlane/setup/.DS_Store +0 -0
@@ -0,0 +1,20 @@
|
|
1
|
+
module Match
|
2
|
+
class Setup
|
3
|
+
def run(path)
|
4
|
+
template = File.read("#{Match::ROOT}/lib/assets/MatchfileTemplate")
|
5
|
+
|
6
|
+
UI.important "Please create a new, private git repository"
|
7
|
+
UI.important "to store the certificates and profiles there"
|
8
|
+
url = UI.input("URL of the Git Repo: ")
|
9
|
+
|
10
|
+
template.gsub!("[[GIT_URL]]", url)
|
11
|
+
File.write(path, template)
|
12
|
+
UI.success "Successfully created '#{path}'. You can open the file using a code editor."
|
13
|
+
|
14
|
+
UI.important "You can now run `match development`, `match adhoc` and `match appstore`"
|
15
|
+
UI.message "On the first run for each environment it will create the provisioning profiles and"
|
16
|
+
UI.message "certificates for you. From then on, it will automatically import the existing profiles."
|
17
|
+
UI.message "For more information visit https://github.com/fastlane/fastlane/tree/master/match"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module Match
|
2
|
+
# Ensures the certificate and profiles are also available on iTunes Connect
|
3
|
+
class SpaceshipEnsure
|
4
|
+
def initialize(user)
|
5
|
+
# We'll try to manually fetch the password
|
6
|
+
# to tell the user that a password is optional
|
7
|
+
require 'credentials_manager'
|
8
|
+
|
9
|
+
keychain_entry = CredentialsManager::AccountManager.new(user: user)
|
10
|
+
|
11
|
+
if keychain_entry.password(ask_if_missing: false).to_s.length == 0
|
12
|
+
UI.important("You can also run `match` in readonly mode to not require any access to the")
|
13
|
+
UI.important("Developer Portal. This way you only share the keys and credentials")
|
14
|
+
UI.command("match --readonly")
|
15
|
+
UI.important("More information https://github.com/fastlane/fastlane/tree/master/match#access-control")
|
16
|
+
end
|
17
|
+
|
18
|
+
UI.message("Verifying that the certificate and profile are still valid on the Dev Portal...")
|
19
|
+
Spaceship.login(user)
|
20
|
+
Spaceship.select_team
|
21
|
+
end
|
22
|
+
|
23
|
+
def bundle_identifier_exists(username: nil, app_identifier: nil)
|
24
|
+
found = Spaceship.app.find(app_identifier)
|
25
|
+
return if found
|
26
|
+
|
27
|
+
require 'sigh'
|
28
|
+
Sigh::Runner.new.print_produce_command({
|
29
|
+
username: username,
|
30
|
+
app_identifier: app_identifier
|
31
|
+
})
|
32
|
+
UI.error("An app with that bundle ID needs to exist in order to create a provisioning profile for it")
|
33
|
+
UI.error("================================================================")
|
34
|
+
available_apps = Spaceship.app.all.collect { |a| "#{a.bundle_id} (#{a.name})" }
|
35
|
+
UI.message("Available apps:\n- #{available_apps.join("\n- ")}")
|
36
|
+
UI.error("Make sure to run `match` with the same user and team every time.")
|
37
|
+
UI.user_error!("Couldn't find bundle identifier '#{app_identifier}' for the user '#{username}'")
|
38
|
+
end
|
39
|
+
|
40
|
+
def certificate_exists(username: nil, certificate_id: nil)
|
41
|
+
found = Spaceship.certificate.all.find do |cert|
|
42
|
+
cert.id == certificate_id
|
43
|
+
end
|
44
|
+
return if found
|
45
|
+
|
46
|
+
UI.error("Certificate '#{certificate_id}' (stored in your git repo) is not available on the Developer Portal")
|
47
|
+
UI.error("for the user #{username}")
|
48
|
+
UI.error("Make sure to use the same user and team every time you run 'match' for this")
|
49
|
+
UI.error("Git repository. This might be caused by revoking the certificate on the Dev Portal")
|
50
|
+
UI.user_error!("To reset the certificates of your Apple account, you can use the `match nuke` feature, more information on https://github.com/fastlane/fastlane/tree/master/match")
|
51
|
+
end
|
52
|
+
|
53
|
+
def profile_exists(username: nil, uuid: nil)
|
54
|
+
found = Spaceship.provisioning_profile.all.find do |profile|
|
55
|
+
profile.uuid == uuid
|
56
|
+
end
|
57
|
+
|
58
|
+
unless found
|
59
|
+
UI.error("Provisioning profile '#{uuid}' is not available on the Developer Portal")
|
60
|
+
UI.error("for the user #{username}")
|
61
|
+
UI.error("Make sure to use the same user and team every time you run 'match' for this")
|
62
|
+
UI.error("Git repository. This might be caused by deleting the provisioning profile on the Dev Portal")
|
63
|
+
UI.user_error!("To reset the provisioning profiles of your Apple account, you can use the `match nuke` feature, more information on https://github.com/fastlane/fastlane/tree/master/match")
|
64
|
+
end
|
65
|
+
|
66
|
+
if found.valid?
|
67
|
+
return found
|
68
|
+
else
|
69
|
+
UI.important("'#{found.name}' is available on the Developer Portal, however it's 'Invalid', fixing this now for you 🔨")
|
70
|
+
# it's easier to just create a new one, than to repair an existing profile
|
71
|
+
# it has the same effects anyway, including a new UUID of the provisioning profile
|
72
|
+
found.delete!
|
73
|
+
# return nil to re-download the new profile in runner.rb
|
74
|
+
return nil
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Match
|
2
|
+
class TablePrinter
|
3
|
+
# logs public key's name, user, organisation, country, availability dates
|
4
|
+
def self.print_certificate_info(cert_info: nil)
|
5
|
+
params = {
|
6
|
+
rows: cert_info,
|
7
|
+
title: "Installed Certificate".green
|
8
|
+
}
|
9
|
+
|
10
|
+
puts ""
|
11
|
+
puts Terminal::Table.new(params)
|
12
|
+
puts ""
|
13
|
+
rescue => ex
|
14
|
+
UI.error(ex)
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.print_summary(app_identifier: nil, type: nil)
|
18
|
+
rows = []
|
19
|
+
|
20
|
+
type = type.to_sym
|
21
|
+
|
22
|
+
rows << ["App Identifier", "", app_identifier]
|
23
|
+
rows << ["Type", "", type]
|
24
|
+
|
25
|
+
{
|
26
|
+
Utils.environment_variable_name(app_identifier: app_identifier, type: type) => "Profile UUID",
|
27
|
+
Utils.environment_variable_name_profile_name(app_identifier: app_identifier, type: type) => "Profile Name",
|
28
|
+
Utils.environment_variable_name_team_id(app_identifier: app_identifier, type: type) => "Development Team ID"
|
29
|
+
}.each do |env_key, name|
|
30
|
+
rows << [name, env_key, ENV[env_key]]
|
31
|
+
end
|
32
|
+
|
33
|
+
params = {}
|
34
|
+
params[:rows] = rows
|
35
|
+
params[:title] = "Installed Provisioning Profile".green
|
36
|
+
params[:headings] = ['Parameter', 'Environment Variable', 'Value']
|
37
|
+
|
38
|
+
puts ""
|
39
|
+
puts Terminal::Table.new(params)
|
40
|
+
puts ""
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Match
|
2
|
+
class Utils
|
3
|
+
def self.import(item_path, keychain, password: "")
|
4
|
+
keychain_path = FastlaneCore::Helper.keychain_path(keychain)
|
5
|
+
FastlaneCore::KeychainImporter.import_file(item_path, keychain_path, keychain_password: password, output: $verbose)
|
6
|
+
end
|
7
|
+
|
8
|
+
# Fill in an environment variable, ready to be used in _xcodebuild_
|
9
|
+
def self.fill_environment(key, value)
|
10
|
+
UI.important "Setting environment variable '#{key}' to '#{value}'" if $verbose
|
11
|
+
ENV[key] = value
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.environment_variable_name(app_identifier: nil, type: nil)
|
15
|
+
base_environment_variable_name(app_identifier: app_identifier, type: type).join("_")
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.environment_variable_name_team_id(app_identifier: nil, type: nil)
|
19
|
+
(base_environment_variable_name(app_identifier: app_identifier, type: type) + ["team-id"]).join("_")
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.environment_variable_name_profile_name(app_identifier: nil, type: nil)
|
23
|
+
(base_environment_variable_name(app_identifier: app_identifier, type: type) + ["profile-name"]).join("_")
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.get_cert_info(cer_certificate_path)
|
27
|
+
command = "openssl x509 -inform der -in #{cer_certificate_path.shellescape} -subject -dates -noout"
|
28
|
+
command << " &" # start in separate process
|
29
|
+
output = Helper.backticks(command, print: $verbose)
|
30
|
+
|
31
|
+
# openssl output:
|
32
|
+
# subject= /UID={User ID}/CN={Certificate Name}/OU={Certificate User}/O={Organisation}/C={Country}\n
|
33
|
+
# notBefore={Start datetime}\n
|
34
|
+
# notAfter={End datetime}
|
35
|
+
cert_info = output.gsub(/\s*subject=\s*/, "").tr("/", "\n")
|
36
|
+
out_array = cert_info.split("\n")
|
37
|
+
openssl_keys_to_readable_keys = {
|
38
|
+
'UID' => 'User ID',
|
39
|
+
'CN' => 'Common Name',
|
40
|
+
'OU' => 'Organisation Unit',
|
41
|
+
'O' => 'Organisation',
|
42
|
+
'C' => 'Country',
|
43
|
+
'notBefore' => 'Start Datetime',
|
44
|
+
'notAfter' => 'End Datetime'
|
45
|
+
}
|
46
|
+
|
47
|
+
return out_array.map { |x| x.split(/=+/) if x.include? "=" }
|
48
|
+
.compact
|
49
|
+
.map { |k, v| [openssl_keys_to_readable_keys.fetch(k, k), v] }
|
50
|
+
rescue => ex
|
51
|
+
UI.error(ex)
|
52
|
+
return {}
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.base_environment_variable_name(app_identifier: nil, type: nil)
|
56
|
+
["sigh", app_identifier, type]
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
data/pem/README.md
ADDED
@@ -0,0 +1,175 @@
|
|
1
|
+
<h3 align="center">
|
2
|
+
<a href="https://github.com/fastlane/fastlane/tree/master/fastlane">
|
3
|
+
<img src="../fastlane/assets/fastlane.png" width="150" />
|
4
|
+
<br />
|
5
|
+
fastlane
|
6
|
+
</a>
|
7
|
+
</h3>
|
8
|
+
<p align="center">
|
9
|
+
<a href="https://github.com/fastlane/fastlane/tree/master/deliver">deliver</a> •
|
10
|
+
<a href="https://github.com/fastlane/fastlane/tree/master/snapshot">snapshot</a> •
|
11
|
+
<a href="https://github.com/fastlane/fastlane/tree/master/frameit">frameit</a> •
|
12
|
+
<b>pem</b> •
|
13
|
+
<a href="https://github.com/fastlane/fastlane/tree/master/sigh">sigh</a> •
|
14
|
+
<a href="https://github.com/fastlane/fastlane/tree/master/produce">produce</a> •
|
15
|
+
<a href="https://github.com/fastlane/fastlane/tree/master/cert">cert</a> •
|
16
|
+
<a href="https://github.com/fastlane/fastlane/tree/master/spaceship">spaceship</a> •
|
17
|
+
<a href="https://github.com/fastlane/fastlane/tree/master/pilot">pilot</a> •
|
18
|
+
<a href="https://github.com/fastlane/boarding">boarding</a> •
|
19
|
+
<a href="https://github.com/fastlane/fastlane/tree/master/gym">gym</a> •
|
20
|
+
<a href="https://github.com/fastlane/fastlane/tree/master/scan">scan</a> •
|
21
|
+
<a href="https://github.com/fastlane/fastlane/tree/master/match">match</a>
|
22
|
+
</p>
|
23
|
+
-------
|
24
|
+
|
25
|
+
<p align="center">
|
26
|
+
<img src="assets/pem.png" height="110">
|
27
|
+
</p>
|
28
|
+
|
29
|
+
pem
|
30
|
+
============
|
31
|
+
|
32
|
+
[![Twitter: @FastlaneTools](https://img.shields.io/badge/contact-@FastlaneTools-blue.svg?style=flat)](https://twitter.com/FastlaneTools)
|
33
|
+
[![License](https://img.shields.io/badge/license-MIT-green.svg?style=flat)](https://github.com/fastlane/fastlane/blob/master/pem/LICENSE)
|
34
|
+
[![Gem](https://img.shields.io/gem/v/pem.svg?style=flat)](http://rubygems.org/gems/pem)
|
35
|
+
|
36
|
+
###### Automatically generate and renew your push notification profiles
|
37
|
+
|
38
|
+
Tired of manually creating and maintaining your push notification profiles for your iOS apps? Tired of generating a `pem` file for your server?
|
39
|
+
|
40
|
+
`pem` does all that for, just by simply running `pem`.
|
41
|
+
|
42
|
+
`pem` creates new .pem, .cer, and .p12 files to be uploaded to your push server if a valid push notification profile is needed. `pem` does not cover uploading the file to your server.
|
43
|
+
|
44
|
+
To automate iOS Provisioning profiles you can use [sigh](https://github.com/fastlane/fastlane/tree/master/sigh).
|
45
|
+
|
46
|
+
Get in contact with the developer on Twitter: [@FastlaneTools](https://twitter.com/FastlaneTools)
|
47
|
+
|
48
|
+
-------
|
49
|
+
<p align="center">
|
50
|
+
<a href="#features">Features</a> •
|
51
|
+
<a href="#installation">Installation</a> •
|
52
|
+
<a href="#usage">Usage</a> •
|
53
|
+
<a href="#how-does-it-work">How does it work?</a> •
|
54
|
+
<a href="#tips">Tips</a> •
|
55
|
+
<a href="#need-help">Need help?</a>
|
56
|
+
</p>
|
57
|
+
|
58
|
+
-------
|
59
|
+
|
60
|
+
<h5 align="center"><code>pem</code> is part of <a href="https://fastlane.tools">fastlane</a>: The easiest way to automate beta deployments and releases for your iOS and Android apps.</h5>
|
61
|
+
|
62
|
+
# Features
|
63
|
+
Well, it's actually just one: Generate the ```pem``` file for your server.
|
64
|
+
|
65
|
+
|
66
|
+
Check out this gif:
|
67
|
+
|
68
|
+
![assets/PEMRecording.gif](assets/PEMRecording.gif)
|
69
|
+
|
70
|
+
# Installation
|
71
|
+
sudo gem install fastlane
|
72
|
+
|
73
|
+
Make sure, you have the latest version of the Xcode command line tools installed:
|
74
|
+
|
75
|
+
xcode-select --install
|
76
|
+
|
77
|
+
# Usage
|
78
|
+
|
79
|
+
fastlane pem
|
80
|
+
|
81
|
+
Yes, that's the whole command!
|
82
|
+
|
83
|
+
This does the following:
|
84
|
+
|
85
|
+
- Create a new signing request
|
86
|
+
- Create a new push certification
|
87
|
+
- Downloads the certificate
|
88
|
+
- Generates a new ```.pem``` file in the current working directory, which you can upload to your server
|
89
|
+
|
90
|
+
```pem``` will never revoke your existing certificates.
|
91
|
+
|
92
|
+
If you already have a push certificate enabled, which is active for at least 30 more days, `pem` will not create a new certificate. If you still want to create one, use the `force`:
|
93
|
+
|
94
|
+
fastlane pem --force
|
95
|
+
|
96
|
+
You can pass parameters like this:
|
97
|
+
|
98
|
+
fastlane pem -a com.krausefx.app -u username
|
99
|
+
|
100
|
+
If you want to generate a development certificate instead:
|
101
|
+
|
102
|
+
fastlane pem --development
|
103
|
+
|
104
|
+
Set a password for your `p12` file:
|
105
|
+
|
106
|
+
fastlane pem -p "MyPass"
|
107
|
+
|
108
|
+
You can specify a name for the output file:
|
109
|
+
|
110
|
+
fastlane pem -o my.pem
|
111
|
+
|
112
|
+
To get a list of available options run:
|
113
|
+
|
114
|
+
fastlane pem --help
|
115
|
+
|
116
|
+
|
117
|
+
### Note about empty `p12` passwords and Keychain Access.app
|
118
|
+
|
119
|
+
`pem` will produce a valid `p12` without specifying a password, or using the empty-string as the password.
|
120
|
+
While the file is valid, Mac OSX's Keychain Access will not allow you to open the file without specifying a passphrase.
|
121
|
+
|
122
|
+
Instead, you may verify the file is valid using OpenSSL:
|
123
|
+
|
124
|
+
openssl pkcs12 -info -in my.p12
|
125
|
+
|
126
|
+
##### [Like this tool? Be the first to know about updates and new fastlane tools](https://tinyletter.com/krausefx)
|
127
|
+
|
128
|
+
## Environment Variables
|
129
|
+
|
130
|
+
Run `fastlane pem --help` to get a list of available environment variables.
|
131
|
+
|
132
|
+
# How does it work?
|
133
|
+
|
134
|
+
`pem` uses [spaceship](https://spaceship.airforce) to communicate with the Apple Developer Portal to request a new push certificate for you.
|
135
|
+
|
136
|
+
## How is my password stored?
|
137
|
+
```pem``` uses the [password manager](https://github.com/fastlane/fastlane/tree/master/credentials_manager) from `fastlane`. Take a look the [CredentialsManager README](https://github.com/fastlane/fastlane/tree/master/credentials_manager) for more information.
|
138
|
+
|
139
|
+
# Tips
|
140
|
+
|
141
|
+
## [`fastlane`](https://fastlane.tools) Toolchain
|
142
|
+
|
143
|
+
- [`fastlane`](https://fastlane.tools): The easiest way to automate beta deployments and releases for your iOS and Android apps
|
144
|
+
- [`deliver`](https://github.com/fastlane/fastlane/tree/master/deliver): Upload screenshots, metadata and your app to the App Store
|
145
|
+
- [`snapshot`](https://github.com/fastlane/fastlane/tree/master/snapshot): Automate taking localized screenshots of your iOS app on every device
|
146
|
+
- [`frameit`](https://github.com/fastlane/fastlane/tree/master/frameit): Quickly put your screenshots into the right device frames
|
147
|
+
- [`sigh`](https://github.com/fastlane/fastlane/tree/master/sigh): Because you would rather spend your time building stuff than fighting provisioning
|
148
|
+
- [`produce`](https://github.com/fastlane/fastlane/tree/master/produce): Create new iOS apps on iTunes Connect and Dev Portal using the command line
|
149
|
+
- [`cert`](https://github.com/fastlane/fastlane/tree/master/cert): Automatically create and maintain iOS code signing certificates
|
150
|
+
- [`spaceship`](https://github.com/fastlane/fastlane/tree/master/spaceship): Ruby library to access the Apple Dev Center and iTunes Connect
|
151
|
+
- [`pilot`](https://github.com/fastlane/fastlane/tree/master/pilot): The best way to manage your TestFlight testers and builds from your terminal
|
152
|
+
- [`boarding`](https://github.com/fastlane/boarding): The easiest way to invite your TestFlight beta testers
|
153
|
+
- [`gym`](https://github.com/fastlane/fastlane/tree/master/gym): Building your iOS app has never been easier
|
154
|
+
- [`scan`](https://github.com/fastlane/fastlane/tree/master/scan): The easiest way to run tests of your iOS and Mac app
|
155
|
+
- [`match`](https://github.com/fastlane/fastlane/tree/master/match): Easily sync your certificates and profiles across your team using git
|
156
|
+
|
157
|
+
##### [Like this tool? Be the first to know about updates and new fastlane tools](https://tinyletter.com/krausefx)
|
158
|
+
|
159
|
+
## Use the 'Provisioning Quicklook plugin'
|
160
|
+
Download and install the [Provisioning Plugin](https://github.com/chockenberry/Provisioning).
|
161
|
+
|
162
|
+
It will show you the ```pem``` files like this:
|
163
|
+
![assets/QuickLookScreenshot.png](assets/QuickLookScreenshot.png)
|
164
|
+
|
165
|
+
|
166
|
+
# Need help?
|
167
|
+
Please submit an issue on GitHub and provide information about your setup
|
168
|
+
|
169
|
+
# Code of Conduct
|
170
|
+
Help us keep `pem` open and inclusive. Please read and follow our [Code of Conduct](https://github.com/fastlane/fastlane/blob/master/CODE_OF_CONDUCT.md).
|
171
|
+
|
172
|
+
# License
|
173
|
+
This project is licensed under the terms of the MIT license. See the LICENSE file.
|
174
|
+
|
175
|
+
> This project and all fastlane 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 fastlane 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 fastlane tools.
|
data/pem/lib/pem.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'pem/manager'
|
2
|
+
require 'pem/options'
|
3
|
+
|
4
|
+
require 'fastlane_core'
|
5
|
+
|
6
|
+
module PEM
|
7
|
+
# Use this to just setup the configuration attribute and set it later somewhere else
|
8
|
+
class << self
|
9
|
+
attr_accessor :config
|
10
|
+
end
|
11
|
+
|
12
|
+
TMP_FOLDER = "/tmp/PEM/"
|
13
|
+
FileUtils.mkdir_p TMP_FOLDER
|
14
|
+
|
15
|
+
ENV['FASTLANE_TEAM_ID'] ||= ENV["PEM_TEAM_ID"]
|
16
|
+
ENV['DELIVER_USER'] ||= ENV["PEM_USERNAME"]
|
17
|
+
|
18
|
+
Helper = FastlaneCore::Helper # you gotta love Ruby: Helper.* should use the Helper class contained in FastlaneCore
|
19
|
+
UI = FastlaneCore::UI
|
20
|
+
ROOT = Pathname.new(File.expand_path('../..', __FILE__))
|
21
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'commander'
|
2
|
+
|
3
|
+
HighLine.track_eof = false
|
4
|
+
|
5
|
+
module PEM
|
6
|
+
class CommandsGenerator
|
7
|
+
include Commander::Methods
|
8
|
+
|
9
|
+
def self.start
|
10
|
+
self.new.run
|
11
|
+
end
|
12
|
+
|
13
|
+
def run
|
14
|
+
program :name, 'pem'
|
15
|
+
program :version, Fastlane::VERSION
|
16
|
+
program :description, 'CLI for \'PEM\' - Automatically generate and renew your push notification profiles'
|
17
|
+
program :help, 'Author', 'Felix Krause <pem@krausefx.com>'
|
18
|
+
program :help, 'Website', 'https://fastlane.tools'
|
19
|
+
program :help, 'GitHub', 'https://github.com/fastlane/PEM'
|
20
|
+
program :help_formatter, :compact
|
21
|
+
|
22
|
+
global_option('--verbose') { $verbose = true }
|
23
|
+
|
24
|
+
FastlaneCore::CommanderGenerator.new.generate(PEM::Options.available_options)
|
25
|
+
|
26
|
+
command :renew do |c|
|
27
|
+
c.syntax = 'pem renew'
|
28
|
+
c.description = 'Renews the certificate (in case it expired) and shows the path to the generated pem file'
|
29
|
+
|
30
|
+
c.action do |args, options|
|
31
|
+
PEM.config = FastlaneCore::Configuration.create(PEM::Options.available_options, options.__hash__)
|
32
|
+
PEM::Manager.start
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
default_command :renew
|
37
|
+
|
38
|
+
run!
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'spaceship'
|
3
|
+
|
4
|
+
module PEM
|
5
|
+
# Creates the push profile and stores it in the correct location
|
6
|
+
class Manager
|
7
|
+
class << self
|
8
|
+
def start
|
9
|
+
FastlaneCore::PrintTable.print_values(config: PEM.config, hide_keys: [:new_profile], title: "Summary for PEM #{Fastlane::VERSION}")
|
10
|
+
login
|
11
|
+
|
12
|
+
existing_certificate = certificate.all.detect do |c|
|
13
|
+
c.name == PEM.config[:app_identifier]
|
14
|
+
end
|
15
|
+
|
16
|
+
if existing_certificate
|
17
|
+
remaining_days = (existing_certificate.expires - Time.now) / 60 / 60 / 24
|
18
|
+
UI.message "Existing push notification profile '#{existing_certificate.owner_name}' is valid for #{remaining_days.round} more days."
|
19
|
+
if remaining_days > 30
|
20
|
+
if PEM.config[:force]
|
21
|
+
UI.success "You already have an existing push certificate, but a new one will be created since the --force option has been set."
|
22
|
+
else
|
23
|
+
UI.success "You already have a push certificate, which is active for more than 30 more days. No need to create a new one"
|
24
|
+
UI.success "If you still want to create a new one, use the --force option when running PEM."
|
25
|
+
return false
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
return create_certificate
|
31
|
+
end
|
32
|
+
|
33
|
+
def login
|
34
|
+
UI.message "Starting login with user '#{PEM.config[:username]}'"
|
35
|
+
Spaceship.login(PEM.config[:username], nil)
|
36
|
+
Spaceship.client.select_team
|
37
|
+
UI.message "Successfully logged in"
|
38
|
+
end
|
39
|
+
|
40
|
+
def create_certificate
|
41
|
+
UI.important "Creating a new push certificate for app '#{PEM.config[:app_identifier]}'."
|
42
|
+
|
43
|
+
csr, pkey = Spaceship.certificate.create_certificate_signing_request
|
44
|
+
|
45
|
+
begin
|
46
|
+
cert = certificate.create!(csr: csr, bundle_id: PEM.config[:app_identifier])
|
47
|
+
rescue => ex
|
48
|
+
if ex.to_s.include? "You already have a current"
|
49
|
+
# That's the most common failure probably
|
50
|
+
UI.message ex.to_s
|
51
|
+
UI.user_error!("You already have 2 active push profiles for this application/environment. You'll need to revoke an old certificate to make room for a new one")
|
52
|
+
else
|
53
|
+
raise ex
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
x509_certificate = cert.download
|
58
|
+
certificate_type = (PEM.config[:development] ? 'development' : 'production')
|
59
|
+
filename_base = PEM.config[:pem_name] || "#{certificate_type}_#{PEM.config[:app_identifier]}"
|
60
|
+
filename_base = File.basename(filename_base, ".pem") # strip off the .pem if it was provided.
|
61
|
+
|
62
|
+
output_path = PEM.config[:output_path]
|
63
|
+
FileUtils.mkdir_p(File.expand_path(output_path))
|
64
|
+
|
65
|
+
if PEM.config[:save_private_key]
|
66
|
+
private_key_path = File.join(output_path, "#{filename_base}.pkey")
|
67
|
+
File.write(private_key_path, pkey.to_pem)
|
68
|
+
UI.message("Private key: ".green + Pathname.new(private_key_path).realpath.to_s)
|
69
|
+
end
|
70
|
+
|
71
|
+
if PEM.config[:generate_p12]
|
72
|
+
p12_cert_path = File.join(output_path, "#{filename_base}.p12")
|
73
|
+
p12 = OpenSSL::PKCS12.create(PEM.config[:p12_password], certificate_type, pkey, x509_certificate)
|
74
|
+
File.write(p12_cert_path, p12.to_der)
|
75
|
+
UI.message("p12 certificate: ".green + Pathname.new(p12_cert_path).realpath.to_s)
|
76
|
+
end
|
77
|
+
|
78
|
+
x509_cert_path = File.join(output_path, "#{filename_base}.pem")
|
79
|
+
File.write(x509_cert_path, x509_certificate.to_pem + pkey.to_pem)
|
80
|
+
UI.message("PEM: ".green + Pathname.new(x509_cert_path).realpath.to_s)
|
81
|
+
return x509_cert_path
|
82
|
+
end
|
83
|
+
|
84
|
+
def certificate
|
85
|
+
if PEM.config[:development]
|
86
|
+
Spaceship.certificate.development_push
|
87
|
+
else
|
88
|
+
Spaceship.certificate.production_push
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|