class Pod::Command::Package

Public Class Methods

new(argv) click to toggle source
Calls superclass method
# File lib/pod/command/package.rb, line 29
def initialize(argv)
  @embedded = argv.flag?('embedded')
  @library = argv.flag?('library')
  @dynamic = argv.flag?('dynamic')
  @local = argv.flag?('local', false)
  @package_type = if @embedded
                    :static_framework
                  elsif @dynamic
                    :dynamic_framework
                  elsif @library
                    :static_library
                  else
                    :static_framework
                  end
  @force = argv.flag?('force',true)
  @mangle = argv.flag?('mangle', true)
  @bundle_identifier = argv.option('bundle-identifier', nil)
  @exclude_deps = argv.flag?('exclude-deps', true)
  @name = argv.shift_argument
  @source = argv.shift_argument
  @spec_sources = argv.option('spec-sources', 'git@gitlab.idc.xiaozhu.com:iOS/XZPrivatePodsRepo.git,https://github.com/CocoaPods/Specs.git').split(',')
  subspecs = argv.option('subspecs')
  @subspecs = subspecs.split(',') unless subspecs.nil?
  @config = argv.option('configuration', 'Release')
  @source_dir = Dir.pwd
  @is_spec_from_path = false
  @spec = spec_with_path(@name)
  @is_spec_from_path = true if @spec
  @spec ||= spec_with_name(@name)
  @target_path = ''
  super
end
options() click to toggle source
# File lib/pod/command/package.rb, line 12
def self.options
  [
    ['--force',     'Overwrite existing files.'],
    ['--no-mangle', 'Do not mangle symbols of depedendant Pods.'],
    ['--embedded',  'Generate embedded frameworks.'],
    ['--library',   'Generate static libraries.'],
    ['--dynamic',   'Generate dynamic framework.'],
    ['--local',     'Use local state rather than published versions.'],
    ['--bundle-identifier', 'Bundle identifier for dynamic framework'],
    ['--exclude-deps', 'Exclude symbols from dependencies.'],
    ['--configuration', 'Build the specified configuration (e.g. Debug). Defaults to Release'],
    ['--subspecs', 'Only include the given subspecs'],
    ['--spec-sources=private,https://github.com/CocoaPods/Specs.git', 'The sources to pull dependent ' \
      'pods from (defaults to https://github.com/CocoaPods/Specs.git)']
  ]
end

Public Instance Methods

run() click to toggle source
# File lib/pod/command/package.rb, line 71
def run
  if @spec.nil?
    help! "Unable to find a podspec with path or name `#{@name}`."
    return
  end

  target_dir, work_dir = create_working_directory
  return if target_dir.nil?
  build_package
  `mv "#{work_dir}" "#{target_dir}"`
  `rm -rf #{target_dir}/build`
  Dir.chdir(@source_dir)
  zip_upload_static_server
end
validate!() click to toggle source
Calls superclass method
# File lib/pod/command/package.rb, line 62
def validate!
  super
  help! 'A podspec name or path is required.' unless @spec
  help! 'podspec has binary-only depedencies, mangling not possible.' if @mangle && binary_only?(@spec)
  help! '--bundle-identifier option can only be used for dynamic frameworks' if @bundle_identifier && !@dynamic
  help! '--exclude-deps option can only be used for static libraries' if @exclude_deps && @dynamic
  help! '--local option can only be used when a local `.podspec` path is given.' if @local && !@is_spec_from_path
end

Private Instance Methods

binary_only?(spec) click to toggle source
# File lib/cocoapods-packager/pod_utils.rb, line 66
def binary_only?(spec)
  deps = spec.dependencies.map { |dep| spec_with_name(dep.name) }
  [spec, *deps].each do |specification|
    %w(vendored_frameworks vendored_libraries).each do |attrib|
      if specification.attributes_hash[attrib]
        return true
      end
    end
  end

  false
end
build_dynamic_sandbox(_static_sandbox, _static_installer) click to toggle source
# File lib/cocoapods-packager/pod_utils.rb, line 113
def build_dynamic_sandbox(_static_sandbox, _static_installer)
  dynamic_sandbox_root = Pathname.new(config.sandbox_root + '/Dynamic')
  dynamic_sandbox = Sandbox.new(dynamic_sandbox_root)

  dynamic_sandbox
end
build_dynamic_target(dynamic_sandbox, static_installer, platform) click to toggle source

@param [Pod::Installer] static_installer

@return [Pod::PodTarget]

