fastlane-plugin-sapfire 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +135 -0
- data/lib/fastlane/plugin/sapfire/actions/app_certification_action.rb +79 -0
- data/lib/fastlane/plugin/sapfire/actions/associate_ms_store_action.rb +263 -0
- data/lib/fastlane/plugin/sapfire/actions/build_uwp_app_action.rb +55 -0
- data/lib/fastlane/plugin/sapfire/actions/dotnet_select_action.rb +46 -0
- data/lib/fastlane/plugin/sapfire/actions/ensure_dotnet_version_action.rb +123 -0
- data/lib/fastlane/plugin/sapfire/actions/ms_credentials_action.rb +91 -0
- data/lib/fastlane/plugin/sapfire/actions/msbuild_action.rb +45 -0
- data/lib/fastlane/plugin/sapfire/actions/msbuild_select_action.rb +53 -0
- data/lib/fastlane/plugin/sapfire/actions/nuget_pack_action.rb +46 -0
- data/lib/fastlane/plugin/sapfire/actions/update_uwp_signing_settings_action.rb +73 -0
- data/lib/fastlane/plugin/sapfire/actions/upload_ms_store_action.rb +218 -0
- data/lib/fastlane/plugin/sapfire/actions/upload_nuget_action.rb +95 -0
- data/lib/fastlane/plugin/sapfire/actions_base/msbuild_action_base.rb +42 -0
- data/lib/fastlane/plugin/sapfire/helper/ms_devcenter_helper.rb +292 -0
- data/lib/fastlane/plugin/sapfire/helper/sapfire_helper.rb +55 -0
- data/lib/fastlane/plugin/sapfire/msbuild/module.rb +34 -0
- data/lib/fastlane/plugin/sapfire/msbuild/options.rb +123 -0
- data/lib/fastlane/plugin/sapfire/msbuild/runner.rb +171 -0
- data/lib/fastlane/plugin/sapfire/sln_project/block.rb +30 -0
- data/lib/fastlane/plugin/sapfire/sln_project/global_block.rb +147 -0
- data/lib/fastlane/plugin/sapfire/sln_project/module.rb +14 -0
- data/lib/fastlane/plugin/sapfire/sln_project/project_block.rb +82 -0
- data/lib/fastlane/plugin/sapfire/sln_project/root_block.rb +72 -0
- data/lib/fastlane/plugin/sapfire/version.rb +5 -0
- data/lib/fastlane/plugin/sapfire.rb +16 -0
- metadata +182 -0
@@ -0,0 +1,171 @@
|
|
1
|
+
require "open3"
|
2
|
+
require "fastlane_core/print_table"
|
3
|
+
require_relative "module"
|
4
|
+
require_relative "options"
|
5
|
+
require_relative "../sln_project/module"
|
6
|
+
require_relative "../helper/sapfire_helper"
|
7
|
+
|
8
|
+
module Msbuild
|
9
|
+
class Runner
|
10
|
+
def run
|
11
|
+
params = Msbuild.config.params
|
12
|
+
|
13
|
+
FastlaneCore::PrintTable.print_values(config: params, title: "Summary for msbuild")
|
14
|
+
UI.user_error!("Can't find MSBuild") unless Fastlane::Helper::SapfireHelper.msbuild_specified?
|
15
|
+
UI.user_error!("Can't find dotnet. You selected MSBuild as a library, so dotnet is required to work with it. ") if
|
16
|
+
Msbuild.config.msbuild_type == Msbuild::MsbuildType::LIBRARY && !Fastlane::Helper::SapfireHelper.dotnet_specified?
|
17
|
+
|
18
|
+
prev_cwd = Dir.pwd
|
19
|
+
working_directory = File.dirname(File.expand_path(params[:project]))
|
20
|
+
UI.message("Change working directory to #{working_directory}")
|
21
|
+
Dir.chdir(working_directory)
|
22
|
+
|
23
|
+
params[:jobs] = 1 if params[:jobs].zero?
|
24
|
+
msbuild_path = Msbuild.config.msbuild_path
|
25
|
+
msbuild_args = get_msbuild_args(params, Msbuild.config.overwritten_props)
|
26
|
+
cmd = "#{msbuild_path} #{msbuild_args.join(" ")}"
|
27
|
+
|
28
|
+
check_configuration_platform(params)
|
29
|
+
UI.command(cmd)
|
30
|
+
|
31
|
+
Open3.popen2(cmd) do |_, stdout, wait_thr|
|
32
|
+
until stdout.eof?
|
33
|
+
stdout.each do |l|
|
34
|
+
line = l.force_encoding("utf-8").chomp
|
35
|
+
puts line
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
UI.user_error!("MSBuild execution failed. See the log above.") unless wait_thr.value.success?
|
40
|
+
UI.success("MSBuild has ended successfully") if wait_thr.value.success?
|
41
|
+
end
|
42
|
+
|
43
|
+
rename_package(params)
|
44
|
+
|
45
|
+
UI.message("Change working directory back to #{prev_cwd}")
|
46
|
+
Dir.chdir(prev_cwd)
|
47
|
+
end
|
48
|
+
|
49
|
+
def get_project_property_string(key, value)
|
50
|
+
"-p:#{key}=#{value}"
|
51
|
+
end
|
52
|
+
|
53
|
+
def get_msbuild_args(params, overwritten_props)
|
54
|
+
args = []
|
55
|
+
|
56
|
+
if params.values.include?(:properties)
|
57
|
+
params[:properties].each do |key, value|
|
58
|
+
unless overwritten_props.include?(key)
|
59
|
+
args.append(get_project_property_string(key, value))
|
60
|
+
next
|
61
|
+
end
|
62
|
+
|
63
|
+
# Remove properties that would be overwritten by this action
|
64
|
+
UI.important("Property #{key} will be ignored. Use `#{overwritten_props[key]}` option instead.")
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
configuration = params[:configuration] if
|
69
|
+
params.values.include?(:configuration) && !params[:configuration].empty?
|
70
|
+
|
71
|
+
platform = params[:platform] if
|
72
|
+
params.values.include?(:platform) && !params[:platform].empty?
|
73
|
+
|
74
|
+
need_restore = ([true].include?(params[:restore]) if params.values.include?(:restore)) || false
|
75
|
+
|
76
|
+
need_clean = ([true].include?(params[:clean]) if params.values.include?(:clean)) || false
|
77
|
+
|
78
|
+
appx_output_path = File.expand_path(params[:appx_output_path]) if
|
79
|
+
params.values.include?(:appx_output_path) && !params[:appx_output_path].empty?
|
80
|
+
|
81
|
+
appx_bundle_platforms = params[:appx_bundle_platforms] if
|
82
|
+
params.values.include?(:appx_bundle_platforms) && !params[:appx_bundle_platforms].empty?
|
83
|
+
|
84
|
+
build_mode = params[:build_mode] if
|
85
|
+
params.values.include?(:build_mode) && !params[:build_mode].empty?
|
86
|
+
|
87
|
+
certificate = Msbuild.config.certificate unless
|
88
|
+
Msbuild.config.certificate.nil? || Msbuild.config.certificate.empty?
|
89
|
+
|
90
|
+
certificate_password = Msbuild.config.certificate_password unless
|
91
|
+
Msbuild.config.certificate_password.nil? || Msbuild.config.certificate_password.empty?
|
92
|
+
|
93
|
+
certificate_thumbprint = Msbuild.config.certificate_thumbprint unless
|
94
|
+
Msbuild.config.certificate_thumbprint.nil? || Msbuild.config.certificate_thumbprint.empty?
|
95
|
+
|
96
|
+
signing_enabled = !params[:skip_codesigning] if params.values.include?(:skip_codesigning)
|
97
|
+
|
98
|
+
args.append("-p:Configuration=\"#{configuration}\"") unless configuration.nil?
|
99
|
+
args.append("-p:Platform=\"#{platform}\"") unless platform.nil?
|
100
|
+
args.append("-p:AppxPackageDir=\"#{appx_output_path}\"") unless appx_output_path.nil?
|
101
|
+
args.append("-p:AppxBundlePlatforms=\"#{appx_bundle_platforms}\"") unless appx_bundle_platforms.nil?
|
102
|
+
args.append("-p:AppxBundle=Always") if Msbuild.config.build_type == Msbuild::BuildType::UWP
|
103
|
+
args.append("-p:UapAppxPackageBuildMode=#{build_mode}") unless build_mode.nil?
|
104
|
+
args.append("-p:AppxPackageSigningEnabled=#{signing_enabled}") unless signing_enabled.nil?
|
105
|
+
args.append("-p:PackageCertificateKeyFile=\"#{certificate}\"") unless certificate.nil?
|
106
|
+
args.append("-p:PackageCertificatePassword=#{certificate_password}") unless certificate_password.nil?
|
107
|
+
args.append("-p:PackageCertificateThumbprint=#{certificate_thumbprint}") unless certificate_thumbprint.nil?
|
108
|
+
args.append("-m#{params[:jobs].positive? ? ":#{params[:jobs]}" : ""}")
|
109
|
+
args.append("-r") if need_restore || Msbuild.config.build_type == Msbuild::BuildType::NUGET
|
110
|
+
|
111
|
+
args.append("-t:Clean;Build") if need_clean
|
112
|
+
args.append("-t:Pack") if Msbuild.config.build_type == Msbuild::BuildType::NUGET
|
113
|
+
|
114
|
+
args
|
115
|
+
end
|
116
|
+
|
117
|
+
def check_configuration_platform(params)
|
118
|
+
configuration = params[:configuration] if
|
119
|
+
params.values.include?(:configuration) && !params[:configuration].empty?
|
120
|
+
|
121
|
+
platform = params[:platform] if
|
122
|
+
params.values.include?(:platform) && !params[:platform].empty?
|
123
|
+
|
124
|
+
root_block = SlnProject.open(params[:project])
|
125
|
+
platforms = root_block.global.solution_configuration_platforms.platforms
|
126
|
+
|
127
|
+
UI.user_error!("Configuration #{configuration} was not found in the solution") if
|
128
|
+
configuration.nil? || !platforms.key?(configuration)
|
129
|
+
UI.user_error!("Platform #{platform} for configuration #{configuration} was not found in the solution") if
|
130
|
+
platform.nil? || !platforms[configuration].include?(platform)
|
131
|
+
|
132
|
+
appx_bundle_platforms = params[:appx_bundle_platforms] if
|
133
|
+
params.values.include?(:appx_bundle_platforms) && !params[:appx_bundle_platforms].empty?
|
134
|
+
return if appx_bundle_platforms.nil?
|
135
|
+
|
136
|
+
appx_bundle_platforms.split("|").each do |x|
|
137
|
+
UI.user_error!("Platform #{x} for APPX bundle was not found in the solution") if
|
138
|
+
x.nil? || !platforms[configuration].include?(x)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def rename_package(params)
|
143
|
+
appx_output_name = params[:appx_output_name] if
|
144
|
+
params.values.include?(:appx_output_name) && !params[:appx_output_name].empty?
|
145
|
+
|
146
|
+
return if appx_output_name.nil? || appx_output_name.empty?
|
147
|
+
|
148
|
+
appx_output_path = File.expand_path(params[:appx_output_path]) if
|
149
|
+
params.values.include?(:appx_output_path) && !params[:appx_output_path].empty?
|
150
|
+
appx_output_path = "./" if appx_output_path.nil? || appx_output_path.empty?
|
151
|
+
|
152
|
+
Msbuild::Options::PACKAGE_FORMATS.each do |extension|
|
153
|
+
entries = Dir.entries(appx_output_path).find_all { |x| x.end_with?(extension) }
|
154
|
+
next if entries.nil? || entries.empty?
|
155
|
+
|
156
|
+
old_name = entries[0]
|
157
|
+
new_name = "#{appx_output_name}#{extension}"
|
158
|
+
|
159
|
+
UI.message("Rename #{old_name} to #{new_name}")
|
160
|
+
File.rename(File.join(appx_output_path, old_name), File.join(appx_output_path, new_name))
|
161
|
+
end
|
162
|
+
|
163
|
+
end
|
164
|
+
|
165
|
+
public(:run)
|
166
|
+
private(:get_project_property_string)
|
167
|
+
private(:get_msbuild_args)
|
168
|
+
private(:check_configuration_platform)
|
169
|
+
private(:rename_package)
|
170
|
+
end
|
171
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module SlnProject
|
2
|
+
class Assignment
|
3
|
+
attr_accessor :key, :value
|
4
|
+
|
5
|
+
def initialize(line)
|
6
|
+
parts = line.split("=")
|
7
|
+
|
8
|
+
if parts.empty?
|
9
|
+
self.key = ""
|
10
|
+
self.value = ""
|
11
|
+
return
|
12
|
+
end
|
13
|
+
|
14
|
+
self.key = parts[0].strip
|
15
|
+
self.value = parts[1].strip
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class InnerBlockResult
|
20
|
+
attr_accessor :block, :is_end
|
21
|
+
end
|
22
|
+
|
23
|
+
class BaseBlock
|
24
|
+
def parse(block_str)
|
25
|
+
nil
|
26
|
+
end
|
27
|
+
|
28
|
+
protected(:parse)
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
require_relative "block"
|
2
|
+
|
3
|
+
module SlnProject
|
4
|
+
class GlobalBlock < BaseBlock
|
5
|
+
START_TOKENS = {
|
6
|
+
GlobalSectionToken: "GlobalSection"
|
7
|
+
}.freeze
|
8
|
+
|
9
|
+
END_TOKENS = {
|
10
|
+
GlobalSectionToken: "EndGlobalSection"
|
11
|
+
}.freeze
|
12
|
+
|
13
|
+
attr_accessor :solution_configuration_platforms, :solution_properties
|
14
|
+
|
15
|
+
def parse(block_str)
|
16
|
+
inner_block = nil
|
17
|
+
inner_block_str = ""
|
18
|
+
content_reader = StringIO.new(block_str)
|
19
|
+
|
20
|
+
content_reader.each_line do |line|
|
21
|
+
trim_line = line.strip
|
22
|
+
inner_block = check_start_token(trim_line, inner_block)
|
23
|
+
inner_block = check_end_token(trim_line, inner_block, inner_block_str)
|
24
|
+
|
25
|
+
inner_block_str += "#{trim_line}\n" unless inner_block.nil?
|
26
|
+
inner_block_str = "" if inner_block.nil?
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def check_start_token(line, inner_block)
|
31
|
+
inner_block = GlobalSectionFactory.create(line) if line.start_with?("#{START_TOKENS[:GlobalSectionToken]}(")
|
32
|
+
inner_block
|
33
|
+
end
|
34
|
+
|
35
|
+
def check_end_token(line, inner_block, inner_block_str)
|
36
|
+
return inner_block unless END_TOKENS.any? { |_, v| line == v }
|
37
|
+
|
38
|
+
inner_block.parse(inner_block_str)
|
39
|
+
|
40
|
+
case inner_block.type
|
41
|
+
when GlobalSectionBlock::TYPES[:SolutionConfigurationPlatforms]
|
42
|
+
self.solution_configuration_platforms = inner_block
|
43
|
+
when GlobalSectionBlock::TYPES[:SolutionProperties]
|
44
|
+
self.solution_properties = inner_block
|
45
|
+
end
|
46
|
+
|
47
|
+
nil
|
48
|
+
end
|
49
|
+
|
50
|
+
public(:parse)
|
51
|
+
private(:check_start_token)
|
52
|
+
private(:check_end_token)
|
53
|
+
private(:solution_configuration_platforms=)
|
54
|
+
private(:solution_properties=)
|
55
|
+
end
|
56
|
+
|
57
|
+
class GlobalSectionFactory
|
58
|
+
def self.create(line)
|
59
|
+
type = parse_header(line)
|
60
|
+
|
61
|
+
case type
|
62
|
+
when GlobalSectionBlock::TYPES[:SolutionConfigurationPlatforms]
|
63
|
+
SolutionConfigurationPlatformsBlock.new(type)
|
64
|
+
when GlobalSectionBlock::TYPES[:SolutionProperties]
|
65
|
+
SolutionPropertiesBlock.new(type)
|
66
|
+
else
|
67
|
+
GlobalSectionBlock.new(GlobalSectionBlock::TYPES[:Unknown])
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def self.parse_header(line)
|
72
|
+
key = Assignment.new(line).key
|
73
|
+
pattern = /\((.*?)\)/
|
74
|
+
key.match(pattern)[1]
|
75
|
+
end
|
76
|
+
|
77
|
+
private_class_method(:parse_header, :new)
|
78
|
+
public_class_method(:create)
|
79
|
+
end
|
80
|
+
|
81
|
+
class GlobalSectionBlock < BaseBlock
|
82
|
+
TYPES = {
|
83
|
+
SolutionConfigurationPlatforms: "SolutionConfigurationPlatforms",
|
84
|
+
SolutionProperties: "SolutionProperties",
|
85
|
+
Unknown: "Unknown" # must be always the last
|
86
|
+
}.freeze
|
87
|
+
|
88
|
+
attr_accessor :type
|
89
|
+
|
90
|
+
def initialize(type)
|
91
|
+
self.type = type
|
92
|
+
end
|
93
|
+
|
94
|
+
private(:type=)
|
95
|
+
end
|
96
|
+
|
97
|
+
class SolutionConfigurationPlatformsBlock < GlobalSectionBlock
|
98
|
+
attr_accessor :platforms
|
99
|
+
|
100
|
+
def parse(block_str)
|
101
|
+
is_header = false
|
102
|
+
content_reader = StringIO.new(block_str)
|
103
|
+
self.platforms = {}
|
104
|
+
|
105
|
+
content_reader.each_line do |line|
|
106
|
+
unless is_header
|
107
|
+
is_header = true
|
108
|
+
next
|
109
|
+
end
|
110
|
+
|
111
|
+
assignment = Assignment.new(line).key
|
112
|
+
assignment_parts = assignment.split("|")
|
113
|
+
configuration = assignment_parts[0]
|
114
|
+
platform = assignment_parts[1]
|
115
|
+
|
116
|
+
self.platforms[configuration] = [] unless self.platforms[configuration].is_a?(Array) && !self.platforms[configuration].empty?
|
117
|
+
self.platforms[configuration].append(platform)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
public(:parse)
|
122
|
+
private(:platforms=)
|
123
|
+
end
|
124
|
+
|
125
|
+
class SolutionPropertiesBlock < GlobalSectionBlock
|
126
|
+
attr_accessor :entries
|
127
|
+
|
128
|
+
def parse(block_str)
|
129
|
+
is_header = false
|
130
|
+
content_reader = StringIO.new(block_str)
|
131
|
+
self.entries = {}
|
132
|
+
|
133
|
+
content_reader.each_line do |line|
|
134
|
+
unless is_header
|
135
|
+
is_header = true
|
136
|
+
next
|
137
|
+
end
|
138
|
+
|
139
|
+
assignment = Assignment.new(line)
|
140
|
+
self.entries[assignment.key] = assignment.value
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
public(:parse)
|
145
|
+
private(:entries=)
|
146
|
+
end
|
147
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require_relative "root_block"
|
2
|
+
|
3
|
+
module SlnProject
|
4
|
+
def self.open(path)
|
5
|
+
path = path.to_s
|
6
|
+
raise "Path to SLN-file can't be empty or null" unless path && !path.empty?
|
7
|
+
raise "The SLN-file at path #{path} doesn't exist" unless File.exist?(path)
|
8
|
+
|
9
|
+
content = File.read(path)
|
10
|
+
root_block = RootBlock.new
|
11
|
+
root_block.parse(content)
|
12
|
+
root_block
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require_relative "block"
|
2
|
+
|
3
|
+
module SlnProject
|
4
|
+
class ProjectBlock < BaseBlock
|
5
|
+
START_TOKENS = {
|
6
|
+
ProjectSectionToken: "ProjectSection"
|
7
|
+
}.freeze
|
8
|
+
|
9
|
+
END_TOKENS = {
|
10
|
+
ProjectSectionToken: "EndProjectSection"
|
11
|
+
}.freeze
|
12
|
+
|
13
|
+
attr_accessor :guid, :name, :path
|
14
|
+
|
15
|
+
def parse(block_str)
|
16
|
+
is_header_passed = false
|
17
|
+
inner_block = nil
|
18
|
+
inner_block_str = ""
|
19
|
+
content_reader = StringIO.new(block_str)
|
20
|
+
|
21
|
+
content_reader.each_line do |line|
|
22
|
+
trim_line = line.strip
|
23
|
+
|
24
|
+
unless is_header_passed
|
25
|
+
is_header_passed = true if parse_header(trim_line)
|
26
|
+
end
|
27
|
+
|
28
|
+
inner_block = check_start_token(trim_line, inner_block)
|
29
|
+
inner_block = check_end_token(trim_line, inner_block, inner_block_str)
|
30
|
+
|
31
|
+
inner_block_str += "#{trim_line}\n" unless inner_block.nil?
|
32
|
+
inner_block_str = "" if inner_block.nil?
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def to_s
|
37
|
+
name
|
38
|
+
end
|
39
|
+
|
40
|
+
def check_start_token(line, inner_block)
|
41
|
+
inner_block = ProjectSectionBlock.new if line.start_with?("#{START_TOKENS[:ProjectSectionToken]}(")
|
42
|
+
inner_block
|
43
|
+
end
|
44
|
+
|
45
|
+
def check_end_token(line, inner_block, inner_block_str)
|
46
|
+
return inner_block unless END_TOKENS.any? { |_, v| line == v }
|
47
|
+
|
48
|
+
inner_block.parse(inner_block_str)
|
49
|
+
nil
|
50
|
+
end
|
51
|
+
|
52
|
+
def parse_header(line)
|
53
|
+
assignment = Assignment.new(line)
|
54
|
+
parts = assignment.value.split(",")
|
55
|
+
return false if parts.empty?
|
56
|
+
|
57
|
+
self.name = parts[0].strip.delete("\"")
|
58
|
+
self.path = parts[1].strip.delete("\"")
|
59
|
+
self.guid = parts[2].strip
|
60
|
+
.delete("\"")
|
61
|
+
.delete("{")
|
62
|
+
.delete("}")
|
63
|
+
|
64
|
+
true
|
65
|
+
end
|
66
|
+
|
67
|
+
public(:parse)
|
68
|
+
public(:to_s)
|
69
|
+
private(:check_start_token)
|
70
|
+
private(:check_end_token)
|
71
|
+
private(:parse_header)
|
72
|
+
private(:guid=)
|
73
|
+
private(:name=)
|
74
|
+
private(:path=)
|
75
|
+
end
|
76
|
+
|
77
|
+
class ProjectSectionBlock < BaseBlock
|
78
|
+
def parse(block_str)
|
79
|
+
nil
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require_relative "project_block"
|
2
|
+
require_relative "global_block"
|
3
|
+
require_relative "block"
|
4
|
+
|
5
|
+
module SlnProject
|
6
|
+
class RootBlock < BaseBlock
|
7
|
+
TOKENS = {
|
8
|
+
VisualStudioVersionToken: "VisualStudioVersion",
|
9
|
+
MinimumVisualStudioVersionToken: "MinimumVisualStudioVersion"
|
10
|
+
}.freeze
|
11
|
+
|
12
|
+
START_TOKENS = {
|
13
|
+
ProjectToken: "Project",
|
14
|
+
GlobalToken: "Global"
|
15
|
+
}.freeze
|
16
|
+
|
17
|
+
END_TOKENS = {
|
18
|
+
ProjectToken: "EndProject",
|
19
|
+
GlobalToken: "EndGlobal"
|
20
|
+
}.freeze
|
21
|
+
|
22
|
+
attr_accessor :visual_studio_version, :min_visual_studio_version, :projects, :global
|
23
|
+
|
24
|
+
def parse(block_str)
|
25
|
+
inner_block = nil
|
26
|
+
inner_block_str = ""
|
27
|
+
content_reader = StringIO.new(block_str)
|
28
|
+
|
29
|
+
content_reader.each_line do |line|
|
30
|
+
trim_line = line.strip
|
31
|
+
inner_block = check_start_token(trim_line, inner_block)
|
32
|
+
inner_block = check_end_token(trim_line, inner_block, inner_block_str)
|
33
|
+
|
34
|
+
inner_block_str += "#{trim_line}\n" unless inner_block.nil?
|
35
|
+
inner_block_str = "" if inner_block.nil?
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def check_start_token(line, inner_block)
|
40
|
+
self.visual_studio_version = Assignment.new(line).value if line.start_with?(TOKENS[:VisualStudioVersionToken])
|
41
|
+
self.min_visual_studio_version = Assignment.new(line).value if line.start_with?(TOKENS[:MinimumVisualStudioVersionToken])
|
42
|
+
|
43
|
+
inner_block = ProjectBlock.new if line.start_with?("#{START_TOKENS[:ProjectToken]}(")
|
44
|
+
inner_block = GlobalBlock.new if line.start_with?(START_TOKENS[:GlobalToken])
|
45
|
+
|
46
|
+
inner_block
|
47
|
+
end
|
48
|
+
|
49
|
+
def check_end_token(line, inner_block, inner_block_str)
|
50
|
+
return inner_block unless END_TOKENS.any? { |_, v| line == v }
|
51
|
+
|
52
|
+
inner_block.parse(inner_block_str)
|
53
|
+
|
54
|
+
if line.start_with?(END_TOKENS[:ProjectToken])
|
55
|
+
self.projects = [] if self.projects.nil?
|
56
|
+
self.projects.append(inner_block)
|
57
|
+
elsif line.start_with?(END_TOKENS[:GlobalToken])
|
58
|
+
self.global = inner_block
|
59
|
+
end
|
60
|
+
|
61
|
+
nil
|
62
|
+
end
|
63
|
+
|
64
|
+
public(:parse)
|
65
|
+
private(:check_start_token)
|
66
|
+
private(:check_end_token)
|
67
|
+
private(:visual_studio_version=)
|
68
|
+
private(:min_visual_studio_version=)
|
69
|
+
private(:projects=)
|
70
|
+
private(:global=)
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require "fastlane/plugin/sapfire/version"
|
2
|
+
|
3
|
+
module Fastlane
|
4
|
+
module Sapfire
|
5
|
+
# Return all .rb files inside the "actions" and "helper" directory
|
6
|
+
def self.all_classes
|
7
|
+
Dir[File.expand_path('**/{actions,helper}/*.rb', File.dirname(__FILE__))]
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
# By default we want to import all available actions and helpers
|
13
|
+
# A plugin can contain any number of actions and plugins
|
14
|
+
Fastlane::Sapfire.all_classes.each do |current|
|
15
|
+
require current
|
16
|
+
end
|