Skip to content

Commit 2c465af

Browse files
committed
feat(pbxproj): add swift package
1 parent 304cada commit 2c465af

File tree

9 files changed

+451
-76
lines changed

9 files changed

+451
-76
lines changed

README.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
# XcodeProj
22

3-
XcodeProj parser and data representation
3+
Work-in-progress XcodeProj reader and writer.
44

5-
## Features
5+
Currently optimized for reading and not garanted to be used to modify existing xcodeproj.
6+
7+
## Milestones
68

79
- [x] parse `*.xcodeproj` through [pest]
810
- [x] parse [pest] ast to `PBXRootObject`, as an meaningful abstraction.
11+
- [ ] add helper methods to maniuplate and read pbxproj objects.
912
- [ ] write `ProjectData` back to `*.xcodeproj` filetype.
13+
- [ ] preserve comments and reduce git conflicts.
14+
- [ ] support reading XCWorkspace and XCScheme
1015

1116

1217
[pest]: https://github.com/pest-parser/pest

src/pbxproj/object/build/phase/file.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::{cell::RefCell, rc::Rc};
2+
13
use crate::pbxproj::*;
24

35
/// [`PBXObject`] A File referenced by a build phase, unique to each build phase.
@@ -24,17 +26,14 @@ impl PBXBuildFile {
2426
}
2527

2628
/// Create new [`PBXBuildFile`] from product_reference only
27-
pub fn new_from_product(
28-
product_reference: String,
29-
objects: Option<WeakPBXObjectCollection>,
30-
) -> Self {
29+
pub fn new_from_swift_product(reference: String, objects: WeakPBXObjectCollection) -> Self {
3130
Self {
3231
settings: Default::default(),
3332
platform_filter: Default::default(),
3433
file_reference: Default::default(),
35-
product_reference: Some(product_reference),
34+
product_reference: Some(reference),
3635
build_phase_reference: Default::default(),
37-
objects: objects.unwrap_or_default(),
36+
objects,
3837
}
3938
}
4039

@@ -44,9 +43,11 @@ impl PBXBuildFile {
4443
}
4544

4645
/// Get Product using self.product_reference
47-
pub fn get_product(&self, _data: &PBXRootObject) -> Option<XCSwiftPackageProductDependency> {
48-
// productReference?.getObject()
49-
todo!()
46+
pub fn product(&self) -> Option<Rc<RefCell<XCSwiftPackageProductDependency>>> {
47+
self.objects
48+
.upgrade()?
49+
.borrow()
50+
.get_swift_package_product_dependency(self.product_reference.as_ref()?)
5051
}
5152

5253
/// Set Product.

src/pbxproj/object/collection.rs

Lines changed: 112 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::{PBXObject, PBXTarget, XCRemoteSwiftPackageReference};
1+
use super::*;
22
use std::{
33
cell::RefCell,
44
collections::HashMap,
@@ -30,19 +30,75 @@ impl PBXObjectCollection {
3030
self.get(reference)?.as_pbx_target().map(|r| r.clone())
3131
}
3232

33-
/// Get XCRemoteSwiftPackageReference from a vec of references
34-
pub fn get_packages_from_references<'a>(
33+
/// Get PBXBuildPhase by reference
34+
pub fn get_build_phase<'a>(&'a self, reference: &str) -> Option<Rc<RefCell<PBXBuildPhase>>> {
35+
self.get(reference)?.as_pbx_build_phase().map(|r| r.clone())
36+
}
37+
38+
/// Get PBXBuildFile by reference
39+
pub fn get_build_file<'a>(&'a self, reference: &str) -> Option<Rc<RefCell<PBXBuildFile>>> {
40+
self.get(reference)?.as_pbx_build_file().map(|r| r.clone())
41+
}
42+
43+
/// Get all PBXBuildPhase
44+
pub fn build_phases<'a>(&'a self) -> Vec<(String, Rc<RefCell<PBXBuildPhase>>)> {
45+
self.iter()
46+
.filter(|o| o.1.is_pbx_build_phase())
47+
.map(|(k, o)| (k.clone(), o.as_pbx_build_phase().unwrap().clone()))
48+
.collect()
49+
}
50+
51+
/// Get all PBXBuildFile
52+
pub fn build_files<'a>(&'a self) -> Vec<(String, Rc<RefCell<PBXBuildFile>>)> {
53+
self.iter()
54+
.filter(|o| o.1.is_pbx_build_file())
55+
.map(|(k, o)| (k.clone(), o.as_pbx_build_file().unwrap().clone()))
56+
.collect()
57+
}
58+
59+
/// Get All XCSwiftPackageProductDependency Objects
60+
pub fn swift_package_product_dependencies<'a>(
3561
&'a self,
36-
references: &Vec<String>,
37-
) -> Vec<(String, Rc<RefCell<XCRemoteSwiftPackageReference>>)> {
38-
references
39-
.iter()
40-
.map(|id| {
41-
let package = self.get(id)?.as_xc_remote_swift_package_reference()?;
42-
Some((id.clone(), package.clone()))
62+
) -> Vec<(String, Rc<RefCell<XCSwiftPackageProductDependency>>)> {
63+
self.iter()
64+
.map(|(k, v)| {
65+
Some((
66+
k.clone(),
67+
v.as_xc_swift_package_product_dependency()?.clone(),
68+
))
4369
})
4470
.flatten()
45-
.collect()
71+
.collect::<Vec<_>>()
72+
}
73+
74+
/// Get All XCRemoteSwiftPackageReference Objects
75+
pub fn swift_package_references<'a>(
76+
&'a self,
77+
) -> Vec<(String, Rc<RefCell<XCRemoteSwiftPackageReference>>)> {
78+
self.iter()
79+
.map(|(k, v)| Some((k.clone(), v.as_xc_remote_swift_package_reference()?.clone())))
80+
.flatten()
81+
.collect::<Vec<_>>()
82+
}
83+
84+
/// Get XCSwiftPackageProductDependency by reference
85+
pub fn get_swift_package_product_dependency<'a>(
86+
&'a self,
87+
object_reference: &str,
88+
) -> Option<Rc<RefCell<XCSwiftPackageProductDependency>>> {
89+
self.get(object_reference)?
90+
.as_xc_swift_package_product_dependency()
91+
.map(|r| r.clone())
92+
}
93+
94+
/// Get XCSwiftPackageProductDependency by reference
95+
pub fn get_swift_package_reference<'a>(
96+
&'a self,
97+
object_reference: &str,
98+
) -> Option<Rc<RefCell<XCRemoteSwiftPackageReference>>> {
99+
self.get(object_reference)?
100+
.as_xc_remote_swift_package_reference()
101+
.map(|r| r.clone())
46102
}
47103

