CocoaPods/CocoaPods — pull request #253 by irrationalfab (2012-05-09 14:11:38+00:00)
Title: Specification refactor

Attempt to refactor the specification class. It is still a work in progress.

##### Objective

Have a clean hierarchy of specifications nodes:

- each specification inherits all its subspecs.
- for specification dryness common attributes can be specified by a node and will be inherited by all its subspecs.
- simplify code removing download only pods and wrappers [#223].
- If a specification contains incompatible subspecs it can specify a main subspec

---

##### Discusion

This is an experiment performed in total freedom (even in code style) and might have unwanted features that can be rolled back.

###### SubSpec class

The subspec class was decoupling inheritance logic from attributes specification and thus was removed and replaced with meta programming. Every specification can have a parent. If no parent is provided it is a top level specification.

Moreover, the subspec class was requiring its parent and this logic has been removed, in favor of the inheritance logic specified at the attribute level.

###### Inheritance

```ruby
dependency 'RestKit'
```
Will require result in the following specs being loaded:

`````
- RestKit
- RestKit/Network
- RestKit/ObjectMapping
- RestKit/ObjectMapping/CoreData
- RestKit/ObjectMapping/JSON
- RestKit/ObjectMapping/XML
- RestKit/UI
````

However, to handle incompatible different strategies it is possible to specify a main subspec:

`````ruby
dependency do |s|
s.main_subspec = 'JSON'
s.subspec 'JSON' do |js|
js.dependency 'RestKit/Network'
js.dependency 'RestKit/UI'
js.dependency 'RestKit/ObjectMapping/JSON'
js.dependency 'RestKit/ObjectMapping/CoreData'
end
s.subspec 'XML' do |js|
js.dependency 'RestKit/Network'
js.dependency 'RestKit/UI'
js.dependency 'RestKit/ObjectMapping/XML'
js.dependency 'RestKit/ObjectMapping/CoreData'
end
[...]
end
````

Is not fully implemented yet but this will result in the `RestKit` spec returning `RestKit/JSON` instead of itself so pod installs tells to newbies that they are using a json specific strategy.

###### Attributes inheritance

Some attributes can be specified only at the top level. They are what uniquely identifies a pod, can't be assigned by pods that have a parent (raises) and always return the top level value.

Other attributes are resolved back in the chain. For example every spec inherits all the frameworks required by its parents. The same logic will be applied to source files and if there are any duplicates local pod will filter the unique values. Looking at the code should be clear how every attribute is handled.

---

##### Todo

- deprecate clean paths
- add `readme_file` attribute to specification.
- nuke any file that is not specified in the podspec.
- will dry podpecs.
- in case if needed add a `preserve_files` attribute.
- local pod will receive a all the specifications sharing a common parent
- it will be able to remove duplicates (source files, frameworks, xconfig, ...).
- it will be able to clean all unused files.
- `Speficiation#activate_for_platform` activates a given platform so the attr readers return the value for the platform and clients will not need to be aware of which attributes are multiplatform.
- update the 0.6 branch of the master repo

---

###### Related Issues

- [#223] Pod subspec not adding other subspec dependencies to the project
- [#141] Specifying a podspec which contains subspecs throws exception
- [#87] Think of a good way to do clean_paths for a spec with subspecs