Class: Pixab::ComponentSynchronizer

Inherits:
Object
  • Object
show all
Defined in:
lib/projects/ComponentSynchronizer.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(repo_manager = RepoManager.new, commands = nil) ⇒ ComponentSynchronizer

Returns a new instance of ComponentSynchronizer.



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/projects/ComponentSynchronizer.rb', line 18

def initialize(repo_manager = RepoManager.new, commands = nil)
  @repo_manager = repo_manager
  @is_need_build = false
  @is_need_remote_repo = false
  @is_need_pod_install = false
  @is_use__target_branch = true
  @need_merge_origin = true
  @is_need_stash = false

  if commands.nil?
    return
  end
  commands.each_index do |index|
    command = commands[index]
    case command
    when "--build"
      @is_need_build = true
    when "--remote-repo"
      @is_need_remote_repo = true
    when "--no-pod-install"
      @is_need_pod_install = false
    when "--pod-install"
      @is_need_pod_install = true
    when "--current-branch"
      @is_use__target_branch = false
    when "--no-merge-origin"
      @need_merge_origin = false
    when "--stash"
      @is_need_stash = true
    else
    end
  end

end

Instance Attribute Details

#is_need_buildObject

Returns the value of attribute is_need_build.



15
16
17
# File 'lib/projects/ComponentSynchronizer.rb', line 15

def is_need_build
  @is_need_build
end

#is_need_pod_installObject

Returns the value of attribute is_need_pod_install.



15
16
17
# File 'lib/projects/ComponentSynchronizer.rb', line 15

def is_need_pod_install
  @is_need_pod_install
end

#is_need_remote_repoObject

Returns the value of attribute is_need_remote_repo.



15
16
17
# File 'lib/projects/ComponentSynchronizer.rb', line 15

def is_need_remote_repo
  @is_need_remote_repo
end

#is_need_stashObject

Returns the value of attribute is_need_stash.



15
16
17
# File 'lib/projects/ComponentSynchronizer.rb', line 15

def is_need_stash
  @is_need_stash
end

#is_use__target_branchObject

Returns the value of attribute is_use__target_branch.



15
16
17
# File 'lib/projects/ComponentSynchronizer.rb', line 15

def is_use__target_branch
  @is_use__target_branch
end

#main_repo_nameObject (readonly)

Returns the value of attribute main_repo_name.



16
17
18
# File 'lib/projects/ComponentSynchronizer.rb', line 16

def main_repo_name
  @main_repo_name
end

#need_merge_originObject

Returns the value of attribute need_merge_origin.



15
16
17
# File 'lib/projects/ComponentSynchronizer.rb', line 15

def need_merge_origin
  @need_merge_origin
end

#repo_managerObject (readonly)

Returns the value of attribute repo_manager.



16
17
18
# File 'lib/projects/ComponentSynchronizer.rb', line 16

def repo_manager
  @repo_manager
end

#reposObject (readonly)

Returns the value of attribute repos.



16
17
18
# File 'lib/projects/ComponentSynchronizer.rb', line 16

def repos
  @repos
end

#updated_repo_namesObject (readonly)

Returns the value of attribute updated_repo_names.



16
17
18
# File 'lib/projects/ComponentSynchronizer.rb', line 16

def updated_repo_names
  @updated_repo_names
end

Instance Method Details

#buildObject

编译



232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
# File 'lib/projects/ComponentSynchronizer.rb', line 232

def build
  workspace_name = nil
  expect_ext = ".xcworkspace"
  Dir.foreach(Dir.pwd) do |entry|
    if File.extname(entry) == expect_ext
      workspace_name = entry
      break
    end
  end
  
  if workspace_name.nil?
    puts "Error: no workspace available for build".red
    exit(1)
  end
  
  scheme = File.basename(workspace_name, expect_ext)
  
  stdout, stderr, status = Open3.capture3("xcodebuild -workspace #{workspace_name} -scheme #{scheme} -showdestinations")
  reg = /{ platform:iOS,.+name:(?!Any iOS Devic)(.*) }/
  destinations = []
  stdout.scan(reg) do |match|
     destinations.push(match.first)
  end
  selected_item_name = nil
  if destinations.empty?
    puts "Error: no devices available for build".red
    exit(1)
  elsif destinations.length == 1
    selected_item_name = destinations.first
  else
    selected_item_name = Utilities.display_choose_list(destinations, [destinations.last],"设备","请选择编译设备").first
  end
  if selected_item_name.nil?
    exit(1)
  end
  
  system("xcodebuild -workspace #{workspace_name} -scheme #{scheme} -configuration Debug -destination 'platform=iOS,name=#{selected_item_name}'")
  Utilities.check_shell_result("Error: xcode build failed")
end

#merge_and_checkObject

合并代码并检查冲突



156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/projects/ComponentSynchronizer.rb', line 156

def merge_and_check
  if not need_merge_origin
    return
  end
  
  system "mbox merge --repo #{main_repo_name}"
  FileUtils.cd("#{repo_manager.root_path}/#{main_repo_name}")
  `git --no-pager diff --check`
  conflict_hint = "Error: code conflict!\n"
  conflict_hint += "step1: Resolve `#{main_repo_name}` code conflicts\n"
  conflict_hint += "step2: Execute this script again"
  Utilities.check_shell_result(conflict_hint)
