class Archiver

Public Class Methods

new(module_name, version, sources, flutter_wrapper, pub_upgrade, flutter_version, build_run, working_dir, repo, build_modes) click to toggle source
# File lib/cocoapods-flutter/native/archive/archive.rb, line 35
def initialize(module_name, version, sources, flutter_wrapper, pub_upgrade, flutter_version, build_run, working_dir, repo, build_modes)
  @module_name = module_name
  @version = version
  @sources = sources
  @flutter_wrapper = flutter_wrapper
  @pub_upgrade = pub_upgrade
  @flutter_version = flutter_version
  @build_run = build_run
  @working_dir = working_dir
  @product_dir = "#{@working_dir}/.product/"
  @pod_repo = repo
  @build_modes = build_modes
end

Public Instance Methods

archive() click to toggle source
# File lib/cocoapods-flutter/native/archive/archive.rb, line 49
def archive

  @pub_upgrade ? pub_upgrade : pub_get
  if local_podfile_exists?
    use_local_podfile
  else
    setup_pod_sources
  end

  if @build_run
    excute_build_run
  end
  build_framework
  @plugins = fetch_plugins

  if @build_modes.include?('debug')
    debug
  end

  if @build_modes.include?('release')
    release
  end

  Pod::UserInterface.message "All is ready to use!, now you can use 'flutter_pod '#{@module_name}', '#{@version}', :mode=>'debug/release' to use the pod"
end
make_flutter_pods(mode) click to toggle source
# File lib/cocoapods-flutter/native/archive/archive.rb, line 75
def make_flutter_pods(mode)
  @pub_upgrade ? pub_upgrade : pub_get
  setup_pod_sources
  if @build_run
    excute_build_run
  end

  build_app mode

  flutter_spec_dir = @product_dir + 'Flutter'
  flutter_spec_file = flutter_spec_dir + '/Flutter.podspec.json'
  flutter_spec = Pod::Spec.from_file @working_dir + '/.ios/Flutter/engine/Flutter.podspec'
  flutter_spec.vendored_frameworks = ['Flutter.framework', 'App.framework']
  plugin_registrant_spec_file = @working_dir + '/.ios/Flutter/FlutterPluginRegistrant/FlutterPluginRegistrant.podspec'

  unless Dir.exist? flutter_spec_dir
    FileUtils.mkdir_p flutter_spec_dir
  end

  File.open flutter_spec_file, "w+" do |file|
    file.write flutter_spec.to_pretty_json
  end

  FileUtils.cp_r @working_dir + '/.ios/Flutter/engine/Flutter.framework', flutter_spec_dir
  FileUtils.cp_r @working_dir + '/.ios/Flutter/App.framework', flutter_spec_dir

  plugins = fetch_plugins
  plugins.append Plugins.new('Flutter',flutter_spec_file,flutter_spec)
  plugins.append Plugins.new('FlutterPluginRegistrant',plugin_registrant_spec_file, Pod::Spec.from_file(plugin_registrant_spec_file))

  plugins
end

Private Instance Methods

build_app(mode) click to toggle source
# File lib/cocoapods-flutter/native/archive/archive.rb, line 227
def build_app(mode)
  if CommandRunner.run(@flutter_wrapper, 'build','ios',"--#{mode}" ,"--no-codesign") == false
    # FileUtils.remove_dir product_dir, true
    raise "Error running #{@flutter_wrapper} build ios --#{mode} --no-codesign"
  end
end
build_framework() click to toggle source
# File lib/cocoapods-flutter/native/archive/archive.rb, line 203
def build_framework

  commands = [
      @flutter_wrapper,
      'build',
      'ios-framework',
      "--output=#{@product_dir}",
      '--no-profile'
  ]

  if @build_modes.include?('debug') == false
    commands.append '--no-debug'
  end

  if @build_modes.include?('release') == false
    commands.append '--no-release'
  end

  if CommandRunner.run(*commands) == false
    # FileUtils.remove_dir product_dir, true
    raise "Error running #{commands.join ' '} "
  end
