big_keeper 0.1.0

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.
Files changed (47) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +50 -0
  3. data/Gemfile +6 -0
  4. data/Gemfile.lock +106 -0
  5. data/LICENSE.txt +21 -0
  6. data/README.md +41 -0
  7. data/Rakefile +2 -0
  8. data/big_keeper.gemspec +40 -0
  9. data/bin/big-keeper +14 -0
  10. data/bin/setup +8 -0
  11. data/docs/en-US/FEATURE.md +0 -0
  12. data/docs/zh-CN/BIGKEEPER_FILE.md +62 -0
  13. data/docs/zh-CN/FEATURE.md +88 -0
  14. data/docs/zh-CN/README.md +76 -0
  15. data/lib/big_keeper/command/feature_finish.rb +47 -0
  16. data/lib/big_keeper/command/feature_pull.rb +23 -0
  17. data/lib/big_keeper/command/feature_push.rb +39 -0
  18. data/lib/big_keeper/command/feature_start.rb +60 -0
  19. data/lib/big_keeper/command/feature_switch.rb +43 -0
  20. data/lib/big_keeper/command/feature_update.rb +60 -0
  21. data/lib/big_keeper/command/hotfix_start.rb +0 -0
  22. data/lib/big_keeper/command/podfile_lock.rb +16 -0
  23. data/lib/big_keeper/command/release_home.rb +51 -0
  24. data/lib/big_keeper/command/release_module.rb +27 -0
  25. data/lib/big_keeper/command/start_module_release.sh +44 -0
  26. data/lib/big_keeper/model/gitflow_type.rb +19 -0
  27. data/lib/big_keeper/model/operate_type.rb +19 -0
  28. data/lib/big_keeper/model/podfile_type.rb +44 -0
  29. data/lib/big_keeper/service/git_service.rb +75 -0
  30. data/lib/big_keeper/service/module_service.rb +90 -0
  31. data/lib/big_keeper/service/stash_service.rb +42 -0
  32. data/lib/big_keeper/util/bigkeeper_parser.rb +167 -0
  33. data/lib/big_keeper/util/git_operator.rb +95 -0
  34. data/lib/big_keeper/util/gitflow_operator.rb +40 -0
  35. data/lib/big_keeper/util/info_plist_operator.rb +46 -0
  36. data/lib/big_keeper/util/podfile_detector.rb +140 -0
  37. data/lib/big_keeper/util/podfile_operator.rb +111 -0
  38. data/lib/big_keeper/version.rb +3 -0
  39. data/lib/big_keeper.rb +151 -0
  40. data/resources/readme/big-keeper-readme.001.png +0 -0
  41. data/resources/readme/big-keeper-readme.002.png +0 -0
  42. data/resources/readme/big-keeper-readme.003.png +0 -0
  43. data/resources/readme/big-keeper-readme.004.png +0 -0
  44. data/resources/readme/big-keeper-readme.005.png +0 -0
  45. data/resources/readme/big-keeper-readme.006.png +0 -0
  46. data/resources/readme/big-keeper-readme.007.png +0 -0
  47. metadata +191 -0
