fastlane-plugin-match_import 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +149 -0
- data/lib/fastlane/plugin/match_import/actions/match_export_action.rb +49 -0
- data/lib/fastlane/plugin/match_import/actions/match_export_apns_action.rb +47 -0
- data/lib/fastlane/plugin/match_import/actions/match_import_action.rb +49 -0
- data/lib/fastlane/plugin/match_import/actions/match_import_apns_action.rb +47 -0
- data/lib/fastlane/plugin/match_import/actions/match_remove_action.rb +49 -0
- data/lib/fastlane/plugin/match_import/actions/match_remove_invalid_apns_action.rb +47 -0
- data/lib/fastlane/plugin/match_import/apns_export_file_options.rb +34 -0
- data/lib/fastlane/plugin/match_import/apns_file_options.rb +42 -0
- data/lib/fastlane/plugin/match_import/apns_remove_invalid_file_options.rb +30 -0
- data/lib/fastlane/plugin/match_import/commands_generator.rb +159 -0
- data/lib/fastlane/plugin/match_import/custom_file_options.rb +43 -0
- data/lib/fastlane/plugin/match_import/encryption/openssl.rb +18 -0
- data/lib/fastlane/plugin/match_import/helper/match_import_helper.rb +16 -0
- data/lib/fastlane/plugin/match_import/options.rb +26 -0
- data/lib/fastlane/plugin/match_import/runner.rb +153 -0
- data/lib/fastlane/plugin/match_import/runner_apns.rb +295 -0
- data/lib/fastlane/plugin/match_import/utils.rb +81 -0
- data/lib/fastlane/plugin/match_import/version.rb +6 -0
- data/lib/fastlane/plugin/match_import.rb +26 -0
- metadata +189 -0
@@ -0,0 +1,159 @@
|
|
1
|
+
require 'commander'
|
2
|
+
require 'fastlane_core/configuration/configuration'
|
3
|
+
|
4
|
+
require_relative '../match_import'
|
5
|
+
|
6
|
+
HighLine.track_eof = false
|
7
|
+
module Fastlane
|
8
|
+
module MatchImport
|
9
|
+
class CommandsGenerator
|
10
|
+
include Commander::Methods
|
11
|
+
|
12
|
+
def self.start
|
13
|
+
self.new.run
|
14
|
+
end
|
15
|
+
|
16
|
+
def run
|
17
|
+
program :name, 'match_import'
|
18
|
+
program :version, Fastlane::MatchImport::VERSION
|
19
|
+
program :description, Fastlane::MatchImport::DESCRIPTION
|
20
|
+
program :help, 'Author', 'Sergii Batsevych <serbats@ukr.net>'
|
21
|
+
program :help, 'Website', 'https://fastlane.tools'
|
22
|
+
program :help, 'GitHub', 'https://github.com/serbats/fastlane-plugin-match_import'
|
23
|
+
program :help_formatter, :compact
|
24
|
+
|
25
|
+
global_option('--verbose') { FastlaneCore::Globals.verbose = true }
|
26
|
+
|
27
|
+
command :import do |c|
|
28
|
+
c.syntax = 'match_import import'
|
29
|
+
c.description = Fastlane::MatchImport::DESCRIPTION
|
30
|
+
|
31
|
+
FastlaneCore::CommanderGenerator.new.generate(Fastlane::MatchImport::CustomFileOptions.available_options, command: c)
|
32
|
+
|
33
|
+
c.action do |args, options|
|
34
|
+
if args.count > 0
|
35
|
+
FastlaneCore::UI.user_error!("Please run `match_import import --file_name='*.txt' --source_path='testDir' --destination_path='repoDir'`")
|
36
|
+
end
|
37
|
+
|
38
|
+
params = FastlaneCore::Configuration.create(Fastlane::MatchImport::CustomFileOptions.available_options, options.__hash__)
|
39
|
+
params.load_configuration_file("Matchfile")
|
40
|
+
|
41
|
+
Match::Encryption.register_backend(type: "git", encryption_class: MatchImport::Encryption::OpenSSL)
|
42
|
+
Match::Encryption.register_backend(type: "s3", encryption_class: MatchImport::Encryption::OpenSSL)
|
43
|
+
|
44
|
+
Fastlane::MatchImport::Runner.new.run(params)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
command :export do |c|
|
49
|
+
c.syntax = 'match_import export'
|
50
|
+
c.description = Fastlane::MatchImport::DESCRIPTION
|
51
|
+
|
52
|
+
FastlaneCore::CommanderGenerator.new.generate(Fastlane::MatchImport::CustomFileOptions.available_options, command: c)
|
53
|
+
|
54
|
+
c.action do |args, options|
|
55
|
+
if args.count > 0
|
56
|
+
FastlaneCore::UI.user_error!("Please run `match_import export --file_name='*.txt' --source_path='repoDir' --destination_path='testDir'`")
|
57
|
+
end
|
58
|
+
|
59
|
+
params = FastlaneCore::Configuration.create(Fastlane::MatchImport::CustomFileOptions.available_options, options.__hash__)
|
60
|
+
params.load_configuration_file("Matchfile")
|
61
|
+
|
62
|
+
Match::Encryption.register_backend(type: "git", encryption_class: MatchImport::Encryption::OpenSSL)
|
63
|
+
Match::Encryption.register_backend(type: "s3", encryption_class: MatchImport::Encryption::OpenSSL)
|
64
|
+
|
65
|
+
Fastlane::MatchImport::Runner.new.run_export(params)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
command :remove do |c|
|
70
|
+
c.syntax = 'match_import remove'
|
71
|
+
c.description = Fastlane::MatchImport::DESCRIPTION
|
72
|
+
|
73
|
+
FastlaneCore::CommanderGenerator.new.generate(Fastlane::MatchImport::CustomFileOptions.available_options, command: c)
|
74
|
+
|
75
|
+
c.action do |args, options|
|
76
|
+
if args.count > 0
|
77
|
+
FastlaneCore::UI.user_error!("Please run `match_import remove --file_name='*.txt' --source_path='repoDir'`")
|
78
|
+
end
|
79
|
+
|
80
|
+
params = FastlaneCore::Configuration.create(Fastlane::MatchImport::CustomFileOptions.available_options, options.__hash__)
|
81
|
+
params.load_configuration_file("Matchfile")
|
82
|
+
|
83
|
+
Match::Encryption.register_backend(type: "git", encryption_class: MatchImport::Encryption::OpenSSL)
|
84
|
+
Match::Encryption.register_backend(type: "s3", encryption_class: MatchImport::Encryption::OpenSSL)
|
85
|
+
|
86
|
+
Fastlane::MatchImport::Runner.new.run_remove(params)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
command :import_apns do |c|
|
91
|
+
c.syntax = 'match_import import_apns'
|
92
|
+
c.description = Fastlane::MatchImport::DESCRIPTION
|
93
|
+
|
94
|
+
FastlaneCore::CommanderGenerator.new.generate(Fastlane::MatchImport::APNSFileOptions.available_options, command: c)
|
95
|
+
|
96
|
+
c.action do |args, options|
|
97
|
+
if args.count > 0
|
98
|
+
FastlaneCore::UI.user_error!("Please run `match_import import_apns --type='development' --cert_file_name='PushDev.cer' --p12_file_name='PushDev.p12'`")
|
99
|
+
end
|
100
|
+
|
101
|
+
params = FastlaneCore::Configuration.create(Fastlane::MatchImport::APNSFileOptions.available_options, options.__hash__)
|
102
|
+
params.load_configuration_file("Matchfile")
|
103
|
+
|
104
|
+
Match::Encryption.register_backend(type: "git", encryption_class: MatchImport::Encryption::OpenSSL)
|
105
|
+
Match::Encryption.register_backend(type: "s3", encryption_class: MatchImport::Encryption::OpenSSL)
|
106
|
+
|
107
|
+
Fastlane::MatchImport::RunnerAPNS.new.run(params)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
command :export_apns do |c|
|
112
|
+
c.syntax = 'match_import export_apns'
|
113
|
+
c.description = Fastlane::MatchImport::DESCRIPTION
|
114
|
+
|
115
|
+
FastlaneCore::CommanderGenerator.new.generate(Fastlane::MatchImport::APNSExportFileOptions.available_options, command: c)
|
116
|
+
|
117
|
+
c.action do |args, options|
|
118
|
+
if args.count > 0
|
119
|
+
FastlaneCore::UI.user_error!("Please run `match_import export_apns --type='development' --keychain_name='FastlaneKeychain' --keychain_password='password' --destination_path='testDir'`")
|
120
|
+
end
|
121
|
+
|
122
|
+
params = FastlaneCore::Configuration.create(Fastlane::MatchImport::APNSExportFileOptions.available_options, options.__hash__)
|
123
|
+
params.load_configuration_file("Matchfile")
|
124
|
+
|
125
|
+
Match::Encryption.register_backend(type: "git", encryption_class: MatchImport::Encryption::OpenSSL)
|
126
|
+
Match::Encryption.register_backend(type: "s3", encryption_class: MatchImport::Encryption::OpenSSL)
|
127
|
+
|
128
|
+
Fastlane::MatchImport::RunnerAPNS.new.run_export(params)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
command :remove_invalid_apns do |c|
|
133
|
+
c.syntax = 'match_import remove_invalid_apns'
|
134
|
+
c.description = Fastlane::MatchImport::DESCRIPTION
|
135
|
+
|
136
|
+
FastlaneCore::CommanderGenerator.new.generate(Fastlane::MatchImport::APNSRemoveInvalidFileOptions.available_options, command: c)
|
137
|
+
|
138
|
+
c.action do |args, options|
|
139
|
+
if args.count > 0
|
140
|
+
FastlaneCore::UI.user_error!("Please run `match_import remove_invalid_apns --type='development'`")
|
141
|
+
end
|
142
|
+
|
143
|
+
params = FastlaneCore::Configuration.create(Fastlane::MatchImport::APNSRemoveInvalidFileOptions.available_options, options.__hash__)
|
144
|
+
params.load_configuration_file("Matchfile")
|
145
|
+
|
146
|
+
Match::Encryption.register_backend(type: "git", encryption_class: MatchImport::Encryption::OpenSSL)
|
147
|
+
Match::Encryption.register_backend(type: "s3", encryption_class: MatchImport::Encryption::OpenSSL)
|
148
|
+
|
149
|
+
Fastlane::MatchImport::RunnerAPNS.new.run_remove_invalid(params)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
default_command(:import)
|
154
|
+
|
155
|
+
run!
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
|
2
|
+
require 'fastlane_core'
|
3
|
+
require 'match'
|
4
|
+
|
5
|
+
module Fastlane
|
6
|
+
module MatchImport
|
7
|
+
class CustomFileOptions
|
8
|
+
def self.exclude_match_options
|
9
|
+
# [:type, :output_path, :keychain_name, :keychain_password]
|
10
|
+
# Don't know how to exclude unused options and don't get error like:
|
11
|
+
# Could not find option 'type' in the list of available options
|
12
|
+
[]
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.available_options
|
16
|
+
all = Fastlane::MatchImport::Options.available_options
|
17
|
+
|
18
|
+
exclude_match_options.each do |key|
|
19
|
+
(i = all.find_index { |item| item.key == key }) && all.delete_at(i)
|
20
|
+
end
|
21
|
+
|
22
|
+
return all + custom_options
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.custom_options
|
26
|
+
[
|
27
|
+
FastlaneCore::ConfigItem.new(key: :file_name,
|
28
|
+
env_name: "MATCH_IMPORT_FILENAME",
|
29
|
+
description: "File to import. Could contain mask like '*.txt'",
|
30
|
+
optional: false),
|
31
|
+
FastlaneCore::ConfigItem.new(key: :destination_path,
|
32
|
+
env_name: "MATCH_IMPORT_DESTINATION_PATH",
|
33
|
+
description: "Path to copy imported file to",
|
34
|
+
optional: true),
|
35
|
+
FastlaneCore::ConfigItem.new(key: :source_path,
|
36
|
+
env_name: "MATCH_IMPORT_SOURCE_PATH",
|
37
|
+
description: "Path to take importing file from",
|
38
|
+
optional: true)
|
39
|
+
]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'match'
|
2
|
+
|
3
|
+
module Fastlane
|
4
|
+
module MatchImport
|
5
|
+
module Encryption
|
6
|
+
class OpenSSL < Match::Encryption::OpenSSL
|
7
|
+
def iterate(source_path)
|
8
|
+
super
|
9
|
+
# apns *.cer and *.p12 are encrypted/decrypted by 'super' call
|
10
|
+
Dir[File.join(source_path, "customImport/customImport/customImport", "custom", "**", "*")].each do |path|
|
11
|
+
next if File.directory?(path)
|
12
|
+
yield(path)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'fastlane_core/ui/ui'
|
2
|
+
|
3
|
+
module Fastlane
|
4
|
+
UI = FastlaneCore::UI unless Fastlane.const_defined?("UI")
|
5
|
+
|
6
|
+
module Helper
|
7
|
+
class MatchImportHelper
|
8
|
+
# class methods that you define here become available in your action
|
9
|
+
# as `Helper::MatchImportHelper.your_method`
|
10
|
+
#
|
11
|
+
def self.show_message
|
12
|
+
UI.message("Hello from the match_import plugin helper!")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
|
2
|
+
require 'fastlane_core'
|
3
|
+
require 'match'
|
4
|
+
|
5
|
+
module Fastlane
|
6
|
+
module MatchImport
|
7
|
+
class Options
|
8
|
+
def self.exclude_match_options
|
9
|
+
# [:output_path, :additional_cert_types, :readonly, :generate_apple_certs, :skip_provisioning_profiles, :force, :force_for_new_devices, :skip_confirmation, :template_name]
|
10
|
+
# Don't know how to exclude unused options and don't get error like:
|
11
|
+
# Could not find option 'type' in the list of available options
|
12
|
+
[]
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.available_options
|
16
|
+
all = Match::Options.available_options
|
17
|
+
|
18
|
+
exclude_match_options.each do |key|
|
19
|
+
(i = all.find_index { |item| item.key == key }) && all.delete_at(i)
|
20
|
+
end
|
21
|
+
|
22
|
+
return all
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,153 @@
|
|
1
|
+
require 'fastlane_core/print_table'
|
2
|
+
|
3
|
+
module Fastlane
|
4
|
+
module MatchImport
|
5
|
+
class Runner
|
6
|
+
attr_accessor :files_to_commit
|
7
|
+
attr_accessor :storage
|
8
|
+
|
9
|
+
def run(params)
|
10
|
+
self.files_to_commit = []
|
11
|
+
|
12
|
+
FastlaneCore::PrintTable.print_values(config: params,
|
13
|
+
hide_keys: [],
|
14
|
+
title: "Summary for match_import #{Fastlane::MatchImport::VERSION}")
|
15
|
+
|
16
|
+
MatchImport::Utils.update_optional_values_depending_on_storage_type(params)
|
17
|
+
|
18
|
+
# Get and verify custom file path
|
19
|
+
file_path = MatchImport::Utils.ensure_valid_file_path(params[:file_name], params[:source_path], "File to import")
|
20
|
+
# Verify destination path is one level dir. Othervise encrypt/decript won't work
|
21
|
+
destination_path = MatchImport::Utils.ensure_valid_one_level_path(params[:destination_path])
|
22
|
+
|
23
|
+
# Choose the right storage and encryption implementations
|
24
|
+
storage = MatchImport::Utils.storage(params, false)
|
25
|
+
|
26
|
+
# Init the encryption only after the `storage.download` was called to have the right working directory
|
27
|
+
encryption = MatchImport::Utils.encryption(params, storage)
|
28
|
+
|
29
|
+
storage_workspace = storage.prefixed_working_directory
|
30
|
+
|
31
|
+
# Hack to avoid conflicts with "fastlane match" encryption.
|
32
|
+
# It uses pattern: [File.join(source_path, "**", "*.{cer,p12,mobileprovision,provisionprofile}")]
|
33
|
+
# To avoid conflicts we use three level deep folder.
|
34
|
+
output_dir = File.join(storage_workspace, "customImport/customImport/customImport", "custom")
|
35
|
+
output_dir = File.join(output_dir, destination_path) if destination_path
|
36
|
+
|
37
|
+
# Make dir if doesn't exist
|
38
|
+
FileUtils.mkdir_p(output_dir)
|
39
|
+
# dest_path = File.join(output_dir, params[:file_name])
|
40
|
+
dest_path = output_dir
|
41
|
+
|
42
|
+
# Copy file
|
43
|
+
# IO.copy_stream(file_path, dest_path)
|
44
|
+
|
45
|
+
Dir[file_path].each do |file|
|
46
|
+
dest_file = File.join(dest_path, File.basename(file))
|
47
|
+
if File.file?(dest_file) && FileUtils.compare_file(file, dest_file)
|
48
|
+
UI.success("File '#{file}' already exist at destination and is unchanged")
|
49
|
+
else
|
50
|
+
self.files_to_commit << dest_path
|
51
|
+
|
52
|
+
FileUtils.cp(file, dest_path)
|
53
|
+
UI.success("Finish copying '#{file}' to '#{dest_path}'") if FastlaneCore::Globals.verbose?
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
if self.files_to_commit.count > 0
|
58
|
+
encryption.encrypt_files if encryption
|
59
|
+
storage.save_changes!(files_to_commit: self.files_to_commit)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def run_export(params)
|
64
|
+
FastlaneCore::PrintTable.print_values(config: params,
|
65
|
+
hide_keys: [],
|
66
|
+
title: "Summary for match_import #{Fastlane::MatchImport::VERSION}")
|
67
|
+
|
68
|
+
MatchImport::Utils.update_optional_values_depending_on_storage_type(params)
|
69
|
+
|
70
|
+
# Verify source path is one level dir. Othervise encrypt/decript won't work
|
71
|
+
source_path = MatchImport::Utils.ensure_valid_one_level_path(params[:source_path])
|
72
|
+
|
73
|
+
# Choose the right storage and encryption implementations
|
74
|
+
storage = MatchImport::Utils.storage(params, true)
|
75
|
+
|
76
|
+
# Init the encryption only after the `storage.download` was called to have the right working directory
|
77
|
+
MatchImport::Utils.encryption(params, storage)
|
78
|
+
|
79
|
+
storage_workspace = storage.prefixed_working_directory
|
80
|
+
|
81
|
+
# Hack to avoid conflicts with "fastlane match" encryption.
|
82
|
+
# It uses pattern: [File.join(source_path, "**", "*.{cer,p12,mobileprovision,provisionprofile}")]
|
83
|
+
# To avoid conflicts we use three level deep folder.
|
84
|
+
input_dir = File.join(storage_workspace, "customImport/customImport/customImport", "custom")
|
85
|
+
source_path = source_path.nil? ? input_dir : File.join(input_dir, source_path)
|
86
|
+
|
87
|
+
# Get and verify custom file path
|
88
|
+
file_path = MatchImport::Utils.ensure_valid_file_path(params[:file_name], source_path, "File to export")
|
89
|
+
|
90
|
+
output_dir = params[:destination_path].nil? ? '.' : params[:destination_path]
|
91
|
+
|
92
|
+
# Make dir if doesn't exist
|
93
|
+
FileUtils.mkdir_p(output_dir)
|
94
|
+
# dest_path = File.join(output_dir, params[:file_name])
|
95
|
+
dest_path = output_dir
|
96
|
+
|
97
|
+
# Copy file
|
98
|
+
# IO.copy_stream(file_path, dest_path)
|
99
|
+
|
100
|
+
Dir[file_path].each do |file|
|
101
|
+
dest_file = File.join(dest_path, File.basename(file))
|
102
|
+
if File.file?(dest_file) && FileUtils.compare_file(file, dest_file)
|
103
|
+
UI.success("File '#{file}' already exist at destination and is unchanged")
|
104
|
+
else
|
105
|
+
FileUtils.cp(file, dest_path)
|
106
|
+
UI.success("Finish copying '#{file}' to '#{dest_path}'") if FastlaneCore::Globals.verbose?
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def run_remove(params)
|
112
|
+
self.files_to_commit = []
|
113
|
+
|
114
|
+
FastlaneCore::PrintTable.print_values(config: params,
|
115
|
+
hide_keys: [],
|
116
|
+
title: "Summary for match_import #{Fastlane::MatchImport::VERSION}")
|
117
|
+
|
118
|
+
MatchImport::Utils.update_optional_values_depending_on_storage_type(params)
|
119
|
+
|
120
|
+
# Verify source path is one level dir. Othervise encrypt/decript won't work
|
121
|
+
source_path = MatchImport::Utils.ensure_valid_one_level_path(params[:source_path])
|
122
|
+
|
123
|
+
# Choose the right storage and encryption implementations
|
124
|
+
storage = MatchImport::Utils.storage(params, false)
|
125
|
+
|
126
|
+
storage_workspace = storage.prefixed_working_directory
|
127
|
+
|
128
|
+
# Hack to avoid conflicts with "fastlane match" encryption.
|
129
|
+
# It uses pattern: [File.join(source_path, "**", "*.{cer,p12,mobileprovision,provisionprofile}")]
|
130
|
+
# To avoid conflicts we use three level deep folder.
|
131
|
+
input_dir = File.join(storage_workspace, "customImport/customImport/customImport", "custom")
|
132
|
+
source_path = source_path.nil? ? input_dir : File.join(input_dir, source_path)
|
133
|
+
|
134
|
+
# Get and verify custom file path
|
135
|
+
file_path = MatchImport::Utils.ensure_valid_file_path(params[:file_name], source_path, "File to remove")
|
136
|
+
|
137
|
+
# Copy file
|
138
|
+
# IO.copy_stream(file_path, dest_path)
|
139
|
+
|
140
|
+
Dir[file_path].each do |file|
|
141
|
+
self.files_to_commit << file
|
142
|
+
|
143
|
+
FileUtils.rm(file)
|
144
|
+
UI.success("Finish removing '#{file}'") if FastlaneCore::Globals.verbose?
|
145
|
+
end
|
146
|
+
|
147
|
+
if self.files_to_commit.count > 0
|
148
|
+
storage.save_changes!(files_to_commit: self.files_to_commit)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|