qcloudhive 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +7 -0
  2. data/.idea/.rakeTasks +7 -0
  3. data/.idea/Hive.iml +54 -0
  4. data/.idea/dictionaries/dongzhao.xml +7 -0
  5. data/.idea/misc.xml +4 -0
  6. data/.idea/modules.xml +8 -0
  7. data/.idea/vcs.xml +6 -0
  8. data/.idea/workspace.xml +699 -0
  9. data/CODE_OF_CONDUCT.md +74 -0
  10. data/Documents/Images/93A5AC58-17D5-4D3F-B5A8-E509CF429BD0.png +0 -0
  11. data/Documents/Images/C702C824-11B1-47A8-BB15-9F6F14F2B649.png +0 -0
  12. data/Gem/qcloudhive/.idea/misc.xml +4 -0
  13. data/Gem/qcloudhive/.idea/modules.xml +8 -0
  14. data/Gem/qcloudhive/.idea/qcloudhive.iml +8 -0
  15. data/Gem/qcloudhive/.idea/workspace.xml +383 -0
  16. data/Gemfile +4 -0
  17. data/Gemfile.lock +122 -0
  18. data/LICENSE.txt +21 -0
  19. data/README.md +273 -0
  20. data/Rakefile +5 -0
  21. data/bin/console +14 -0
  22. data/bin/setup +8 -0
  23. data/exe/Hive +302 -0
  24. data/lib/qcloudhive.rb +16 -0
  25. data/lib/qcloudhive/config.rb +176 -0
  26. data/lib/qcloudhive/feature.rb +92 -0
  27. data/lib/qcloudhive/framework.rb +192 -0
  28. data/lib/qcloudhive/git_helper.rb +75 -0
  29. data/lib/qcloudhive/gitlab.rb +69 -0
  30. data/lib/qcloudhive/manifest.rb +346 -0
  31. data/lib/qcloudhive/module.rb +228 -0
  32. data/lib/qcloudhive/pod_helper.rb +119 -0
  33. data/lib/qcloudhive/product.rb +32 -0
  34. data/lib/qcloudhive/project.rb +108 -0
  35. data/lib/qcloudhive/repo.rb +177 -0
  36. data/lib/qcloudhive/spec_helper.rb +45 -0
  37. data/lib/qcloudhive/utils.rb +46 -0
  38. data/lib/qcloudhive/version.rb +3 -0
  39. data/lib/qcloudhive/xcodeproj.rb +163 -0
  40. data/qcloudhive.gemspec +43 -0
  41. data/resources/shellscriptes/HiveApp.sh +156 -0
  42. data/resources/shellscriptes/HiveFramework +158 -0
  43. data/resources/shellscriptes/build_framework.sh +76 -0
  44. data/resources/templates/AppDefaultTemplate/.gitignore +41 -0
  45. data/resources/templates/AppDefaultTemplate/AppDefaultTemplate.xcodeproj/project.pbxproj +290 -0
  46. data/resources/templates/AppDefaultTemplate/AppDefaultTemplate.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  47. data/resources/templates/AppDefaultTemplate/AppDefaultTemplate/Info.plist +24 -0
  48. data/resources/templates/AppDefaultTemplate/Podfile +9 -0
  49. data/resources/templates/HiveAppTemplate/.gitignore +41 -0
  50. data/resources/templates/HiveAppTemplate/HiveAppTemplate.xcodeproj/project.pbxproj +539 -0
  51. data/resources/templates/HiveAppTemplate/HiveAppTemplate.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  52. data/resources/templates/HiveAppTemplate/HiveAppTemplate/AppDelegate.h +17 -0
  53. data/resources/templates/HiveAppTemplate/HiveAppTemplate/AppDelegate.m +51 -0
  54. data/resources/templates/HiveAppTemplate/HiveAppTemplate/Assets.xcassets/AppIcon.appiconset/Contents.json +68 -0
  55. data/resources/templates/HiveAppTemplate/HiveAppTemplate/Base.lproj/LaunchScreen.storyboard +27 -0
  56. data/resources/templates/HiveAppTemplate/HiveAppTemplate/Base.lproj/Main.storyboard +26 -0
  57. data/resources/templates/HiveAppTemplate/HiveAppTemplate/Info.plist +45 -0
  58. data/resources/templates/HiveAppTemplate/HiveAppTemplate/ViewController.h +15 -0
  59. data/resources/templates/HiveAppTemplate/HiveAppTemplate/ViewController.m +29 -0
  60. data/resources/templates/HiveAppTemplate/HiveAppTemplate/main.m +16 -0
  61. data/resources/templates/HiveAppTemplate/HiveAppTemplateTests/HiveAppTemplateTests.m +39 -0
  62. data/resources/templates/HiveAppTemplate/HiveAppTemplateTests/Info.plist +22 -0
  63. data/resources/templates/HiveAppTemplate/HiveAppTemplateUITests/HiveAppTemplateUITests.m +40 -0
  64. data/resources/templates/HiveAppTemplate/HiveAppTemplateUITests/Info.plist +22 -0
  65. data/resources/templates/HiveAppTemplate/Podfile +20 -0
  66. data/resources/templates/commonConf.sh +9 -0
  67. data/resources/templates/manifests/build.rb +8 -0
  68. data/resources/templates/manifests/default.xml +12 -0
  69. data/resources/templates/template.podspec +37 -0
  70. 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