# File lib/cocoapods-packager/pod_utils.rb, line 152
def build_dynamic_target(dynamic_sandbox, static_installer, platform)
  spec_targets = static_installer.pod_targets.select do |target|
    target.name == @spec.name
  end
  static_target = spec_targets[0]

  file_accessors = create_file_accessors(static_target, dynamic_sandbox)

  archs = []
  dynamic_target = Pod::PodTarget.new(dynamic_sandbox, true, static_target.user_build_configurations, archs, platform, static_target.specs, static_target.target_definitions, file_accessors)
  dynamic_target
end
build_in_sandbox(platform) click to toggle source
# File lib/pod/command/package.rb, line 88
def build_in_sandbox(platform)
  config.installation_root  = Pathname.new(Dir.pwd)
  config.sandbox_root       = 'Pods'

  static_sandbox = build_static_sandbox(@dynamic)
  static_installer = install_pod(platform.name, static_sandbox)

  if @dynamic
    dynamic_sandbox = build_dynamic_sandbox(static_sandbox, static_installer)
    install_dynamic_pod(dynamic_sandbox, static_sandbox, static_installer, platform)
  end

  begin
    perform_build(platform, static_sandbox, dynamic_sandbox, static_installer)
  ensure # in case the build fails; see Builder#xcodebuild.
    Pathname.new(config.sandbox_root).rmtree
    FileUtils.rm_f('Podfile.lock')
  end
end
build_package() click to toggle source
# File lib/pod/command/package.rb, line 108
def build_package
  builder = SpecBuilder.new(@spec, @source, @embedded, @dynamic)
  newspec = builder.spec_metadata
  need_platforms = @spec.available_platforms.select {|plat| plat.name == :ios}
  need_platforms.each do |platform|
    build_in_sandbox(platform)

    newspec += builder.spec_platform(platform)
  end

  newspec += builder.spec_close
  File.open(@spec.name + '.podspec', 'w') { |file| file.write(newspec) }
end
build_static_sandbox(dynamic) click to toggle source
# File lib/cocoapods-packager/pod_utils.rb, line 6
def build_static_sandbox(dynamic)
  static_sandbox_root = if dynamic
                          Pathname.new(config.sandbox_root + '/Static')
                        else
                          Pathname.new(config.sandbox_root)
                        end
  Sandbox.new(static_sandbox_root)
end
copy_dynamic_target(static_sandbox, _dynamic_target, dynamic_sandbox) click to toggle source
# File lib/cocoapods-packager/pod_utils.rb, line 188
def copy_dynamic_target(static_sandbox, _dynamic_target, dynamic_sandbox)
  command = "cp -a #{static_sandbox.root}/#{@spec.name} #{dynamic_sandbox.root}"
  `#{command}`
end
create_file_accessors(target, dynamic_sandbox) click to toggle source
# File lib/cocoapods-packager/pod_utils.rb, line 193
def create_file_accessors(target, dynamic_sandbox)
  pod_root = dynamic_sandbox.pod_dir(target.root_spec.name)

  path_list = Sandbox::PathList.new(pod_root)
  target.specs.map do |spec|
    Sandbox::FileAccessor.new(path_list, spec.consumer(target.platform))
  end
end
create_target_directory() click to toggle source
# File lib/pod/command/package.rb, line 170
def create_target_directory
  target_dir = "#{@source_dir}/#{@spec.name}-#{@spec.version}"
  if File.exist? target_dir
    if @force
      Pathname.new(target_dir).rmtree
    else
      UI.puts "Target directory '#{target_dir}' already exists."
      return nil
    end
  end
  @target_path = target_dir
  target_dir
end
create_working_directory() click to toggle source
# File lib/pod/command/package.rb, line 184
def create_working_directory
  target_dir = create_target_directory
  return if target_dir.nil?

  work_dir = Dir.tmpdir + '/cocoapods-' + Array.new(8) { rand(36).to_s(36) }.join
  Pathname.new(work_dir).mkdir
  Dir.chdir(work_dir)

  [target_dir, work_dir]
end
install_dynamic_pod(dynamic_sandbox, static_sandbox, static_installer, platform) click to toggle source

@param [Pod::Sandbox] dynamic_sandbox

@param [Pod::Sandbox] static_sandbox

@param [Pod::Installer] static_installer

@param [Pod::Platform] platform