end
debug() click to toggle source
# File lib/cocoapods-flutter/native/archive/archive.rb, line 116
def debug
  app_file, sdk_file = zip_files @plugins, 'Debug'
  upload_files app_file, sdk_file, 'Debug'
  make_pod 'Debug'
end
excute_build_run() click to toggle source
# File lib/cocoapods-flutter/native/archive/archive.rb, line 197
def excute_build_run
  if CommandRunner.run(@flutter_wrapper, 'packages','pub','run','build_runner','build','--delete-conflicting-outputs') == false
    raise "Error running #{@flutter_wrapper} packages pub run build_runner build --delete-conflicting-outputs"
  end
end
fetch_plugins() click to toggle source
# File lib/cocoapods-flutter/native/archive/archive.rb, line 234
def fetch_plugins
  results = []
  flutter_plugins_list = @working_dir + '/.flutter-plugins'
  lines = IO.readlines(flutter_plugins_list)
  lines.each do |line|
    unless line =~ /^#/
      key_val = line.split '='
      key = key_val[0]
      value = key_val[1]
      value = value.gsub /\n/, ''
      path = "#{value}ios/#{key}.podspec"
      results.append Plugins.new(key, path, Pod::Specification.from_file(path))
    end
  end
  results
end
ignore_dependency?(name) click to toggle source
# File lib/cocoapods-flutter/native/archive/archive.rb, line 357
def ignore_dependency?(name)
  if name == 'Flutter'
    return true
  end

  for plugin in @plugins
    if plugin.name == name
      return true
    end
  end
  return false
end
local_podfile_exists?() click to toggle source
# File lib/cocoapods-flutter/native/archive/archive.rb, line 134
def local_podfile_exists?
  local_podfile_dir = @working_dir + '/local_podfile'
  File.exist? local_podfile_dir
