Skip to content

Commit 8252a3c

Browse files
committed
SPM: allow specs to declare Swift Package Manager depenencies with spm_dependency
1 parent 9320bf5 commit 8252a3c

File tree

9 files changed

+171
-0
lines changed

9 files changed

+171
-0
lines changed

lib/cocoapods-core/specification.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
require 'cocoapods-core/specification/root_attribute_accessors'
77
require 'cocoapods-core/specification/set'
88
require 'cocoapods-core/specification/json'
9+
require 'cocoapods-core/specification/spm_requirement'
910

1011
module Pod
1112
# The Specification provides a DSL to describe a Pod. A pod is defined as a

lib/cocoapods-core/specification/consumer.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
require 'cocoapods-core/specification/root_attribute_accessors'
2+
require 'cocoapods-core/specification/spm_requirement'
23

34
module Pod
45
class Specification
@@ -234,6 +235,14 @@ def dependencies
234235
end
235236
end
236237

238+
#-----------------------------------------------------------------------#
239+
def spm_dependencies
240+
value = value_for_attribute(:spm_dependencies)
241+
value.map do |spm_dependency|
242+
{:url => spm_dependency[:url], :requirement => Pod::Specification::SpmRequirement.new(spm_dependency[:requirement]), :products => spm_dependency[:products]}
243+
end
244+
end
245+
237246
# Raw values need to be prepared as soon as they are read so they can be
238247
# safely merged to support multi platform attributes and inheritance
239248
#-----------------------------------------------------------------------#

lib/cocoapods-core/specification/dsl.rb

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -755,6 +755,34 @@ def dependency=(args)
755755

756756
#------------------#
757757

758+
attribute :spm_dependencies,
759+
:container => Array,
760+
:inherited => true
761+
762+
# Dependency on Swift Manager Packages.
763+
#
764+
# ---
765+
#
766+
# Dependencies should specify versions requirements.
767+
#
768+
# @example
769+
# spec.spm_dependency(
770+
# :url => 'https://github.com/apple/swift-atomics.git',
771+
# :requirement' => {:kind => 'upToNextMajorVersion', :minimumVersion => '1.1.0'},
772+
# :products' => ['Atomics']
773+
# )
774+
775+
def spm_dependency(url: , requirement:, products:)
776+
attributes_hash['spm_dependencies'] ||= []
777+
attributes_hash['spm_dependencies'] << {
778+
:url => url,
779+
:requirement => requirement,
780+
:products => products,
781+
}
782+
end
783+
784+
#------------------#
785+
758786
# @!method info_plist=(info_plist)
759787
#
760788
# Key-Value pairs to add to the generated `Info.plist`.

lib/cocoapods-core/specification/linter.rb

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,28 @@ def _validate_scheme(s)
471471
end
472472
end
473473

474+
475+
# Performs validations related to the `spm_dependencies` attribute.
476+
#
477+
def _validate_spm_dependencies(s)
478+
unless s.empty?
479+
s.each do |spm_dependency|
480+
if spm_dependency[:url].nil?
481+
results.add_error('spm_dependencies', 'SPM dependencies should specify a url.')
482+
end
483+
if spm_dependency[:requirement].nil?
484+
results.add_error('spm_dependencies', 'SPM dependencies should specify a requirement.')
485+
end
486+
if requirement_errors = SpmRequirement.validate(spm_dependency[:requirement])
487+
results.add_error('spm_dependencies', requirement_errors)
488+
end
489+
if spm_dependency[:products].nil?
490+
results.add_error('spm_dependencies', 'SPM dependencies should specify products.')
491+
end
492+
end
493+
end
494+
end
495+
474496
# Performs validations related to github sources.
475497
#
476498
def perform_github_source_checks(s)
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
module Pod
2+
class Specification
3+
# This class validates and represents swift package manager dependecy requirements
4+
class SpmRequirement
5+
REQUIRED_KEYS = {
6+
:upToNextMajorVersion => [:minimumVersion],
7+
:upToNextMinorVersion => [:minimumVersion],
8+
:exactVersion => [:version],
9+
:versionRange => %i[minimumVersion maximumVersion],
10+
}.freeze
11+
12+
def initialize(requirement_hash)
13+
@requirement = requirement_hash
14+
validate
15+
end
16+
17+
def kind
18+
@requirement[:kind]
19+
end
20+
21+
def ==(other)
22+
@requirement == other.instance_variable_get(:@requirement)
23+
end
24+
25+
def validate
26+
raise 'Kind should be string' unless kind.is_a?(String)
27+
raise "Unknown requirement kind #{kind}" if REQUIRED_KEYS[kind.to_sym].nil?
28+
29+
REQUIRED_KEYS[kind.to_sym].each do |key|
30+
raise "Missing key #{key} for requirement #{@requirement}" unless @requirement[key]
31+
end
32+
end
33+
34+
def to_h
35+
@requirement.map { |k,v| [k.to_s, v.to_s] }.to_h
36+
end
37+
38+
def self.validate(requirement_hash)
39+
if (requirement_hash.is_a? SpmRequirement)
40+
requirement_hash.validate
41+
nil
42+
else
43+
new(requirement_hash)
44+
nil
45+
end
46+
rescue => e
47+
e.message
48+
end
49+
end
50+
end
51+
end