# File lib/cocoapods-packager/pod_utils.rb, line 128
def install_dynamic_pod(dynamic_sandbox, static_sandbox, static_installer, platform)
  # 1 Create a dynamic target for only the spec pod.
  dynamic_target = build_dynamic_target(dynamic_sandbox, static_installer, platform)

  # 2. Build a new xcodeproj in the dynamic_sandbox with only the spec pod as a target.
  project = prepare_pods_project(dynamic_sandbox, dynamic_target.name, static_installer)

  # 3. Copy the source directory for the dynamic framework from the static sandbox.
  copy_dynamic_target(static_sandbox, dynamic_target, dynamic_sandbox)

  # 4. Create the file references.
  install_file_references(dynamic_sandbox, [dynamic_target], project)

  # 5. Install the target.
  install_library(dynamic_sandbox, dynamic_target, project)

  # 6. Write the actual .xcodeproj to the dynamic sandbox.
  write_pod_project(project, dynamic_sandbox)
end
install_file_references(dynamic_sandbox, pod_targets, pods_project) click to toggle source
# File lib/cocoapods-packager/pod_utils.rb, line 202
def install_file_references(dynamic_sandbox, pod_targets, pods_project)
  installer = Pod::Installer::Xcode::PodsProjectGenerator::FileReferencesInstaller.new(dynamic_sandbox, pod_targets, pods_project)
  installer.install!
end
install_library(dynamic_sandbox, dynamic_target, project) click to toggle source
# File lib/cocoapods-packager/pod_utils.rb, line 207
def install_library(dynamic_sandbox, dynamic_target, project)
  return if dynamic_target.target_definitions.flat_map(&:dependencies).empty?
  target_installer = Pod::Installer::Xcode::PodsProjectGenerator::PodTargetInstaller.new(dynamic_sandbox, project, dynamic_target)
  result = target_installer.install!
  native_target = result.native_target

  # Installs System Frameworks
  if dynamic_target.should_build?
    dynamic_target.file_accessors.each do |file_accessor|
      file_accessor.spec_consumer.frameworks.each do |framework|
        native_target.add_system_framework(framework)
      end
      file_accessor.spec_consumer.libraries.each do |library|
        native_target.add_system_library(library)
      end
    end
  end
end
install_pod(platform_name, sandbox) click to toggle source
# File lib/cocoapods-packager/pod_utils.rb, line 15
def install_pod(platform_name, sandbox)
  podfile = podfile_from_spec(
    @path,
    @spec.name,
    platform_name,
    @spec.deployment_target(platform_name),
    @subspecs,
    @spec_sources
  )

  static_installer = Installer.new(sandbox, podfile)
  static_installer.install!

  unless static_installer.nil?
    static_installer.pods_project.targets.each do |target|
      target.build_configurations.each do |config|
        config.build_settings['CLANG_MODULES_AUTOLINK'] = 'NO'
        config.build_settings['GCC_GENERATE_DEBUGGING_SYMBOLS'] = 'NO'
      end
    end
    static_installer.pods_project.save
  end

  static_installer
end
perform_build(platform, static_sandbox, dynamic_sandbox, static_installer) click to toggle source
# File lib/pod/command/package.rb, line 195
def perform_build(platform, static_sandbox, dynamic_sandbox, static_installer)
  static_sandbox_root = config.sandbox_root.to_s

  if @dynamic
    static_sandbox_root = "#{static_sandbox_root}/#{static_sandbox.root.to_s.split('/').last}"
    dynamic_sandbox_root = "#{config.sandbox_root}/#{dynamic_sandbox.root.to_s.split('/').last}"
  end

  builder = Pod::Builder.new(
    platform,
    static_installer,
    @source_dir,
    static_sandbox_root,
    dynamic_sandbox_root,
    static_sandbox.public_headers.root,
    @spec,
    @embedded,
    @mangle,
    @dynamic,
    @config,
    @bundle_identifier,
    @exclude_deps
  )

  builder.build(@package_type)

  return unless @embedded
  builder.link_embedded_resources
end
podfile_from_spec(path, spec_name, platform_name, deployment_target, subspecs, sources) click to toggle source
# File lib/cocoapods-packager/pod_utils.rb, line 41
def podfile_from_spec(path, spec_name, platform_name, deployment_target, subspecs, sources)
  options = {}
  if path
    if @local
      options[:path] = path
    else
      options[:podspec] = path
    end
  end
  options[:subspecs] = subspecs if subspecs
  Pod::Podfile.new do
    sources.each { |s| source s }
    platform(platform_name, deployment_target)
    pod(spec_name, options)

    install!('cocoapods',
             :integrate_targets => false,
             :deterministic_uuids => false)

    target('packager') do
      inherit! :complete
    end
  end
end
prepare_pods_project(dynamic_sandbox, spec_name, installer) click to toggle source

@param [Pod::Sandbox] dynamic_sandbox

@param [String] spec_name

@param [Pod::Installer] installer

