class Fastlane::Ref::RefMain

Public Class Methods

analysis(note,inspect_info,pods_path,pods_hash) click to toggle source
# File lib/fastlane/plugin/rocket/ref/ref_main.rb, line 226
def self.analysis(note,inspect_info,pods_path,pods_hash)

  rule = "#import\""
  rule1 = ".podspec.json:"

  tmp_note = note.clone
  tmp_note = tmp_note.gsub(" ","")

  #解析note
  notes = note.split("\n")
  notes.each do |tmp|
    if tmp == "" || tmp.include?(rule1)
      next
    end

    tmps = tmp.split(":")
    #获取库名和文件名
    tmp_file_path = tmps.first
    tmp_paths = tmp_file_path.gsub(pods_path,"").to_s.split("/")
    dep_name = tmp_paths[1]
    dep_file_name = tmp_paths[-1]

    #判断podsepc是否引用
    podsepc_status = false
    podsepc_rule = "/#{dep_name}.podspec.json:\"#{inspect_info.name}\""
    if tmp_note.include?(podsepc_rule) 
      podsepc_status = true
    end

    #获取有引用具体内容
    tmp_text = tmps[-1]
    if tmp_text.start_with?("//")
      next
    end

    version = pods_hash[dep_name].version
    
    
    #add引用不规范
    if tmp_text.include?(rule)
      tmp_file = tmp_text.split("\"")[1]
      tmp_files_h_name_str = pods_hash[dep_name].files_h_name.join(",")
      if tmp_files_h_name_str.include?(tmp_file)
        next
      end
      inspect_info.add_reference_errors(dep_name,version,tmp_file_path,tmp_text,podsepc_status)
    end

    #add有引用
    inspect_info.add_deps(dep_name,version,tmp_file_path,tmp_text,podsepc_status)
  end
end
inspect(all,pods,pods_hash) click to toggle source
# File lib/fastlane/plugin/rocket/ref/ref_main.rb, line 305
def self.inspect(all,pods,pods_hash)
  inspect_pods = Hash.new
  if all == true
    inspect_pods = pods_hash.clone
  else
    pods.each do |pod|
      pod_info = pods_hash[pod]
      if pod_info == nil
        Tools.warning("#{pod}不存在该工程的Pods中,请确定该库无拼写错误!")
        next
      end
      pod_info.get_files_h_name
      inspect_pods[pod] = pod_info
    end
  end

  if inspect_pods.empty?
    raise "检查库不存在该工程的Pods中!"
  end
  return inspect_pods
end
lock_file(inspect_pods,has_info = true) click to toggle source
# File lib/fastlane/plugin/rocket/ref/ref_main.rb, line 328
def self.lock_file(inspect_pods,has_info = true)
  lock_text = ""
  count = inspect_pods.keys.size
  for i in 0..count-1
    inspect_info = inspect_pods.values[i]
    Tools.title("解析#{inspect_info.name}中,进度#{i+1}/#{count}")
    
    if inspect_info.deps.keys.size != 0 || inspect_info.reference_errors.keys.size != 0
      lock_text += "\n-------------------#{inspect_info.name}(#{inspect_info.version})-------------------\n"
    end

    if inspect_info.deps.keys.size != 0
      lock_text += "-\s使用库却没有在podsepc引入的列表\n"
        inspect_info.deps.values.each do |deps_infos|
          name = deps_infos.first.name
          podsepc_status = deps_infos.first.podspec_quote

          if podsepc_status == true
            next
          end

          lock_text += "\s-\s#{name}\n"
          deps_infos.each do |dep|
            lock_text += "\s\s-\s#{dep.file_name} => #{dep.notes}\n"
          end
        end
      
    end
    
    if inspect_info.reference_errors.size != 0
      lock_text += "-\s引用方式错误的列表\n"

        inspect_info.reference_errors.values.each do |errors_infos|
          name = errors_infos.first.name
          lock_text += "\s-\s#{name}\n"
          errors_infos.each do |error|
            lock_text += "\s\s-\s#{error.file_name} => #{error.notes}\n"
          end
        end
    
    end
    Tools.log("解析完成")
  end
  f=File.new(LOCK_PATH,"w+")
  f.puts(lock_text)
  f.close

  
