Skip to content

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

Merged
merged 10 commits into from
Jul 4, 2018

Conversation

ViktorSimko
Copy link
Contributor

No description provided.

Copy link
Contributor

@aciidgh aciidgh left a 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.

}

// Get the ignored files and exclude them
let ignoredFiles = try repositoryProvider.openCheckout(at: srcroot).getIgnoredFiles()
Copy link
Contributor

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.

if !isFile($0) { return false }
if let `extension` = $0.extension {
if SupportedLanguageExtension.cFamilyExtensions.contains(`extension`) { return false }
if SupportedLanguageExtension.swiftExtensions.contains(`extension`) { return false }
Copy link
Contributor

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.

@@ -181,3 +199,17 @@ func findDirectoryReferences(path: AbsolutePath) throws -> [AbsolutePath] {
return isDirectory($0)
})
}

/// Finds the non-source files from `path` recursively
Copy link
Contributor

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.

// 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) {
Copy link
Contributor

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.


// Get the ignored files and exclude them
let ignoredFiles = try repositoryProvider.openCheckout(at: srcroot).getIgnoredFiles()
extraFiles = extraFiles.filter {
Copy link
Contributor

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] {
Copy link
Contributor

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.

Copy link
Contributor Author

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?

Copy link
Contributor

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.

Copy link
Contributor

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.

@@ -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)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please avoid whitespace diffs.

let ignoredFiles = try repositoryProvider.openCheckout(at: srcroot).getIgnoredFiles()
extraFiles = extraFiles.filter {
return !ignoredFiles.contains($0)
}
Copy link
Contributor

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))
} ?? []
Copy link
Contributor

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.

@aciidgh aciidgh added the WIP Work in progress label Mar 1, 2018
@ViktorSimko ViktorSimko force-pushed the SR-1741 branch 2 times, most recently from c43fab6 to 7b95046 Compare March 3, 2018 21:50
@giginet
Copy link
Contributor

giginet commented Mar 4, 2018

How should we handle global .gitignore?

@hartbit
Copy link
Contributor

hartbit commented Jun 12, 2018

@giginet What's the particular problem with a global .gitignore? Doesn't check-ignore already handle them?

@ViktorSimko
Copy link
Contributor Author

Yes, check-ignore handles every input file to the exclusion.

@ViktorSimko
Copy link
Contributor Author

I've added tests for this.

@ViktorSimko
Copy link
Contributor Author

@aciidb0mb3r Could you please review this?

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) }
Copy link
Contributor

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.”)

@hartbit
Copy link
Contributor

hartbit commented Jun 19, 2018

Minor stylistic comment, but this LGTM! @aciidb0mb3r what do you think?

@ViktorSimko
Copy link
Contributor Author

@hartbit Thanks for the review! I've fixed the parentheses around the closures.

@@ -92,6 +92,13 @@ public class GitRepositoryProvider: RepositoryProvider {
}
}
Copy link
Contributor

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 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about isGitIgnored?

// as a reference to the project.
var extraFiles = try findNonSourceFiles(path: srcroot)

let sourcesDirectory = srcroot.appending(component: "Sources")
Copy link
Contributor

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.

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) })
Copy link
Contributor

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?

@@ -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
Copy link
Contributor

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.

@ViktorSimko
Copy link
Contributor Author

@aciidb0mb3r Thanks for the review, I've made the requested changes.

@hartbit
Copy link
Contributor

hartbit commented Jun 20, 2018

@aciidb0mb3r I don’t agree with calling the function isGitIgnored: it’s a requirement on Repository and won’t make any sense if and when we provide an implementation for any other repository system (SVN, Mercurial). I think it should definitely be called isIgnored.

@aciidgh
Copy link
Contributor

aciidgh commented Jun 20, 2018

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.

@ViktorSimko
Copy link
Contributor Author

ViktorSimko commented Jun 21, 2018

I can also agree with @hartbit .
For me, isIgnored would be expressing enough.
It's a member of WorkingCheckout so I think it's clear that it means "ignored by whatever VCS we are using".

@hartbit
Copy link
Contributor

hartbit commented Jun 21, 2018

is singular does feel wrong as it checks for multiple files thought: areFilesIgnored(at:)?

@ViktorSimko
Copy link
Contributor Author

Yeah, that's right.
areFilesIgnored(at:) seems to be better.

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
@ViktorSimko
Copy link
Contributor Author

I've removed the Git related changes from this.

}
}

if let checkout = workingCheckout {
Copy link
Contributor

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

Copy link
Contributor Author

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.

@aciidgh
Copy link
Contributor

aciidgh commented Jul 4, 2018

@swift-ci test with toolchain

if !isFile($0) { return false }
if let `extension` = $0.extension, SupportedLanguageExtension.validExtensions.contains(`extension`) {
return false
}
Copy link
Contributor

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
@aciidgh
Copy link
Contributor

aciidgh commented Jul 4, 2018

Ok, this looks good to me! Thanks a lot for all your work here!!

@aciidgh
Copy link
Contributor

aciidgh commented Jul 4, 2018

@swift-ci please smoke test

@aciidgh aciidgh removed the WIP Work in progress label Jul 4, 2018
@aciidgh aciidgh merged commit f98bc3e into swiftlang:master Jul 4, 2018
@ViktorSimko
Copy link
Contributor Author

Thank you for reviewing my code and helping me!

neonichu added a commit to neonichu/swift-package-manager that referenced this pull request Aug 30, 2018
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.
aciidgh pushed a commit that referenced this pull request Sep 7, 2018
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.
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

Successfully merging this pull request may close these issues.

5 participants