Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fully qualified Names of source files #40

Closed
olbrichj opened this issue Aug 9, 2017 · 13 comments
Closed

Fully qualified Names of source files #40

olbrichj opened this issue Aug 9, 2017 · 13 comments

Comments

@olbrichj
Copy link

olbrichj commented Aug 9, 2017

Hey,

sorry if this is the wrong place to ask, but I can't find anything anywhere else.

Is there an option to get the fully qualified name of the sourcefiles? In project.pbxproj.objects I can only find the direct filename.

Thanks

@yonaskolb
Copy link
Collaborator

Do you mean the path to the file? If so you would have to traverse the groups it exists in, and build up the path that way.
That would be a good helper method, we should add it

@olbrichj
Copy link
Author

olbrichj commented Aug 9, 2017

Thanks :)
Yes I'm referring to the path to the file. Either starting at root of the project, or even better at root of the system /Users/xx/project/.../main.swift.
I'll check if I figure out how to traverse it. Currently I'm struggling with the documentation.

@olbrichj
Copy link
Author

olbrichj commented Aug 9, 2017

I've written a small example. Not sure if I got everything. Is there an option to separate by target?

let project = try! XcodeProj(path: "Demo.xcodeproj")
let pbxproj = project.pbxproj
let buildGroups = pbxproj.objects.groups

for group in buildGroups {
    if let path = group.path {
        for child in group.children {
            if let found = pbxproj.objects.index(where: { $0.reference == child }) {
                var name = ""
                switch pbxproj.objects[found] {
                case .pbxFileReference(let file): name = file.path!
                default:
                    break
                }
                print(path + "/" + name)
            }
        }
    }
}

@yonaskolb
Copy link
Collaborator

  • instead of pbxproj.objects.index(where: you could use pbxproj.objects.first(where:
  • you'd have to do this recursively to handle nested groups, and build up the path along the way
  • you'd have to handle the path differently base on the group sourceTree
  • if you want to filter by target, you'd have to check if there was a build file for a certain target

What's your use case? Maybe there's a different way to achieve what you're after

@olbrichj
Copy link
Author

olbrichj commented Aug 9, 2017

Thanks for your input. I'd still love to see a helper method for this :)

Currently I'm trying to write some kind of IDE for iOS/OSX development. To get a list of all source files I'd love to import the Xcode.proj. This way I would know, which files are actually used and not just part of the structure.

@pepicrft pepicrft added this to the 0.1.2 milestone Aug 25, 2017
@pepicrft pepicrft removed this from the 0.1.2 milestone Sep 7, 2017
@stale
Copy link

stale bot commented Nov 28, 2017

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot closed this as completed Dec 5, 2017
@pepicrft
Copy link
Contributor

pepicrft commented Dec 5, 2017

This shouldn't be closed. Reopening.

@pepicrft pepicrft reopened this Dec 5, 2017
@stale stale bot removed the status:wont-fix label Dec 5, 2017
@ilyapuchka
Copy link
Contributor

I'm using this code to get full path of file element:

extension PBXProj.Objects {
    func fullPath(fileElement: PBXFileElement, reference: String, sourceRoot: Path) -> Path? {
        switch fileElement.sourceTree {
        case .absolute?:
            return fileElement.path.flatMap({ Path($0) })
        case .sourceRoot?:
            return fileElement.path.flatMap({ Path($0, relativeTo: sourceRoot) })
        case .group?:
            guard let group = pbxproj.objects.groups.first(where: { $0.value.children.contains(reference) }) else { return sourceRoot }
            guard let groupPath = fullPath(fileElement: group.value, reference: group.key, sourceRoot: sourceRoot) else { return nil }
            return fileElement.path.flatMap({ Path($0, relativeTo: groupPath) })
        default:
            return nil
        }
    }
}
extension Path {
    init(_ string: String, relativeTo relativePath: Path) {
        var path = Path(string)
        if !path.isAbsolute {
            path = (relativePath + path).absolute()
        }
        self.init(path.string)
    }
}

It only encounters absolute paths and paths relative to groups or sources root, but it should be possible to extend it to other source tree types if it's possible to provide corresponding environment variables.
P.S. it probably can be optimised as it iterates over all groups for each intermediate group.

@pepicrft
Copy link
Contributor

@ilyapuchka I think that would be a great addition to xcproj. Would you mind adding it? We could optimize it in future iterations if it's necessary.

@olbrichj
Copy link
Author

These methods are great. Just one question:

How to I generate the sourceRoot? Since the project file can be anywhere in subdirectories I'm wondering whether I can get the sourceRoot somewhere within xcproj.

@ilyapuchka
Copy link
Contributor

Basically it's just the path to the project file. In Xcode it is an environment variable so you can't get it from the project, unless it defines a custom build setting that equals to this value.

@ilyapuchka
Copy link
Contributor

Closed with #213

@olbrichj
Copy link
Author

olbrichj commented Feb 3, 2018

That makes it easy :) thx

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants