require 'fileutils' module Pod class Command # This is an example of a cocoapods plugin adding a top-level subcommand # to the 'pod' command. # # You can also create subcommands of existing or new commands. Say you # wanted to add a subcommand to `list` to show newly deprecated pods, # (e.g. `pod list deprecated`), there are a few things that would need # to change. # # - move this file to `lib/pod/command/list/deprecated.rb` and update # the class to exist in the the Pod::Command::List namespace # - change this class to extend from `List` instead of `Command`. This # tells the plugin system that it is a subcommand of `list`. # - edit `lib/cocoapods_plugins.rb` to require this file # # @todo Create a PR to add your plugin to CocoaPods/cocoapods.org # in the `plugins.json` file, once your plugin is released. # class TuyaOssPublish < Command self.summary = 'Build binary and upload to oss.' self.description = <<-DESC cocoapods-tuya-oss-publish will call pod package and then upload binary to oss. Usually used for sdk. DESC self.arguments = [ CLAide::Argument.new('REPO', true), CLAide::Argument.new('[NAME.podspec]', true), ] def self.options [ ['--library', 'Generate static libraries.'], ['--spec-sources=private,https://github.com/CocoaPods/Specs.git', 'The sources to pull dependant ' \ 'pods from (defaults to https://github.com/CocoaPods/Specs.git)'], ['--upload-to', 'The place where zip archive upload to, Defaults to oss. (oss/maven/bintray)'], ['--force', 'Override existing remote archive.'], ['--oss-endpoint', 'Aliyun oss endpoint, defaults to https://oss-cn-hangzhou.aliyuncs.com.'], ['--oss-access-key-id', 'Aliyun oss access key id.'], ['--oss-access-key-secret', 'Aliyun oss access key secret.'], ['--oss-bucket-name', 'Aliyun oss bucket name.'], ['--oss-base-path', 'Aliyun oss base path, defaults to /.'], ['--maven-auth', 'Maven auth (USER[:PASSWORD]).'], ['--maven-group-id', 'Maven group id, defaults to com.tuya.ios.'], ['--bintray-auth', 'Bintray auth (USER[:PASSWORD]).'], ['--bintray-subject', 'Bintray subject.'], ['--bintray-repo', 'Bintray repo.'], ] end def initialize(argv) @repo = argv.shift_argument @local_repo_path = "#{ENV["HOME"]}/.cocoapods/repos/#{@repo}" @podspec_path = argv.shift_argument @library = argv.flag?('library') # framework/library @spec_sources = argv.option('spec-sources') @upload_to = argv.option('upload-to', 'oss') @force = argv.flag?('force', false) @oss_endpoint = argv.option('oss-endpoint', 'https://oss-cn-hangzhou.aliyuncs.com') @oss_access_key_id = argv.option('oss-access-key-id') @oss_access_key_secret = argv.option('oss-access-key-secret') @oss_bucket_name = argv.option('oss-bucket-name') @oss_base_path = argv.option('oss-base-path', '') super end def validate! super help! 'A spec-repo name or url is required.' unless @repo help! "#{@repo} repo not exist in ~/.cocoapods/repos/." unless File.directory?(@local_repo_path) help! 'A podspec file path is required.' unless @podspec_path if @upload_to == 'oss' help! 'A oss-access-key-id is required.' unless @oss_access_key_id help! 'A oss-access-key-secret is required.' unless @oss_access_key_secret help! 'A oss-bucket-name is required.' unless @oss_bucket_name else help! 'upload-to param is required.' end end def run @podspec = Pod::Specification::from_file(@podspec_path) UI.puts "Building #{@dynamic ? "dynamic" : "static"} #{@library ? "library" : "framework"}: #{@podspec.name} (#{@podspec.version})" self.package if @upload_to == 'oss' url = self.upload_to_oss(self.archive, @force) end binary_spec = self.create_binary_podspec(@podspec, url) self.repo_push_without_build(binary_spec) end def package # pod package podspec_path = "#{@podspec.name}.podspec.json" File.write(podspec_path, @podspec.to_pretty_json) argv = CLAide::ARGV.new([ podspec_path, "--no-mangle", "--exclude-deps", "--spec-sources=#{@spec_sources}", @library ? "--library" : "", "--force", "--verbose", ]) begin package = TYPackage.new(argv) package.run rescue => exception UI.puts(exception) help! "#{@podspec.name} (#{@podspec.version}) build failed." ensure File.delete(podspec_path) end end def create_binary_podspec(source_spec, archive_url) keys_to_be_removed = [ "source", "prefix_header_contents", "prefix_header_file", "source_files", "public_header_files", "private_header_files", "vendored_frameworks", "vendored_libraries", "subspecs", # TODO copy resources # "resource_bundles", # "resources", ] # Remove source-related keys binary_spec = source_spec.to_hash for key in keys_to_be_removed do if binary_spec.key?(key) binary_spec.delete(key) end for platform in source_spec.available_platforms if binary_spec.key?(platform.name) if binary_spec[platform.name].key?(key) binary_spec[platform.name].delete(key) end else binary_spec[platform.name] = {} end end end binary_spec['static_framework'] = true # set source url binary_spec['source'] = { 'type': 'zip', 'http': archive_url, } # set vendored_libraries/vendored_frameworks for platform in source_spec.available_platforms if @library binary_spec[platform.name]['vendored_libraries'] = "#{platform.name}/*.a" else binary_spec[platform.name]['vendored_frameworks'] = "#{platform.name}/*.framework" end end # set headers if @library binary_spec['public_header_files'] = "Headers/**/*.h" end binary_spec = Specification.from_hash(binary_spec) UI.puts(binary_spec.to_pretty_json) binary_spec end def repo_push_without_build(spec) local_repo_path = "#{ENV["HOME"]}/.cocoapods/repos/#{@repo}" repo_spec_dir = "#{local_repo_path}/Specs/#{spec.name}/#{spec.version}" repo_spec_path = "#{repo_spec_dir}/#{spec.name}.podspec.json" # repo update exit_code = system("""cd #{repo_spec_dir} \ && git fetch \ && REPO_COMMIT_HASH=`git rev-parse origin/master` \ && git reset --hard $REPO_COMMIT_HASH """) if exit_code != 0 help! 'pod repo update failed.' end # write File.delete(repo_spec_path) if File.exist?(repo_spec_path) FileUtils.mkdir_p(repo_spec_path) File.write(repo_spec_path, spec.to_pretty_json) # commit exit_code = system("""cd #{repo_spec_dir} \ && git add . \ && git commit -m \"⚠️ [Add] #{spec.name} (#{spec.version})\" \ && git push """) if exit_code != 0 help! 'pod repo push failed.' end end end end end