end
make_pod(mode) click to toggle source
# File lib/cocoapods-flutter/native/archive/archive.rb, line 370
def make_pod(mode)

  dependency_graph = Molinillo::DependencyGraph.new
  @plugins.each do |plugin|
    plugin.spec.all_dependencies.each do |dep|
      unless ignore_dependency? dep.name
        dependency_graph.add_vertex(dep.name, dep, true)
      end
    end
  end

  remote = Remote.new()
  sdk_download_url = remote.download_url "Flutter", @flutter_version, mode.downcase
  app_download_url = remote.download_url @module_name, @version, mode.downcase
  spec = Pod::Spec.new do |s|
    s.swift_version         = '5.0'
    s.name                  = "#{@module_name}_#{mode.downcase}"
    s.version               = @version
    s.summary               = @module_name
    s.description           = @module_name
    s.homepage              = 'http://dreamtracer.top'
    s.license               = { :type => 'BSD' }
    s.author                = { 'Dreamtracer' => 'http://dreamtracer.top' }
    s.source                = { :http => app_download_url }
    s.ios.deployment_target = '10.0'
    s.prepare_command = "ruby download_sdk.rb #{sdk_download_url}"
    s.pod_target_xcconfig = { 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64 x86_64' }
    s.user_target_xcconfig = { 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64 x86_64' }
    vendored_frameworks = ["App.framework", "Flutter.framework", "FlutterPluginRegistrant.framework"]
    @plugins.each do |plugin|
      vendored_frameworks.append "#{plugin.name}.framework"
    end
    s.vendored_frameworks   = vendored_frameworks

    dependency_graph.each do |vertex|
      s.dependency vertex.payload.name, vertex.payload.requirement.to_s
    end
    s.resources = ['info.json', 'pubspec.lock']
  end
  temp_dir = Dir.tmpdir
  spec_file = temp_dir + "/#{@module_name}_#{mode.downcase}.podspec.json"
  File.open spec_file, "w+" do |file|
    file.write spec.to_pretty_json
  end

  Dir.chdir temp_dir do |dir|
    Pod::Command::Repo::Push.run([@pod_repo, '--skip-import-validation', '--verbose', '--allow-warnings', "--sources=#{@sources.join(',')}"])
    File.delete spec_file
  end

end
pub_get() click to toggle source
# File lib/cocoapods-flutter/native/archive/archive.rb, line 128
def pub_get
  if CommandRunner.run(@flutter_wrapper, 'pub', 'get') == false
    raise "Pub get fail"
  end
end
pub_upgrade() click to toggle source
# File lib/cocoapods-flutter/native/archive/archive.rb, line 122
def pub_upgrade
  if CommandRunner.run(@flutter_wrapper, 'pub', 'upgrade') == false
    raise "Pub upgrade fail"
  end
end
release() click to toggle source
# File lib/cocoapods-flutter/native/archive/archive.rb, line 110
def release
  app_file, sdk_file = zip_files @plugins, 'Release'
  upload_files app_file, sdk_file, 'Release'
  make_pod 'Release'
end
sdk_download() click to toggle source
# File lib/cocoapods-flutter/native/archive/archive.rb, line 290
  def sdk_download

    ruby_code = <<-CODE
#!/usr/bin/env ruby

require 'digest'
require 'open-uri'

sdk_url = ARGV[0]

def md5(url)
  Digest::MD5.hexdigest url
end
def download(url, dest)
  open(url) do |u|
    File.open(dest, "w+") do |file|
      file.write u.read
    end
  end
end
home_dir = Dir.home
cache_dir = home_dir + "/.cocoapods/.cache"
if Dir.exist?(cache_dir) == false
  Dir.mkdir cache_dir
end
#SDK下载
sdk_dir = cache_dir + "/\#{md5 sdk_url}"
sdk_file = sdk_dir + "/Flutter.zip"
if Dir.exist?(sdk_dir) == false
  Dir.mkdir sdk_dir
  download sdk_url, sdk_file
end
if File.exist? "Flutter.framework"
  `rm -rf Flutter.framework`
end
`unzip \#{sdk_file} -d \#{Dir.pwd}`
    CODE

    ruby_code

  end
setup_pod_sources() click to toggle source
# File lib/cocoapods-flutter/native/archive/archive.rb, line 139
def setup_pod_sources
  Pod::UserInterface.info 'Setup pod sources...'
  origin_pod_file_root_dir = @working_dir + '/.ios'
  origin_pod_file_dir = origin_pod_file_root_dir+ '/Podfile'
  temp_pod_file_dir_1 = @working_dir + '/tmp1.txt'
  temp_pod_file_dir_2 = @working_dir + '/tmp2.txt'
  if File.exist? temp_pod_file_dir_1
    FileUtils.remove_file temp_pod_file_dir_1
  end
  if File.exist? temp_pod_file_dir_2
    FileUtils.remove_file temp_pod_file_dir_2
  end

  # origin_pod_file = File.open origin_pod_file_dir
  temp_pod_file_1 = File.open temp_pod_file_dir_1, "w+"
  temp_pod_file_2 = File.open temp_pod_file_dir_2, "w+"

  @sources.each do |s|
    temp_pod_file_2.puts "source '#{s}'"
  end

  lines = IO.readlines(origin_pod_file_dir)

  lines.each do |line|
    if line =~ /platform\s+:ios\s*,\s*'\s*[0-9]*.[0-9]*\s*'/
      temp_pod_file_1.puts "platform :ios, '9.0'"
    elsif line =~ /source\s+/
      Pod::UserInterface.message 'Ignore ' + line
    else
      temp_pod_file_1.puts line
    end
  end

  temp_pod_file_1.close

  lines = IO.readlines(temp_pod_file_1)
  lines.each do |line|
    temp_pod_file_2.puts line
  end
  temp_pod_file_2.close

  File.open origin_pod_file_dir, "w+" do |file|
    file.write IO.readlines(temp_pod_file_2).join('')
    file.close
  end

end
upload_files(app_file, flutter_sdk, mode) click to toggle source
# File lib/cocoapods-flutter/native/archive/archive.rb, line 332
def upload_files(app_file, flutter_sdk, mode)
  Pod::UserInterface.info 'Start upload resources'
  remote = Remote.new()
  Pod::UserInterface.info "Checking #{@module_name}_#{@version}_#{mode.downcase}..."
  result = remote.exist? @module_name, @version, mode.downcase
  if result
    Pod::UserInterface.info "Found #{@module_name}_#{@version}_#{mode.downcase} and deleting..."
    remote.delete @module_name, @version, mode.downcase
  end
  Pod::UserInterface.info "Uploading #{@module_name}_#{@version}_#{mode.downcase}..."
  remote.upload @module_name, @version, mode.downcase, app_file


  Pod::UserInterface.info "Checking Flutter_#{@flutter_version}_#{mode.downcase}..."
  result = remote.exist? 'Flutter', @flutter_version, mode.downcase
  unless result
    Pod::UserInterface.info "No Flutter_#{@flutter_version}_#{mode.downcase} found, start uploading..."
    remote.upload 'Flutter', @flutter_version, mode.downcase, flutter_sdk
  end
  if result
    Pod::UserInterface.info "Flutter_#{@flutter_version}_#{mode.downcase} was found, skip upload"
  end

end
use_local_podfile() click to toggle source
# File lib/cocoapods-flutter/native/archive/archive.rb, line 187
def use_local_podfile
  origin_pod_file_root_dir = @working_dir + '/.ios'
  origin_pod_file_dir = origin_pod_file_root_dir+ '/Podfile'
  if File.exist? origin_pod_file_dir
    File.delete(origin_pod_file_dir)
  end
  local_podfile_dir = @working_dir + '/local_podfile'
  FileUtils.copy_file local_podfile_dir, origin_pod_file_dir
end
zip_files(plugins, mode) click to toggle source
# File lib/cocoapods-flutter/native/archive/archive.rb, line 251
def zip_files(plugins, mode)
  product_dir = @product_dir + "#{mode}"
  zip_file_dir = product_dir + "/zip"
  if Dir.exist? zip_file_dir
    FileUtils.remove_dir zip_file_dir, true
  end
  FileUtils.mkdir_p zip_file_dir
  zip_file = zip_file_dir + "/#{@module_name}.zip"
  Zip::File.open(zip_file, Zip::File::CREATE) do |zipfile|
    stdin, stdout, stderr, wait_thr = Open3.popen3('git', 'rev-parse', 'HEAD')
    commit = stdout.gets.gsub /\n/, ''
    info_hash = {
        :name => @module_name,
        :commit => commit,
        :version => @version,
        :sdk_version => @flutter_version
    }
    json = JSON.pretty_generate info_hash
    zipfile.get_output_stream("info.json") { |f| f.write json }
    zipfile.add 'pubspec.lock', "#{@working_dir}/pubspec.lock"
    zipfile.get_output_stream("download_sdk.rb") { |f| f.write sdk_download }
    zipfile.add_dir "App.framework", "#{product_dir}/App.framework"
    zipfile.add_dir "FlutterPluginRegistrant.framework","#{product_dir}/FlutterPluginRegistrant.framework"
    plugins.each do |plugin|
      file = File.join(product_dir, "#{plugin.spec.name}.framework")
      if Dir.exist? file
        zipfile.add_dir("#{plugin.spec.name}.framework", file)
      end
    end
  end

  sdk_file = zip_file_dir + "/Flutter.zip"
  Zip::File.open sdk_file, Zip::File::CREATE do |zipfile|
    file = File.join(product_dir, "Flutter.framework")
    zipfile.add_dir "Flutter.framework", file
  end
  [zip_file, sdk_file]
end