Skip to content

Latest commit

 

History

History
229 lines (183 loc) · 5.96 KB

xcodeproj.md

File metadata and controls

229 lines (183 loc) · 5.96 KB

xcodeproj

https://github.com/CocoaPods/Xcodeproj

需求:使用脚本自动拉取资源,添加到工程目录中。

解决方案:最终找到xcodeproj,这个ruby的开源程序,Cocoapods就是采用这个工具来修改工程项目的。

不说废话,直接贴代码,关键信息已经替换掉:

#!/usr/bin/ruby

require 'xcodeproj'
require 'fileutils'
require "open-uri"  
require 'json'
require 'pathname'
require 'zip'


# 获取最新生产包的下载链接
def get_download_url_request(uri)
	data_response = nil;
	open(uri) do |http|  
  		data_response = http.read;
	end
	if data_response == nil then
		return nil;
	end
	data = JSON.parse(data_response)['data'];
	if data == nil then
		return nil;
	end
	download_url = JSON.parse(data_response)['data']['downloadUrl'];
	puts "最新的RN代码下载链接为:#{download_url}";
	return download_url;
end

# 下载RN代码
def download_newest_rn_code(download_url, file_dir, file_name)
	# 下载文件
	data_response = nil;
	open(download_url) do |http|  
  		data_response = http.read;
	end 
	# 写入到文件
	path = File.join(file_dir, file_name);
	puts "写入到文件:#{path}";
	aFile = File.new(path, 'w+');
	if aFile then
		aFile.syswrite(data_response);
		puts "写入文件成功!!!";
  	else
		puts "创建文件失败!!!";
	end
	# 解压文件
	puts "解压文件:#{path}";
	Zip::File.open(path) do |zipfile|
  		zipfile.each do |entry|
    		unless File.exist?(entry.name)
    			entry_path = File.join(file_dir, entry.name);
    			FileUtils::mkdir_p(File.dirname(entry_path));
    			zipfile.extract(entry, entry_path) unless File.exist?(entry_path);
      		end
    	end
  	end
  	# 删除zip文件
  	puts "删除zip文件:#{path}";
  	FileUtils.rm_r path;
end


# 递归删除group目录下的所有资源文件
def removeBuildPhaseFilesRecursively(aTarget, aGroup)
	aGroup.files.each do |file|
  		aTarget.resources_build_phase.remove_file_reference(file);
	end
	aGroup.groups.each do |group|
	  removeBuildPhaseFilesRecursively(aTarget, group);
	end
end

# 删除bundles目录下所有引用
def removeBundlesReference(aProject, aGroup)
	group = aProject.main_group.find_subpath(aGroup, false);
	if !group.empty? then
		aProject.targets.each do |target|
			if target.to_s == 'test-dev' || target.to_s == 'test-release' || target.to_s == 'test-appstore' then
				removeBuildPhaseFilesRecursively(target, group);
			end
		end
		group.clear();
		aProject.save();
	end
end

# 删除目录下所有文件
def deleteDirectory(dirPath)
	if Dir.exist?dirPath then
		FileUtils.rm_r dirPath;		
	end
end

# copy最新的代码到工程目录
def copyCodeAndResources(src, dest)
	FileUtils.cp_r src, dest;
	puts "删除解压出来的临时文件";
	deleteDirectory(src);
end


# 添加项目引用
def addBundlesReference(aProject, aGroup, folder_dir)
	group = aProject.main_group.find_subpath(aGroup, false);
	puts "遍历新的bundles目录,目录下有:\n"
	Dir.foreach(folder_dir) do |entry|
		if entry != "." and entry != '..' then
			puts entry;
			file_ref = group.new_reference(entry);
			aProject.targets.each do |target|
				if target.to_s == 'test-dev' || target.to_s == 'test-release' || target.to_s == 'test-appstore' then
					target.resources_build_phase.add_file_reference(file_ref);
				end
			end
		end
	end
	aProject.save();
end


##########################################################脚本入口

def update_rn_code()

	# 参数配置
	# 工程根目录
	project_root_path = File.expand_path('../../.') ;
	# 脚本所在目录
	script_path = Pathname.new(File.dirname(__FILE__)).realpath;
	# xcodeproj项目路径
	xcodeproj_path = "#{project_root_path}/test/test.xcodeproj";
	# RN代码物理路径
	rn_folder_path = "#{project_root_path}/test/test/src/common/rn/bundles"
	# 获取线上环境更新链接API
	download_url_api = "http://test.com/rncode";
	# RN代码相对group,这个是试出来的,很麻烦
	rn_group_path = "test/src/common/rn/bundles";
	# 下载下来的文件命名
	download_file_name = "CodePush";
	# 下载下来的文件类型
	download_file_extension = ".zip";

	puts "\n";
	puts "从CodePush上拉最新的RN代码...";
	puts "\n";
	puts "******************相关配置******************";
	puts "项目根目录:#{project_root_path}";
	puts "脚本路径:#{script_path}";
	puts "xcodeproj文件路径:#{xcodeproj_path}";
	puts "rn代码物理路径:#{rn_folder_path}";
	puts "获取下载链接API:#{download_url_api}";
	puts "******************相关配置******************";
	puts "\n";

	# 读取xcodeproj文件
	project = Xcodeproj::Project.open(xcodeproj_path);


	# 获取最新生产包的下载链接
	puts "\n"
	puts "1. 获取最新生产包的下载链接\n";
	download_url = get_download_url_request(download_url_api);

	unless download_url then
		puts "\n"
		puts "******************悲伤的故事******************";
		puts "获取最新生产包的下载链接失败,放弃更新RN代码.";
		puts "******************悲伤的故事******************";
		return nil;
	end

	# 下载RN代码
	puts "\n"
	puts "2. 下载RN代码\n";
	download_newest_rn_code(download_url, script_path, "#{download_file_name}#{download_file_extension}");

	# 删除bundles目录下所有引用
	puts "\n"
	puts "3. 删除bundles目录下所有引用\n";
	removeBundlesReference(project, rn_group_path);

	# 删除bundles目录下所有文件
	puts "\n"
	puts "4. 删除bundles目录下所有文件\n";
	deleteDirectory(rn_folder_path);

	# 复制最新的代码和资源到项目目录
	puts "\n"
	puts "5. 复制最新的代码和资源到项目目录\n";
	copyCodeAndResources(File.join(script_path, download_file_name), rn_folder_path);

	# 添加项目引用
	puts "\n"
	puts "6. 添加项目引用\n";
	addBundlesReference(project, rn_group_path, rn_folder_path);

	puts "\n"
	puts "******************喜大普奔******************";
	puts "更新RN代码成功";
	puts "******************喜大普奔******************";

end

##########################################################脚本入口