souyuz-ventaapps 0.8.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 2c5247b94e3d061a400ff6ba5b914c467ff7af4c9e49556e33aa3410b82110bf
4
+ data.tar.gz: f1ae3ca1a02681cea17d49f62f702aa0246413cf932f8bb27e3d52f12009447f
5
+ SHA512:
6
+ metadata.gz: 869078476f954a2c7869a8fd27b9532812c436910ee5e971cce10c5b638c2a660415ae9a3c674d71f5c62e960158474922a6dca9fe018b6954958a6fba7b00dd
7
+ data.tar.gz: d7e82806600890ca639086a7e8ff1acd090dee64bce7e9b7c903f5b955e6497f7836abb1cad8ee3bfca95a9173fd312a14f59c5687131631f0574848d1315a04
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016-2017 Felix Rudat
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,30 @@
1
+ # Souyuz
2
+
3
+ [![Build Status](https://travis-ci.org/voydz/souyuz.svg?branch=master)](https://travis-ci.org/voydz/souyuz)
4
+
5
+ A fastlane component to make Xamarin builds a breeze. Souyuz is now avaialbe as an **Fastlane plugin** see [fastlane-plugin-souyuz](fastlane-plugin-souyuz) for details.
6
+
7
+ *NOTE: While souyuz should continue working with your existing configuration just fine, consider using the Fastlane plugin.*
8
+
9
+ ## Using MSBuild
10
+
11
+ Since Version 0.7.0 souyuz is using `msbuild` by default, because according to Xamarin `xbuild` is deprecated and will be removed soon.
12
+
13
+ This change should not affect you under normal circumstances. Anyway, if you experience any issues there is a new config option `compiler_bin`, where you can easily pass `xbuild` in again.
14
+
15
+ Usage example:
16
+
17
+ ```ruby
18
+ souyuz(
19
+ compiler_bin: 'xbuild' # if xbuild is in your $PATH env variable
20
+ )
21
+ ```
22
+
23
+ ## ToDos
24
+
25
+ * clean up code (!!!)
26
+ * replace path concat with `File.join()`
27
+
28
+ ## Licensing
29
+
30
+ Souyuz is licensed under the MIT License. See [LICENSE](LICENSE) for the full license text.
data/bin/souyuz ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH.push File.expand_path("../../lib", __FILE__)
3
+
4
+ require "souyuz"
5
+ require "souyuz/commands_generator"
6
+ Souyuz::CommandsGenerator.start
@@ -0,0 +1,46 @@
1
+ require "commander"
2
+ require "fastlane"
3
+
4
+ HighLine.track_eof = false
5
+
6
+ module Souyuz
7
+ class CommandsGenerator
8
+ include Commander::Methods
9
+ UI = FastlaneCore::UI
10
+
11
+ FastlaneCore::CommanderGenerator.new.generate(Souyuz::Options.available_options)
12
+
13
+ def self.start
14
+ new.run
15
+ end
16
+
17
+ def convert_options(options)
18
+ o = options.__hash__.dup
19
+ o.delete(:verbose)
20
+ o
21
+ end
22
+
23
+ def run
24
+ program :version, Souyuz::VERSION
25
+ program :description, Souyuz::DESCRIPTION
26
+ program :help, "Author", "Felix Rudat <voydz@hotmail.com>"
27
+ program :help_formatter, :compact
28
+
29
+ global_option("--verbose") { $verbose = true }
30
+
31
+ command :build do |c|
32
+ c.syntax = "souyuz"
33
+ c.description = "Just builds your app"
34
+ c.action do |_args, options|
35
+ config = FastlaneCore::Configuration.create(Souyuz::Options.available_options,
36
+ convert_options(options))
37
+ Souyuz::Manager.new.work(config)
38
+ end
39
+ end
40
+
41
+ default_command :build
42
+
43
+ run!
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,144 @@
1
+ require 'nokogiri'
2
+
3
+ module Souyuz
4
+ # This class detects all kinds of default values
5
+ class DetectValues
6
+ # This is needed as these are more complex default values
7
+ # Returns the finished config object
8
+ def self.set_additional_default_values
9
+ config = Souyuz.config
10
+
11
+ # TODO: detect_platform automatically for :platform config
12
+
13
+ # set correct implicit build platform for android
14
+ if config[:platform] == Platform::ANDROID
15
+ config[:build_platform] = 'AnyCPU'
16
+ end
17
+
18
+ # Detect the project
19
+ Souyuz.project = Msbuild::Project.new(config)
20
+ detect_solution
21
+ detect_project # we can only do that *after* we detected the solution
22
+
23
+ doc_csproj = get_parser_handle config[:project_path]
24
+
25
+ detect_output_path doc_csproj
26
+ detect_manifest doc_csproj
27
+ detect_info_plist
28
+ detect_assembly_name doc_csproj # we can only do that for android *after* we detected the android manitfest
29
+
30
+ return config
31
+ end
32
+
33
+ # Helper Methods
34
+
35
+ def self.detect_solution
36
+ return if Souyuz.config[:solution_path]
37
+
38
+ sln = find_file('*.sln', 3) # search for solution
39
+ UI.user_error! 'Not able to find solution file automatically, try to specify it via `solution_path` parameter.' unless sln
40
+
41
+ Souyuz.config[:solution_path] = abs_path sln
42
+ end
43
+
44
+ def self.detect_project
45
+ return if Souyuz.config[:project_path]
46
+
47
+ path = Souyuz.config[:solution_path]
48
+ projects = Msbuild::SolutionParser.parse(path)
49
+ .get_platform Souyuz.config[:platform]
50
+
51
+ UI.user_error! "Not able to find any project in solution, that matches the platform `#{Souyuz.config[:platform]}`." unless projects.any?
52
+
53
+ project = projects.first
54
+ csproj = fix_path_relative project.project_path # get path relative to project root
55
+ UI.user_error! 'Not able to find project file automatically, try to specify it via `project_path` parameter.' unless csproj
56
+
57
+ Souyuz.config[:project_name] = project.project_name
58
+ Souyuz.config[:project_path] = abs_path csproj
59
+ end
60
+
61
+ def self.detect_output_path(doc_csproj)
62
+ return if Souyuz.config[:output_path]
63
+
64
+ configuration = Souyuz.config[:build_configuration]
65
+ platform = Souyuz.config[:build_platform]
66
+
67
+ doc_node = doc_csproj.xpath("/*[local-name()='Project']/*[local-name()='PropertyGroup'][translate(@*[local-name() = 'Condition'],'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz') = \" '$(configuration)|$(platform)' == '#{configuration.downcase}|#{platform.downcase}' \"]/*[local-name()='OutputPath']/text()")
68
+ output_path = doc_node.text
69
+ UI.user_error! 'Not able to find output path automatically, try to specify it via `output_path` parameter.' unless output_path
70
+
71
+ Souyuz.config[:output_path] = abs_project_path output_path
72
+ end
73
+
74
+ def self.detect_manifest(doc_csproj)
75
+ return if Souyuz.config[:manifest_path] or Souyuz.config[:platform] != Platform::ANDROID
76
+
77
+ doc_node = doc_csproj.css('PropertyGroup > AndroidManifest')
78
+ Souyuz.config[:manifest_path] = abs_project_path doc_node.text
79
+ end
80
+
81
+ def self.detect_info_plist
82
+ return if Souyuz.config[:plist_path] or Souyuz.config[:platform] != Platform::IOS
83
+
84
+ plist_path = find_file('Info.plist', 1) # search for plist
85
+ UI.user_error! 'Not able to find Info.plist automatically, try to specify it via `plist_path` parameter.' unless plist_path
86
+
87
+ Souyuz.config[:plist_path] = abs_project_path plist_path
88
+ end
89
+
90
+ def self.detect_assembly_name(doc_csproj)
91
+ return if Souyuz.config[:assembly_name]
92
+
93
+ if [Platform::IOS, Platform::OSX].include? Souyuz.config[:platform]
94
+ Souyuz.config[:assembly_name] = doc_csproj.css('PropertyGroup > AssemblyName').text
95
+ elsif Souyuz.config[:platform] == Platform::ANDROID
96
+ doc = get_parser_handle Souyuz.config[:manifest_path] # explicitly for this call, no cache needed
97
+ Souyuz.config[:assembly_name] = doc.xpath('string(//manifest/@package)')
98
+ end
99
+ end
100
+
101
+ private_class_method
102
+
103
+ def self.find_file(query, depth)
104
+ itr = 0
105
+ files = []
106
+
107
+ loop do
108
+ files = Dir.glob(query)
109
+ query = "../#{query}"
110
+ itr += 1
111
+ break if files.any? or itr > depth
112
+ end
113
+
114
+ return files.first # pick first file
115
+ end
116
+
117
+ def self.get_parser_handle(filename)
118
+ f = File.open(filename)
119
+ doc = Nokogiri::XML(f)
120
+ f.close
121
+
122
+ return doc
123
+ end
124
+
125
+ def self.fix_path_relative(path)
126
+ root = File.dirname Souyuz.config[:solution_path] # failsafe to __FILE__ and __DIR__
127
+ path = "#{root}/#{path}"
128
+ path
129
+ end
130
+
131
+ def self.abs_project_path(path)
132
+ path = path.gsub('\\', '/') # dir separator fix
133
+ platform_path = Souyuz.config[:project_path]
134
+ path = "#{File.dirname platform_path}/#{path}"
135
+ path
136
+ end
137
+
138
+ def self.abs_path(path)
139
+ path = path.gsub('\\', '/') # dir separator fix
140
+ path = File.expand_path(path) # absolute dir
141
+ path
142
+ end
143
+ end
144
+ end
@@ -0,0 +1,55 @@
1
+ module Souyuz
2
+ # Responsible for building the zipalign command
3
+ class AndroidZipalignCommandGenerator
4
+ class << self
5
+ def generate
6
+ parts = prefix
7
+ parts << zipalign_apk
8
+ parts += options
9
+ parts << Souyuz.cache[:signed_apk_path]
10
+ parts << Souyuz.cache[:build_apk_path]
11
+ parts += pipe
12
+
13
+ parts
14
+ end
15
+
16
+ def detect_build_tools
17
+ UI.user_error! "Please ensure that the Android SDK is installed and the ANDROID_HOME variable is set correctly" unless ENV['ANDROID_HOME']
18
+
19
+ # determine latest buildtool version
20
+ buildtools = File.join(ENV['ANDROID_HOME'], 'build-tools')
21
+ version = Dir.entries(buildtools).sort.last
22
+
23
+ UI.success "Using Buildtools Version: #{version}..."
24
+
25
+ [buildtools, version]
26
+ end
27
+
28
+ def zipalign_apk
29
+ buildtools, version = detect_build_tools
30
+ zipalign = ENV['ANDROID_HOME'] ? File.join(buildtools, version, 'zipalign') : 'zipalign'
31
+
32
+ zipalign
33
+ end
34
+
35
+ def options
36
+ options = []
37
+ options << "-v" if $verbose
38
+ options << "-f"
39
+ options << "4"
40
+
41
+ options
42
+ end
43
+
44
+ def prefix
45
+ [""]
46
+ end
47
+
48
+ def pipe
49
+ pipe = []
50
+
51
+ pipe
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,69 @@
1
+ module Souyuz
2
+ # Responsible for building the fully working build command
3
+ class BuildCommandGenerator
4
+ class << self
5
+ def generate
6
+ parts = prefix
7
+ parts << compiler_bin
8
+ parts += options
9
+ parts += targets
10
+ parts += project
11
+ parts += pipe
12
+
13
+ parts
14
+ end
15
+
16
+ def prefix
17
+ [""]
18
+ end
19
+
20
+ def compiler_bin
21
+ Souyuz.config[:compiler_bin]
22
+ end
23
+
24
+ def options
25
+ config = Souyuz.config
26
+
27
+ options = []
28
+ options << "/p:Configuration=#{config[:build_configuration]}" if config[:build_configuration]
29
+ options << config[:extra_build_options] if config[:extra_build_options]
30
+ options << "/p:Platform=#{config[:build_platform]}" if Souyuz.project.ios? and config[:build_platform]
31
+ options << "/p:BuildIpa=true" if Souyuz.project.ios?
32
+ options << "/p:AndroidPackageFormat=aab" if config[:is_aab]?
33
+ if config[:solution_path]
34
+ solution_dir = File.dirname(config[:solution_path])
35
+ options << "/p:SolutionDir=#{solution_dir}/"
36
+ end
37
+
38
+ options
39
+ end
40
+
41
+ def build_targets
42
+ Souyuz.config[:build_target].map! { |t| "/t:#{t}" }
43
+ end
44
+
45
+ def targets
46
+ targets = []
47
+ targets += build_targets
48
+ targets << "/t:SignAndroidPackage" if Souyuz.project.android?
49
+
50
+ targets
51
+ end
52
+
53
+ def project
54
+ path = []
55
+
56
+ path << Souyuz.config[:project_path] if Souyuz.project.android?
57
+ path << Souyuz.config[:solution_path] if Souyuz.project.ios? or Souyuz.project.osx?
58
+
59
+ path
60
+ end
61
+
62
+ def pipe
63
+ pipe = []
64
+
65
+ pipe
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,51 @@
1
+ module Souyuz
2
+ # Responsible for building the jarsigner command
3
+ class JavaSignCommandGenerator
4
+ class << self
5
+ def generate
6
+ build_apk_path = Souyuz.cache[:build_apk_path]
7
+ Souyuz.cache[:signed_apk_path] = "#{build_apk_path}-unaligned"
8
+
9
+ parts = prefix
10
+ parts << detect_jarsigner_executable
11
+ parts += options
12
+ parts << build_apk_path
13
+ parts << Souyuz.config[:keystore_alias]
14
+ parts += pipe
15
+
16
+ parts
17
+ end
18
+
19
+ def prefix
20
+ [""]
21
+ end
22
+
23
+ def detect_jarsigner_executable
24
+ jarsigner = ENV['JAVA_HOME'] ? File.join(ENV['JAVA_HOME'], 'bin', 'jarsigner') : 'jarsigner'
25
+
26
+ jarsigner
27
+ end
28
+
29
+ def options
30
+ config = Souyuz.config
31
+
32
+ options = []
33
+ options << "-verbose" if $verbose
34
+ options << "-sigalg MD5withRSA"
35
+ options << "-digestalg SHA1"
36
+ options << "-storepass \"#{config[:keystore_password]}\""
37
+ options << "-keystore \"#{config[:keystore_path]}\""
38
+ options << "-tsa #{config[:keystore_tsa]}"
39
+ options << "-signedjar \"#{Souyuz.cache[:signed_apk_path]}\""
40
+
41
+ options
42
+ end
43
+
44
+ def pipe
45
+ pipe = []
46
+
47
+ pipe
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,44 @@
1
+ module Souyuz
2
+ # Responsible for building the zip dsym command
3
+ class ZipDsymCommandGenerator
4
+ class << self
5
+ def generate
6
+ parts = prefix
7
+ parts << detect_zip_executable
8
+ parts += options
9
+ parts += pipe
10
+
11
+ parts
12
+ end
13
+
14
+ def prefix
15
+ [""]
16
+ end
17
+
18
+ def detect_zip_executable
19
+ # dunno if anyone wants a zip which is not available thorgh PATH
20
+ # but if this case exists, we provide the opportunity to do so
21
+ zip = ENV['SOUYUZ_ZIP_PATH'] || 'zip'
22
+
23
+ zip
24
+ end
25
+
26
+ def options
27
+ build_dsym_path = Souyuz.cache[:build_dsym_path]
28
+
29
+ options = []
30
+ options << "-r"
31
+ options << "#{build_dsym_path}.zip"
32
+ options << build_dsym_path
33
+
34
+ options
35
+ end
36
+
37
+ def pipe
38
+ pipe = []
39
+
40
+ pipe
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,15 @@
1
+ require "fastlane"
2
+
3
+ module Souyuz
4
+ class Manager
5
+ def work(options)
6
+ Souyuz.config = options
7
+
8
+ FastlaneCore::PrintTable.print_values(config: Souyuz.config,
9
+ hide_keys: [],
10
+ title: "Summary for souyuz #{Souyuz::VERSION}")
11
+
12
+ return Runner.new.run
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,43 @@
1
+ module Souyuz
2
+ module Msbuild
3
+ class Project
4
+ attr_accessor :options
5
+
6
+ def initialize(options)
7
+ @options = options
8
+ end
9
+
10
+ def project_name
11
+ @options[:project_name]
12
+ end
13
+
14
+ def project_path
15
+ @options[:project_path]
16
+ end
17
+
18
+ def ios?
19
+ is_platform? Souyuz::Platform::IOS
20
+ end
21
+
22
+ def osx?
23
+ is_platform? Souyuz::Platform::OSX
24
+ end
25
+
26
+ def android?
27
+ is_platform? Souyuz::Platform::ANDROID
28
+ end
29
+
30
+ def is_platform?(platform)
31
+ return case platform
32
+ when Souyuz::Platform::IOS
33
+ then self.project_name.downcase.include? 'ios'
34
+ when Souyuz::Platform::OSX
35
+ then self.project_name.downcase.include? 'mac'
36
+ when Souyuz::Platform::ANDROID
37
+ then self.project_name.downcase.include? 'droid'
38
+ else false
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,19 @@
1
+ module Souyuz
2
+ module Msbuild
3
+ class Solution
4
+ attr_accessor :projects
5
+
6
+ def initialize
7
+ @projects = []
8
+ end
9
+
10
+ def add_project(project)
11
+ @projects << project
12
+ end
13
+
14
+ def get_platform(platform)
15
+ @projects.select { |p| p.is_platform? platform }
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,34 @@
1
+ module Souyuz
2
+ module Msbuild
3
+ class SolutionParser
4
+ def self.parse(filename)
5
+ solution = Solution.new
6
+
7
+ File.open(filename) do |f|
8
+ f.read.split("\n").each do |line|
9
+ if line.start_with? "Project"
10
+ options = parse_line line
11
+ solution.add_project Project.new(options) # maybe we should not use the project class for this
12
+ end
13
+ end
14
+ end
15
+
16
+ return solution
17
+ end
18
+
19
+ def self.parse_line(line)
20
+ name = get_project_name line
21
+ project_file = get_project_file line
22
+ return { project_name: name, project_path: project_file }
23
+ end
24
+
25
+ def self.get_project_name(project_line)
26
+ project_line.split("\"")[3]
27
+ end
28
+
29
+ def self.get_project_file(project_line)
30
+ project_line.split("\"")[5].gsub('\\', '/')
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,91 @@
1
+ require "fastlane"
2
+
3
+ module Souyuz
4
+ class Options
5
+ def self.available_options
6
+ [
7
+ FastlaneCore::ConfigItem.new(key: :silent,
8
+ env_name: "SOUYUZ_SILENT",
9
+ description: "Hide all information that's not necessary while building",
10
+ default_value: false,
11
+ is_string: false),
12
+ FastlaneCore::ConfigItem.new(key: :compiler_bin,
13
+ env_name: "SOUYUZ_COMPILER_BIN",
14
+ description: "Path to the compiler binary",
15
+ default_value: 'msbuild'),
16
+ FastlaneCore::ConfigItem.new(key: :build_configuration,
17
+ env_name: "SOUYUZ_BUILD_CONFIGURATION",
18
+ description: "Build configuration value",
19
+ default_value: 'Release'),
20
+ FastlaneCore::ConfigItem.new(key: :build_platform,
21
+ env_name: "SOUYUZ_BUILD_PLATFORM",
22
+ description: "Build platform value",
23
+ default_value: 'iPhone'),
24
+ FastlaneCore::ConfigItem.new(key: :build_target,
25
+ env_name: "SOUYUZ_BUILD_TARGET",
26
+ description: "Build targets to build",
27
+ default_value: ['Build'],
28
+ type: Array),
29
+ FastlaneCore::ConfigItem.new(key: :extra_build_options,
30
+ env_name: "SOUYUZ_EXTRA_BUILD_OPTIONS",
31
+ description: "Extra options to pass to `msbuild`. Example: `/p:MYOPTION=true`",
32
+ optional: true),
33
+ FastlaneCore::ConfigItem.new(key: :output_path,
34
+ env_name: "SOUYUZ_BUILD_OUTPUT_PATH",
35
+ description: "Build output path",
36
+ optional: true),
37
+ FastlaneCore::ConfigItem.new(key: :project_name,
38
+ env_name: "SOUYUZ_BUILD_PROJECT_NAME",
39
+ description: "Build project name",
40
+ optional: true),
41
+ FastlaneCore::ConfigItem.new(key: :assembly_name,
42
+ env_name: "SOUYUZ_BUILD_ASSEMBLY_NAME",
43
+ description: "Build assembly name",
44
+ optional: true),
45
+ FastlaneCore::ConfigItem.new(key: :platform,
46
+ env_name: "SOUYUZ_PLATFORM",
47
+ description: "Targeted device platform (i.e. android, ios, osx)",
48
+ optional: false),
49
+ FastlaneCore::ConfigItem.new(key: :solution_path,
50
+ env_name: "SOUYUZ_SOLUTION_PATH",
51
+ description: "Path to the build solution (sln) file",
52
+ optional: true),
53
+ FastlaneCore::ConfigItem.new(key: :project_path,
54
+ env_name: "SOUYUZ_PROJECT_PATH",
55
+ description: "Path to the build project (csproj) file",
56
+ optional: true),
57
+ FastlaneCore::ConfigItem.new(key: :manifest_path,
58
+ env_name: "SOUYUZ_ANDROID_MANIFEST_PATH",
59
+ description: "Path to the android manifest (xml) file",
60
+ optional: true),
61
+ FastlaneCore::ConfigItem.new(key: :plist_path,
62
+ env_name: "SOUYUZ_IOS_PLIST_PATH",
63
+ description: "Path to the iOS plist file",
64
+ optional: true),
65
+ FastlaneCore::ConfigItem.new(key: :keystore_path,
66
+ env_name: "SOUYUZ_ANDROID_KEYSTORE_PATH",
67
+ description: "Path to the keystore",
68
+ optional: true),
69
+ FastlaneCore::ConfigItem.new(key: :keystore_alias,
70
+ env_name: "SOUYUZ_ANDROID_KEYSTORE_ALIAS",
71
+ description: "Alias of the keystore",
72
+ optional: true),
73
+ FastlaneCore::ConfigItem.new(key: :keystore_password,
74
+ env_name: "SOUYUZ_ANDROID_KEYSTORE_PASSWORD",
75
+ description: "Password of the keystore",
76
+ optional: true),
77
+ FastlaneCore::ConfigItem.new(key: :keystore_tsa,
78
+ default_value: 'http://timestamp.digicert.com',
79
+ env_name: "SOUYUZ_ANDROID_KEYSTORE_TSA",
80
+ description: "TSA for jarsigner",
81
+ optional: true),
82
+ FastlaneCore::ConfigItem.new(key: :is_aab,
83
+ env_name: "SOUYUZ_AAB",
84
+ description: "Flag to indicate that generating AAB",
85
+ default_value: false,
86
+ is_string: false,
87
+ optional: true)
88
+ ]
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,15 @@
1
+ module Souyuz
2
+ module Platform
3
+ IOS = 'ios'
4
+ OSX = 'osx'
5
+ ANDROID = 'android'
6
+
7
+ def self.from_lane_context(context)
8
+ current_platform = context[:PLATFORM_NAME].to_s
9
+
10
+ # map in the future, if necessary
11
+
12
+ current_platform
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,125 @@
1
+ require 'fastlane'
2
+
3
+ module Souyuz
4
+ class Runner
5
+ def run
6
+ config = Souyuz.config
7
+
8
+ build_app
9
+
10
+ if Souyuz.project.ios? or Souyuz.project.osx?
11
+ compress_and_move_dsym
12
+ path = ipa_file
13
+
14
+ path
15
+ elsif Souyuz.project.android?
16
+ if config[:is_aab]
17
+ path = aab_file
18
+ else
19
+ path = apk_file
20
+ if config[:keystore_path] && config[:keystore_alias]
21
+ UI.success "Jar it, sign it, zip it..."
22
+
23
+ jarsign_and_zipalign
24
+ end
25
+
26
+ path
27
+ end
28
+ end
29
+
30
+ def build_app
31
+ command = BuildCommandGenerator.generate
32
+ FastlaneCore::CommandExecutor.execute(command: command,
33
+ print_all: true,
34
+ print_command: !Souyuz.config[:silent])
35
+ end
36
+
37
+ #
38
+ # android build stuff to follow..
39
+ #
40
+
41
+ def apk_file
42
+ build_path = Souyuz.project.options[:output_path]
43
+ assembly_name = Souyuz.project.options[:assembly_name]
44
+
45
+ Souyuz.cache[:build_apk_path] = "#{build_path}/#{assembly_name}.apk"
46
+
47
+ "#{build_path}/#{assembly_name}.apk"
48
+ end
49
+
50
+ def aab_file
51
+ build_path = Souyuz.project.options[:output_path]
52
+ assembly_name = Souyuz.project.options[:assembly_name]
53
+
54
+ Souyuz.cache[:build_apk_path] = "#{build_path}/#{assembly_name}.aab"
55
+
56
+ "#{build_path}/#{assembly_name}.aab"
57
+ end
58
+
59
+ def jarsign_and_zipalign
60
+ command = JavaSignCommandGenerator.generate
61
+ FastlaneCore::CommandExecutor.execute(command: command,
62
+ print_all: false,
63
+ print_command: !Souyuz.config[:silent])
64
+
65
+ UI.success "Successfully signed apk #{Souyuz.cache[:build_apk_path]}"
66
+
67
+ command = AndroidZipalignCommandGenerator.generate
68
+ FastlaneCore::CommandExecutor.execute(command: command,
69
+ print_all: true,
70
+ print_command: !Souyuz.config[:silent])
71
+ end
72
+
73
+ #
74
+ # ios build stuff to follow..
75
+ #
76
+
77
+ def package_path
78
+ build_path = Souyuz.project.options[:output_path]
79
+ assembly_name = Souyuz.project.options[:assembly_name]
80
+
81
+ # in the upcomming switch we determin the output path of iOS ipa files
82
+ # those change in the Xamarin.iOS Cycle 9 release
83
+ # see https://developer.xamarin.com/releases/ios/xamarin.ios_10/xamarin.ios_10.4/
84
+ if File.exist? "#{build_path}/#{assembly_name}.ipa"
85
+ # after Xamarin.iOS Cycle 9
86
+ package_path = build_path
87
+ else
88
+ # before Xamarin.iOS Cycle 9
89
+ package_path = Dir.glob("#{build_path}/#{assembly_name} *").sort.last
90
+ end
91
+
92
+ package_path
93
+ end
94
+
95
+ def ipa_file
96
+ assembly_name = Souyuz.project.options[:assembly_name]
97
+
98
+ "#{package_path}/#{assembly_name}.ipa"
99
+ end
100
+
101
+ def compress_and_move_dsym
102
+ build_path = Souyuz.project.options[:output_path]
103
+ assembly_name = Souyuz.project.options[:assembly_name]
104
+
105
+ build_dsym_path = "#{build_path}/#{assembly_name}.app.dSYM"
106
+ unless File.exist? build_dsym_path
107
+ UI.success "Did not found dSYM at #{build_dsym_path}, skipping..."
108
+ return
109
+ end
110
+
111
+ Souyuz.cache[:build_dsym_path] = build_dsym_path
112
+
113
+ command = ZipDsymCommandGenerator.generate
114
+ FastlaneCore::CommandExecutor.execute(command: command,
115
+ print_all: true,
116
+ print_command: !Souyuz.config[:silent])
117
+
118
+ # move dsym aside ipa
119
+ dsym_path = "#{dsym_path}.zip"
120
+ if File.exist? dsym_path
121
+ FileUtils.mv(dsym_path, "#{package_path}/#{File.basename dsym_path}")
122
+ end
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,5 @@
1
+
2
+ module Souyuz
3
+ VERSION = "0.8.1"
4
+ DESCRIPTION = "A fastlane component to make Xamarin builds a breeze"
5
+ end
data/lib/souyuz.rb ADDED
@@ -0,0 +1,34 @@
1
+ require 'souyuz/version'
2
+ require 'souyuz/platform'
3
+ require 'souyuz/manager'
4
+ require 'souyuz/generators/build_command_generator'
5
+ require 'souyuz/generators/android_zipalign_command_generator'
6
+ require 'souyuz/generators/java_sign_command_generator'
7
+ require 'souyuz/generators/zip_dsym_command_generator'
8
+ require 'souyuz/runner'
9
+ require 'souyuz/options'
10
+ require 'souyuz/detect_values'
11
+ require 'souyuz/msbuild/project'
12
+ require 'souyuz/msbuild/solution'
13
+ require 'souyuz/msbuild/solution_parser'
14
+
15
+ require 'fastlane'
16
+
17
+ module Souyuz
18
+ class << self
19
+ attr_accessor :config
20
+
21
+ attr_accessor :project
22
+
23
+ attr_accessor :cache
24
+
25
+ def config=(value)
26
+ @config = value
27
+ DetectValues.set_additional_default_values
28
+ @cache = {}
29
+ end
30
+ end
31
+
32
+ Helper = FastlaneCore::Helper # you gotta love Ruby: Helper.* should use the Helper class contained in FastlaneCore
33
+ UI = FastlaneCore::UI
34
+ end
metadata ADDED
@@ -0,0 +1,174 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: souyuz-ventaapps
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.8.1
5
+ platform: ruby
6
+ authors:
7
+ - Felix Rudat
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-08-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: fastlane
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 2.29.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 2.29.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: highline
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.7'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.7'
41
+ - !ruby/object:Gem::Dependency
42
+ name: nokogiri
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.7'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.7'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rubocop
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '='
88
+ - !ruby/object:Gem::Version
89
+ version: 0.49.1
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '='
95
+ - !ruby/object:Gem::Version
96
+ version: 0.49.1
97
+ - !ruby/object:Gem::Dependency
98
+ name: bundler
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rake
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ description: A fastlane component to make Xamarin builds a breeze
126
+ email: voydz@hotmail.com
127
+ executables:
128
+ - souyuz
129
+ extensions: []
130
+ extra_rdoc_files: []
131
+ files:
132
+ - LICENSE
133
+ - README.md
134
+ - bin/souyuz
135
+ - lib/souyuz.rb
136
+ - lib/souyuz/commands_generator.rb
137
+ - lib/souyuz/detect_values.rb
138
+ - lib/souyuz/generators/android_zipalign_command_generator.rb
139
+ - lib/souyuz/generators/build_command_generator.rb
140
+ - lib/souyuz/generators/java_sign_command_generator.rb
141
+ - lib/souyuz/generators/zip_dsym_command_generator.rb
142
+ - lib/souyuz/manager.rb
143
+ - lib/souyuz/msbuild/project.rb
144
+ - lib/souyuz/msbuild/solution.rb
145
+ - lib/souyuz/msbuild/solution_parser.rb
146
+ - lib/souyuz/options.rb
147
+ - lib/souyuz/platform.rb
148
+ - lib/souyuz/runner.rb
149
+ - lib/souyuz/version.rb
150
+ homepage: https://github.com/VentaApps/souyuz
151
+ licenses:
152
+ - MIT
153
+ metadata: {}
154
+ post_install_message:
155
+ rdoc_options: []
156
+ require_paths:
157
+ - lib
158
+ required_ruby_version: !ruby/object:Gem::Requirement
159
+ requirements:
160
+ - - ">="
161
+ - !ruby/object:Gem::Version
162
+ version: 2.2.0
163
+ required_rubygems_version: !ruby/object:Gem::Requirement
164
+ requirements:
165
+ - - ">="
166
+ - !ruby/object:Gem::Version
167
+ version: '0'
168
+ requirements: []
169
+ rubyforge_project:
170
+ rubygems_version: 2.7.8
171
+ signing_key:
172
+ specification_version: 4
173
+ summary: A fastlane component to make Xamarin builds a breeze
174
+ test_files: []