@@ -0,0 +1,167 @@
1
+ # Bigkeeper module
2
+ module BigKeeper
3
+ def self.version(name)
4
+ BigkeeperParser.parse_version(name)
5
+ end
6
+
7
+ def self.user(name)
8
+ BigkeeperParser.parse_user(name)
9
+ yield if block_given?
10
+ end
11
+
12
+ def self.home(name, params)
13
+ BigkeeperParser.parse_home(name, params)
14
+ end
15
+
16
+ def self.pod(name, params)
17
+ BigkeeperParser.parse_pod(name, params)
18
+ end
19
+
20
+ def self.modules
21
+ BigkeeperParser.parse_modules
22
+ yield if block_given?
23
+ end
24
+
25
+ # Bigkeeper file parser
26
+ class BigkeeperParser
27
+ @@config = {}
28
+ @@current_user = ''
29
+
30
+ def self.parse(bigkeeper)
31
+ if @@config.empty?
32
+ content = File.read bigkeeper
33
+
34
+ content.gsub!(/version\s/, 'BigKeeper::version ')
35
+ content.gsub!(/user\s/, 'BigKeeper::user ')
36
+ content.gsub!(/home\s/, 'BigKeeper::home ')
37
+ content.gsub!(/pod\s/, 'BigKeeper::pod ')
38
+ content.gsub!(/modules\s/, 'BigKeeper::modules ')
39
+ eval content
40
+ # p @@config
41
+ end
42
+ end
43
+
44
+ def self.parse_version(name)
45
+ @@config[:version] = name
46
+ end
47
+
48
+ def self.parse_user(name)
49
+ @@current_user = name
50
+ users = @@config[:users]
51
+ users = {} if users.nil?
52
+ users[name] = {}
53
+ @@config[:users] = users
54
+ end
55
+
56
+ def self.parse_home(name, params)
57
+ @@config[:home] = params
58
+ @@config[:name] = name
59
+ end
60
+
61
+ def self.parse_pod(name, params)
62
+ if params[:path]
63
+ parse_user_pod(name, params)
64
+ elsif params[:git]
65
+ parse_modules_pod(name, params)
66
+ else
67
+ raise %(There should be ':path =>' or ':git =>' for pod #{name})
68
+ end
69
+ end
70
+
71
+ def self.parse_user_pod(name, params)
72
+ users = @@config[:users]
73
+ user = users[@@current_user]
74
+ pods = user[:pods]
75
+ pods = {} if pods.nil?
76
+ pods[name] = params
77
+ user[:pods] = pods
78
+ @@config[:users] = users
79
+ end
80
+
81
+ def self.parse_modules_pod(name, params)
82
+ modules = @@config[:modules]
83
+ modules[name] = params
84
+ @@config[:modules] = modules
85
+ end
86
+
87
+ def self.parse_modules
88
+ modules = @@config[:modules]
89
+ modules = {} if modules.nil?
90
+ @@config[:modules] = modules
91
+ end
92
+
93
+ def self.version
94
+ @@config[:version]
95
+ end
96
+
97
+ def self.home_name
98
+ @@config[:name]
99
+ end
100
+
101
+ def self.home_git()
102
+ @@config[:home][:git]
103
+ end
104
+
105
+ def self.home_pulls()
106
+ @@config[:home][:pulls]
107
+ end
108
+
109
+ def self.module_full_path(home_path, user_name, module_name)
110
+ if @@config[:users] \
111
+ && @@config[:users][user_name] \
112
+ && @@config[:users][user_name][:pods] \
113
+ && @@config[:users][user_name][:pods][module_name] \
114
+ && @@config[:users][user_name][:pods][module_name][:path]
115
+ @@config[:users][user_name][:pods][module_name][:path]
116
+ else
117
+ File.expand_path("#{home_path}/../#{module_name}")
118
+ end
119
+ end
120
+
121
+ def self.module_path(user_name, module_name)
122
+ if @@config[:users] \
123
+ && @@config[:users][user_name] \
124
+ && @@config[:users][user_name][:pods] \
125
+ && @@config[:users][user_name][:pods][module_name] \
126
+ && @@config[:users][user_name][:pods][module_name][:path]
127
+ @@config[:users][user_name][:pods][module_name][:path]
128
+ else
129
+ "../#{module_name}"
130
+ end
131
+ end
132
+
133
+ def self.module_git(module_name)
134
+ @@config[:modules][module_name][:git]
135
+ end
136
+
137
+ def self.module_pulls(module_name)
138
+ @@config[:modules][module_name][:pulls]
139
+ end
140
+
141
+ def self.verify_modules(modules)
142
+ modules.each do |item|
143
+ raise "Can not find module #{item} in Bigkeeper file" unless @@config[:modules][item]
144
+ end
145
+ end
146
+
147
+ def self.module_names
148
+ @@config[:modules].keys
149
+ end
150
+
151
+ def self.config
152
+ @@config
153
+ end
154
+ end
155
+
156
+ # BigkeeperParser.parse('/Users/mmoaay/Documents/eleme/BigKeeperMain/Bigkeeper')
157
+ # BigkeeperParser.parse('/Users/mmoaay/Documents/eleme/BigKeeperMain/Bigkeeper')
158
+ #
159
+ # p BigkeeperParser.home_git()
160
+ # p BigkeeperParser.home_pulls()
161
+ # p BigkeeperParser.module_path('perry', 'BigKeeperModular')
162
+ # p BigkeeperParser.module_path('', 'BigKeeperModular')
163
+ # p BigkeeperParser.module_git('BigKeeperModular')
164
+ # pulls = BigkeeperParser.module_pulls('BigKeeperModular')
165
+ # `open #{pulls}`
166
+ # p BigkeeperParser.module_names
167
+ end
@@ -0,0 +1,95 @@
1
+ module BigKeeper
2
+ # Operator for got
3
+ class GitOperator
4
+ def current_branch(path)
5
+ Dir.chdir(path) do
6
+ `git rev-parse --abbrev-ref HEAD`.chop
7
+ end
8
+ end
9
+
10
+ def has_branch(path, branch_name)
11
+ has_branch = false
12
+ IO.popen("cd #{path}; git branch -a") do |io|
13
+ io.each do |line|
14
+ has_branch = true if line.include? branch_name
15
+ end
16
+ end
17
+ has_branch
18
+ end
19
+
20
+ def git_checkout(path, branch_name)
21
+ Dir.chdir(path) do
22
+ `git checkout #{branch_name}`
23
+ end
24
+ end
25
+
26
+ def git_fetch(path)
27
+ Dir.chdir(path) do
28
+ `git fetch origin`
29
+ end
30
+ end
31
+
32
+ def git_rebase(path, branch_name)
33
+ Dir.chdir(path) do
34
+ `git rebase origin/#{branch_name}`
35
+ end
36
+ end
37
+
38
+ def clone(path, git_base)
39
+ Dir.chdir(path) do
40
+ `git clone #{git_base}`
41
+ end
42
+ end
43
+
44
+ def commit(path, message)
45
+ Dir.chdir(path) do
46
+ `git add .`
47
+ `git commit -m "#{message}"`
48
+ end
49
+ end
50
+
51
+ def push(path, branch_name)
52
+ Dir.chdir(path) do
53
+ p `git push origin #{branch_name}`
54
+ end
55
+ end
56
+
57
+ def pull(path, branch_name)
58
+ Dir.chdir(path) do
59
+ p `git pull origin #{branch_name}`
60
+ end
61
+ end
62
+
63
+ def has_changes(path)
64
+ has_changes = true
65
+ clear_flag = 'nothing to commit, working tree clean'
66
+ IO.popen("cd #{path}; git status") do |io|
67
+ io.each do |line|
68
+ has_changes = false if line.include? clear_flag
69
+ end
70
+ end
71
+ has_changes
72
+ end
73
+
74
+ def del(path, branch_name)
75
+ Dir.chdir(path) do
76
+ p `git branch -D #{branch_name}`
77
+ p `git push origin --delete #{branch_name}`
78
+ end
79
+ end
80
+
81
+ def user
82
+ `git config user.name`.chop
83
+ end
84
+
85
+ def tag(path, version)
86
+ Dir.chdir(path) do
87
+ p `git tag -a #{version} -m "release: V #{version}" master`
88
+ p `git push --tags`
89
+ end
90
+ end
91
+ end
92
+
93
+ # p GitOperator.new.user
94
+ # BigStash::StashOperator.new("/Users/mmoaay/Documents/eleme/BigKeeperMain").list
95
+ end
@@ -0,0 +1,40 @@
1
+ require 'big_keeper/model/gitflow_type'
2
+
3
+ module BigKeeper
4
+ # Operator for gitflow
5
+ class GitflowOperator
6
+ def start(path, name, type)
7
+ init_git_flow(path)
8
+ Dir.chdir(path) do
9
+ gitflow_type_name = GitflowType.name(type)
10
+ p `git flow #{gitflow_type_name} start #{name}`
11
+ end
12
+ end
13
+
14
+ def init_git_flow(path)
15
+ Dir.chdir(path) do
16
+ clear_flag = 'Already initialized for gitflow'
17
+ IO.popen('git flow init -d') do |io|
18
+ io.each do |line|
19
+ unless line.include? clear_flag
20
+ `git push origin master`
21
+ `git push origin develop`
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ def finish_release(path, release_name)
29
+ Dir.chdir(path) do
30
+ p `git checkout master`
31
+ p `git merge release/#{release_name}`
32
+ p `git push`
33
+ p `git checkout develop`
34
+ p `git merge release/#{release_name}`
35
+ p `git push`
36
+ p `git branch -d release/#{release_name}`
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/ruby
2
+ require 'plist' # gem install plist
3
+ require 'big_stash/stash_operator'
4
+ require 'pathname'
5
+
6
+ module BigKeeper
7
+ # Operator for Info.plist
8
+ class InfoPlistOperator
9
+ def change_version_build(path, version)
10
+ if find_infoPlist_filePath(path) == ''
11
+ raise %(Not find be Info.plist at #{path})
12
+ end
13
+ info_plist_path = find_infoPlist_filePath(path)
14
+ result = Plist.parse_xml(info_plist_path)
15
+ result['CFBundleShortVersionString'] = version.to_s
16
+ result['CFBundleVersion'] = getBuildVersion(version, result['CFBundleShortVersionString'], result['CFBundleVersion'])
17
+ Plist::Emit.save_plist(result, info_plist_path)
18
+ puts %Q('Version has changed to #{version}')
19
+ end
20
+
21
+ # Find Info.plist file path
22
+ # @return [String] pathName of info.plist
23
+ def find_infoPlist_filePath(path)
24
+ paths = Pathname.new(path).children.select { |pn| pn.extname == '.xcodeproj' }
25
+ xcodePath = paths[0].to_s.split('/')[-1]
26
+ projectName = xcodePath.split('.')[0]
27
+ projectPath = ''
28
+ Pathname.new("#{path}/#{projectName}").children.select { |pn|
29
+ if pn.to_s == "#{path}/#{projectName}/Info.plist"
30
+ projectPath = "#{path}/#{projectName}/Info.plist"
31
+ end
32
+ }
33
+ projectPath
34
+ end
35
+
36
+ private
37
+ def getBuildVersion(build_string, old_build_string, old_build_version)
38
+ if build_string == old_build_string
39
+ return old_build_version.to_i + 1
40
+ else
41
+ version_arr = build_string.split('.')
42
+ return version_arr[0].to_i * 1000 + version_arr[1].to_i * 100 + version_arr[2].to_i * 10
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,140 @@
1
+ require '../util/param_parser'
2
+
3
+ params = BigKeeper::ParamParser.new.detect_podfile_unlock_items
4
+ main_path = File.expand_path(params[:main_path])
5
+
6
+ $modular_name_list = ["ELMKnightCollegeModule","LPDFoundationKit",
7
+ "LPDIntelligentDispatchModular","LPDUserRelevanceModular",
8
+ "LPDFeedbackModular","LPDQualityControlKit","LPDWalletModular",
9
+ "LPDRiderClassificationModular","LPDTransferOrderModular",
10
+ "LPDActivityModular","LPDPOIAddressService"]
11
+
12
+ class PodfileDetector
13
+
14
+ $unlock_pod_list = []
15
+ $modify_pod_list = {}
16
+ def get_unlock_pod_list(main_path)
17
+ podfile_lines = File.readlines("#{main_path}/Podfile")
18
+ p 'Analyzing Podfile...' unless podfile_lines.size.zero?
19
+ podfile_lines.collect do |sentence|
20
+ deal_podfile_line(sentence) unless sentence =~(/\'\d+.\d+.\d+'/)
21
+ end
22
+ p $unlock_pod_list
23
+ $modify_pod_list = deal_lock_file(main_path,$unlock_pod_list)
24
+ p $modify_pod_list
25
+ end
26
+
27
+ def deal_podfile_line(sentence)
28
+ if sentence.include?('pod ')
29
+ pod_model = Podfile_Modle.new(sentence)
30
+ # p pod_model
31
+ if !pod_model.name.empty? && pod_model.configurations != '[\'Debug\']' && pod_model.path == nil && pod_model.tag == nil
32
+ $unlock_pod_list << pod_model.name unless $modular_name_list.include?(pod_model.name)
33
+ end
34
+ return pod_model
35
+ end
36
+ end
37
+
38
+ def get_pod_name(sentence)
39
+ # match_data = /\'\w*\'/.match(sentence)
40
+ # pod_name = match_data.to_a[0].delete('\'')
41
+ pod_model = deal_podfile_line(sentence)
42
+ pod_name = pod_model.name if pod_model != nil && pod_model.configurations.nil
43
+ # puts pod_name
44
+ $unlock_pod_list << pod_name unless modular_name_list.include pod_name
45
+ end
46
+
47
+ def deal_lock_file(main_path,deal_list)
48
+ $result = {}
49
+ podfile_lock_lines = File.readlines("#{main_path}/Podfile.lock")
50
+ p 'Analyzing Podfile.lock...' unless podfile_lock_lines.size.zero?
51
+ podfile_lock_lines.select do |sentence|
52
+
53
+ if sentence.include?('DEPENDENCIES') #指定范围解析 Dependencies 之前
54
+ break
55
+ end
56
+
57
+ temp_sentence = sentence.strip
58
+ pod_name = get_lock_podname(temp_sentence)
59
+ # p pod_name
60
+ if deal_list.include?(pod_name)
61
+ current_version = $result[pod_name]
62
+ temp_version = get_lock_version(temp_sentence)
63
+ if temp_version != nil
64
+ if current_version != nil
65
+ # p "cur_version #{current_version} temp_version #{temp_version}"
66
+ $result[pod_name] = chose_version(current_version,temp_version)
67
+ else
68
+ $result[pod_name] = temp_version
69
+ end
70
+ end
71
+ end
72
+ end
73
+ return $result
74
+ end
75
+
76
+ def get_lock_podname(sentence) #获得pod名称
77
+ # p sentence.delete('- :~>=')
78
+ match_result = /(\d+.\d+.\d+)|(\d+.\d+)/.match(sentence.delete('- :~>='))
79
+ pod_name = match_result.pre_match unless match_result == nil
80
+ return pod_name.delete('(') unless pod_name == nil
81
+ end
82
+
83
+ def get_lock_version(sentence)#获得pod版本号
84
+ sentence.scan(/\d+.\d+.\d+/) do |version|
85
+ return version
86
+ end
87
+ return nil
88
+ end
89
+
90
+ def chose_version(cur_version,temp_version)
91
+ cur_list = cur_version.split('.')
92
+ temp_list = temp_version.split('.')
93
+ temp_list << 0.to_s if temp_list.size == 2
94
+ if cur_list[0] >= temp_list[0]
95
+ if cur_list[1] >= temp_list[1]
96
+ if cur_list[2] > temp_list[2]
97
+ return cur_version
98
+ end
99
+ return temp_version
100
+ end
101
+ return temp_version
102
+ end
103
+ return temp_version
104
+ end
105
+
106
+ end
107
+
108
+ class Podfile_Modle
109
+ attr_accessor :name,:git,:path,:configurations,:branch,:tag,:comment
110
+ def initialize(sentence)
111
+ if sentence.include?('#')
112
+ list = sentence.split('#')
113
+ @comment = list[1]
114
+ sentence = list[0]
115
+ end
116
+
117
+ sentence_slip_list = sentence.split(',')
118
+ return if sentence_slip_list.size.zero?
119
+ for piece in sentence_slip_list do
120
+ if /:git =>/ =~ piece
121
+ @git = $~.post_match.strip
122
+ elsif /:path =>/ =~ piece
123
+ @path = $~.post_match.strip
124
+ elsif /:configurations =>/ =~ piece
125
+ @configurations = $~.post_match.strip
126
+ elsif /:branch =>/ =~ piece
127
+ @branch = $~.post_match.strip
128
+ elsif /:tag =>/ =~ piece
129
+ @tag = $~.post_match.strip
130
+ elsif /pod /=~ piece
131
+ @name = $~.post_match.delete("'\n ")
132
+ end
133
+ # p %Q{model name:#{@name},git:#{@git},path:#{@path},config:#{@configurations},branch:#{@branch},tag:#{@tag},comment:#{@comment}}
134
+ end
135
+ end
136
+ end
137
+
138
+ # p params
139
+ # p main_path
140
+ PodfileDetector.new.get_unlock_pod_list(main_path)
@@ -0,0 +1,111 @@
1
+ require 'tempfile'
2
+ require 'fileutils'
3
+ require 'big_keeper/model/podfile_type'
4
+
5
+ module BigKeeper
6
+ # Operator for podfile
7
+ class PodfileOperator
8
+ def has(podfile, module_name)
9
+ File.open(podfile, 'r') do |file|
10
+ file.each_line do |line|
11
+ if line.include?module_name
12
+ return true
13
+ end
14
+ end
15
+ end
16
+ false
17
+ end
18
+
19
+ def modules_with_type(podfile, modules, type)
20
+ matched_modules = []
21
+ File.open(podfile, 'r') do |file|
22
+ file.each_line do |line|
23
+ modules.each do |module_name|
24
+ if line =~ /pod\s*'#{module_name}',#{ModuleType.regex(type)}/
25
+ matched_modules << module_name
26
+ break
27
+ end
28
+ end
29
+ end
30
+ end
31
+ matched_modules
32
+ end
33
+
34
+ def find_and_replace(podfile, module_name, module_type, source)
35
+ temp_file = Tempfile.new('.Podfile.tmp')
36
+
37
+ begin
38
+ File.open(podfile, 'r') do |file|
39
+ file.each_line do |line|
40
+ if line.include?module_name
41
+ temp_file.puts generate_module_config(module_name, module_type, source)
42
+ else
43
+ temp_file.puts line
44
+ end
45
+ end
46
+ end
47
+ temp_file.close
48
+ FileUtils.mv(temp_file.path, podfile)
49
+ ensure
50
+ temp_file.close
51
+ temp_file.unlink
52
+ end
53
+ end
54
+
55
+ def generate_module_config(module_name, module_type, source)
56
+ module_config = ''
57
+ if ModuleType::PATH == module_type
58
+ module_config = %Q( pod #{module_name}, :path => '#{source}')
59
+ elsif ModuleType::GIT == module_type
60
+ # puts source.base
61
+ # puts source.addition
62
+ if GitType::BRANCH == source.type
63
+ module_config = %Q( pod '#{module_name}', :git => '#{source.base}', :branch => '#{source.addition}')
64
+ elsif GitType::TAG == source.type
65
+ module_config = %Q( pod '#{module_name}', :git => '#{source.base}', :tag => '#{source.addition}')
66
+ elsif GitType::COMMIT == source.type
67
+ module_config = %Q( pod '#{module_name}', :git => '#{source.base}', :commit => '#{source.addition}')
68
+ else
69
+ module_config = %Q( pod '#{module_name}', :git => '#{source.base}')
70
+ end
71
+ else
72
+ module_config = %Q( pod #{module_name}, '#{source}')
73
+ end
74
+ module_config
75
+ end
76
+
77
+ def replace_all_module_release(podfile, module_names, version, source)
78
+
79
+ module_names.each do |module_name|
80
+ PodfileOperator.new.find_and_replace(podfile,
81
+ module_name,
82
+ ModuleType::GIT,
83
+ source)
84
+ end
85
+
86
+
87
+
88
+ # temp_file = Tempfile.new('.Podfile.tmp')
89
+ # begin
90
+ # File.open(podfile, 'r') do |file|
91
+ # file.each_line do |line|
92
+ # module_names.each do |module_name|
93
+ # if line.include?module_name
94
+ # temp_file.puts generate_module_config(module_name, ModuleType::GIT, source)
95
+ # else
96
+ # # temp_file.puts line
97
+ # end
98
+ # end
99
+ # end
100
+ # end
101
+ # temp_file.close
102
+ # FileUtils.mv(temp_file.path, podfile)
103
+ # ensure
104
+ # temp_file.close
105
+ # temp_file.unlink
106
+ # end
107
+ end
108
+
109
+ private :generate_module_config
110
+ end
111
+ end
@@ -0,0 +1,3 @@
1
+ module BigKeeper
2
+ VERSION = "0.1.0"
3
+ end