end
run(params,available_options) click to toggle source
# File lib/fastlane/plugin/rocket/ref/ref_main.rb, line 21
def self.run(params,available_options)
  Tools.formatLog(params,available_options);  

  pod_author = Tools.return_shell("git config user.name")
  user_id = Tools.return_shell("git config user.id")
  if user_id.nil? ||user_id.empty?
    raise "请设置:git config user.id。user.id为gitlab的User ID,在用户设置里查看"
  end

  git = ENV["R_REF_GIT"]
  branch = ENV["R_REF_BRANCH"]
  all = false
  pods = []
  if ENV["R_REF_PODS"] != "ALL"
    pods = ENV["R_REF_PODS"].split(",");
  else
    all = true
  end

  Tools.title("拉取工程仓库")
  Tools.log("缓存地址 => #{REF_PATH}")
  Tools.clone(git,branch,XCODEPROJ_PATH)

  Tools.title("拉取HDSourceSpecs")
  Tools.clone(Tools::SOURCESPECS,"master",SOURCESPECS_PATH)

  Tools.title("pod update")
  project_path = update()
  
  Tools.title("生成pod对象集合")
  lock_path = "#{project_path}/Podfile.lock"
  pods_path = "#{project_path}/Pods"
  pods_hash = RefPodInfo.analysis(lock_path,pods_path,SOURCESPECS_PATH)

  Tools.title("生成被引用的库集合")
  inspect_pods = inspect(all,pods,pods_hash)

  Tools.title("开始检查...")
  #获取工程所有文件
  files_hash = RefPodInfo.files(pods_hash)
  files = files_hash.values
  files_str = files.join("\" \"")
  #去掉空格
  Tools.shell("sed -i ''  \"s/ //g\" \"#{files_str}\"")

  #获取所有库的podsepc地址
  git_paths = RefPodInfo.git_paths(pods_hash)
  git_paths_str = git_paths.join("\" \"")

  count = inspect_pods.keys.size
  for i in 0..count-1
    inspect_key = inspect_pods.keys[i]
    inspect_info = inspect_pods[inspect_key]
    name = inspect_info.name
    Tools.title("检查#{name}中,进度#{i+1}/#{count}")


    #查看podsepc是否被引用
    podsepc_rule = "\"#{name}\":"
    podspec_shell = "fgrep '#{podsepc_rule}'  \"#{git_paths_str}\""

    #去掉检查库本身
    tmp_hash = files_hash.clone
    tmp_hash.delete(name)
    select_files_str = tmp_hash.values.join("\" \"")
    
    #定义规则
    rules = []
    rules << "import#{name}"
    rules << "import<#{name}/"
    rules << "import\"#{name}/"
    #该库所有文件
    if inspect_info.files_h_name.size != 0
      rules << "#import\"" + inspect_info.files_h_name.join("' -e '#import\"")
    end
    

    rule_str = "-e '" + rules.join("' -e '") + "'"
    note = Tools.return_shell("fgrep #{rule_str} \"#{select_files_str}\"&&#{podspec_shell}")
    if note != -1
      analysis(note,inspect_info,pods_path,pods_hash)
    end
    Tools.log("#{name}检查完成")
  end

  Tools.title("生成 #{LOCK_PATH}中...")
  lock_file(inspect_pods,all)
  Tools.log("使用命令打开查看详情:open #{LOCK_PATH}")

  Tools.title("修复问题")
  Tools.delete_path(PODS_PATH)
  update_pods = Hash.new
  branch_pods = Hash.new #分支问题
  #提交到gitlab

  inspect_pods.values.each do |inspect_info|

    if inspect_info.deps.keys.size == 0 && inspect_info.reference_errors.keys.size == 0
      next
    end
    Tools.title("修正#{inspect_info.name}引用问题...")
    inspect_info.deps.keys.each do |key|
      dep_info = inspect_info.deps[key].first
      pod = pods_hash[key]

      if dep_info.podspec_quote == true && !inspect_info.reference_errors.has_key?(key)
        next
      end

      tmp_file = Dir.glob("#{PODS_PATH}/**/#{key}.podspec").first
      if tmp_file.nil?
        pod_path = "#{PODS_PATH}/#{key}"
        unless File.directory?(pod_path)
          Tools.clone(pod.git,branch,pod_path)
          unless File.directory?(pod_path)
            Tools.clone(pod.git,pod.version,pod_path)
            branch_pods[key] = "master"
          else
            Tools.clone(pod.git,pod.version,pod_path)
            branch_pods[key] = branch
          end
        end
      else
        pod_path = tmp_file.gsub("/#{key}.podspec","")
      end

      if dep_info.podspec_quote == false
        podsepc_file = Dir.glob("#{pod_path}/**/#{key}.podspec").first
        
        spec_n = Tools.return_shell("fgrep \"spec.name\" \"#{podsepc_file}\"")

        Tools.shell("sed -i '' '$s/end//' '#{podsepc_file}'")
        if spec_n == -1 
          str = "  s.dependency '#{inspect_info.name}'\nend"
        else
          str = "  spec.dependency '#{inspect_info.name}'\nend"
        end
        
        f = open("#{podsepc_file}","a")
        f.puts(str)
        f.close
      end
      

      #修复引用错误
      if inspect_info.reference_errors.has_key?(key)
        errors = inspect_info.reference_errors[key]
        
        errors.each do |error|
          file = Dir.glob("#{pod_path}/**/#{error.file_name}").first
          notes = error.notes
          old = "\"#{notes.split("\"")[1]}\""
          str = "<#{inspect_info.name}/#{notes.split("\"")[1]}>"

          tmp_notes = Tools.return_shell("grep '#{str}' \"#{file}\"")
          if tmp_notes == -1
            Tools.shell("sed -i ''  's##{old}##{str}#g' \"#{file}\"")
            Tools.log("#{error.file_name}:#{old} => #{str}")
          else
            Tools.return_shell("sed -i '' '/#{old}/d' \"#{file}\"")
            Tools.log("#{error.file_name}:#{old} => Delete")
          end
          
        end

      end
      update_pods[key] = pod_path
    end
  end


  tmp_branch = "reocket_ref_fix"
  web_urls = []
  update_pods.keys.each do |key| 
    Tools.title("批量提交修改记录:#{key}")
    path = update_pods[key]
    branch_pod = branch_pods[key]
    Tools.shell_list([
      "cd #{path}",
      "git status",
      "if [ `git branch --list #{tmp_branch}` ];then git branch -D #{tmp_branch};fi",
      "git checkout -b #{tmp_branch}",
      "git add --all",
      "git commit -m '[rocket][fix]修复使用库的类,却没有在podsepc引用的问题 提交人:#{pod_author}'",
      "git push -f origin #{tmp_branch}"
   ])

   pod = pods_hash[key]
   name =  pod.git.split("/")[-1].split(".git").first
   #获取项目的id
   projects = Tools.net_get("http://gitlab.dushuclub.io/api/v4/projects",{"search":"#{name}"})
   if projects.size == 0
    next
   end
   project_id = projects.first["id"]
   params = {"id":"#{project_id}","source_branch":"#{tmp_branch}","target_branch":"#{branch_pod}","title":"[rocket][fix]修复使用库的类,却没有在podsepc引用的问题","remove_source_branch":"true","assignee_id":"#{user_id}"}
   merge_requests = Tools.net_post("http://gitlab.dushuclub.io/api/v4/projects/#{project_id}/merge_requests",params)
   web_url = merge_requests["web_url"]
   web_urls << web_url
  end
  Tools.log("修正完成...")
  web_urls = web_urls.uniq
  Tools.logs("合并请求",web_urls)
end
update() click to toggle source
# File lib/fastlane/plugin/rocket/ref/ref_main.rb, line 279
def self.update()
  #获取podfile地址
  podfile_path = Dir.glob("#{XCODEPROJ_PATH}/Podfile").first
  if podfile_path == nil
    raise "工程中未找到Podfile文件,请确定该工程是iOS工程?工程地址 => #{XCODEPROJ_PATH}"
  end

  #通过podfile获取项目的目录
  project_path = File.dirname(podfile_path)

  #判断是否存在Makefile文件
  makefile_path = Dir.glob("#{project_path}/Makefile").first
  make = "make"
  if makefile_path == nil
    make = "pod update"
  end

  # 以源码形式执行pod update
  Tools.shell_list([
    "cd #{project_path}",
    "sed -i ''  \"s/hd_all_binary!/#hd_all_binary!/g\" \"Podfile\"",
    make
  ])
  return project_path
end