qcloudhive 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/.idea/.rakeTasks +7 -0
- data/.idea/Hive.iml +54 -0
- data/.idea/dictionaries/dongzhao.xml +7 -0
- data/.idea/misc.xml +4 -0
- data/.idea/modules.xml +8 -0
- data/.idea/vcs.xml +6 -0
- data/.idea/workspace.xml +699 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Documents/Images/93A5AC58-17D5-4D3F-B5A8-E509CF429BD0.png +0 -0
- data/Documents/Images/C702C824-11B1-47A8-BB15-9F6F14F2B649.png +0 -0
- data/Gem/qcloudhive/.idea/misc.xml +4 -0
- data/Gem/qcloudhive/.idea/modules.xml +8 -0
- data/Gem/qcloudhive/.idea/qcloudhive.iml +8 -0
- data/Gem/qcloudhive/.idea/workspace.xml +383 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +122 -0
- data/LICENSE.txt +21 -0
- data/README.md +273 -0
- data/Rakefile +5 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/exe/Hive +302 -0
- data/lib/qcloudhive.rb +16 -0
- data/lib/qcloudhive/config.rb +176 -0
- data/lib/qcloudhive/feature.rb +92 -0
- data/lib/qcloudhive/framework.rb +192 -0
- data/lib/qcloudhive/git_helper.rb +75 -0
- data/lib/qcloudhive/gitlab.rb +69 -0
- data/lib/qcloudhive/manifest.rb +346 -0
- data/lib/qcloudhive/module.rb +228 -0
- data/lib/qcloudhive/pod_helper.rb +119 -0
- data/lib/qcloudhive/product.rb +32 -0
- data/lib/qcloudhive/project.rb +108 -0
- data/lib/qcloudhive/repo.rb +177 -0
- data/lib/qcloudhive/spec_helper.rb +45 -0
- data/lib/qcloudhive/utils.rb +46 -0
- data/lib/qcloudhive/version.rb +3 -0
- data/lib/qcloudhive/xcodeproj.rb +163 -0
- data/qcloudhive.gemspec +43 -0
- data/resources/shellscriptes/HiveApp.sh +156 -0
- data/resources/shellscriptes/HiveFramework +158 -0
- data/resources/shellscriptes/build_framework.sh +76 -0
- data/resources/templates/AppDefaultTemplate/.gitignore +41 -0
- data/resources/templates/AppDefaultTemplate/AppDefaultTemplate.xcodeproj/project.pbxproj +290 -0
- data/resources/templates/AppDefaultTemplate/AppDefaultTemplate.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
- data/resources/templates/AppDefaultTemplate/AppDefaultTemplate/Info.plist +24 -0
- data/resources/templates/AppDefaultTemplate/Podfile +9 -0
- data/resources/templates/HiveAppTemplate/.gitignore +41 -0
- data/resources/templates/HiveAppTemplate/HiveAppTemplate.xcodeproj/project.pbxproj +539 -0
- data/resources/templates/HiveAppTemplate/HiveAppTemplate.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
- data/resources/templates/HiveAppTemplate/HiveAppTemplate/AppDelegate.h +17 -0
- data/resources/templates/HiveAppTemplate/HiveAppTemplate/AppDelegate.m +51 -0
- data/resources/templates/HiveAppTemplate/HiveAppTemplate/Assets.xcassets/AppIcon.appiconset/Contents.json +68 -0
- data/resources/templates/HiveAppTemplate/HiveAppTemplate/Base.lproj/LaunchScreen.storyboard +27 -0
- data/resources/templates/HiveAppTemplate/HiveAppTemplate/Base.lproj/Main.storyboard +26 -0
- data/resources/templates/HiveAppTemplate/HiveAppTemplate/Info.plist +45 -0
- data/resources/templates/HiveAppTemplate/HiveAppTemplate/ViewController.h +15 -0
- data/resources/templates/HiveAppTemplate/HiveAppTemplate/ViewController.m +29 -0
- data/resources/templates/HiveAppTemplate/HiveAppTemplate/main.m +16 -0
- data/resources/templates/HiveAppTemplate/HiveAppTemplateTests/HiveAppTemplateTests.m +39 -0
- data/resources/templates/HiveAppTemplate/HiveAppTemplateTests/Info.plist +22 -0
- data/resources/templates/HiveAppTemplate/HiveAppTemplateUITests/HiveAppTemplateUITests.m +40 -0
- data/resources/templates/HiveAppTemplate/HiveAppTemplateUITests/Info.plist +22 -0
- data/resources/templates/HiveAppTemplate/Podfile +20 -0
- data/resources/templates/commonConf.sh +9 -0
- data/resources/templates/manifests/build.rb +8 -0
- data/resources/templates/manifests/default.xml +12 -0
- data/resources/templates/template.podspec +37 -0
- metadata +321 -0
@@ -0,0 +1,92 @@
|
|
1
|
+
require_relative "utils.rb"
|
2
|
+
require_relative "git_helper.rb"
|
3
|
+
require "git"
|
4
|
+
require 'versionomy'
|
5
|
+
|
6
|
+
module QCloudHive
|
7
|
+
class QCloudHiveFeature
|
8
|
+
|
9
|
+
end
|
10
|
+
|
11
|
+
def QCloudHive.startFeature(cmd, opts)
|
12
|
+
end
|
13
|
+
|
14
|
+
def QCloudHive.listFeature(cmd, opts)
|
15
|
+
end
|
16
|
+
|
17
|
+
def QCloudHive.pushFeature(cmd, opts)
|
18
|
+
Config.manifest.projects.each { |p|
|
19
|
+
if not p.gitRepo.clean?
|
20
|
+
Error("模块:#{p.path} 在本地有未提交的修改,请检查并提交后再进行PUSH操作")
|
21
|
+
end
|
22
|
+
}
|
23
|
+
|
24
|
+
Config.manifest.projects.each { |p|
|
25
|
+
currentBranch = p.gitRepo.branches[p.gitRepo.current_branch]
|
26
|
+
currentFreature = ProjectFeature.new(p, currentBranch)
|
27
|
+
if currentFreature.remoteBranch.nil?
|
28
|
+
puts "#{p.path} 提交 #{currentBranch.name}"
|
29
|
+
L.info("#{p.gitRepo} git repo xxxxxx")
|
30
|
+
p.gitRepo.push('origin', currentBranch.name, {"--set-upstream"=>currentBranch.name})
|
31
|
+
else
|
32
|
+
compareRet = currentFreature.compareRemote
|
33
|
+
if compareRet == 1
|
34
|
+
puts "#{p.path} 提交 #{currentBranch.name}"
|
35
|
+
L.info("#{p.gitRepo} git repo")
|
36
|
+
p.gitRepo.push('origin', currentBranch.name, {"--set-upstream"=>currentBranch.name})
|
37
|
+
elsif compareRet == -1
|
38
|
+
puts "#{p.path} 没有进行push操作 远端有新的修改,请及时Pull⬇️⬇️⬇️".blue
|
39
|
+
else
|
40
|
+
end
|
41
|
+
end
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
def QCloudHive.commitFeature(cmd, opts)
|
46
|
+
message = GetOptValue(cmd, opts, :i_message)
|
47
|
+
Config.manifest.projects.each { |p|
|
48
|
+
if p.exsitLocal?
|
49
|
+
git = p.gitRepo
|
50
|
+
if (not git.nil?) and (not git.clean?)
|
51
|
+
L.info("#{git.dir} commit clean #{git.clean?}")
|
52
|
+
git.add(:all=>true)
|
53
|
+
git.commit_all(message)
|
54
|
+
else
|
55
|
+
L.info("#{git.dir} is clean")
|
56
|
+
end
|
57
|
+
end
|
58
|
+
}
|
59
|
+
end
|
60
|
+
|
61
|
+
def QCloudHive.checkDependencies(cmd, opts)
|
62
|
+
Config.manifest.projects.each { |p|
|
63
|
+
L.info("#{p.path} exist #{p.exsitLocal?}")
|
64
|
+
if p.exsitLocal? and (not p.podspec.nil?)
|
65
|
+
L.info("#{p.path}")
|
66
|
+
version = Versionomy.parse(p.podspec.version.version)
|
67
|
+
versionNumber = version.major*1000*1000 + version.minor*1000 + version.tiny
|
68
|
+
str = "
|
69
|
+
#ifndef #{p.moduleName}ModuleVersion_h
|
70
|
+
#define #{p.moduleName}ModuleVersion_h
|
71
|
+
#define #{p.moduleName}ModuleVersionNumber #{versionNumber}
|
72
|
+
FOUNDATION_EXTERN NSString * const #{p.moduleName}ModuleVersion;
|
73
|
+
FOUNDATION_EXTERN NSString * const #{p.moduleName}ModuleName;
|
74
|
+
#endif
|
75
|
+
"
|
76
|
+
file = Pathname(p.localPath).join("Pod/Classes/#{p.moduleName}Version.h")
|
77
|
+
File.open(file, "w") { |f|
|
78
|
+
f.write str
|
79
|
+
}
|
80
|
+
|
81
|
+
file = Pathname(p.localPath).join("Pod/Classes/#{p.moduleName}Version.m")
|
82
|
+
File.open(file, "w") { |f|
|
83
|
+
f.write "
|
84
|
+
#import \"#{p.moduleName}Version.h\"
|
85
|
+
NSString * const #{p.moduleName}ModuleVersion = @\"#{p.podspec.version.version}\";
|
86
|
+
NSString * const #{p.moduleName}ModuleName = @\"#{p.moduleName}\";
|
87
|
+
"
|
88
|
+
}
|
89
|
+
end
|
90
|
+
}
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,192 @@
|
|
1
|
+
|
2
|
+
require_relative "config.rb"
|
3
|
+
require "rake"
|
4
|
+
require 'fileutils'
|
5
|
+
require "set"
|
6
|
+
require "pathname"
|
7
|
+
class Pathname
|
8
|
+
def fileName
|
9
|
+
if not extname.nil?
|
10
|
+
return basename.to_s[0..(basename.to_s.length-extname.length-1)]
|
11
|
+
end
|
12
|
+
return basename.to_s
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
module QCloudHive
|
17
|
+
class BuildShell
|
18
|
+
attr_accessor :productsDir
|
19
|
+
attr_accessor :config
|
20
|
+
attr_accessor :name
|
21
|
+
attr_accessor :other_cflags
|
22
|
+
attr_accessor :sdk
|
23
|
+
def to_cmd
|
24
|
+
cmd ="xcodebuild -configuration #{config} -sdk #{sdk} -workspace #{name}.xcworkspace -scheme #{name} clean\n"
|
25
|
+
cmd +="xcodebuild DEPLOYMENT_POSTPROCESSING=YES STRIP_STYLE=debugging "
|
26
|
+
if not other_cflags.nil?
|
27
|
+
cmd += " OTHER_CFLAGS=#{other_cflags}"
|
28
|
+
end
|
29
|
+
cmd += " -configuration #{config}"
|
30
|
+
cmd += " -workspace #{name}.xcworkspace -scheme #{name}"
|
31
|
+
cmd += " -sdk #{sdk} -derivedDataPath #{productsDir} "
|
32
|
+
cmd
|
33
|
+
end
|
34
|
+
end
|
35
|
+
def QCloudHive.beginShell(path, shell)
|
36
|
+
Rake::sh "cd #{path}\n #{shell}"
|
37
|
+
end
|
38
|
+
|
39
|
+
def QCloudHive.UnlinkedModule(name, hiveXcodeProject)
|
40
|
+
podspec = hiveXcodeProject.hiveSpecModules.select { |s|
|
41
|
+
s.name == name
|
42
|
+
}.first
|
43
|
+
if podspec.nil?
|
44
|
+
Error "您不想链接的模块#{name}, 不存在本地"
|
45
|
+
end
|
46
|
+
unlinked = []
|
47
|
+
L.info "$$$$$$$$#{podspec.path}"
|
48
|
+
if not podspec.path.nil?
|
49
|
+
pod = Pod::Specification.from_file(podspec.path)
|
50
|
+
vendored_libraries = pod.attributes_hash["vendored_libraries"]
|
51
|
+
vendoredFrameworks = pod.attributes_hash["vendored_frameworks"]
|
52
|
+
if not vendoredFrameworks.nil?
|
53
|
+
vendoredFrameworks.each { |e|
|
54
|
+
unlinked << Pathname.new(e).fileName
|
55
|
+
}
|
56
|
+
end
|
57
|
+
if not vendored_libraries.nil?
|
58
|
+
vendored_libraries.each { |e|
|
59
|
+
name = Pathname.new(e).fileName
|
60
|
+
if name.start_with?("lib")
|
61
|
+
name = name[3..-1]
|
62
|
+
end
|
63
|
+
unlinked << name
|
64
|
+
}
|
65
|
+
end
|
66
|
+
L.info "Unlinked #{unlinked}"
|
67
|
+
return unlinked
|
68
|
+
end
|
69
|
+
end
|
70
|
+
def QCloudHive.BuildFramework(cmd, opts)
|
71
|
+
name = opts[:i_name]
|
72
|
+
if name == nil
|
73
|
+
L.error "ERROR! no project name, please input one"
|
74
|
+
L.error cmd.help
|
75
|
+
exit(1)
|
76
|
+
end
|
77
|
+
buildSimArch = opts[:i_build_sim]
|
78
|
+
if buildSimArch.nil?
|
79
|
+
buildSimArch = true
|
80
|
+
end
|
81
|
+
L.info "build sim #{buildSimArch}"
|
82
|
+
unlinked = opts[:i_unlinked_frameworks]
|
83
|
+
if unlinked.nil?
|
84
|
+
unlinked = []
|
85
|
+
end
|
86
|
+
L.info "un linked frameworks #{unlinked}"
|
87
|
+
output = Dir.pwd
|
88
|
+
rootShellPath = Config.scriptesDirectory
|
89
|
+
Rake::sh "#{rootShellPath}HiveFramework #{name}"
|
90
|
+
|
91
|
+
projectDir = "#{output}/#{name}"
|
92
|
+
project = Xcodeproj::Project.open("#{output}/#{name}/#{name}.xcodeproj")
|
93
|
+
project.targets.each do |target|
|
94
|
+
if target.name == name
|
95
|
+
target.build_configurations.each do |config|
|
96
|
+
config.build_settings['ENABLE_BITCODE'] = 'NO'
|
97
|
+
puts "set bitcode NO"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
puts "target name #{name}"
|
101
|
+
end
|
102
|
+
|
103
|
+
project.save
|
104
|
+
|
105
|
+
Rake::sh "cd #{name} \n" +
|
106
|
+
"pod update\n"
|
107
|
+
# delete unlinked frameworks
|
108
|
+
project = Xcodeproj::Project.open("#{output}/#{name}/#{name}.xcodeproj")
|
109
|
+
xcconfigFiles = project.files.select{ |f|
|
110
|
+
L.info "file #{f.path}"
|
111
|
+
f.path.end_with?(".xcconfig")
|
112
|
+
}
|
113
|
+
L.info("config files #{xcconfigFiles}")
|
114
|
+
hiveXcodeProject = QCloudHive.xcodeprojectByPath(Pathname.new("#{output}/#{name}").realpath.to_s)
|
115
|
+
xcconfigFiles.each { |f|
|
116
|
+
path = Pathname.new(projectDir).join(f.path)
|
117
|
+
config = Xcodeproj::Config.new(path)
|
118
|
+
linked = config.other_linker_flags[:libraries].to_a
|
119
|
+
L.info "#{config.other_linker_flags}"
|
120
|
+
frameworkLinked = config.other_linker_flags[:frameworks].to_a
|
121
|
+
L.info "linked #{linked}"
|
122
|
+
# unlinked.each { |e|
|
123
|
+
# linked.delete e
|
124
|
+
# willUnlink = UnlinkedModule(e, hiveXcodeProject)
|
125
|
+
# L.info "will unlink #{willUnlink}"
|
126
|
+
# linked -= willUnlink
|
127
|
+
# frameworkLinked -= willUnlink
|
128
|
+
# }
|
129
|
+
linked = linked.compact
|
130
|
+
frameworkLinked = frameworkLinked.compact
|
131
|
+
config.other_linker_flags[:libraries] = linked.to_set
|
132
|
+
config.other_linker_flags[:frameworks] = frameworkLinked.to_set
|
133
|
+
L.info "final linked #{linked}"
|
134
|
+
config.save_as(path)
|
135
|
+
}
|
136
|
+
#
|
137
|
+
|
138
|
+
productsDir = "Products"
|
139
|
+
productsDir = "#{projectDir}/#{productsDir}"
|
140
|
+
if not Pathname.new(productsDir).exist?
|
141
|
+
Pathname.new(productsDir).mkdir
|
142
|
+
end
|
143
|
+
|
144
|
+
|
145
|
+
|
146
|
+
buildCMD = BuildShell.new()
|
147
|
+
buildCMD.config = "Release"
|
148
|
+
buildCMD.productsDir = productsDir
|
149
|
+
buildCMD.other_cflags = "\"-fembed-bitcode\""
|
150
|
+
buildCMD.name = name
|
151
|
+
buildCMD.sdk = "iphoneos"
|
152
|
+
beginShell(name,buildCMD.to_cmd)
|
153
|
+
|
154
|
+
|
155
|
+
deviceFramework="#{productsDir}/Build/Products/#{buildCMD.config}-iphoneos/#{name}.framework"
|
156
|
+
|
157
|
+
if buildSimArch == true
|
158
|
+
buildCMD = BuildShell.new()
|
159
|
+
buildCMD.config = "Release"
|
160
|
+
buildCMD.productsDir = productsDir
|
161
|
+
buildCMD.other_cflags = "\"-fembed-bitcode\""
|
162
|
+
buildCMD.name = name
|
163
|
+
buildCMD.sdk = "iphonesimulator"
|
164
|
+
|
165
|
+
beginShell(name,buildCMD.to_cmd)
|
166
|
+
simFramework="#{productsDir}/Build/Products/#{buildCMD.config}-iphonesimulator/#{name}.framework"
|
167
|
+
Rake::sh " lipo -create #{deviceFramework}/#{name} #{simFramework}/#{name} -output #{deviceFramework}/#{name}"
|
168
|
+
|
169
|
+
end
|
170
|
+
|
171
|
+
puts "Copy frameworks"
|
172
|
+
outputFramework = "#{name}.framework"
|
173
|
+
outputFrameworkPath = Pathname.new(outputFramework)
|
174
|
+
if outputFrameworkPath.exist?
|
175
|
+
FileUtils.rm_rf(outputFrameworkPath.to_path)
|
176
|
+
end
|
177
|
+
Rake::sh "cp -rvf #{deviceFramework} #{outputFramework}"
|
178
|
+
Rake::sh "cp #{name}/.hivemodules #{outputFramework}/"
|
179
|
+
headersPath = Pathname.new("#{outputFramework}/Headers/")
|
180
|
+
if not headersPath.exist?
|
181
|
+
headersPath.mkdir
|
182
|
+
end
|
183
|
+
if Pathname("#{name}/Pods/Headers/Public").exist?
|
184
|
+
shell = "find #{name}/Pods/Headers/Public -name \"*.h\" -exec cp {} #{outputFramework}/Headers/ \\;"
|
185
|
+
Rake::sh shell
|
186
|
+
end
|
187
|
+
willRmBuild = opts[:i_rm_build]
|
188
|
+
if willRmBuild != false
|
189
|
+
FileUtils.rm_rf("#{name}")
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
|
2
|
+
module QCloudHive
|
3
|
+
class GITURLDecoder
|
4
|
+
attr_reader :originURL
|
5
|
+
attr_reader :projectName
|
6
|
+
attr_reader :name
|
7
|
+
|
8
|
+
def initialize(originURL)
|
9
|
+
@originURL = originURL
|
10
|
+
if @originURL == nil
|
11
|
+
raise NameError("改地址为空!!!")
|
12
|
+
end
|
13
|
+
uri = URI(originURL)
|
14
|
+
uriPath = uri.path.split(".").first
|
15
|
+
if uriPath.start_with?("/")
|
16
|
+
uriPath= uriPath[1..uriPath.length]
|
17
|
+
end
|
18
|
+
name = uriPath.split("/").last
|
19
|
+
@projectName = uriPath
|
20
|
+
@name = name
|
21
|
+
end
|
22
|
+
def validate?()
|
23
|
+
if @originURL == nil
|
24
|
+
return false
|
25
|
+
end
|
26
|
+
if @name == nil
|
27
|
+
return false
|
28
|
+
end
|
29
|
+
if @projectName == nil
|
30
|
+
return false
|
31
|
+
end
|
32
|
+
return true
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
module Git
|
37
|
+
class Base
|
38
|
+
def clean?()
|
39
|
+
begin
|
40
|
+
if status.changed.count > 0
|
41
|
+
L.info("****************************")
|
42
|
+
L.info("changed #{status.changed}")
|
43
|
+
return false
|
44
|
+
end
|
45
|
+
if status.untracked.count >0
|
46
|
+
L.info("****************************")
|
47
|
+
L.info("untracked #{status.untracked}")
|
48
|
+
return false
|
49
|
+
end
|
50
|
+
|
51
|
+
if status.deleted.count > 0
|
52
|
+
L.info("****************************")
|
53
|
+
L.info("deleted #{status.deleted}")
|
54
|
+
return false
|
55
|
+
end
|
56
|
+
|
57
|
+
if status.added.count > 0
|
58
|
+
L.info("****************************")
|
59
|
+
L.info("added #{status.added}")
|
60
|
+
return false
|
61
|
+
end
|
62
|
+
rescue => err
|
63
|
+
puts "读取Git数据失败#{err}"
|
64
|
+
return false
|
65
|
+
end
|
66
|
+
return true
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
class Branch
|
71
|
+
def local?
|
72
|
+
full.start_with?("remotes") == false
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'gitlab'
|
2
|
+
require 'singleton'
|
3
|
+
require_relative "config.rb"
|
4
|
+
require_relative "utils.rb"
|
5
|
+
|
6
|
+
module QCloudHive
|
7
|
+
module CodeOA
|
8
|
+
def CodeOA.setup(token)
|
9
|
+
Gitlab.endpoint = "http://git.code.oa.com/api/v3"
|
10
|
+
Gitlab.private_token = token
|
11
|
+
end
|
12
|
+
def CodeOA.exist?(projectName)
|
13
|
+
project = existProjectByName?(projectName)
|
14
|
+
L.debug "project #{project}"
|
15
|
+
if project != nil
|
16
|
+
return true
|
17
|
+
else
|
18
|
+
return false
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def CodeOA.branch(project, name)
|
23
|
+
begin
|
24
|
+
Gitlab.branch(project, name)
|
25
|
+
rescue Gitlab::Error::NotFound
|
26
|
+
return nil
|
27
|
+
end
|
28
|
+
end
|
29
|
+
def CodeOA.existProjectByName?(projectName)
|
30
|
+
projects = Gitlab.project_search(projectName)
|
31
|
+
L.info "所有项目 #{projects.count}"
|
32
|
+
aimProjects = projects.select{ |p|
|
33
|
+
L.debug "#{projectName} #{p.name} #{p.namespace.path} #{Config.team}"
|
34
|
+
p.name == projectName && p.namespace.path == Config.team
|
35
|
+
}
|
36
|
+
if aimProjects.count > 0
|
37
|
+
return aimProjects.first
|
38
|
+
else
|
39
|
+
return nil
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def CodeOA.createProject(projectName)
|
44
|
+
project = CodeOA.existProjectByName?(projectName)
|
45
|
+
if project != nil
|
46
|
+
puts ("#{name}已经在CodeOA上存在,将不会在git.code.oa.com上再次新建改项目")
|
47
|
+
return project
|
48
|
+
else
|
49
|
+
Gitlab.create_project(projectName, {
|
50
|
+
:description => "#{projectName}的仓库",
|
51
|
+
:namespace_id => Config.namespaceID
|
52
|
+
})
|
53
|
+
CodeOA.existProjectByName?(projectName)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def CodeOA.branchs(project)
|
58
|
+
Gitlab.branches(project.id)
|
59
|
+
end
|
60
|
+
|
61
|
+
def CodeOA.empty?(project)
|
62
|
+
if Gitlab.branches(project.id).count == 0
|
63
|
+
true
|
64
|
+
else
|
65
|
+
false
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,346 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
require 'uri'
|
3
|
+
require_relative "config.rb"
|
4
|
+
|
5
|
+
module QCloudHive
|
6
|
+
class ManifestProject
|
7
|
+
attr_accessor :remote
|
8
|
+
attr_accessor :path
|
9
|
+
attr_accessor :name
|
10
|
+
attr_accessor :moduleName
|
11
|
+
def initialize(remote, name ,path)
|
12
|
+
@remote = remote
|
13
|
+
@name = name
|
14
|
+
@path = path
|
15
|
+
@moduleName = name.split("/").last
|
16
|
+
#private values
|
17
|
+
@serverProject = nil
|
18
|
+
@podspec = nil
|
19
|
+
@git = nil
|
20
|
+
@podStorageSpec = nil
|
21
|
+
@localPath
|
22
|
+
end
|
23
|
+
def localPath
|
24
|
+
if @localPath == nil
|
25
|
+
root = Pathname(Config.projectRootDirectory)
|
26
|
+
@localPath = root.join(self.path).to_path
|
27
|
+
end
|
28
|
+
@localPath
|
29
|
+
end
|
30
|
+
def serverProject
|
31
|
+
if @serverProject.nil?
|
32
|
+
@serverProject = CodeOA.existProjectByName?(moduleName)
|
33
|
+
end
|
34
|
+
@serverProject
|
35
|
+
end
|
36
|
+
def podStorageSpec
|
37
|
+
if @podStorageSpec.nil?
|
38
|
+
L.info("search module #{moduleName}")
|
39
|
+
@podStorageSpec = HivePod.search(moduleName)
|
40
|
+
|
41
|
+
end
|
42
|
+
@podStorageSpec
|
43
|
+
end
|
44
|
+
def podspec
|
45
|
+
if @podspec.nil?
|
46
|
+
HivePod.podspecs.each { |pspec|
|
47
|
+
if pspec.name == self.moduleName
|
48
|
+
@podspec = pspec.podspec
|
49
|
+
end
|
50
|
+
}
|
51
|
+
if @podspec.nil?
|
52
|
+
@podspec = self.podStorageSpec
|
53
|
+
end
|
54
|
+
end
|
55
|
+
@podspec
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
def gitRepo
|
60
|
+
if @git.nil?
|
61
|
+
root = Pathname(Config.projectRootDirectory)
|
62
|
+
gitPath = root.join(self.path)
|
63
|
+
begin
|
64
|
+
@git = Git.open(gitPath)
|
65
|
+
rescue => err
|
66
|
+
puts "创建Git工程失败 #{gitPath} #{err}"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
@git
|
70
|
+
end
|
71
|
+
def exsitLocal?
|
72
|
+
return self.gitRepo.nil? == false
|
73
|
+
end
|
74
|
+
def exsitPodRepo?
|
75
|
+
return self.podStorageSpec.nil? == false
|
76
|
+
end
|
77
|
+
def exsitServer?
|
78
|
+
return self.serverProject.nil? == false
|
79
|
+
end
|
80
|
+
|
81
|
+
def needReleasePod?
|
82
|
+
if exsitLocal?
|
83
|
+
return false
|
84
|
+
end
|
85
|
+
version = self.podspec.version.first
|
86
|
+
tag = gitRepo.tags.select { |e| e.name == version.to_s }.first
|
87
|
+
if tag.nil?
|
88
|
+
return true
|
89
|
+
end
|
90
|
+
master = gitRepo.branches["master"]
|
91
|
+
if tag.sha != master.gcommit.sha
|
92
|
+
return true
|
93
|
+
end
|
94
|
+
return false
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
class ProjectFeature
|
99
|
+
def initialize(project, branch)
|
100
|
+
@project = project
|
101
|
+
@branch = branch
|
102
|
+
#
|
103
|
+
@remoteBranch = nil
|
104
|
+
end
|
105
|
+
def remoteBranch
|
106
|
+
if @remoteBranch.nil?
|
107
|
+
@remoteBranch = CodeOA.branch(@project.serverProject.id, @branch.name)
|
108
|
+
end
|
109
|
+
@remoteBranch
|
110
|
+
end
|
111
|
+
|
112
|
+
def local?
|
113
|
+
if @branch.nil?
|
114
|
+
return false
|
115
|
+
end
|
116
|
+
localBranch.local?
|
117
|
+
end
|
118
|
+
|
119
|
+
def compareRemote
|
120
|
+
localSha = @branch.gcommit.sha
|
121
|
+
localDate = DateTime.parse(@branch.gcommit.committer_date.to_s)
|
122
|
+
remtoeDate = DateTime.parse(self.remoteBranch.commit.committed_date)
|
123
|
+
if self.remoteBranch.commit.id != localSha
|
124
|
+
return localDate <=> remtoeDate
|
125
|
+
end
|
126
|
+
return 0
|
127
|
+
end
|
128
|
+
|
129
|
+
def compareMaster
|
130
|
+
if @branch.name == "master"
|
131
|
+
return 0
|
132
|
+
end
|
133
|
+
master = @project.gitRepo.branches["master"]
|
134
|
+
localDate = DateTime.parse(@branch.gcommit.committer_date.to_s)
|
135
|
+
masterLocalDate = master.gcommit.committer_date
|
136
|
+
masterDate = DateTime.parse(masterLocalDate.to_s)
|
137
|
+
localDate <=> masterDate
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
class ManifestRemote
|
142
|
+
attr_accessor :name
|
143
|
+
attr_accessor :fetch
|
144
|
+
|
145
|
+
def initialize(name, fetch)
|
146
|
+
@name = name
|
147
|
+
@fetch = fetch
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
class ManifestDefault
|
152
|
+
attr_accessor :revision
|
153
|
+
attr_accessor :remote
|
154
|
+
attr_accessor :sync_j
|
155
|
+
def initialize
|
156
|
+
@revision = "master"
|
157
|
+
@remote = "origin"
|
158
|
+
@sync_j = "16"
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
class Manifest
|
163
|
+
attr_accessor :projects
|
164
|
+
attr_accessor :remotes
|
165
|
+
attr_accessor :default
|
166
|
+
|
167
|
+
def initialize(filePath)
|
168
|
+
@manifestPath = filePath
|
169
|
+
@doc = Nokogiri::XML(File.open(filePath))
|
170
|
+
@default = ManifestDefault.new
|
171
|
+
@projects = []
|
172
|
+
@doc.xpath("//project").each { |p|
|
173
|
+
remote = p.attribute("remote").value
|
174
|
+
name = p.attribute("name").value
|
175
|
+
if name.start_with?("/")
|
176
|
+
name= name[1..name.length]
|
177
|
+
end
|
178
|
+
path = p.attribute("path").value
|
179
|
+
project = ManifestProject.new(remote, name, path)
|
180
|
+
@projects << project
|
181
|
+
L.debug project
|
182
|
+
}
|
183
|
+
|
184
|
+
@remotes = []
|
185
|
+
@doc.xpath("//remote").each { |r|
|
186
|
+
name = r.attribute("name").value
|
187
|
+
fetch = r.attribute("fetch").value
|
188
|
+
if not fetch.end_with?("/")
|
189
|
+
fetch = fetch+"/"
|
190
|
+
end
|
191
|
+
remote = ManifestRemote.new(name, fetch)
|
192
|
+
@remotes << remote
|
193
|
+
}
|
194
|
+
end
|
195
|
+
|
196
|
+
def addModule(url, path)
|
197
|
+
uri = URI(url)
|
198
|
+
host = uri.host
|
199
|
+
scheme = uri.scheme
|
200
|
+
remote = nil
|
201
|
+
uriPath = uri.path.split(".").first
|
202
|
+
if uriPath.start_with?("/")
|
203
|
+
uriPath= uriPath[1..uriPath.length]
|
204
|
+
end
|
205
|
+
name = uriPath.split("/").last
|
206
|
+
@projects.each { |p|
|
207
|
+
if p.name == uriPath
|
208
|
+
return @projects
|
209
|
+
end
|
210
|
+
}
|
211
|
+
@remotes.each { |r|
|
212
|
+
rfetch = URI(r.fetch)
|
213
|
+
if rfetch.host == host and rfetch.scheme == scheme
|
214
|
+
remote = r.name
|
215
|
+
end
|
216
|
+
}
|
217
|
+
projectPath = "#{name}"
|
218
|
+
if path != nil
|
219
|
+
if path.start_with?("/")
|
220
|
+
path = path[1..-1]
|
221
|
+
end
|
222
|
+
if path.end_with?("/")
|
223
|
+
projectPath = "#{path}#{name}"
|
224
|
+
else
|
225
|
+
if path.length > 0
|
226
|
+
projectPath = "#{path}/#{name}"
|
227
|
+
else
|
228
|
+
projectPath = "#{name}"
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
232
|
+
remote = ManifestProject.new(remote, uriPath ,projectPath)
|
233
|
+
@projects << remote
|
234
|
+
end
|
235
|
+
|
236
|
+
def existModule?(name)
|
237
|
+
@projects.select{ |p|
|
238
|
+
if p.name.start_with?(Config.team)
|
239
|
+
p.name == Config.team+"/#{name}"
|
240
|
+
else
|
241
|
+
p.name == name
|
242
|
+
end
|
243
|
+
}.count > 0
|
244
|
+
end
|
245
|
+
|
246
|
+
def moduleByName(name)
|
247
|
+
@projects.each { |p|
|
248
|
+
L.info p.name
|
249
|
+
}
|
250
|
+
@projects.select{ |p|
|
251
|
+
if p.name.start_with?(Config.team)
|
252
|
+
p.name == Config.team+"/#{name}"
|
253
|
+
else
|
254
|
+
p.name == name
|
255
|
+
end
|
256
|
+
}.first
|
257
|
+
end
|
258
|
+
|
259
|
+
def deleteModule(url)
|
260
|
+
uri = URI(url)
|
261
|
+
uriPath = uri.path.split(".").first
|
262
|
+
if uriPath.start_with?("/")
|
263
|
+
uriPath= uriPath[1..uriPath.length]
|
264
|
+
end
|
265
|
+
L.debug "#{@projects}"
|
266
|
+
@projects=@projects.select{ |e|
|
267
|
+
e.name != uriPath
|
268
|
+
}
|
269
|
+
L.debug "#{@projects}"
|
270
|
+
end
|
271
|
+
|
272
|
+
def deleteModuleByName(name)
|
273
|
+
L.debug "#{@projects}"
|
274
|
+
@projects=@projects.select{ |e|
|
275
|
+
e.moduleName != name
|
276
|
+
}
|
277
|
+
L.debug "#{@projects}"
|
278
|
+
end
|
279
|
+
|
280
|
+
def toXML
|
281
|
+
doc = Nokogiri::XML('''<?xml version="1.0" encoding="UTF-8"?><manifest></manifest>''')
|
282
|
+
manifest = doc.xpath("//manifest").first
|
283
|
+
|
284
|
+
@remotes.each { |r|
|
285
|
+
ele = Nokogiri::XML::Element.new("remote", doc)
|
286
|
+
ele.set_attribute("name", r.name)
|
287
|
+
ele.set_attribute("fetch", r.fetch)
|
288
|
+
manifest.add_child(ele)
|
289
|
+
}
|
290
|
+
|
291
|
+
default = Nokogiri::XML::Element.new("default", doc)
|
292
|
+
default.set_attribute("revision", @default.revision)
|
293
|
+
default.set_attribute("remote", @default.remote)
|
294
|
+
default.set_attribute("sync-j", @default.sync_j)
|
295
|
+
manifest.add_child(default)
|
296
|
+
|
297
|
+
@projects.each { |r|
|
298
|
+
ele =Nokogiri::XML::Element.new("project", doc)
|
299
|
+
ele.set_attribute("name",r.name)
|
300
|
+
ele.set_attribute("remote" ,r.remote )
|
301
|
+
ele.set_attribute("path" ,r.path)
|
302
|
+
manifest.add_child(ele)
|
303
|
+
}
|
304
|
+
return doc.to_s
|
305
|
+
end
|
306
|
+
|
307
|
+
def flushStorage
|
308
|
+
File.open(@manifestPath, "w") { |f|
|
309
|
+
f.write toXML
|
310
|
+
}
|
311
|
+
end
|
312
|
+
def remoteByName(name)
|
313
|
+
@remotes.select { |e| e.name == name }.first
|
314
|
+
end
|
315
|
+
def sourceURLByModuleName(name)
|
316
|
+
L.debug "#{@projects}"
|
317
|
+
moduleSpec = @projects.select{ |e|
|
318
|
+
e.moduleName != name
|
319
|
+
}.first
|
320
|
+
if moduleSpec.nil?
|
321
|
+
return nil
|
322
|
+
end
|
323
|
+
remote = remoteByName(moduleSpec.remote)
|
324
|
+
return "#{remote.fetch}#{moduleSpec.name}"
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
328
|
+
|
329
|
+
|
330
|
+
def QCloudHive.syncManifest
|
331
|
+
repoRootPath = Config.repoRoot
|
332
|
+
manifestsPath=repoRootPath+"./manifests/"
|
333
|
+
cmd = ""
|
334
|
+
cmd = addCMD(cmd,"cd #{manifestsPath}")
|
335
|
+
cmd = addCMD(cmd, "git add .")
|
336
|
+
cmd = addCMD(cmd, "git commit -m \"Project Edited\"")
|
337
|
+
cmd = addCMD(cmd, "git checkout default")
|
338
|
+
cmd = addCMD(cmd, "git push origin HEAD:default")
|
339
|
+
cmd = addCMD(cmd, "git checkout master")
|
340
|
+
cmd = addCMD(cmd, "git merge default")
|
341
|
+
cmd = addCMD(cmd, "git push origin HEAD:master")
|
342
|
+
cmd = addCMD(cmd, "git checkout default")
|
343
|
+
L.debug cmd
|
344
|
+
Rake::sh cmd
|
345
|
+
end
|
346
|
+
end
|