-
Notifications
You must be signed in to change notification settings - Fork 1.4k
SR-1741: Add non-source files from source directories and root, ignore files from .gitignore #1507
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
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for working on this! I left some comments inline.
Sources/Xcodeproj/generate().swift
Outdated
} | ||
|
||
// Get the ignored files and exclude them | ||
let ignoredFiles = try repositoryProvider.openCheckout(at: srcroot).getIgnoredFiles() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we need to handle the case when there is no repository at srcroot
.
Sources/Xcodeproj/generate().swift
Outdated
if !isFile($0) { return false } | ||
if let `extension` = $0.extension { | ||
if SupportedLanguageExtension.cFamilyExtensions.contains(`extension`) { return false } | ||
if SupportedLanguageExtension.swiftExtensions.contains(`extension`) { return false } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can use validExtensions
here instead.
Sources/Xcodeproj/generate().swift
Outdated
@@ -181,3 +199,17 @@ func findDirectoryReferences(path: AbsolutePath) throws -> [AbsolutePath] { | |||
return isDirectory($0) | |||
}) | |||
} | |||
|
|||
/// Finds the non-source files from `path` recursively |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since recursively is a parameter, this should be reworded.
Sources/Xcodeproj/generate().swift
Outdated
// Find non-source files in the source directories and root that should be added | ||
// as a reference to the project. | ||
var extraFiles = try findNonSourceFiles(path: srcroot) | ||
if let sourcesExtraFiles = try? findNonSourceFiles(path: srcroot.appending(component: "Sources"), recursively: true) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we don't need to use try?
here.
Sources/Xcodeproj/generate().swift
Outdated
|
||
// Get the ignored files and exclude them | ||
let ignoredFiles = try repositoryProvider.openCheckout(at: srcroot).getIgnoredFiles() | ||
extraFiles = extraFiles.filter { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could just be extraFiles = extraFiles.filter(ignoredFiles.contains)
.
@@ -391,6 +391,16 @@ public class GitRepository: Repository, WorkingCheckout { | |||
return localFileSystem.isDirectory(AbsolutePath(firstLine)) | |||
} | |||
|
|||
public func getIgnoredFiles() -> [AbsolutePath] { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could have a big impact on performance because we will end up looking at each file in the .build directory, which is generally big. We should find a way to do this in a better way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the review.
Yeah, this slipped my mind.
Maybe we could use git check-ignore
on the files found by findNonSourceFiles
.
Or should we also ignore the files if there isn't a repository for the package?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using git check-ignore
sounds like a good idea. And if there isn't a repository for the package, then by definition no files are ignored in a Git sense, so I don't think there's an issue there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah I meant to say that we should make sure we don't throw when there is no repository.
Sources/Xcodeproj/pbxproj().swift
Outdated
@@ -294,7 +297,6 @@ func xcodeProject( | |||
let name = (sourcesGroup == nil ? groupName : target.name) | |||
let group = (sourcesGroup ?? parentGroup) | |||
.addGroup(path: (path == "." ? "" : path), pathBase: .projectDir, name: name) | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please avoid whitespace diffs.
Sources/Xcodeproj/generate().swift
Outdated
let ignoredFiles = try repositoryProvider.openCheckout(at: srcroot).getIgnoredFiles() | ||
extraFiles = extraFiles.filter { | ||
return !ignoredFiles.contains($0) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can pass a closure to walk function that will avoid iterating the ignored directories, which is a little better for performance. We should also get some tests to prove this PR works.
args: Git.tool, "-C", path.asString, "ls-files", "-o", "-i", "--exclude-standard").chomp() | ||
return result?.split(separator: "\n").map(String.init).map { | ||
return path.appending(RelativePath($0)) | ||
} ?? [] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should not ignore the failures here and mark this method throwing.
c43fab6
to
7b95046
Compare
How should we handle global |
@giginet What's the particular problem with a global |
Yes, |
I've added tests for this. |
@aciidb0mb3r Could you please review this? |
Sources/Xcodeproj/generate().swift
Outdated
if try repositoryProvider.checkoutExists(at: srcroot) { | ||
// Get the ignored files and exclude them | ||
let repository = try repositoryProvider.openCheckout(at: srcroot) | ||
extraFiles = try extraFiles.filter { try !repository.isIgnored($0) } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor nitpick: Can you surround the closure with parentheses to match the informal project style? For reference, it follows the Rule of Kevin (“When a trailing closure argument is functional, use parentheses. When it is procedural, use braces.”)
Minor stylistic comment, but this LGTM! @aciidb0mb3r what do you think? |
@hartbit Thanks for the review! I've fixed the parentheses around the closures. |
@@ -92,6 +92,13 @@ public class GitRepositoryProvider: RepositoryProvider { | |||
} | |||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should land git related changes in a separate PR.
@@ -387,6 +397,22 @@ public class GitRepository: Repository, WorkingCheckout { | |||
return localFileSystem.isDirectory(AbsolutePath(firstLine)) | |||
} | |||
|
|||
/// Returns true if the file at `path` is ignored by `git` | |||
public func isIgnored(_ path: AbsolutePath) throws -> Bool { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about isGitIgnored
?
Sources/Xcodeproj/generate().swift
Outdated
// as a reference to the project. | ||
var extraFiles = try findNonSourceFiles(path: srcroot) | ||
|
||
let sourcesDirectory = srcroot.appending(component: "Sources") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should use the (root) package object to get this path as it maybe something else other than Sources.
Sources/Xcodeproj/generate().swift
Outdated
if try repositoryProvider.checkoutExists(at: srcroot) { | ||
// Get the ignored files and exclude them | ||
let repository = try repositoryProvider.openCheckout(at: srcroot) | ||
extraFiles = try extraFiles.filter({ try !repository.isIgnored($0) }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is going to shell out for every single extra file which will have a huge performance impact. Is there a way to pass multiple files in an invocation?
Sources/Xcodeproj/generate().swift
Outdated
@@ -77,10 +79,32 @@ public func generate( | |||
// references in the project. | |||
let extraDirs = try findDirectoryReferences(path: srcroot) | |||
|
|||
// Find non-source files in the source directories and root that should be added |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should factor out this entire diff into a new method.
@aciidb0mb3r Thanks for the review, I've made the requested changes. |
@aciidb0mb3r I don’t agree with calling the function |
Ah, thats a good point. Maybe we should call it something else? isIgnored feels a bit vague but I can't think of something better either. |
I can also agree with @hartbit . |
|
Yeah, that's right. |
Add test cases for the inclusion of files in the root directory, for the inclusion of non-source files in source directories and for the exclusion of files by git.
Put parentheses around the functional trailing closures
…ction Pass all the extra file paths to `isGitIgnored` at once to improve performance
I've removed the Git related changes from this. |
Sources/Xcodeproj/generate().swift
Outdated
} | ||
} | ||
|
||
if let checkout = workingCheckout { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, maybe we shouldn't do this unless we have a working checkout because otherwise we will end up adding dot files like .DS_Store
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I can agree on this, also I think in most cases there will be a working checkout, so requiring it for this feature shouldn't cause many issues.
@swift-ci test with toolchain |
Sources/Xcodeproj/generate().swift
Outdated
if !isFile($0) { return false } | ||
if let `extension` = $0.extension, SupportedLanguageExtension.validExtensions.contains(`extension`) { | ||
return false | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should also exclude dot files here.
…onSourceFiles Like this, we won't check the extension for dot files unnecessarily
Ok, this looks good to me! Thanks a lot for all your work here!! |
@swift-ci please smoke test |
Thank you for reviewing my code and helping me! |
In swiftlang#1507, we started adding "extra" files to the generated Xcode project. This makes some enhancements to that feature: - Introduce a new flag `--skip-extra-files` to go back to the pre-4.2 behaviour (best behaviour) of not including these files at all - Do not add a file reference for "Package.resolved" since this shouldn't be edited by hand and most people also never have to read it - Move the "extra" file references after the products group. This may be debatable, but I think it more clean to have all file references related to the package manifest grouped together at the top instead of having these interspersed throughout the main group.
In #1507, we started adding "extra" files to the generated Xcode project. This makes some enhancements to that feature: - Introduce a new flag `--skip-extra-files` to go back to the pre-4.2 behaviour (best behaviour) of not including these files at all - Do not add a file reference for "Package.resolved" since this shouldn't be edited by hand and most people also never have to read it - Move the "extra" file references after the products group. This may be debatable, but I think it more clean to have all file references related to the package manifest grouped together at the top instead of having these interspersed throughout the main group.
No description provided.