# File lib/cocoapods-packager/pod_utils.rb, line 171
def prepare_pods_project(dynamic_sandbox, spec_name, installer)
  # Create a new pods project
  pods_project = Pod::Project.new(dynamic_sandbox.project_path)

  # Update build configurations
  installer.analysis_result.all_user_build_configurations.each do |name, type|
    pods_project.add_build_configuration(name, type)
  end

  # Add the pod group for only the dynamic framework
  local = dynamic_sandbox.local?(spec_name)
  path = dynamic_sandbox.pod_dir(spec_name)
  was_absolute = dynamic_sandbox.local_path_was_absolute?(spec_name)
  pods_project.add_pod_group(spec_name, path, local, was_absolute)
  pods_project
end
sftp_upload(ftp) click to toggle source
# File lib/pod/command/package.rb, line 144
def sftp_upload(ftp)
  local_path = "#{@target_path}/#{@spec.name}-#{@spec.version}.zip"
  remote_path = "/home/devuser/local/www/staticpods/#{@spec.name}/#{@spec.name}-#{@spec.version}.zip"
  ftp.upload!(local_path,remote_path) do |event ,uploader,*args|
    case event
    when :open 
      # args[0] : file metadata
      UI.puts "framework starting upload: #{args[0].local} -> #{args[0].remote} (#{args[0].size} bytes}"
    when :put 
      # args[0] : file metadata
      # args[1] : byte offset in remote file
      # args[2] : data being written (as string)
      UI.puts "framework writing  to #{args[0].remote}"
    when :close 
      # args[0] : file metadata
      UI.puts "framework finished with #{args[0].remote}"
    when :mkdir 
      # args[0] : remote path name
      UI.puts "framework creating directory #{args[0]}"
    when :finish 
      UI.puts "framework all done!"
    else
      UI.puts "encounter unknown case"
    end
  end
end
spec_with_name(name) click to toggle source
# File lib/cocoapods-packager/pod_utils.rb, line 79
def spec_with_name(name)
  return if name.nil?

  set = Pod::Config.instance.sources_manager.search(Dependency.new(name))
  return nil if set.nil?

  set.specification.root
end
spec_with_path(path) click to toggle source
# File lib/cocoapods-packager/pod_utils.rb, line 88
def spec_with_path(path)
  return if path.nil?
  path = Pathname.new(path)
  path = Pathname.new(Dir.pwd).join(path) unless path.absolute?
  return unless path.exist?

  @path = path.expand_path

  if @path.directory?
    help! @path + ': is a directory.'
    return
  end

  unless ['.podspec', '.json'].include? @path.extname
    help! @path + ': is not a podspec.'
    return
  end

  Specification.from_file(@path)
end
upload_ftp_server() click to toggle source
# File lib/pod/command/package.rb, line 132
def upload_ftp_server
  Net::SFTP.start('10.0.2.77','devuser',:password => 'love1993') do |ftp|
    ftp.open("/home/devuser/local/www/staticpods/#{@spec.name}") do |response|
      if response.ok?
        sftp_upload(ftp) 
      else
        ftp.mkdir!("/home/devuser/local/www/staticpods/#{@spec.name}")
        sftp_upload(ftp)
      end
    end
  end
end
write_pod_project(dynamic_project, dynamic_sandbox) click to toggle source
# File lib/cocoapods-packager/pod_utils.rb, line 226
def write_pod_project(dynamic_project, dynamic_sandbox)
  UI.message "- Writing Xcode project file to #{UI.path dynamic_sandbox.project_path}" do
    dynamic_project.pods.remove_from_project if dynamic_project.pods.empty?
    dynamic_project.development_pods.remove_from_project if dynamic_project.development_pods.empty?
    dynamic_project.sort(:groups_position => :below)
    dynamic_project.recreate_user_schemes(false)

    # Edit search paths so that we can find our dependency headers
    dynamic_project.targets.first.build_configuration_list.build_configurations.each do |config|
      config.build_settings['HEADER_SEARCH_PATHS'] = "$(inherited) #{Dir.pwd}/Pods/Static/Headers/**"
      config.build_settings['USER_HEADER_SEARCH_PATHS'] = "$(inherited) #{Dir.pwd}/Pods/Static/Headers/**"
      config.build_settings['OTHER_LDFLAGS'] = '$(inherited) -ObjC'
    end
    dynamic_project.save
  end
end
zip_upload_static_server() click to toggle source
# File lib/pod/command/package.rb, line 122
def zip_upload_static_server
  Dir.chdir(@target_path)
  `zip -r #{@spec.name}-#{@spec.version}.zip *`
  if $?.exitstatus != 0
    UI.puts "#{@target_path} zip failed"
  else
    upload_ftp_server
  end
end