48104
/// Get PBXTarget from a vec of references
@@ -52,10 +108,7 @@ impl PBXObjectCollection {
52108
) -> Vec<(String, Rc<RefCell<PBXTarget>>)> {
53109
references
54110
.iter()
55-
.map(|id| {
56-
let target = self.get_target(id)?;
57-
Some((id.clone(), target.clone()))
58-
})
111+
.map(|id| Some((id.clone(), self.get_target(id)?)))
59112
.flatten()
60113
.collect()
61114
}
@@ -79,4 +132,48 @@ impl PBXObjectCollection {
79132
})
80133
.map(|(key, o)| (key.clone(), o.as_pbx_target().unwrap().clone()))
81134
}
135+
136+
/// Get XCRemoteSwiftPackageReference from a vec of references
137+
pub fn get_swift_package_reference_from_references<'a>(
138+
&'a self,
139+
references: &Vec<String>,
140+
) -> Vec<(String, Rc<RefCell<XCRemoteSwiftPackageReference>>)> {
141+
references
142+
.iter()
143+
.map(|reference| {
144+
Some((
145+
reference.clone(),
146+
self.get_swift_package_reference(reference)?,
147+
))
148+
})
149+
.flatten()
150+
.collect()
151+
}
152+
153+
/// Get PBXBuildPhase from a vec of references
154+
pub fn get_build_phases_from_reference<'a>(
155+
&'a self,
156+
references: &Vec<String>,
157+
) -> Vec<(String, Rc<RefCell<PBXBuildPhase>>)> {
158+
references
159+
.iter()
160+
.map(|reference| Some((reference.clone(), self.get_build_phase(reference)?)))
161+
.flatten()
162+
.collect()
163+
}
164+
165+
/// Get XCSwiftPackageProductDependency form a given target reference
166+
pub fn get_product_dependency_from_target_reference<'a>(
167+
&'a self,
168+
target_reference: &str,
169+
) -> Option<(String, Rc<RefCell<XCSwiftPackageProductDependency>>)> {
170+
self.swift_package_product_dependencies()
171+
.into_iter()
172+
.find(|(_, p)| {
173+
p.borrow()
174+
.package_reference()
175+
.map(|v| v == target_reference)
176+
.unwrap_or_default()
177+
})
178+
}
82179
}

src/pbxproj/object/file/group.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@ impl PBXGroup {
2727
// .flatten()
2828
// .collect::<Vec<_>>()
2929
// }
30+
31+
/// Get a reference to the pbxgroup's children references.
32+
#[must_use]
33+
pub fn children_references(&self) -> &HashSet<String> {
34+
&self.children_references
35+
}
3036
}
3137

3238
impl PBXObjectExt for PBXGroup {

0 commit comments

Comments
 (0)