Class: ZergXcode::Plugins::Retarget

Inherits:
Object
  • Object
show all
Includes:
Objects
Defined in:
lib/zerg_xcode/plugins/retarget.rb

Instance Method Summary collapse

Instance Method Details

#helpObject



4
5
6
7
8
9
10
11
12
13
# File 'lib/zerg_xcode/plugins/retarget.rb', line 4

def help
  {:short => 'reassign files to a target or set of targets',
   :long => <<"END" }
Usage: retarget project_path pattern [target target..]

Reassigns all the files matching a pattern to a target or set of targets. The
files matching the pattern will be removed from all other targets. If no target
is specified, the files are removed from all targets.
END
end

#retarget!(project, regexp, targets) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/zerg_xcode/plugins/retarget.rb', line 24

def retarget!(project, regexp, targets)
  # maps each file type to the type of the phase it's in
  file_type_phases = {}
  # maps each file to the phase it's in
  file_phases = {}
  # maps each PBXFileRef to the PBXBuildFile pointing to it
  build_files = {}
  
  # populate the maps
  project['targets'].each do |target|
    target.all_files.each do |file|
      build_file = file[:build_object]
      phase_type = file[:phase]['isa']
      build_files[file[:object]] = build_file
      file_type_phases[build_file.file_type] = phase_type
      file_phases[file[:object]] = phase_type
    end
  end
  
  # compute target sets
  in_targets = project['targets'].select do |target|
    targets.include? target['name']
  end
  out_targets = project['targets'] - in_targets
  
  # clean up targets outside the args
  out_targets.each do |target|
    target['buildPhases'].each do |phase|
      phase['files'].reject! { |build_file| regexp =~ build_file.filename }
    end
  end

  # build a list of the files in the project matching the pattern
  new_files = project.all_files.map { |file| file[:object] }.select do |file|
    regexp =~ file['path']
  end
  # build PBXBuildFile wrappers around files that don't have them
  new_files.each do |file|
    next if build_files[file]
    
    build_file = PBXBuildFile.new 'fileRef' => file
    build_files[file] = build_file
    file_phases[file] = file_type_phases[build_file.file_type] ||
        build_file.guessed_build_phase_type
  end
  
  # add files to targets matching the args
  in_targets.each do |target|
    already_in = Set.new(target.all_files.map { |file| file[:object] })      
    new_files.each do |file|
      file_ref = file[:object]
      next if already_in.include? file
      phase_type = file_phases[file]
      phase = target['buildPhases'].find { |p| p['isa'] ==  phase_type }
      unless phase
        phase = PBXBuildPhase.new_phase phase_type
        target['buildPhases'] << phase
      end
      phase['files'] << build_files[file]
    end
  end
end

#run(args) ⇒ Object



15
16
17
18
19
20
21
22
# File 'lib/zerg_xcode/plugins/retarget.rb', line 15

def run(args)
  path = args.shift
  pattern = args.shift
  regexp = Regexp.compile pattern
  project = ZergXcode.load path
  retarget! project, regexp, args
  project.save!
end