spec/specification/consumer_spec.rb

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -602,6 +602,30 @@ module Pod
602602

603603
#-------------------------------------------------------------------------#
604604

605+
describe 'SPM Dependencies' do
606+
before do
607+
@spec = Spec.new do |s|
608+
s.name = 'Pod'
609+
s.spm_dependency(
610+
:url => "https://github.com/apple/example-package-fisheryates.git",
611+
:requirement => { :kind => "upToNextMajorVersion", :minimumVersion => "1.0.0" },
612+
:products => ["FisherYates"],
613+
)
614+
end
615+
@consumer = Specification::Consumer.new(@spec, :ios)
616+
end
617+
618+
it 'returns the spm_dependencies with SpmRequirement' do
619+
@consumer.spm_dependencies.should == [{
620+
:url => "https://github.com/apple/example-package-fisheryates.git",
621+
:requirement => Specification::SpmRequirement.new({ :kind => "upToNextMajorVersion", :minimumVersion => "1.0.0" }),
622+
:products => ["FisherYates"],
623+
}]
624+
end
625+
end
626+
627+
#-------------------------------------------------------------------------#
628+
605629
describe 'Private helpers' do
606630
before do
607631
@spec = Spec.new do |s|

spec/specification/dsl_spec.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,17 @@ module Pod
312312

313313
#------------------#
314314

315+
describe 'spm_dependency' do
316+
it 'allows to specify a single spm_dependency' do
317+
@spec.spm_dependency(:url => "foo", :requirement => {:kind => "upToNextMajorVersion", :minimumVersion => "1.0.0"}, :products => ["Foo"])
318+
@spec.attributes_hash['spm_dependencies'].should == [
319+
{ :url => 'foo', :requirement => {:kind => "upToNextMajorVersion", :minimumVersion => "1.0.0"}, :products => ["Foo"] },
320+
]
321+
end
322+
end
323+
324+
#------------------#
325+
315326
it 'allows to specify whether the specification requires ARC' do
316327
@spec.requires_arc = false
317328
@spec.attributes_hash['requires_arc'].should == false

spec/specification/json_spec.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,24 @@ module Pod
572572
result.swift_versions.map(&:to_s).should == %w(3.2 4.0 4.1)
573573
result.swift_version.to_s.should == '4.1'
574574
end
575+
576+
describe 'Swift Package Manger dependencies' do
577+
it 'writes spm dependency' do
578+
@spec.spm_dependency(
579+
:url => 'http://github.com/foo/foo',
580+
:requirement => {:kind => 'upToNextMajorVersion', :minimumVersion => '1.0.0'},
581+
:products => ['Foo'],
582+
)
583+
hash = @spec.to_hash
584+
hash['spm_dependencies'].should == [
585+
{
586+
:url => 'http://github.com/foo/foo',
587+
:requirement => {:kind => 'upToNextMajorVersion', :minimumVersion => '1.0.0'},
588+
:products => ['Foo']
589+
}
590+
]
591+
end
592+
end
575593
end
576594
end
577595
end

spec/specification/linter_spec.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -693,6 +693,13 @@ def result_should_include(*values)
693693
@spec.compiler_flags = '-some_flag', '-another -Wno_flags'
694694
result_should_include('warnings', 'disabled', 'compiler_flags')
695695
end
696+
697+
#------------------#
698+
699+
it 'check if spm dependency requirement upToNextMinorVersion has a minimumVersion key' do
700+
@spec.spm_dependency(:url => 'https://github.com/foo/foo', :requirement => { :kind => 'upToNextMinorVersion' }, :products => ['Foo'])
701+
result_should_include('missing key minimumVersion')
702+
end
696703
end
697704

698705
#--------------------------------------#

0 commit comments

Comments
 (0)