end

#pod_installObject

执行 pod install



226
227
228
229
# File 'lib/projects/ComponentSynchronizer.rb', line 226

def pod_install
  system "mbox pod install --repo-update"
  Utilities.check_shell_result("Error: execute `mbox pod install --repo-update` failed")
end

#pop_stashObject

恢复暂存的修改



108
109
110
111
112
# File 'lib/projects/ComponentSynchronizer.rb', line 108

def pop_stash
  FileUtils.cd("#{repo_manager.root_path}/#{main_repo_name}")
  puts "\n📦 正在恢复暂存的本地修改".green
  system "git stash pop"
end

#read_repo_infosObject

读取组件信息



115
116
117
118
# File 'lib/projects/ComponentSynchronizer.rb', line 115

def read_repo_infos
  @repos = repo_manager.sub_repos
  @main_repo_name = repo_manager.main_repo["name"]
end

#replace_local_to_remoteObject

将本地调试仓修改为远程仓



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/projects/ComponentSynchronizer.rb', line 121

def replace_local_to_remote
  active_repo_names = ""
  repos.each do |repo|
    is_avtive = true
    components = repo["components"]
    if !components.nil?
      components.each do |component|
        if component["tool"] == "CocoaPods"
          is_avtive = !component["active"].empty?
          break
        end
      end
    end
    if is_avtive 
      active_repo_names += " #{repo["name"]}"
    end
  end
  
  if !active_repo_names.empty?
    system "mbox deactivate#{active_repo_names}"
    system "mbox pod install"
    Utilities.check_shell_result("Error: execute `mbox pod install` failed")
  end
  return active_repo_names
end

#replace_podfileObject

替换主工程Podfile



171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
# File 'lib/projects/ComponentSynchronizer.rb', line 171

def replace_podfile
  progressbar = ProgressBar.create(
    total: repos.length,
    format: '%t |%B| %p%%',
    length: 50
  )

  # 获取每个子库最新的commit id
  repo_commite_id = {}
  repos.each do |repo|
    repo_name = repo["name"]

    FileUtils.cd("#{repo_manager.root_path}/#{repo_name}")
    repo_target_branch = @is_use__target_branch ? repo_target_branch = repo["target_branch"] : GitUtils.current_branch
    unless GitUtils.check_remote_branch_exists_fast("origin/#{repo_target_branch}") 
      progressbar.increment
      next
    end

    stdout, status = Open3.capture2("git fetch origin #{repo_target_branch} --quiet")
    unless status.success?
      progressbar.increment
      break
    end

    commit_id = `git log origin/#{repo_target_branch} -n 1 --pretty=format:"%H"`
    if !commit_id.nil?
      repo_commite_id[repo_name] = commit_id
    end

    progressbar.increment
  end
  
  podfile_path = "#{repo_manager.root_path}/#{main_repo_name}/AirBrushPodfiles/pix_ab_component.rb" 
  podfile_content = File.read(podfile_path)
  updated_repo_names = []
  repo_commite_id.each do |key, value|
    reg = /#{key}.+:commit => '(.+)'/
    podfile_content.match(reg)
    if $1 != value
      podfile_content.sub!($1,value)
      updated_repo_names.push(key)
    end
  end
  
  if !updated_repo_names.empty?
    File.open(podfile_path, "w+") do |aFile|
      aFile.syswrite(podfile_content)
    end
  end
  
  @updated_repo_names = updated_repo_names
end

#reset_remote_to_local(active_repo_names) ⇒ Object

将远程仓重置为本地调试仓



148
149
150
151
152
153
# File 'lib/projects/ComponentSynchronizer.rb', line 148

def reset_remote_to_local(active_repo_names)
  if active_repo_names.nil? || active_repo_names.empty?
    return
  end
  system "mbox activate#{active_repo_names}"
end

#runObject



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/projects/ComponentSynchronizer.rb', line 53

def run
  read_repo_infos

  did_stash = false
  if is_need_stash
    did_stash = stash_changes
  end

  begin
    active_repo_names = nil
    if is_need_remote_repo
      puts "\n⤴️ 正在将本地调试仓替换为远程仓\n".green
      active_repo_names = replace_local_to_remote
    end

    puts "\n🔀 正在合并主工程代码".green
    merge_and_check 

    puts "\n📥 正在读取最新提交".green
    replace_podfile

    if is_need_pod_install
      puts "\n📦 正在执行pod install\n".green
      pod_install
    end

    if is_need_remote_repo 
      puts "\n⤵️ 正在将远程仓复原为本地调试仓\n".green
      reset_remote_to_local(active_repo_names)
    end

    if is_need_build
      puts "\n🛠️ 正在进行Xcode编译\n".green
      FileUtils.cd("#{repo_manager.root_path}/#{main_repo_name}")
      build
    end
  ensure
    if did_stash
      pop_stash
    end
  end
end

#stash_changesObject

暂存本地修改



97
98
99
100
101
102
103
104
105
# File 'lib/projects/ComponentSynchronizer.rb', line 97

def stash_changes
  FileUtils.cd("#{repo_manager.root_path}/#{main_repo_name}")
  if GitUtils.has_uncommit_code
    puts "\n📦 正在暂存本地修改".green
    system "git stash push -m 'pixab-sync-auto-stash'"
    return true
  end
  return false
end