Class: XCCache::SPM::Package::Description

Inherits:
BaseObject show all
Includes:
Cacheable
Defined in:
lib/xccache/spm/desc/desc.rb

Constant Summary

Constants inherited from BaseObject

BaseObject::ATTRS

Instance Attribute Summary

Attributes inherited from HashRepresentable

#path, #raw

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Cacheable

#__cacheable_module_name, #cacheable, included

Methods inherited from BaseObject

#cast_to, #display_name, #fetch, #full_name, #inspect, #name, #pkg_desc_of, #pkg_name, #pkg_slug, #src_dir, #to_s

Methods included from Config::Mixin

#config

Methods inherited from JSONRepresentable

#load, #save

Methods inherited from HashRepresentable

#[], #[]=, #initialize, #load, #merge!, #save

Constructor Details

This class inherits a constructor from XCCache::HashRepresentable

Class Method Details

.combine_descs(descs) ⇒ Object



118
119
120
121
122
# File 'lib/xccache/spm/desc/desc.rb', line 118

def self.combine_descs(descs)
  descs_by_name = descs.flat_map { |d| [[d.name, d], [d.pkg_slug, d]] }.to_h
  descs.each { |d| d.retrieve_pkg_desc = proc { |name| descs_by_name[name] } }
  descs_by_name
end

.descs_in_dir(root_dir, save_to_dir: nil) ⇒ Object



25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/xccache/spm/desc/desc.rb', line 25

def self.descs_in_dir(root_dir, save_to_dir: nil)
  dirs = [root_dir] + root_dir.glob(".build/checkouts/*").reject { |p| p.glob("Package*.swift").empty? }
  descs = dirs.parallel_map do |dir|
    desc = Description.in_dir(dir, save_to_dir: save_to_dir)
    unless save_to_dir.nil?
      desc.save
      desc.save(to: desc.path.parent / "#{desc.name}.json") if desc.name != dir.basename.to_s
    end
    desc
  end
  [descs, combine_descs(descs)]
end

.descs_in_metadata_dirObject



10
11
12
13
# File 'lib/xccache/spm/desc/desc.rb', line 10

def self.
  descs = Config.instance..glob("*.json").map { |p| Description.new(p) }
  [descs, combine_descs(descs)]
end

.in_dir(dir, save_to_dir: nil) ⇒ Object



15
16
17
18
19
20
21
22
23
# File 'lib/xccache/spm/desc/desc.rb', line 15

def self.in_dir(dir, save_to_dir: nil)
  path = save_to_dir / "#{dir.basename}.json" unless save_to_dir.nil?
  begin
    raw = JSON.parse(Sh.capture_output("swift package dump-package --package-path #{dir}"))
    Description.new(path, raw: raw)
  rescue StandardError => e
    UI.error("Failed to dump package in #{dir}. Error: #{e}")
  end
end

Instance Method Details

#binary_targetsObject



62
63
64
# File 'lib/xccache/spm/desc/desc.rb', line 62

def binary_targets
  @binary_targets ||= targets.select(&:binary?)
end

#dependenciesObject



46
47
48
# File 'lib/xccache/spm/desc/desc.rb', line 46

def dependencies
  @dependencies ||= fetch("dependencies", Dependency)
end

#get_target(name) ⇒ Object



70
71
72
# File 'lib/xccache/spm/desc/desc.rb', line 70

def get_target(name)
  targets.find { |t| t.name == name }
end

#gitObject



114
115
116
# File 'lib/xccache/spm/desc/desc.rb', line 114

def git
  @git ||= Git.new(src_dir) if Dir.git?(src_dir)
end

#has_target?(name) ⇒ Boolean

Returns:

  • (Boolean)


66
67
68
# File 'lib/xccache/spm/desc/desc.rb', line 66

def has_target?(name)
  targets.any? { |t| t.name == name }
end

#local?Boolean

Returns:

  • (Boolean)


84
85
86
87
# File 'lib/xccache/spm/desc/desc.rb', line 84

def local?
  # Workaround: If the pkg dir is under the build checkouts dir -> remote
  !src_dir.to_s.start_with?((config.spm_build_dir / "checkouts").to_s)
end

#metadataObject



42
43
44
# File 'lib/xccache/spm/desc/desc.rb', line 42

def 
  raw["_metadata"] ||= {}
end

#productsObject



54
55
56
# File 'lib/xccache/spm/desc/desc.rb', line 54

def products
  @products ||= fetch("products", Product)
end

#resolve_recursive_dependencies(platform: nil) ⇒ Object



80
81
82
# File 'lib/xccache/spm/desc/desc.rb', line 80

def resolve_recursive_dependencies(platform: nil)
  products.to_h { |p| [p, p.recursive_targets(platform: platform)] }
end

#rootObject



38
39
40
# File 'lib/xccache/spm/desc/desc.rb', line 38

def root
  self
end

#targetsObject



58
59
60
# File 'lib/xccache/spm/desc/desc.rb', line 58

def targets
  @targets ||= fetch("targets", Target).map(&:downcast)
end

#targets_of_products(name) ⇒ Object



74
75
76
77
78
# File 'lib/xccache/spm/desc/desc.rb', line 74

def targets_of_products(name)
  matched_products = products.select { |p| p.name == name }
  matched_products
    .flat_map { |p| targets.select { |t| p.target_names.include?(t.name) } }
end

#traverseObject



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/xccache/spm/desc/desc.rb', line 89

def traverse
  nodes, edges, parents = [], [], {}
  to_visit = targets.dup
  visited = Set.new
  until to_visit.empty?
    cur = to_visit.pop
    next if visited.include?(cur)

    visited << cur
    nodes << cur
    yield cur if block_given?

    # For macro impl, we don't need their dependencies, just the tool binary
    # So, no need to care about swift-syntax dependencies
    next if cur.macro?
    cur.direct_dependency_targets.each do |t|
      to_visit << t
      edges << [cur, t]
      parents[t] ||= []
      parents[t] << cur
    end
  end
  [nodes, edges, parents]
end

#uniform_dependenciesObject



50
51
52
# File 'lib/xccache/spm/desc/desc.rb', line 50

def uniform_dependencies
  dependencies.filter_map(&:pkg_desc)
end