souyuz 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +12 -0
- data/bin/souyuz +6 -0
- data/lib/souyuz/commands_generator.rb +47 -0
- data/lib/souyuz/detect_values.rb +126 -0
- data/lib/souyuz/generators/android_zipalign_command_generator.rb +44 -0
- data/lib/souyuz/generators/build_command_generator.rb +58 -0
- data/lib/souyuz/generators/java_sign_command_generator.rb +54 -0
- data/lib/souyuz/manager.rb +16 -0
- data/lib/souyuz/msbuild/project.rb +44 -0
- data/lib/souyuz/msbuild/solution.rb +20 -0
- data/lib/souyuz/msbuild/solution_parser.rb +35 -0
- data/lib/souyuz/options.rb +58 -0
- data/lib/souyuz/platform.rb +8 -0
- data/lib/souyuz/runner.rb +87 -0
- data/lib/souyuz/version.rb +5 -0
- data/lib/souyuz.rb +32 -0
- metadata +151 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 368484d22e8d6d287966ced20c877224071eb3f2
|
4
|
+
data.tar.gz: c3c8638ab220b8c3c46ed778c0f87b7552f5bb5c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0765c3c1902728fce692fb5ccf8512c09d68b4b7cc1609872598f1e15ca15c98501d03d81a24e10dad3e4a604a2b41da3a3e9af9295beb8ac1bcefae04430555
|
7
|
+
data.tar.gz: 26ccd09dc6b46e041f5e83679c880515c29e748b1c25e2a475c99f550e12e359102c3fbb213623f76759297dff77dd59b6e8cdca45d9f0353d6e05b3ba74d355
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2016 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,12 @@
|
|
1
|
+
# Souyuz
|
2
|
+
|
3
|
+
A fastlane component to make Xamarin builds a breeze.
|
4
|
+
|
5
|
+
## ToDos
|
6
|
+
|
7
|
+
* replace path concat with `File.join()`
|
8
|
+
* automatically determine `:platform`
|
9
|
+
|
10
|
+
## Licensing
|
11
|
+
|
12
|
+
Souyuz is licensed under the MIT License. See [LICENSE](LICENSE) for the full license text.
|
data/bin/souyuz
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
require "commander"
|
3
|
+
require "fastlane_core"
|
4
|
+
|
5
|
+
HighLine.track_eof = false
|
6
|
+
|
7
|
+
module Souyuz
|
8
|
+
class CommandsGenerator
|
9
|
+
include Commander::Methods
|
10
|
+
UI = FastlaneCore::UI
|
11
|
+
|
12
|
+
FastlaneCore::CommanderGenerator.new.generate(Souyuz::Options.available_options)
|
13
|
+
|
14
|
+
def self.start
|
15
|
+
new.run
|
16
|
+
end
|
17
|
+
|
18
|
+
def convert_options(options)
|
19
|
+
o = options.__hash__.dup
|
20
|
+
o.delete(:verbose)
|
21
|
+
o
|
22
|
+
end
|
23
|
+
|
24
|
+
def run
|
25
|
+
program :version, Souyuz::VERSION
|
26
|
+
program :description, Souyuz::DESCRIPTION
|
27
|
+
program :help, "Author", "Felix Rudat <voydz@hotmail.com>"
|
28
|
+
program :help_formatter, :compact
|
29
|
+
|
30
|
+
global_option("--verbose") { $verbose = true }
|
31
|
+
|
32
|
+
command :build do |c|
|
33
|
+
c.syntax = "souyuz"
|
34
|
+
c.description = "Just builds your app"
|
35
|
+
c.action do |_args, options|
|
36
|
+
config = FastlaneCore::Configuration.create(Souyuz::Options.available_options,
|
37
|
+
convert_options(options))
|
38
|
+
Souyuz::Manager.new.work(config)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
default_command :build
|
43
|
+
|
44
|
+
run!
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
require 'nokogiri'
|
3
|
+
|
4
|
+
module Souyuz
|
5
|
+
# This class detects all kinds of default values
|
6
|
+
class DetectValues
|
7
|
+
# This is needed as these are more complex default values
|
8
|
+
# Returns the finished config object
|
9
|
+
def self.set_additional_default_values
|
10
|
+
config = Souyuz.config
|
11
|
+
|
12
|
+
# TODO detect_platform automatically for :platform config
|
13
|
+
|
14
|
+
# set correct implicit build platform for android
|
15
|
+
if config[:platform] == Platform::ANDROID
|
16
|
+
config[:build_platform] = 'AnyCPU'
|
17
|
+
end
|
18
|
+
|
19
|
+
# Detect the project
|
20
|
+
Souyuz.project = Msbuild::Project.new(config)
|
21
|
+
detect_solution
|
22
|
+
detect_project # we can only do that *after* we detected the solution
|
23
|
+
|
24
|
+
doc_csproj = get_parser_handle config[:project_path]
|
25
|
+
|
26
|
+
detect_output_path doc_csproj
|
27
|
+
detect_manifest doc_csproj
|
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
|
+
itr = 0
|
38
|
+
query = '*.sln'
|
39
|
+
|
40
|
+
begin
|
41
|
+
files = Dir.glob(query)
|
42
|
+
query = "../#{query}"
|
43
|
+
itr += 1
|
44
|
+
end until files.any? or itr > 3
|
45
|
+
|
46
|
+
sln = files.first # pick first file as solution
|
47
|
+
UI.user_error! 'Not able to find solution file automatically, try to specify it via `solution_path` parameter.' unless sln
|
48
|
+
|
49
|
+
Souyuz.config[:solution_path] = abs_path sln
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.detect_project
|
53
|
+
return if Souyuz.config[:project_path]
|
54
|
+
|
55
|
+
path = Souyuz.config[:solution_path]
|
56
|
+
projects = Msbuild::SolutionParser.parse(path)
|
57
|
+
.get_platform Souyuz.config[:platform]
|
58
|
+
|
59
|
+
UI.user_error! "Not able to find any project in solution, that matches the platform `#{Souyuz.config[:platform]}`." unless projects.any?
|
60
|
+
|
61
|
+
project = projects.first
|
62
|
+
csproj = fix_path_relative project.project_path # get path relative to project root
|
63
|
+
UI.user_error! 'Not able to find project file automatically, try to specify it via `project_path` parameter.' unless csproj
|
64
|
+
|
65
|
+
Souyuz.config[:project_name] = project.project_name
|
66
|
+
Souyuz.config[:project_path] = abs_path csproj
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.detect_output_path(doc_csproj)
|
70
|
+
return if Souyuz.config[:output_path]
|
71
|
+
|
72
|
+
configuration = Souyuz.config[:build_configuration]
|
73
|
+
platform = Souyuz.config[:build_platform]
|
74
|
+
|
75
|
+
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()")
|
76
|
+
Souyuz.config[:output_path] = abs_project_path doc_node.text
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.detect_manifest(doc_csproj)
|
80
|
+
return if Souyuz.config[:manifest_path] or Souyuz.config[:platform] != Platform::ANDROID
|
81
|
+
|
82
|
+
doc_node = doc_csproj.css('PropertyGroup > AndroidManifest')
|
83
|
+
Souyuz.config[:manifest_path] = abs_project_path doc_node.text
|
84
|
+
end
|
85
|
+
|
86
|
+
def self.detect_assembly_name(doc_csproj)
|
87
|
+
return if Souyuz.config[:assembly_name]
|
88
|
+
|
89
|
+
if [ Platform::IOS, Platform::MAC ].include? Souyuz.config[:platform]
|
90
|
+
Souyuz.config[:assembly_name] = doc_csproj.css('PropertyGroup > AssemblyName').text
|
91
|
+
elsif Souyuz.config[:platform] == Platform::ANDROID
|
92
|
+
doc = get_parser_handle Souyuz.config[:manifest_path] # explicitly for this call, no cache needed
|
93
|
+
Souyuz.config[:assembly_name] = doc.xpath('string(//manifest/@package)')
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
private
|
98
|
+
|
99
|
+
def self.get_parser_handle(filename)
|
100
|
+
f = File::open(filename)
|
101
|
+
doc = Nokogiri::XML(f)
|
102
|
+
f.close
|
103
|
+
|
104
|
+
return doc
|
105
|
+
end
|
106
|
+
|
107
|
+
def self.fix_path_relative(path)
|
108
|
+
root = File.dirname Souyuz.config[:solution_path] # failsafe to __FILE__ and __DIR__
|
109
|
+
path = "#{root}/#{path}"
|
110
|
+
path
|
111
|
+
end
|
112
|
+
|
113
|
+
def self.abs_project_path(path)
|
114
|
+
path = path.gsub('\\', '/') # dir separator fix
|
115
|
+
platform_path = Souyuz.config[:project_path]
|
116
|
+
path = "#{File.dirname platform_path}/#{path}"
|
117
|
+
path
|
118
|
+
end
|
119
|
+
|
120
|
+
def self.abs_path(path)
|
121
|
+
path = path.gsub('\\', '/') # dir separator fix
|
122
|
+
path = File.expand_path(path) # absolute dir
|
123
|
+
path
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module Souyuz
|
3
|
+
# Responsible for building the zipalign command
|
4
|
+
# TODO implement
|
5
|
+
class AndroidZipalignCommandGenerator
|
6
|
+
class << self
|
7
|
+
def generate
|
8
|
+
|
9
|
+
parts = prefix
|
10
|
+
parts += pipe
|
11
|
+
|
12
|
+
parts
|
13
|
+
end
|
14
|
+
|
15
|
+
def detect_build_tools
|
16
|
+
# determine latest buildtool version
|
17
|
+
buildtools = File.join(ENV['ANDROID_HOME'], 'build-tools')
|
18
|
+
version = Dir.entries(buildtools).sort.last
|
19
|
+
|
20
|
+
UI.success "Using Buildtools Version: #{version}..."
|
21
|
+
|
22
|
+
[buildtools, version]
|
23
|
+
end
|
24
|
+
|
25
|
+
def zipalign_apk
|
26
|
+
buildtools, version = detect_build_tools
|
27
|
+
zipalign = ENV['ANDROID_HOME'] ? File.join(buildtools, version, 'zipalign') : 'zipalign'
|
28
|
+
|
29
|
+
sh "\"#{zipalign}\" -f -v 4 #{signed_apk} #{aligned_apk}"
|
30
|
+
Helper.backticks(command, print: !Souyuz.config[:silent])
|
31
|
+
end
|
32
|
+
|
33
|
+
def prefix
|
34
|
+
["set -o pipefail &&"]
|
35
|
+
end
|
36
|
+
|
37
|
+
def pipe
|
38
|
+
pipe = []
|
39
|
+
|
40
|
+
pipe
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module Souyuz
|
3
|
+
# Responsible for building the fully working xbuild command
|
4
|
+
class BuildCommandGenerator
|
5
|
+
class << self
|
6
|
+
def generate
|
7
|
+
parts = prefix
|
8
|
+
parts << "xbuild"
|
9
|
+
parts += options
|
10
|
+
parts += targets
|
11
|
+
parts << project
|
12
|
+
parts += pipe
|
13
|
+
|
14
|
+
parts
|
15
|
+
end
|
16
|
+
|
17
|
+
def prefix
|
18
|
+
["set -o pipefail &&"]
|
19
|
+
end
|
20
|
+
|
21
|
+
def options
|
22
|
+
config = Souyuz.config
|
23
|
+
|
24
|
+
options = []
|
25
|
+
options << "/p:Configuration=#{config[:build_configuration]}" if config[:build_configuration]
|
26
|
+
options << "/p:Platform=#{config[:build_platform]}" if Souyuz.project.ios? and config[:build_platform]
|
27
|
+
options << "/p:BuildIpa=true" if Souyuz.project.ios?
|
28
|
+
|
29
|
+
options
|
30
|
+
end
|
31
|
+
|
32
|
+
def build_targets
|
33
|
+
Souyuz.config[:build_target].map! { |t| "/t:#{t}" }
|
34
|
+
end
|
35
|
+
|
36
|
+
def targets
|
37
|
+
targets = []
|
38
|
+
targets += build_targets
|
39
|
+
targets << "/t:SignAndroidPackage" if Souyuz.project.android?
|
40
|
+
|
41
|
+
targets
|
42
|
+
end
|
43
|
+
|
44
|
+
def project
|
45
|
+
config = Souyuz.config
|
46
|
+
|
47
|
+
Souyuz.config[:project_path] if Souyuz.project.android?
|
48
|
+
Souyuz.config[:solution_path] if Souyuz.project.ios? or Souyuz.project.mac?
|
49
|
+
end
|
50
|
+
|
51
|
+
def pipe
|
52
|
+
pipe = []
|
53
|
+
|
54
|
+
pipe
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module Souyuz
|
3
|
+
# Responsible for building the jarsigner command
|
4
|
+
# TODO implement
|
5
|
+
class JavaSignCommandGenerator
|
6
|
+
class << self
|
7
|
+
def generate
|
8
|
+
build_apk_path = Souyuz.cache[:build_apk_path]
|
9
|
+
signed_apk_path = "#{build_apk_path}-unaligned.apk"
|
10
|
+
|
11
|
+
parts = prefix
|
12
|
+
parts << detect_jarsigner_executable
|
13
|
+
parts += options
|
14
|
+
parts << build_apk_path
|
15
|
+
parts << Souyuz.config[:keystore_alias]
|
16
|
+
parts += pipe
|
17
|
+
|
18
|
+
parts
|
19
|
+
end
|
20
|
+
|
21
|
+
def prefix
|
22
|
+
["set -o pipefail &&"]
|
23
|
+
end
|
24
|
+
|
25
|
+
def detect_jarsigner_executable
|
26
|
+
jarsigner = ENV['JAVA_HOME'] ? File.join(ENV['JAVA_HOME'], 'bin', 'jarsigner') : 'jarsigner'
|
27
|
+
UI.user_error! 'Jarsigner executable not found, check if your `JAVA_HOME` env is set' unless system jarsigner
|
28
|
+
|
29
|
+
jarsigner
|
30
|
+
end
|
31
|
+
|
32
|
+
def options
|
33
|
+
config = Souyuz.config
|
34
|
+
|
35
|
+
options = []
|
36
|
+
options << "-verbose" if $verbose
|
37
|
+
options << "-sigalg MD5withRSA"
|
38
|
+
options << "-digestalg SHA1"
|
39
|
+
options << "-storepass #{config[:keystore_password]}"
|
40
|
+
options << "-keystore #{config[:keystore_path]}"
|
41
|
+
options << "-tsa #{config[:keystore_tsa]}"
|
42
|
+
options << "-signedjar #{Souyuz.cache[:build_apk_path]}"
|
43
|
+
|
44
|
+
options
|
45
|
+
end
|
46
|
+
|
47
|
+
def pipe
|
48
|
+
pipe = []
|
49
|
+
|
50
|
+
pipe
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
require "fastlane_core"
|
3
|
+
|
4
|
+
module Souyuz
|
5
|
+
class Manager
|
6
|
+
def work(options)
|
7
|
+
Souyuz.config = options
|
8
|
+
|
9
|
+
FastlaneCore::PrintTable.print_values(config: Souyuz.config,
|
10
|
+
hide_keys: [],
|
11
|
+
title: "Summary for souyuz #{Souyuz::VERSION}")
|
12
|
+
|
13
|
+
return Runner.new.run
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module Souyuz
|
3
|
+
module Msbuild
|
4
|
+
class Project
|
5
|
+
attr_accessor :options
|
6
|
+
|
7
|
+
def initialize(options)
|
8
|
+
@options = options
|
9
|
+
end
|
10
|
+
|
11
|
+
def project_name
|
12
|
+
@options[:project_name]
|
13
|
+
end
|
14
|
+
|
15
|
+
def project_path
|
16
|
+
@options[:project_path]
|
17
|
+
end
|
18
|
+
|
19
|
+
def ios?
|
20
|
+
is_platform? Souyuz::Platform::IOS
|
21
|
+
end
|
22
|
+
|
23
|
+
def mac?
|
24
|
+
is_platform? Souyuz::Platform::MAC
|
25
|
+
end
|
26
|
+
|
27
|
+
def android?
|
28
|
+
is_platform? Souyuz::Platform::ANDROID
|
29
|
+
end
|
30
|
+
|
31
|
+
def is_platform?(platform)
|
32
|
+
return case platform
|
33
|
+
when Souyuz::Platform::IOS
|
34
|
+
then self.project_name.downcase.include? 'ios'
|
35
|
+
when Souyuz::Platform::MAC
|
36
|
+
then self.project_name.downcase.include? 'mac'
|
37
|
+
when Souyuz::Platform::ANDROID
|
38
|
+
then self.project_name.downcase.include? 'droid'
|
39
|
+
else false
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module Souyuz
|
3
|
+
module Msbuild
|
4
|
+
class Solution
|
5
|
+
attr_accessor :projects
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@projects = []
|
9
|
+
end
|
10
|
+
|
11
|
+
def add_project(project)
|
12
|
+
@projects << project
|
13
|
+
end
|
14
|
+
|
15
|
+
def get_platform(platform)
|
16
|
+
@projects.select { |p| p.is_platform? platform }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module Souyuz
|
3
|
+
module Msbuild
|
4
|
+
class SolutionParser
|
5
|
+
def self.parse(filename)
|
6
|
+
solution = Solution.new
|
7
|
+
|
8
|
+
File::open(filename) do |f|
|
9
|
+
f.read.split("\n").each do |line|
|
10
|
+
if line.start_with? "Project"
|
11
|
+
options = parse_line line
|
12
|
+
solution.add_project Project.new(options) #maybe we should not use the project class for this
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
return solution
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.parse_line(line)
|
21
|
+
name = get_project_name line
|
22
|
+
project_file = get_project_file line
|
23
|
+
return { project_name: name, project_path: project_file }
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.get_project_name(project_line)
|
27
|
+
project_line.split("\"")[3]
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.get_project_file(project_line)
|
31
|
+
project_line.split("\"")[5].gsub('\\', '/')
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
require "fastlane_core"
|
3
|
+
require "credentials_manager"
|
4
|
+
|
5
|
+
module Souyuz
|
6
|
+
class Options
|
7
|
+
def self.available_options
|
8
|
+
[
|
9
|
+
FastlaneCore::ConfigItem.new(key: :silent,
|
10
|
+
env_name: "SOUYUZ_SILENT",
|
11
|
+
description: "Hide all information that's not necessary while building",
|
12
|
+
default_value: false,
|
13
|
+
is_string: false),
|
14
|
+
FastlaneCore::ConfigItem.new(key: :build_configuration,
|
15
|
+
env_name: "SOUYUZ_BUILD_CONFIGURATION",
|
16
|
+
description: "Xbuild configuration value",
|
17
|
+
default_value: 'Release'),
|
18
|
+
FastlaneCore::ConfigItem.new(key: :build_platform,
|
19
|
+
env_name: "SOUYUZ_BUILD_PLATFORM",
|
20
|
+
description: "Xbuild platform value",
|
21
|
+
default_value: 'iPhone'),
|
22
|
+
FastlaneCore::ConfigItem.new(key: :build_target,
|
23
|
+
env_name: "SOUYUZ_BUILD_TARGET",
|
24
|
+
description: "Xbuild targets to build",
|
25
|
+
default_value: [ 'Build' ],
|
26
|
+
type: Array),
|
27
|
+
FastlaneCore::ConfigItem.new(key: :output_path,
|
28
|
+
env_name: "SOUYUZ_BUILD_OUTPUT_PATH",
|
29
|
+
description: "Xbuild output path",
|
30
|
+
optional: true),
|
31
|
+
FastlaneCore::ConfigItem.new(key: :project_name,
|
32
|
+
env_name: "SOUYUZ_BUILD_PROJECT_NAME",
|
33
|
+
description: "Xbuild project name",
|
34
|
+
optional: true),
|
35
|
+
FastlaneCore::ConfigItem.new(key: :assembly_name,
|
36
|
+
env_name: "SOUYUZ_BUILD_ASSEMBLY_NAME",
|
37
|
+
description: "Xbuild assembly name",
|
38
|
+
optional: true),
|
39
|
+
FastlaneCore::ConfigItem.new(key: :platform,
|
40
|
+
env_name: "SOUYUZ_PLATFORM",
|
41
|
+
description: "Targeted device platform (i.e. android, ios, mac)",
|
42
|
+
optional: false),
|
43
|
+
FastlaneCore::ConfigItem.new(key: :solution_path,
|
44
|
+
env_name: "SOUYUZ_SOLUTION_PATH",
|
45
|
+
description: "Path to the xbuild solution (sln) file",
|
46
|
+
optional: true),
|
47
|
+
FastlaneCore::ConfigItem.new(key: :project_path,
|
48
|
+
env_name: "SOUYUZ_PROJECT_PATH",
|
49
|
+
description: "Path to the xbuild project (csproj) file",
|
50
|
+
optional: true),
|
51
|
+
FastlaneCore::ConfigItem.new(key: :manifest_path,
|
52
|
+
env_name: "SOUYUZ_ANDROID_MANIFEST_PATH",
|
53
|
+
description: "Path to the android manifest (xml) file",
|
54
|
+
optional: true),
|
55
|
+
]
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module Souyuz
|
3
|
+
class Runner
|
4
|
+
def run
|
5
|
+
build_app
|
6
|
+
|
7
|
+
if Souyuz.project.ios? or Souyuz.project.mac?
|
8
|
+
compress_and_move_dsym
|
9
|
+
path = ipa_file
|
10
|
+
|
11
|
+
path
|
12
|
+
elsif Souyuz.project.android?
|
13
|
+
path = apk_file
|
14
|
+
# jarsign_and_zipalign TODO implement later
|
15
|
+
|
16
|
+
path
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def build_app
|
21
|
+
command = BuildCommandGenerator.generate
|
22
|
+
FastlaneCore::CommandExecutor.execute(command: command,
|
23
|
+
print_all: true,
|
24
|
+
print_command: !Souyuz.config[:silent])
|
25
|
+
end
|
26
|
+
|
27
|
+
#
|
28
|
+
# android build stuff to follow..
|
29
|
+
#
|
30
|
+
|
31
|
+
def apk_file
|
32
|
+
build_path = Souyuz.project.options[:output_path]
|
33
|
+
assembly_name = Souyuz.project.options[:assembly_name]
|
34
|
+
|
35
|
+
"#{build_path}/#{assembly_name}.apk"
|
36
|
+
end
|
37
|
+
|
38
|
+
def jarsign_and_zipalign
|
39
|
+
command = JavaSignCommandGenerator.generate
|
40
|
+
FastlaneCore::CommandExecutor.execute(command: command,
|
41
|
+
print_all: true,
|
42
|
+
print_command: !Souyuz.config[:silent])
|
43
|
+
|
44
|
+
command = AndroidZipalignCommandGenerator.generate
|
45
|
+
FastlaneCore::CommandExecutor.execute(command: command,
|
46
|
+
print_all: true,
|
47
|
+
print_command: !Souyuz.config[:silent])
|
48
|
+
end
|
49
|
+
|
50
|
+
#
|
51
|
+
# ios build stuff to follow..
|
52
|
+
#
|
53
|
+
|
54
|
+
def package_path
|
55
|
+
build_path = Souyuz.project.options[:output_path]
|
56
|
+
assembly_name = Souyuz.project.options[:assembly_name]
|
57
|
+
|
58
|
+
package_path = Dir.glob("#{build_path}/#{assembly_name} *").sort.last
|
59
|
+
end
|
60
|
+
|
61
|
+
def ipa_file
|
62
|
+
assembly_name = Souyuz.project.options[:assembly_name]
|
63
|
+
|
64
|
+
"#{package_path}/#{assembly_name}.ipa"
|
65
|
+
end
|
66
|
+
|
67
|
+
def compress_and_move_dsym
|
68
|
+
require 'fileutils'
|
69
|
+
build_path = Souyuz.project.options[:output_path]
|
70
|
+
assembly_name = Souyuz.project.options[:assembly_name]
|
71
|
+
dsym_path = "#{build_path}/#{assembly_name}.app.dSYM"
|
72
|
+
|
73
|
+
# compress dsym using zip
|
74
|
+
if File.exists? dsym_path
|
75
|
+
zip = ENV['SOUYUZ_ZIP_PATH'] || 'zip'
|
76
|
+
command = "#{zip} -r #{dsym_path}.zip #{dsym_path}"
|
77
|
+
Helper.backticks(command, print: !Souyuz.config[:silent])
|
78
|
+
dsym_path = "#{dsym_path}.zip"
|
79
|
+
end
|
80
|
+
|
81
|
+
# move dsym aside ipa
|
82
|
+
if File.exists? dsym_path
|
83
|
+
FileUtils.mv(dsym_path, "#{package_path}/#{File.basename dsym_path}")
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
data/lib/souyuz.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
require 'souyuz/version'
|
3
|
+
require 'souyuz/platform'
|
4
|
+
require 'souyuz/manager'
|
5
|
+
require 'souyuz/generators/build_command_generator'
|
6
|
+
require 'souyuz/runner'
|
7
|
+
require 'souyuz/options'
|
8
|
+
require 'souyuz/detect_values'
|
9
|
+
require 'souyuz/msbuild/project'
|
10
|
+
require 'souyuz/msbuild/solution'
|
11
|
+
require 'souyuz/msbuild/solution_parser'
|
12
|
+
|
13
|
+
require 'fastlane_core'
|
14
|
+
|
15
|
+
module Souyuz
|
16
|
+
class << self
|
17
|
+
attr_accessor :config
|
18
|
+
|
19
|
+
attr_accessor :project
|
20
|
+
|
21
|
+
attr_accessor :cache
|
22
|
+
|
23
|
+
def config=(value)
|
24
|
+
@config = value
|
25
|
+
DetectValues.set_additional_default_values
|
26
|
+
@cache = {}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
Helper = FastlaneCore::Helper # you gotta love Ruby: Helper.* should use the Helper class contained in FastlaneCore
|
31
|
+
UI = FastlaneCore::UI
|
32
|
+
end
|
metadata
ADDED
@@ -0,0 +1,151 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: souyuz
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Felix Rudat
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-05-26 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: nokogiri
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.6'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: fastlane_core
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.41.2
|
34
|
+
- - "<"
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: 1.0.0
|
37
|
+
type: :runtime
|
38
|
+
prerelease: false
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 0.41.2
|
44
|
+
- - "<"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 1.0.0
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: magic_encoding
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: bundler
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
type: :development
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: rake
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
type: :development
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
- !ruby/object:Gem::Dependency
|
90
|
+
name: rspec
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - "~>"
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: 3.1.0
|
96
|
+
type: :development
|
97
|
+
prerelease: false
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - "~>"
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: 3.1.0
|
103
|
+
description: A fastlane component to make Xamarin builds a breeze
|
104
|
+
email: voydz@hotmail.com
|
105
|
+
executables:
|
106
|
+
- souyuz
|
107
|
+
extensions: []
|
108
|
+
extra_rdoc_files: []
|
109
|
+
files:
|
110
|
+
- LICENSE
|
111
|
+
- README.md
|
112
|
+
- bin/souyuz
|
113
|
+
- lib/souyuz.rb
|
114
|
+
- lib/souyuz/commands_generator.rb
|
115
|
+
- lib/souyuz/detect_values.rb
|
116
|
+
- lib/souyuz/generators/android_zipalign_command_generator.rb
|
117
|
+
- lib/souyuz/generators/build_command_generator.rb
|
118
|
+
- lib/souyuz/generators/java_sign_command_generator.rb
|
119
|
+
- lib/souyuz/manager.rb
|
120
|
+
- lib/souyuz/msbuild/project.rb
|
121
|
+
- lib/souyuz/msbuild/solution.rb
|
122
|
+
- lib/souyuz/msbuild/solution_parser.rb
|
123
|
+
- lib/souyuz/options.rb
|
124
|
+
- lib/souyuz/platform.rb
|
125
|
+
- lib/souyuz/runner.rb
|
126
|
+
- lib/souyuz/version.rb
|
127
|
+
homepage: http://rubygems.org/gems/souyuz
|
128
|
+
licenses:
|
129
|
+
- MIT
|
130
|
+
metadata: {}
|
131
|
+
post_install_message:
|
132
|
+
rdoc_options: []
|
133
|
+
require_paths:
|
134
|
+
- lib
|
135
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
136
|
+
requirements:
|
137
|
+
- - ">="
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: 2.0.0
|
140
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
141
|
+
requirements:
|
142
|
+
- - ">="
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '0'
|
145
|
+
requirements: []
|
146
|
+
rubyforge_project:
|
147
|
+
rubygems_version: 2.5.0
|
148
|
+
signing_key:
|
149
|
+
specification_version: 4
|
150
|
+
summary: A fastlane component to make Xamarin builds a breeze
|
151
|
+
test_files: []
|