diff --git a/cocoapods-imy-bin/cocoapods-imy-bin.gemspec b/cocoapods-imy-bin/cocoapods-imy-bin.gemspec index bf6dae2..7a86301 100755 --- a/cocoapods-imy-bin/cocoapods-imy-bin.gemspec +++ b/cocoapods-imy-bin/cocoapods-imy-bin.gemspec @@ -13,7 +13,7 @@ Gem::Specification.new do |spec| spec.homepage = 'https://github.com/su350380433/cocaopods-imy-bin' spec.license = 'MIT' - spec.files = Dir["lib/**/*.rb","spec/**/*.rb"] + %w{README.md LICENSE.txt } + spec.files = Dir["lib/**/*.rb","spec/**/*.rb","lib/**/*.plist"] + %w{README.md LICENSE.txt } #spec.files = `git ls-files`.split($/) spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } diff --git a/cocoapods-imy-bin/lib/cocoapods-imy-bin/command/bin/auto.rb b/cocoapods-imy-bin/lib/cocoapods-imy-bin/command/bin/auto.rb index 9c78319..281f834 100755 --- a/cocoapods-imy-bin/lib/cocoapods-imy-bin/command/bin/auto.rb +++ b/cocoapods-imy-bin/lib/cocoapods-imy-bin/command/bin/auto.rb @@ -21,7 +21,7 @@ def self.options ['--all-make', '对该组件的依赖库,全部制作为二进制组件'], ['--configuration', 'Build the specified configuration (e.g. Release ). Defaults to Debug'], ['--env', "该组件上传的环境 %w[dev debug_iphoneos release_iphoneos]"] - ] + ].concat(Pod::Command::Gen.options).concat(super).uniq end def initialize(argv) @@ -41,6 +41,7 @@ def initialize(argv) @verbose = argv.flag?('verbose',true) @config = argv.option('configuration', 'Debug') + @additional_args = argv.remainder! super end @@ -56,7 +57,8 @@ def run sources_sepc.uniq.each do |spec| begin fail_push_specs << spec unless CBin::Upload::Helper.new(spec,@code_dependencies,@sources).upload - rescue + rescue Object => exception + UI.puts exception fail_push_specs << spec end end @@ -86,15 +88,15 @@ def run end #制作二进制包 - # `pod bin archive --verbose --code-dependencies --no-clean --sources=https://gitlab.xxx.com/iOS/imyspecs.git,https://cdn.cocoapods.org/ --use-libraries` + def run_archive argvs = [ "--sources=#{sources_option(@code_dependencies, @sources)},https:\/\/cdn.cocoapods.org", - "--use-libraries", - "--verbose" + @additional_args ] argvs << spec_file if spec_file + argvs.delete(Array.new) unless @clean argvs += ['--no-clean'] diff --git a/cocoapods-imy-bin/lib/cocoapods-imy-bin/command/bin/local.rb b/cocoapods-imy-bin/lib/cocoapods-imy-bin/command/bin/local.rb index 403a2ca..c7cd1f0 100755 --- a/cocoapods-imy-bin/lib/cocoapods-imy-bin/command/bin/local.rb +++ b/cocoapods-imy-bin/lib/cocoapods-imy-bin/command/bin/local.rb @@ -61,11 +61,11 @@ def initialize(argv) def run # 清除之前的缓存 - temp = File.join(@local_build_dir, @platform.to_s) - FileUtils.rm_r(temp) if File.exist? temp - if File.exist?(CBin::Config::Builder.instance.zip_dir) - FileUtils.rm_r(CBin::Config::Builder.instance.zip_dir) - end + # temp = File.join(@local_build_dir, @platform.to_s) + # FileUtils.rm_r(temp) if File.exist? temp + # if File.exist?(CBin::Config::Builder.instance.zip_dir) + # FileUtils.rm_rf(Dir.glob("#{CBin::Config::Builder.instance.zip_dir}/*")) + # end sources_spec = [] Dir.chdir(CBin::Config::Builder.instance.local_psec_dir) do @@ -107,6 +107,7 @@ def build(make_binary_specs) # 获取没有制作二进制版本的spec集合 sources_sepc << spec end + fail_build_specs = [] sources_sepc.uniq.each do |spec| begin @@ -146,9 +147,17 @@ def build(make_binary_specs) private def library_exist(spec) - File.exist?(File.join(@local_build_dir, "lib#{spec.name}.a")) + File.exist?(File.join(@local_build_dir, "lib#{spec.name}.a")) || is_framework(spec) + end + # 使用了user_framework 会有#{@spec.name}.framework + # 未使用的 需要判断文件 + def is_framework(spec) + res = File.exist?(File.join(@local_build_dir, "#{spec.name}.framework")) + unless res + res = File.exist?(File.join(CBin::Config::Builder.instance.xcode_BuildProductsPath_dir, "#{spec.name}","Swift Compatibility Header")) + end + res end - end end diff --git a/cocoapods-imy-bin/lib/cocoapods-imy-bin/config/config.rb b/cocoapods-imy-bin/lib/cocoapods-imy-bin/config/config.rb index 0c43246..3beb95f 100755 --- a/cocoapods-imy-bin/lib/cocoapods-imy-bin/config/config.rb +++ b/cocoapods-imy-bin/lib/cocoapods-imy-bin/config/config.rb @@ -14,7 +14,7 @@ def template_hash 'configuration_env' => { description: '编译环境', default: 'dev', selection: %w[dev debug_iphoneos release_iphoneos] }, 'code_repo_url' => { description: '源码私有源 Git 地址', default: 'git@github.com:su350380433/example_spec_source.git' }, 'binary_repo_url' => { description: '二进制私有源 Git 地址', default: 'git@github.com:su350380433/example_spec_bin_dev.git' }, - 'binary_download_url' => { description: '二进制下载地址,内部会依次传入组件名称与版本,替换字符串中的 %s ', default: 'http://localhost:8080/frameworks/%s/%s.zip' }, + 'binary_download_url' => { description: '二进制下载地址,内部会依次传入组件名称与版本,替换字符串中的 %s ', default: 'http://localhost:8080/frameworks/%s/%s/zip' }, # 'binary_type' => { description: '二进制打包类型', default: 'framework', selection: %w[framework library] }, 'download_file_type' => { description: '下载二进制文件类型', default: 'zip', selection: %w[zip tgz tar tbz txz dmg] } } diff --git a/cocoapods-imy-bin/lib/cocoapods-imy-bin/config/config_builder.rb b/cocoapods-imy-bin/lib/cocoapods-imy-bin/config/config_builder.rb index 10846c3..38aee48 100755 --- a/cocoapods-imy-bin/lib/cocoapods-imy-bin/config/config_builder.rb +++ b/cocoapods-imy-bin/lib/cocoapods-imy-bin/config/config_builder.rb @@ -12,6 +12,7 @@ def self.instance def initialize load_build_config + # clean end # 加载配置项 @@ -35,6 +36,13 @@ def load_build_config end + def clean + #清除之前的缓存 + FileUtils.rm_rf(Dir.glob("#{zip_dir}/*")) if File.exist?(zip_dir) + FileUtils.rm_rf(Dir.glob("#{binary_json_dir}/*")) if File.exist?(binary_json_dir) + FileUtils.rm_rf(Dir.glob("#{local_psec_dir}/*")) if File.exist?(local_psec_dir) + end + # 制作二进制打包 工程目录 def gen_name 'bin-archive' @@ -49,10 +57,19 @@ def gen_dir end end + def framework_name(spec) "#{spec.name}.framework" end + def framework_name_version(spec) + "#{spec.name}.framework_#{spec.version}" + end + + def framework_zip_file(spec) + File.join(zip_dir_name, framework_name_version(spec)) + end + def framework_file(spec) File.join(zip_dir_name, framework_name(spec)) end @@ -110,7 +127,8 @@ def binary_json_dir #编译target名,如 seeyou def target_name @target_name ||= begin - Pod::Config.instance.podfile.root_target_definitions.first.children.first.to_s.split('-').last + target_name_str = Pod::Config.instance.podfile.root_target_definitions.first.children.first.to_s + target_name_str[5,target_name_str.length] end end @@ -129,6 +147,7 @@ def xcode_build_name if @xcode_build_name.nil? || Dir.exist?(@xcode_build_name) @xcode_build_name = "xcode-build/Build/Intermediates.noindex/ArchiveIntermediates/#{target_name}/IntermediateBuildFilesPath/UninstalledProducts/iphoneos/" end + puts @xcode_build_name @xcode_build_name end end @@ -146,7 +165,25 @@ def xcode_build_dir end end end - + #完整的xcodebuild BuildProductsPath输出路径, + def xcode_BuildProductsPath_dir + @xcode_BuildProductsPath_dir ||= begin + temp_xcode_BuildProductsPath_dir = "xcode-build/Build/Intermediates.noindex/ArchiveIntermediates/#{target_name}/BuildProductsPath/" + full_path = File.join(root_dir, temp_xcode_BuildProductsPath_dir) + + if (File.exist?(full_path)) + Dir.chdir(full_path) do + iphoneos = Dir.glob('*-iphoneos') + if iphoneos.length > 0 + full_path = File.join(full_path,iphoneos.first) + else + UI.warn "====== 找不到 *-iphoneos @xcode_BuildProductsPath_dir = #{@xcode_BuildProductsPath_dir}" + end + end + end + Pathname.new(full_path) + end + end #处理编译产物后存储根目录,会存放spec、 json、zip的父目录,默认是工程的同级目录下,"#{basename}-build-temp" diff --git a/cocoapods-imy-bin/lib/cocoapods-imy-bin/gem_version.rb b/cocoapods-imy-bin/lib/cocoapods-imy-bin/gem_version.rb index bf52943..bb68fb3 100755 --- a/cocoapods-imy-bin/lib/cocoapods-imy-bin/gem_version.rb +++ b/cocoapods-imy-bin/lib/cocoapods-imy-bin/gem_version.rb @@ -1,6 +1,6 @@ module CBin - VERSION = '0.2.9' + VERSION = '0.3.0.12' end module Pod diff --git a/cocoapods-imy-bin/lib/cocoapods-imy-bin/helpers.rb b/cocoapods-imy-bin/lib/cocoapods-imy-bin/helpers.rb index 76eaf23..ae28679 100755 --- a/cocoapods-imy-bin/lib/cocoapods-imy-bin/helpers.rb +++ b/cocoapods-imy-bin/lib/cocoapods-imy-bin/helpers.rb @@ -2,3 +2,4 @@ require 'cocoapods-imy-bin/helpers/spec_creator' require 'cocoapods-imy-bin/helpers/spec_files_helper' require 'cocoapods-imy-bin/helpers/spec_source_creator' +require 'cocoapods-imy-bin/helpers/build_utils' diff --git a/cocoapods-imy-bin/lib/cocoapods-imy-bin/helpers/Info.plist b/cocoapods-imy-bin/lib/cocoapods-imy-bin/helpers/Info.plist new file mode 100644 index 0000000..591fe88 Binary files /dev/null and b/cocoapods-imy-bin/lib/cocoapods-imy-bin/helpers/Info.plist differ diff --git a/cocoapods-imy-bin/lib/cocoapods-imy-bin/helpers/build_helper.rb b/cocoapods-imy-bin/lib/cocoapods-imy-bin/helpers/build_helper.rb index 42e3f69..c08b7ee 100755 --- a/cocoapods-imy-bin/lib/cocoapods-imy-bin/helpers/build_helper.rb +++ b/cocoapods-imy-bin/lib/cocoapods-imy-bin/helpers/build_helper.rb @@ -38,9 +38,12 @@ def build build_static_framework unless @skip_archive - build_static_library - zip_static_framework if @zip &&= @framework_output - zip_static_library + unless CBin::Build::Utils.is_framework(@spec) + build_static_library + zip_static_library + else + zip_static_framework + end end end @@ -71,15 +74,15 @@ def build_static_library end def zip_static_framework - Dir.chdir(zip_dir) do - output_name = "#{framework_name}.zip" + Dir.chdir(File.join(workspace_directory,@framework_path.root_path)) do + output_name = File.join(zip_dir, framework_name_zip) unless File.exist?(framework_name) - raise Informative, "没有需要压缩的 framework 文件:#{framework_name}" + UI.puts "没有需要压缩的 framework 文件:#{framework_name}" + return end UI.puts "Compressing #{framework_name} into #{output_name}" `zip --symlinks -r #{output_name} #{framework_name}` - end end @@ -114,6 +117,10 @@ def framework_name CBin::Config::Builder.instance.framework_name(@spec) end + def framework_name_zip + CBin::Config::Builder.instance.framework_name_version(@spec) + ".zip" + end + def library_name CBin::Config::Builder.instance.library_name(@spec) end @@ -130,6 +137,7 @@ def gen_name CBin::Config::Builder.instance.gen_dir end + def spec_file @spec_file ||= begin if @podspec diff --git a/cocoapods-imy-bin/lib/cocoapods-imy-bin/helpers/build_utils.rb b/cocoapods-imy-bin/lib/cocoapods-imy-bin/helpers/build_utils.rb new file mode 100755 index 0000000..133ec5a --- /dev/null +++ b/cocoapods-imy-bin/lib/cocoapods-imy-bin/helpers/build_utils.rb @@ -0,0 +1,63 @@ +require 'yaml' +require 'cocoapods-imy-bin/config/config' + +module CBin + class Build + + class Utils + + def Utils.is_framework(spec) + if Utils.uses_frameworks? + return true + end + + return Utils.is_swift_module(spec) + end + + def Utils.is_swift_module(spec) + + is_framework = false + dir = File.join(CBin::Config::Builder.instance.gen_dir, CBin::Config::Builder.instance.target_name) + #auto 走这里 + if File.exist?(dir) + Dir.chdir(dir) do + public_headers = Array.new + spec_header_dir = "./Headers/Public/#{spec.name}" + + unless File.exist?(spec_header_dir) + spec_header_dir = "./Pods/Headers/Public/#{spec.name}" + end + return false unless File.exist?(spec_header_dir) + + is_framework = File.exist?(File.join(spec_header_dir, "#{spec.name}-umbrella.h")) + end + end + + if $ARGV[1] == "local" + is_framework = File.exist?(File.join(CBin::Config::Builder.instance.xcode_build_dir, "#{spec.name}.framework")) + unless is_framework + is_framework = File.exist?(File.join(CBin::Config::Builder.instance.xcode_BuildProductsPath_dir, "#{spec.name}","Swift Compatibility Header")) + end + end + + is_framework + end + + def Utils.uses_frameworks? + uses_frameworks = false + Pod::Config.instance.podfile.target_definitions.each do |key,value| + if key != "Pods" + uses_frameworks = value.uses_frameworks? + if uses_frameworks + break ; + end + end + end + + return uses_frameworks + end + + end + + end +end diff --git a/cocoapods-imy-bin/lib/cocoapods-imy-bin/helpers/framework.rb b/cocoapods-imy-bin/lib/cocoapods-imy-bin/helpers/framework.rb index 82d67b6..19a054f 100755 --- a/cocoapods-imy-bin/lib/cocoapods-imy-bin/helpers/framework.rb +++ b/cocoapods-imy-bin/lib/cocoapods-imy-bin/helpers/framework.rb @@ -7,6 +7,8 @@ class Framework attr_reader :resources_path attr_reader :root_path attr_reader :versions_path + attr_reader :swift_module_path + attr_reader :fwk_path def initialize(name, platform) @name = name @@ -22,8 +24,24 @@ def make end def delete_resources - Pathname.new(@resources_path).rmtree - (Pathname.new(@fwk_path) + Pathname.new('Resources')).delete + Pathname.new(@resources_path).rmtree if File.exist? (@resources_path) + (Pathname.new(@fwk_path) + Pathname.new('Resources')).delete if File.exist?(Pathname.new(@fwk_path) + Pathname.new('Resources')) + end + + def remove_current_version + FileUtils.rm_f(File.join(@fwk_path,@name)) + FileUtils.rm_f(File.join(@fwk_path,"Headers")) + FileUtils.rm_f(File.join(@fwk_path,"Resources")) + + FileUtils.cp_r("#{@versions_path}/.", @fwk_path) + # FileUtils.remove_dir(@versions_path) + FileUtils.remove_dir("#{@fwk_path}/Versions") + + # current_version_path = @versions_path + Pathname.new('../Current') + # `ln -sf A #{current_version_path}` + # `ln -sf Versions/Current/Headers #{@fwk_path}/` + # `ln -sf Versions/Current/Resources #{@fwk_path}/` + # `ln -sf Versions/Current/#{@name} #{@fwk_path}/` end private @@ -36,11 +54,16 @@ def make_current_version `ln -sf Versions/Current/#{@name} #{@fwk_path}/` end + + def make_framework @fwk_path = @root_path + Pathname.new(@name + '.framework') @fwk_path.mkdir unless @fwk_path.exist? @module_map_path = @fwk_path + Pathname.new('Modules') + @swift_module_path = @module_map_path + Pathname.new(@name + '.swiftmodule') + + @versions_path = @fwk_path + Pathname.new('Versions/A') end diff --git a/cocoapods-imy-bin/lib/cocoapods-imy-bin/helpers/local/local_build_helper.rb b/cocoapods-imy-bin/lib/cocoapods-imy-bin/helpers/local/local_build_helper.rb index 26ab4c0..fa65e35 100755 --- a/cocoapods-imy-bin/lib/cocoapods-imy-bin/helpers/local/local_build_helper.rb +++ b/cocoapods-imy-bin/lib/cocoapods-imy-bin/helpers/local/local_build_helper.rb @@ -34,15 +34,20 @@ def initialize(spec, @local_build_dir = local_build_dir @clean = clean @framework_path + @is_library = !is_framework end def build UI.section("Building static framework #{@spec}") do build_static_framework - build_static_library - zip_static_framework if @zip &&= @framework_output - zip_static_library + if @is_library + build_static_library + zip_static_framework if @zip &&= @framework_output + zip_static_library + else + zip_static_framework + end clean_workspace if @clean end @@ -52,7 +57,7 @@ def build def build_static_framework file_accessor = Sandbox::FileAccessor.new(Pathname.new('.').expand_path, @spec.consumer(@platform)) Dir.chdir(workspace_directory) do - builder = CBin::LocalFramework::Builder.new(@spec, file_accessor, @platform, @local_build_dir_name,@local_build_dir) + builder = CBin::LocalFramework::Builder.new(@spec, file_accessor, @platform, @local_build_dir_name,@local_build_dir, @is_library, frameWork_dir) @framework_path = builder.create end end @@ -68,9 +73,10 @@ def build_static_library def zip_static_framework Dir.chdir(zip_dir) do - output_name = "#{framework_name}.zip" + # output_name = "#{framework_name}.zip" + output_name = File.join(zip_dir, framework_name_zip) unless File.exist?(framework_name) - raise Informative, "没有需要压缩的 framework 文件:#{framework_name}" + UI.warn "没有需要压缩的 framework 文件:#{framework_name}" end UI.puts "Compressing #{framework_name} into #{output_name}" @@ -110,6 +116,10 @@ def framework_name CBin::Config::Builder.instance.framework_name(@spec) end + def framework_name_zip + CBin::Config::Builder.instance.framework_name_version(@spec) + ".zip" + end + def library_name CBin::Config::Builder.instance.library_name(@spec) end @@ -126,6 +136,28 @@ def gen_name CBin::Config::Builder.instance.gen_name end + def is_library + File.exist?(File.join(@local_build_dir, "lib#{@spec.name}.a")) + end + + # 使用了user_framework 会有#{@spec.name}.framework + # 未使用的 需要判断文件 + def is_framework + res = File.exist?(File.join(@local_build_dir, "#{@spec.name}.framework")) + unless res + res = File.exist?(File.join(CBin::Config::Builder.instance.xcode_BuildProductsPath_dir, "#{@spec.name}","Swift Compatibility Header")) + end + res + end + + def frameWork_dir + dir = File.join(@local_build_dir, "#{@spec.name}.framework") + unless File.exist?(dir) + dir = File.join(CBin::Config::Builder.instance.xcode_BuildProductsPath_dir, "#{@spec.name}") + end + dir + end + def spec_file @spec_file ||= begin if @podspec diff --git a/cocoapods-imy-bin/lib/cocoapods-imy-bin/helpers/local/local_framework.rb b/cocoapods-imy-bin/lib/cocoapods-imy-bin/helpers/local/local_framework.rb index 1290ca5..02f993c 100755 --- a/cocoapods-imy-bin/lib/cocoapods-imy-bin/helpers/local/local_framework.rb +++ b/cocoapods-imy-bin/lib/cocoapods-imy-bin/helpers/local/local_framework.rb @@ -9,6 +9,8 @@ class LocalFramework attr_reader :resources_path attr_reader :root_path attr_reader :versions_path + attr_reader :swift_module_path + attr_reader :fwk_path def initialize(name, platform, local_build_dir) @name = name @@ -29,6 +31,21 @@ def delete_resources (Pathname.new(@fwk_path) + Pathname.new('Resources')).delete end + def remove_current_version + FileUtils.rm_f(File.join(@fwk_path,@name)) + FileUtils.rm_f(File.join(@fwk_path,"Headers")) + FileUtils.rm_f(File.join(@fwk_path,"Resources")) + + FileUtils.cp_r("#{@versions_path}/.", @fwk_path) + # FileUtils.remove_dir(@versions_path) + FileUtils.remove_dir("#{@fwk_path}/Versions") + + # current_version_path = @versions_path + Pathname.new('../Current') + # `ln -sf A #{current_version_path}` + # `ln -sf Versions/Current/Headers #{@fwk_path}/` + # `ln -sf Versions/Current/Resources #{@fwk_path}/` + # `ln -sf Versions/Current/#{@name} #{@fwk_path}/` + end private def make_current_version @@ -41,10 +58,13 @@ def make_current_version def make_framework @fwk_path = @root_path + Pathname.new(@name + '.framework') + FileUtils.remove_dir(@fwk_path) if @fwk_path.exist? @fwk_path.mkdir unless @fwk_path.exist? @module_map_path = @fwk_path + Pathname.new('Modules') @versions_path = @fwk_path + Pathname.new('Versions/A') + @fwk_path.exist? + @swift_module_path = @module_map_path + Pathname.new(@name + '.swiftmodule') end def make_headers diff --git a/cocoapods-imy-bin/lib/cocoapods-imy-bin/helpers/local/local_framework_builder.rb b/cocoapods-imy-bin/lib/cocoapods-imy-bin/helpers/local/local_framework_builder.rb index 70f91fc..99f2a3f 100755 --- a/cocoapods-imy-bin/lib/cocoapods-imy-bin/helpers/local/local_framework_builder.rb +++ b/cocoapods-imy-bin/lib/cocoapods-imy-bin/helpers/local/local_framework_builder.rb @@ -12,31 +12,55 @@ class LocalFramework class Builder include Pod #Debug下还待完成 - def initialize(spec, file_accessor, platform, local_build_dir_name, local_build_dir) + def initialize(spec, file_accessor, platform, local_build_dir_name, local_build_dir, is_library = true, framework_BuildProductsPath = "") @spec = spec @file_accessor = file_accessor @platform = platform @local_build_dir_name = local_build_dir_name @local_build_dir = local_build_dir + @is_library = is_library + @framework_BuildProductsPath = framework_BuildProductsPath end def create - UI.section("Building static framework #{@spec}") do - output = framework.versions_path + Pathname.new(@spec.name) - - build_static_library_for_ios(output) + begin + #如果是.a 文件, 或者 swift下,是.a文件的 + if @is_library || (!@is_library && @framework_BuildProductsPath != framework_name) + + UI.section("Building static library #{@spec}") do + output = framework.versions_path + Pathname.new(@spec.name) + build_static_library_for_ios(output) + res = copy_headers + # maybe fails for copy_headers + if res + copy_resources + cp_to_source_dir + else + FileUtils.remove_dir(framework.fwk_path) if File.exist?(framework.fwk_path) + return nil + end + end - copy_headers - copy_resources + else + UI.section("Building static framework #{@spec}") do + output = File.join(CBin::Config::Builder.instance.zip_dir,"#{@spec.name}.framework") + build_static_framework_for_ios(output) + end + end - cp_to_source_dir + rescue StandardError + UI.warn "【#{spec.name} | #{spec.version}】组件二进制版本组装失败 ." end + framework end private def cp_to_source_dir + # 删除Versions 软链接 + framework.remove_current_version if CBin::Build::Utils.is_swift_module(@spec) + target_dir = File.join(CBin::Config::Builder.instance.root_dir,CBin::Config::Builder.instance.framework_file(@spec)) FileUtils.rm_rf(target_dir) if File.exist?(target_dir) @@ -46,58 +70,80 @@ def cp_to_source_dir `cp -fa #{@platform}/#{CBin::Config::Builder.instance.framework_name(@spec)} #{target_dir}` end + def copy_headers #by slj 如果没有头文件,去 "Headers/Public"拿 # if public_headers.empty? Dir.chdir(File.join(Pod::Config.instance.installation_root,'Pods')) do - #走 podsepc中的public_headers - public_headers = Array.new - Dir.chdir("./Headers/Public/#{@spec.name}") do - headers = Dir.glob('*.h') - headers.each do |h| - public_headers << Pathname.new(File.join(Dir.pwd,h)) - end - end + if File.exist?("./Headers/Public/#{@spec.name}") + #走 podsepc中的public_headers + public_headers = Array.new - UI.message "Copying public headers #{public_headers.map(&:basename).map(&:to_s)}" + Dir.chdir("./Headers/Public/#{@spec.name}") do + headers = Dir.glob('*.h') + headers.each do |h| + public_headers << Pathname.new(File.join(Dir.pwd,h)) + end + end - public_headers.each do |h| - `ditto #{h} #{framework.headers_path}/#{h.basename}` - end + UI.message "Copying public headers #{public_headers.map(&:basename).map(&:to_s)}" - # If custom 'module_map' is specified add it to the framework distribution - # otherwise check if a header exists that is equal to 'spec.name', if so - # create a default 'module_map' one using it. - if !@spec.module_map.nil? - module_map_file = @file_accessor.module_map - if Pathname(module_map_file).exist? - module_map = File.read(module_map_file) + public_headers.each do |h| + `ditto #{h} #{framework.headers_path}/#{h.basename}` end - elsif public_headers.map(&:basename).map(&:to_s).include?("#{@spec.name}.h") - module_map = <<-MAP + + # If custom 'module_map' is specified add it to the framework distribution + # otherwise check if a header exists that is equal to 'spec.name', if so + # create a default 'module_map' one using it. + if !@spec.module_map.nil? + module_map_file = @file_accessor.module_map + if Pathname(module_map_file).exist? + module_map = File.read(module_map_file) + end + elsif public_headers.map(&:basename).map(&:to_s).include?("#{@spec.name}-umbrella.h") + module_map = <<-MAP framework module #{@spec.name} { - umbrella header "#{@spec.name}.h" + umbrella header "#{@spec.name}-umbrella.h" export * module * { export * } } - MAP - end + MAP + end - unless module_map.nil? - UI.message "Writing module map #{module_map}" - unless framework.module_map_path.exist? - framework.module_map_path.mkpath + unless module_map.nil? + UI.message "Writing module map #{module_map}" + unless framework.module_map_path.exist? + framework.module_map_path.mkpath + end + File.write("#{framework.module_map_path}/module.modulemap", module_map) + + # unless framework.swift_module_path.exist? + # framework.swift_module_path.mkpath + # end + # DO BuildProductsPath swiftModule拷贝到 framework.swift_module_path + swiftmodule_path = File.join(@framework_BuildProductsPath, "#{@spec.name}.swiftmodule") + if File.directory?(swiftmodule_path) + FileUtils.cp_r("#{swiftmodule_path}/.", framework.swift_module_path) + end + swift_Compatibility_Header = "#{@framework_BuildProductsPath}/Swift\ Compatibility\ Header/#{@spec.name}-Swift.h" + FileUtils.cp(swift_Compatibility_Header,framework.headers_path) if File.exist?(swift_Compatibility_Header) + info_plist_file = File.join(File.dirname(File.dirname(__FILE__)),"info.plist") + FileUtils.cp(info_plist_file,framework.fwk_path) end - File.write("#{framework.module_map_path}/module.modulemap", module_map) + else + UI.warn "== Headers/Public/#{@spec.name} no exist" + return false end end + return true end def copy_resources + Dir.chdir(Pod::Config.instance.sandbox_root) do bundles = Dir.glob('./build/*.bundle') @@ -126,7 +172,7 @@ def copy_resources expand_paths(real_source_dir, spec.consumer(@platform).resources) end.compact.uniq - if resources.count == 0 && bundles.count == 0 + if (resources.count == 0 || (resources.count == 1 && resources[0].count == 0)) && bundles.count == 0 framework.delete_resources return end @@ -150,10 +196,17 @@ def build_static_library_for_ios(output) `cp -rp #{library_name} #{output}` end + def build_static_framework_for_ios(output) + FileUtils.cp_r(framework_name, output) + end + def library_name File.join(@local_build_dir, "lib#{@spec.name}.a") end + def framework_name + File.join(@local_build_dir, "#{@spec.name}.framework") + end def expand_paths(source_dir, path_specs) path_specs.map do |path_spec| diff --git a/cocoapods-imy-bin/lib/cocoapods-imy-bin/helpers/spec_source_creator.rb b/cocoapods-imy-bin/lib/cocoapods-imy-bin/helpers/spec_source_creator.rb index 023cf44..52a7ff9 100755 --- a/cocoapods-imy-bin/lib/cocoapods-imy-bin/helpers/spec_source_creator.rb +++ b/cocoapods-imy-bin/lib/cocoapods-imy-bin/helpers/spec_source_creator.rb @@ -20,12 +20,12 @@ def validate! end def create - spec = create_from_code_spec - - # Pod::UI.message '生成二进制 podspec 内容: ' - # spec.to_pretty_json.split("\n").each do |text| - # Pod::UI.message text - # end + # spec = nil + if CBin::Build::Utils.is_framework(@code_spec) + spec = create_framework_from_code_spec + else + spec = create_from_code_spec + end spec end @@ -121,12 +121,69 @@ def create_from_code_spec @spec.vendored_libraries = binary_vendored_libraries @spec.resources = binary_resources if @spec.attributes_hash.keys.include?("resources") @spec.description = <<-EOF - 「 converted automatically by plugin cocoapods-imy-bin @slj 」 + 「 converted automatically by plugin cocoapods-imy-bin @厦门美柚 - slj 」 + #{@spec.description} + EOF + @spec + end + + def create_framework_from_code_spec + @spec = code_spec.dup + # vendored_frameworks | resources | source | source_files | public_header_files + # license | resource_bundles | vendored_libraries + + # Project Linkin + @spec.vendored_frameworks = "#{code_spec.root.name}.framework" + + # Resources + extnames = [] + extnames << '*.bundle' if code_spec_consumer.resource_bundles.any? + if code_spec_consumer.resources.any? + extnames += code_spec_consumer.resources.map { |r| File.basename(r) } + end + if extnames.any? + @spec.resources = framework_contents('Resources').flat_map { |r| extnames.map { |e| "#{r}/#{e}" } } + end + + # Source Location + @spec.source = binary_source + + # Source Code + # @spec.source_files = framework_contents('Headers/*') + # @spec.public_header_files = framework_contents('Headers/*') + + # Unused for binary + spec_hash = @spec.to_hash + # spec_hash.delete('license') + spec_hash.delete('resource_bundles') + spec_hash.delete('exclude_files') + spec_hash.delete('preserve_paths') + # 这里不确定 vendored_libraries 指定的时动态/静态库 + # 如果是静态库的话,需要移除,否则就不移除 + # 最好是静态库都独立成 Pod ,cocoapods-package 打静态库去 collect 目标文件时好做过滤 + # 这里统一只对命名后缀 .a 文件做处理 + # spec_hash.delete('vendored_libraries') + # libraries 只能假设为动态库不做处理了,如果有例外,需要开发者自行处理 + vendored_libraries = spec_hash.delete('vendored_libraries') + vendored_libraries = Array(vendored_libraries).reject { |l| l.end_with?('.a') } + if vendored_libraries.any? + spec_hash['vendored_libraries'] = vendored_libraries + end + + # Filter platforms + platforms = spec_hash['platforms'] + selected_platforms = platforms.select { |k, _v| @platforms.include?(k) } + spec_hash['platforms'] = selected_platforms.empty? ? platforms : selected_platforms + + @spec = Pod::Specification.from_hash(spec_hash) + @spec.description = <<-EOF + 「 converted automatically by plugin cocoapods-imy-bin @厦门美柚 - slj 」 #{@spec.description} -EOF + EOF @spec end + def binary_source { http: format(CBin.config.binary_download_url, code_spec.root.name, code_spec.version), type: CBin.config.download_file_type } end diff --git a/cocoapods-imy-bin/lib/cocoapods-imy-bin/helpers/upload_helper.rb b/cocoapods-imy-bin/lib/cocoapods-imy-bin/helpers/upload_helper.rb index fd2268a..2a907d2 100755 --- a/cocoapods-imy-bin/lib/cocoapods-imy-bin/helpers/upload_helper.rb +++ b/cocoapods-imy-bin/lib/cocoapods-imy-bin/helpers/upload_helper.rb @@ -47,14 +47,19 @@ def spec_creator def curl_zip zip_file = "#{CBin::Config::Builder.instance.library_file(@spec)}.zip" res = File.exist?(zip_file) - print <> "${MODULE_MAP_SEARCH_PATH}" + fi + + printf "\\n\\nmodule ${PRODUCT_MODULE_NAME}.Swift {\\n header \\"${COMPATIBILITY_HEADER_PATH}\\"\\n requires objc\\n}\\n" >> "${MODULE_MAP_PATH}" + + SH + build_phase.input_paths = %W( + ${DERIVED_SOURCES_DIR}/${PRODUCT_MODULE_NAME}-Swift.h + ${PODS_ROOT}/#{relative_module_map_path} + ${PODS_ROOT}/#{relative_umbrella_header_path} + ) + build_phase.output_paths = %W( + ${BUILT_PRODUCTS_DIR}/${PRODUCT_MODULE_NAME}.modulemap + ${BUILT_PRODUCTS_DIR}/#{relative_umbrella_header_path.basename} + ${BUILT_PRODUCTS_DIR}/Swift\ Compatibility\ Header/${PRODUCT_MODULE_NAME}-Swift.h + ) + else + UI.warn("========= null swift add_swift_library_compatibility_header_phase") + old_add_swift_library_compatibility_header_phase(native_target) + end + + end + + #-----------------------------------------------------------------------# + end + end + end + end +end diff --git a/cocoapods-imy-bin/lib/cocoapods-imy-bin/native/podfile_generator.rb b/cocoapods-imy-bin/lib/cocoapods-imy-bin/native/podfile_generator.rb index 99da1a2..cf23ad5 100755 --- a/cocoapods-imy-bin/lib/cocoapods-imy-bin/native/podfile_generator.rb +++ b/cocoapods-imy-bin/lib/cocoapods-imy-bin/native/podfile_generator.rb @@ -126,6 +126,14 @@ def podfile_for_spec(spec) break end end + # setting modular_headers_for + if(target_definition && target_definition.use_modular_headers_hash.values.any?) + target_definition.use_modular_headers_hash.values.each do |f| + f.each { | pod_name| self.set_use_modular_headers_for_pod(pod_name, true) } + end + end + + if target_definition value = target_definition.to_hash['dependencies'] next if value.blank? @@ -139,15 +147,16 @@ def podfile_for_spec(spec) old_value = self.to_hash['dependencies'].first value << old_value unless (old_value == nil || value.include?(old_value)) - set_hash_value(%w(dependencies).first, value) + set_hash_value(%w(dependencies).first, value) value = target_definition.to_hash['configuration_pod_whitelist'] next if value.blank? set_hash_value(%w(configuration_pod_whitelist).first, value) - # self.children = Array.new + end + end end diff --git a/cocoapods-imy-bin/lib/cocoapods-imy-bin/native/target_validator.rb b/cocoapods-imy-bin/lib/cocoapods-imy-bin/native/target_validator.rb new file mode 100755 index 0000000..d2764e7 --- /dev/null +++ b/cocoapods-imy-bin/lib/cocoapods-imy-bin/native/target_validator.rb @@ -0,0 +1,41 @@ +module Pod + class Installer + class Xcode + # The {Xcode::TargetValidator} ensures that the pod and aggregate target + # configuration is valid for installation. + # + class TargetValidator + + + + def verify_swift_pods_have_module_dependencies + error_messages = [] + pod_targets.each do |pod_target| + next unless pod_target.uses_swift? + + non_module_dependencies = [] + pod_target.dependent_targets.each do |dependent_target| + next if !dependent_target.should_build? || dependent_target.defines_module? + non_module_dependencies << dependent_target.name + end + + next if non_module_dependencies.empty? + + error_messages << "The Swift pod `#{pod_target.name}` depends upon #{non_module_dependencies.map { |d| "`#{d}`" }.to_sentence}, " \ + "which #{non_module_dependencies.count == 1 ? 'does' : 'do'} not define modules. " \ + 'To opt into those targets generating module maps '\ + '(which is necessary to import them from Swift when building as static libraries), ' \ + 'you may set `use_modular_headers!` globally in your Podfile, '\ + 'or specify `:modular_headers => true` for particular dependencies.' + end + return false + + # raise Informative, 'The following Swift pods cannot yet be integrated '\ + # "as static libraries:\n\n#{error_messages.join("\n\n")}" + end + + + end + end + end +end diff --git a/cocoapods-imy-bin/lib/cocoapods-imy-bin/native/validator.rb b/cocoapods-imy-bin/lib/cocoapods-imy-bin/native/validator.rb index e50008f..3461486 100755 --- a/cocoapods-imy-bin/lib/cocoapods-imy-bin/native/validator.rb +++ b/cocoapods-imy-bin/lib/cocoapods-imy-bin/native/validator.rb @@ -14,44 +14,7 @@ class Validator # Perform analysis for a given spec (or subspec) # def perform_extensive_analysis(spec) - if spec.non_library_specification? - error('spec', "Validating a non library spec (`#{spec.name}`) is not supported.") - return false - end - validate_homepage(spec) - validate_screenshots(spec) - validate_social_media_url(spec) - validate_documentation_url(spec) - validate_source_url(spec) - - platforms = platforms_to_lint(spec) - - valid = platforms.send(fail_fast ? :all? : :each) do |platform| - UI.message "\n\n#{spec} - Analyzing on #{platform} platform.".green.reversed - @consumer = spec.consumer(platform) - setup_validation_environment - begin - create_app_project - # download_pod - # check_file_patterns - # install_pod - # validate_swift_version - # add_app_project_import - # validate_vendored_dynamic_frameworks - # build_pod - # test_pod unless skip_tests - ensure - tear_down_validation_environment - end - validated? - end - return false if fail_fast && !valid - perform_extensive_subspec_analysis(spec) unless @no_subspecs - rescue => e - message = e.to_s - message << "\n" << e.backtrace.join("\n") << "\n" if config.verbose? - error('unknown', "Encountered an unknown error (#{message}) during validation.") - false + return true end #覆盖