cocoapods-mars 0.0.12

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.
@@ -0,0 +1,120 @@
1
+ # require 'json'
2
+ require 'plist'
3
+ require_relative '../project'
4
+
5
+ module Pod
6
+ class Command
7
+ class Vemars
8
+ class Create < Vemars
9
+ self.summary = 'Create iOS vemars project given name and appKey'
10
+ self.description = <<-DESC
11
+ Create one iOS vemars project given name and appKey
12
+ DESC
13
+
14
+ self.arguments = [
15
+ CLAide::Argument.new('NAME', false),
16
+ CLAide::Argument.new('VERSION', false),
17
+ ]
18
+
19
+ def self.options
20
+ options = [
21
+ ['--language=LANGUAGE', 'language should be objc or swift'],
22
+ ['--silent', 'do not run pod install'],
23
+ ['--bundle_id=bundle_id', 'the bundle_id from Vemars'],
24
+ ['--com=COM1,COM2', 'Selected components in vemars.'],
25
+ ['--config=CONFIG_PATH', 'config path of vemars.'],
26
+ ['--service_url=SERVICE_URL', 'url of vemars CLI service.'],
27
+ ['--git=GIT_URL', 'git url of demo repo'],
28
+ ['--pod_repo_no_update', 'do not run pod repo update'],
29
+ ['--sources','pod repos sources'],
30
+ ['--test','should run test']
31
+ ]
32
+ options.concat(super.reject { |option, _| option == '--silent' })
33
+ end
34
+
35
+ def initialize(argv)
36
+ @name = argv.shift_argument
37
+ @version = argv.shift_argument
38
+ @language = argv.option('language', 'objc')
39
+ git_url = argv.option('git', 'https://github.com/volcengine/ve_Template_iOS.git')
40
+ @silent = argv.flag?('silent', false)
41
+ @test = argv.flag?('test', false)
42
+ @repo_no_update = argv.flag?('pod_repo_no_update',false)
43
+ @appkey = argv.option('appkey', '')
44
+ @bundle_id = argv.option('bundle_id', nil)
45
+ @selected_components = argv.option('com', "").split(',')
46
+ @config_json = argv.option('config', nil)
47
+ service_url = argv.option('service_url',nil)
48
+ sources = argv.option('sources','https://github.com/volcengine/volcengine-specs.git,https://cdn.cocoapods.org/')
49
+ @project = VemarsProject.new(@appkey, @selected_components, @config_json, @version, @bundle_id, @name, @language, git_url,service_url,sources)
50
+ super
51
+ @additional_args = argv.remainder!
52
+ end
53
+
54
+ def validate!
55
+ super
56
+ if !@test
57
+ if @config_json.nil? || @config_json.empty?
58
+ help! 'An config.json for the project is required.'
59
+ end
60
+ unless File.exist? @config_json
61
+ help! "onekit-config.json is not found at #{Dir.pwd}"
62
+ end
63
+ end
64
+ # help! '信息有误' unless @project.validate?
65
+ end
66
+
67
+ def run
68
+ puts 'Hi, welcome to vemars!'
69
+ @project.generate
70
+ podInstallIfNeeded
71
+ if @test
72
+ runXcodeTest
73
+ else
74
+ openXcodeWorkSpace
75
+ end
76
+ end
77
+
78
+ def podInstallIfNeeded
79
+ puts "Current dir: #{Dir.pwd}"
80
+ project_dir = File.join(Dir.pwd, [@project.basicInfo.name, "Project"])
81
+ puts "Pod install directory: #{project_dir}"
82
+ if @silent
83
+ puts "Pod install skipped!"
84
+ puts "You can run Pod install in '#{project_dir}' later!"
85
+ puts "You can run Pod install in '#{project_dir}' later!"
86
+ puts "You can run Pod install in '#{project_dir}' later!"
87
+ return
88
+ end
89
+
90
+ Dir.chdir(project_dir) do
91
+ # system('bundle install')
92
+ # system('bundle exec pod install --repo-update')
93
+ if @repo_no_update
94
+ puts "pod install with no repo update"
95
+ system('pod install --no-repo-update')
96
+ else
97
+ system('pod install --repo-update')
98
+ end
99
+ end
100
+ end
101
+
102
+ def openXcodeWorkSpace
103
+ workspace_dir = File.join(Dir.pwd, [@project.basicInfo.name, "Project","'#{@project.basicInfo.name}'.xcworkspace"])
104
+ system("open -a /Applications/Xcode.app '#{workspace_dir}'")
105
+ end
106
+
107
+
108
+ def runXcodeTest
109
+ puts "run test with xcode build"
110
+ workspace_dir = File.join(Dir.pwd, [@project.basicInfo.name, "Project"])
111
+ Dir.chdir(workspace_dir) do
112
+ cmd = "xcodebuild clean build -workspace '#{@project.basicInfo.name}'.xcworkspace -scheme '#{@project.basicInfo.name}'_InHouse -configuration Debug -destination generic/platform=iOS -sdk iphonesimulator ARCHS=x86_64 ONLY_ACTIVE_ARCH=NO"
113
+ system cmd
114
+ end
115
+ end
116
+
117
+ end
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,92 @@
1
+ require_relative '../project'
2
+
3
+ module Pod
4
+ class Command
5
+ class Vemars
6
+ class Patch < Vemars
7
+ self.summary = 'Patch exisiting iOS project with vemars services'
8
+ self.description = <<-DESC
9
+ Patch exisiting iOS project with vemars services, given
10
+ project directory, same level where Podfile locates,
11
+ vemars baseline version and selected components within vemars
12
+ DESC
13
+
14
+ self.arguments = [
15
+ CLAide::Argument.new('VERSION', false),
16
+ ]
17
+
18
+ def self.options
19
+ options = [
20
+ ['--path=PODFILE_PATH', 'the /path/to/Dir_contains_Podfile'],
21
+ ['--com=COM1,COM2', 'Selected components in vemars.'],
22
+ ['--config=CONFIG_PATH', 'config path of vemars.'],
23
+ ['--service_url=SERVICE_URL', 'url of vemars CLI service.'],
24
+ ['--git=GIT_URL', 'git url of demo repo'],
25
+ ['--pod_repo_no_update', 'do not run pod repo update'],
26
+ ['--sources','pod repos sources']
27
+ ]
28
+ options.concat(super.reject { |option, _| option == '--silent' })
29
+ end
30
+
31
+ def initialize(argv)
32
+ @baseline = argv.shift_argument
33
+ @path = argv.option('path', '')
34
+ @selected_components = argv.option('com', '').split(',')
35
+ @config_json = argv.option('config', '/onekit-config.json')
36
+ @repo_no_update = argv.flag?('pod_repo_no_update',false)
37
+ git_url = argv.option('git', 'https://github.com/volcengine/ve_Template_iOS.git')
38
+ service_url = argv.option('service_url',nil)
39
+ sources = argv.option('sources','https://github.com/volcengine/volcengine-specs.git,https://cdn.cocoapods.org/')
40
+ @project = VemarsProject.new(@appkey, @selected_components, @config_json, @baseline, git_url, service_url,sources)
41
+ super
42
+ @additional_args = argv.remainder!
43
+ end
44
+
45
+ def validate!
46
+ super
47
+ if @path.nil? || @path.empty?
48
+ help! 'A project path where Podfile locates is required '
49
+ end
50
+ unless File.exist? @config_json
51
+ help! "onekit-config.json is not found at #{Dir.pwd}"
52
+ end
53
+ end
54
+
55
+ def run
56
+ @project.patch @path
57
+ podInstallIfNeeded
58
+ openXcodeWorkSpace
59
+ end
60
+
61
+ def podInstallIfNeeded
62
+ puts "Current dir: #{Dir.pwd}"
63
+ project_dir = @path
64
+ puts "Pod install directory: #{project_dir}"
65
+ if @silent
66
+ puts "Pod install skipped!"
67
+ puts "You can run Pod install in '#{project_dir}' later!"
68
+ return
69
+ end
70
+
71
+ Dir.chdir(project_dir) do
72
+ # system('bundle install')
73
+ # system('bundle exec pod install --repo-update')
74
+ if @repo_no_update
75
+ puts "pod install with no repo update"
76
+ system('pod install --no-repo-update')
77
+ else
78
+ system('pod install --repo-update')
79
+ end
80
+ end
81
+ end
82
+
83
+ def openXcodeWorkSpace
84
+ workspaces = Dir.entries(@path).select { |e| e.end_with?(".xcworkspace") }
85
+ full_path = File.join(@path, workspaces.first)
86
+ system("open -a /Applications/Xcode.app '#{full_path}'")
87
+ end
88
+
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,34 @@
1
+ module Pod
2
+ class Command
3
+ class Vemars < Command
4
+ require_relative 'vemars/create'
5
+ require_relative 'vemars/baselines'
6
+ require_relative 'vemars/components'
7
+ require_relative 'vemars/patch'
8
+
9
+ self.summary = 'vemars iOS project generation tool'
10
+ self.description = <<-DESC
11
+ Create a mars iOS project.
12
+ DESC
13
+
14
+ self.abstract_command = true
15
+ # self.default_subcommand = 'create'
16
+ self.command = 'mars'
17
+
18
+ # 解析命令别名
19
+ def self.parse(argv)
20
+ expanded_alias = argv.option('expanded-alias')
21
+ cmd = super(argv)
22
+ if cmd.class == Pod::Command::Vemars
23
+ if !expanded_alias.blank? && (arg = argv.shift_argument)
24
+ require 'shellwords'
25
+ new_argv = expanded_alias.shellsplit + argv.remainder
26
+ cmd = super(CLAide::ARGV.coerce(new_argv))
27
+ end
28
+ end
29
+ cmd
30
+ end
31
+
32
+ end
33
+ end
34
+ end
@@ -0,0 +1 @@
1
+ require 'cocoapods-vemars/command/vemars'
@@ -0,0 +1,3 @@
1
+ module CocoapodsVemars
2
+ VERSION = "0.0.12"
3
+ end
@@ -0,0 +1,14 @@
1
+
2
+ module Pod
3
+ class Podfile
4
+ module DSL
5
+ alias vemars_pod pod
6
+
7
+ def pod(name = nil, *requirements)
8
+ puts "name #{name}"
9
+ vemars_pod(name = nil, *requirements)
10
+ end
11
+
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,111 @@
1
+ module Pod
2
+ class PodfileTemplate
3
+
4
+ attr_reader :componentsList
5
+ attr_reader :sources
6
+ attr_reader :baseline_version
7
+
8
+ IOS_VERSION = '9.0'.freeze
9
+
10
+ def initialize(baseline_version, componentsList, sources)
11
+ @baseline_version = baseline_version
12
+ @componentsList = componentsList
13
+ @sources = sources
14
+ end
15
+
16
+ def to_dsl
17
+ <<-SPEC
18
+
19
+ #{platform}
20
+
21
+ #plugin 'cocoapods-vemars'
22
+ install! 'cocoapods', :deterministic_uuids => false
23
+
24
+ #{source_template}
25
+
26
+ #{releasePod}
27
+ #{target}
28
+ #{post_install_setup}
29
+ SPEC
30
+ end
31
+
32
+ def platform
33
+ <<-SPEC
34
+ platform :ios, #{IOS_VERSION}
35
+ inhibit_all_warnings!
36
+ SPEC
37
+ end
38
+
39
+ def source_template
40
+ source_urls = sources.split(",")
41
+ "#{source_urls.map{ |url| "source '#{url}'"}.join("\n")}"
42
+ end
43
+
44
+ def releasePod
45
+ <<-SPEC
46
+
47
+ def release_pod
48
+ #baseline version #{baseline_version}
49
+ #{@componentsList.map { |component|
50
+ result = "\tpod '#{component.name}'"
51
+ if !component.version.nil?
52
+ result = result + ", '#{component.version}'"
53
+ end
54
+
55
+ if !component.subspecs.nil?
56
+ result = result + ", :subspecs => #{component.subspecs}"
57
+ end
58
+ result
59
+ }.join("\n")}
60
+ end
61
+ SPEC
62
+ end
63
+
64
+ def target
65
+ <<-SPEC
66
+ target 'Template_InHouse' do
67
+ release_pod
68
+ pod 'App/Debug', :path => './../DevPods/', :inhibitat_warnings => false
69
+ end
70
+ SPEC
71
+ end
72
+
73
+ def post_install_setup
74
+ <<-SPEC
75
+ def update_deployment_config(config = nil)
76
+ return if config.nil?
77
+ config.build_settings['ENABLE_BITCODE'] = 'NO'
78
+ if config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'].to_f < 12.0
79
+ config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '12.0'
80
+ end
81
+ end
82
+
83
+ post_install do |installer|
84
+ installer.pods_project.build_configurations.each do |config|
85
+ update_deployment_config(config)
86
+ end
87
+
88
+ installer.pods_project.targets.each do |target|
89
+ target.build_configurations.each do |config|
90
+ update_deployment_config(config)
91
+ end
92
+ end
93
+ ## for generate_multiple_pod_projects = true
94
+ installer.generated_projects.each do |project|
95
+ project.build_configurations.each do |config|
96
+ update_deployment_config(config)
97
+ end
98
+
99
+ project.targets.each do |target|
100
+ target.build_configurations.each do |config|
101
+ update_deployment_config(config)
102
+ end
103
+ end
104
+ end
105
+
106
+ end
107
+ SPEC
108
+ end
109
+ end
110
+
111
+ end
@@ -0,0 +1,35 @@
1
+ require 'Rest'
2
+
3
+ module Pod
4
+ class Baselines_api
5
+ include Concurrent::Async
6
+
7
+ BASELINES_URL = 'https://mars-fwk.vemarsdev.com/mpaas/baseline/baselines'.freeze
8
+ attr_accessor :result
9
+
10
+ public def initialize(url=BASELINES_URL)
11
+ @baseline_url = (url.blank? ? BASELINES_URL : url + "mpaas/baseline/baselines")
12
+ end
13
+
14
+ def getBaselines
15
+ body= "{\"technology_stack\": \"iOS\"}"
16
+ header = {"ContentType" => 'application/json'}
17
+ response = REST.post(@baseline_url, body, header)
18
+ if response.ok?
19
+ json = JSON.parse(response.body)
20
+ error_code = json["error_no"]
21
+ if error_code == 0
22
+ @result = json["data"]['baselines']
23
+ @result = @result.sort.reverse
24
+ puts "Version list: #{@result}"
25
+ else
26
+ puts "Error #{error_code}(#{json["error_msg"]}): #{json["err_detail"]}}"
27
+ end
28
+ else
29
+ puts "response status: #{response.status_code}"
30
+ end
31
+ end
32
+
33
+
34
+ end
35
+ end
@@ -0,0 +1,62 @@
1
+ require_relative 'baselines_api'
2
+ require_relative '../command/component'
3
+
4
+ module Pod
5
+ class Components_api
6
+ include Concurrent::Async
7
+
8
+ COMPONENTS_URL = 'https://mars-fwk.vemarsdev.com/mpaas/baseline/baseline_config'.freeze
9
+
10
+ attr_reader :source
11
+ attr_reader :baseline
12
+ attr_reader :component_list
13
+ attr_reader :baseline_api
14
+ attr_reader :components_url
15
+
16
+ public def initialize(baseline=nil,url=COMPONENTS_URL)
17
+ @baseline = baseline
18
+ @source = ""
19
+ @component_list = []
20
+ @baseline_api = Baselines_api.new(url)
21
+ @components_url = (url.blank? ? COMPONENTS_URL : url + "mpaas/baseline/baseline_config")
22
+ end
23
+
24
+ public def validate!
25
+ baseline_api.await.getBaselines
26
+ if @baseline.nil? && baseline_api.result.length() == 0
27
+ help! "No baselines info existed, please check with server admin"
28
+ elsif @baseline.nil? && baseline_api.result.length() > 0
29
+ @baseline = baseline_api.result[0]
30
+ elsif !@baseline.nil? && baseline_api.result.length() > 0
31
+ if !baseline_api.result.include?(@baseline)
32
+ puts "Invalid baseline version provided!"
33
+ help! "Invalid baseline version provided!"
34
+ end
35
+ end
36
+ end
37
+
38
+ public def getComponents(baseline=@baseline)
39
+ body= "{\"baseline_version\": \"#{baseline}\", \"technology_stack\": \"iOS\"}"
40
+ header = {"ContentType" => 'application/json'}
41
+ response = REST.post(@components_url, body, header)
42
+ deserilise(response)
43
+ return component_list
44
+ end
45
+
46
+ def deserilise(response)
47
+ if response.ok?
48
+ json = JSON.parse(response.body)
49
+ error_code = json["error_no"]
50
+ if error_code == 0
51
+ @source = json['data']['source']
52
+ @component_list = json['data']['iosPlugins'].map { |obj| Component.new(obj) }
53
+ else
54
+ puts "Error #{error_code}(#{json["error_msg"]}): #{json["err_detail"]}}"
55
+ end
56
+ else
57
+ puts "fail to get components, response status: #{response.status_code}"
58
+ end
59
+ end
60
+
61
+ end
62
+ end
@@ -0,0 +1,203 @@
1
+ require_relative '../hook/podfile_template'
2
+ require_relative 'tailor'
3
+ require 'rexml/document'
4
+ include REXML
5
+ require "fileutils"
6
+ require 'tempfile'
7
+ require 'xcodeproj'
8
+
9
+ module Pod
10
+ class Patcher
11
+ include Pod
12
+
13
+ attr_reader :podfile_dir
14
+ attr_reader :template
15
+
16
+ def initialize(podfile_dir, baseline, components_details, source, git_url,demo_tag)
17
+ @podfile_dir = podfile_dir
18
+ @template = PodfileTemplate.new(baseline, components_details, source)
19
+ @components_details = components_details
20
+ @git_url = git_url
21
+ puts git_url
22
+ @hasInjectedSource = false
23
+ @hasInjectedVemarsPods = false
24
+ @demo_tag = demo_tag
25
+ end
26
+
27
+ def execute
28
+ insert_plist
29
+ plugin_demos
30
+ patch_podfile
31
+ end
32
+
33
+ private
34
+ attr_accessor :hasInjectedSource
35
+ attr_accessor :hasInjectedVemarsPods
36
+ attr_reader :components_details
37
+
38
+ def patch_podfile
39
+ podfile_path = find_podfile
40
+ if podfile_path.nil? || podfile_path.empty?
41
+ UI.puts "can not file project Podfile "
42
+ return
43
+ end
44
+ UI.puts "patching project with podfile path #{podfile_path}"
45
+
46
+ tempfile = Tempfile.new('podfile_temp')
47
+ sourceAnchors = source_anchors(podfile_path)
48
+ targetAnchors = target_anchor(podfile_path)
49
+
50
+ File.open(podfile_path, 'r') do |f|
51
+ f.each_line{ |line|
52
+ pre_inject, post_inject = inject_source(sourceAnchors, line)
53
+ if pre_inject.empty?
54
+ pre_inject = inject_vemarsPodsDef(targetAnchors, line)
55
+ end
56
+
57
+ if post_inject.empty?
58
+ post_inject = inject_releasePodInTarget(line)
59
+ end
60
+
61
+ if !pre_inject.empty?
62
+ tempfile.puts pre_inject
63
+ end
64
+ tempfile.puts line
65
+ if !post_inject.empty?
66
+ tempfile.puts post_inject
67
+ end
68
+ }
69
+ end
70
+ tempfile.close
71
+ FileUtils.mv(tempfile.path, podfile_path)
72
+ end
73
+
74
+ def plugin_demos
75
+ clone_project
76
+ tailor_demos
77
+ cleanup
78
+ end
79
+
80
+ def clone_project
81
+ if @demo_tag.nil?
82
+ system("git clone #{@git_url} ./.vemars")
83
+ else
84
+ system("git clone #{@git_url} ./.vemars -b #{@demo_tag} --config advice.detachedHead=false")
85
+ end
86
+ system("mv ./.vemars/DevPods ./DevPods")
87
+ end
88
+
89
+ def tailor_demos
90
+ tailor = DemoTailor.new(@components_details)
91
+ tailor.execute
92
+ end
93
+
94
+ def cleanup
95
+ system("rm -rf ./.vemars")
96
+ end
97
+
98
+ def find_podfile
99
+ locations = []
100
+
101
+ Dir.entries(Dir.pwd).select { |e| e.end_with?(".xcworkspace") }.each do |xcworkspace|
102
+ full_path = File.join(@podfile_dir, xcworkspace, "contents.xcworkspacedata")
103
+ if File.file?(full_path)
104
+ Document.new(File.new(full_path)).elements.each { |e|
105
+ e.elements.each ("FileRef"){ |ref|
106
+ locations << ref.attributes["location"]
107
+ }
108
+ }
109
+ end
110
+ end
111
+
112
+ project = locations.reject { |e| e.include?("Pods/Pods.xcodeproj") }.map { |location|
113
+ File.expand_path("Podfile",File.dirname(File.join(@podfile_dir,location[6..-1])))
114
+ }.select { |full_path| File.file?(full_path) }
115
+
116
+ if project.empty?
117
+
118
+ full_path = File.join(@podfile_dir, "Podfile")
119
+ return full_path if File.file?(full_path)
120
+
121
+ full_path = File.join(@podfile_dir, "Project", "Podfile")
122
+ return full_path if File.file?(full_path)
123
+ end
124
+
125
+ if project.empty?
126
+ UI.puts "can not find Podfile in #{@podfile_dir}"
127
+ end
128
+
129
+ return project.first
130
+ end
131
+
132
+
133
+
134
+ def insert_plist
135
+ puts "insert plist"
136
+ plist_dir = Dir.pwd + "/onekit-config.plist"
137
+ Dir.entries(Dir.pwd).select { |e| e.end_with?(".xcodeproj") }.each do |xcodeproj|
138
+ full_path = File.join(@podfile_dir, xcodeproj)
139
+ puts "insert plist in :#{full_path}"
140
+ project = Xcodeproj::Project.open(full_path)
141
+ file = project.new_file(plist_dir)
142
+ main_target = project.targets.first
143
+ main_target.add_resources([file])
144
+ project.save
145
+ end
146
+ end
147
+
148
+
149
+ def source_anchors(podfile)
150
+ result = []
151
+ File.open podfile do |file|
152
+ result = file.find_all { |line| line.include?('source') }
153
+ end
154
+ return result
155
+ end
156
+
157
+ def target_anchor(podfile)
158
+ result = []
159
+ File.open podfile do |file|
160
+ result = file.find_all { |line| line.include?('target "') | line.include?("target '") }
161
+ end
162
+ return result
163
+ end
164
+
165
+ ## return (pre-inject, post-inject)
166
+ def inject_source(anchor, line)
167
+ return '','' if @hasInjectedSource
168
+
169
+ pre_inject = ''
170
+ post_inject = ''
171
+ if anchor.empty?
172
+ pre_inject = @template.source_template
173
+ @hasInjectedSource = true
174
+
175
+ elsif line.include? anchor[anchor.length - 1]
176
+ post_inject = @template.source_template
177
+ @hasInjectedSource = true
178
+ end
179
+ return pre_inject,post_inject
180
+ end
181
+
182
+ ## return pre_inject
183
+ def inject_vemarsPodsDef(anchor, line)
184
+ return '' if @hasInjectedVemarsPods
185
+
186
+ if !anchor.empty? && line.include?(anchor[0])
187
+ @hasInjectedVemarsPods = true
188
+ return @template.releasePod, ''
189
+ end
190
+ return ''
191
+ end
192
+
193
+
194
+ ## return post_inject
195
+ def inject_releasePodInTarget(line)
196
+ if line.include?('target "') | line.include?("target '")
197
+ return "\trelease_pod \n\tpod 'App/Debug', :path => './DevPods/', :inhibitat_warnings => false"
198
+ end
199
+ return ''
200
+ end
201
+
202
+ end
203
+ end