Skip to content

Ignore normal directory with dots #397

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

Closed
wants to merge 17 commits into from
Closed

Ignore normal directory with dots #397

wants to merge 17 commits into from

Conversation

toshi0383
Copy link
Collaborator

@toshi0383 toshi0383 commented Sep 13, 2018

Fixes #396

@brentleyjones
Copy link
Collaborator

“.bundle”

Sent with GitHawk

Copy link
Owner

@yonaskolb yonaskolb left a comment

Choose a reason for hiding this comment

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

This could potentially break a lot of projects that were relying on directories with an extension to be a file

@toshi0383
Copy link
Collaborator Author

Yea I worry about it too, but if we thought about it at first time, this should be the correct approach, isn't it?

"xcassets",
"complicationset",
"appiconset",
"xcdatamodeld"].contains(ex)
Copy link
Collaborator

Choose a reason for hiding this comment

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

We should add "bundle" and "framework" to this as well.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Will do👌

Copy link
Collaborator

Choose a reason for hiding this comment

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

I wonder if there is an API to detect this? It seems to be OS defined.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Found an API to get UTI in string. 1e21b1d
It's "public.folder" if it's a normal folder.
lproj appears to be "public.folder" too. It looks problematic, but we're whitelisting lproj, so it wouldn't be a problem.

@toshi0383
Copy link
Collaborator Author

extension: appiconset, uti: public.folder
extension: bundle, uti: com.apple.generic-bundle
extension: complicationset, uti: public.folder
extension: framework, uti: com.apple.framework
extension: imageset, uti: public.folder
extension: lproj, uti: public.folder
extension: xcassets, uti: com.apple.dt.assetcatalog
extension: xcdatamodeld, uti: com.apple.xcode.model.data-version

extension Path {

/// Treat this as a resource instead of a normal directory.
var isNonFolderDirectory: Bool {

Choose a reason for hiding this comment

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

isNonFolderDirectory sounds a bit ambiguous. What about isGroupDirectory? That's how Xcode names directories in an Xcode project.

Choose a reason for hiding this comment

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

Then you could just say !myPath.isGroupDirectory

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I understand, but I think it's depends on how you look at the problem.

From Xcode perspective, isGroupDirectory is maybe straight forward, but this specific functionality is seen outside of Xcode too. That's why I've put this as PathKitExtension.

Also, I actually tried to rename it, and ended up with rather complicated code. (Needed additional is a directory, but condition to retrieve non "public.folder" directory.)

        let directories = children
            .filter { $0.isDirectory && $0.isGroupDirectory && $0.extension != "lproj" }
            .sorted { $0.lastComponent < $1.lastComponent }

        let filePaths = children
            .filter { $0.isFile || ($0.isDirectory && !$0.isGroupDirectory) }
            .sorted { $0.lastComponent < $1.lastComponent }

Therefore, I think it's better to define this way (isNonFolderDirectory) in whitelist manner.

Copy link
Owner

Choose a reason for hiding this comment

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

How about isFileDirectory? I agree that isNonFolderDirectory is a bit strange of a name. The actual logic doesn't need to change

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done in 3aac581

.resourceValues(forKeys: [URLResourceKey.typeIdentifierKey])
.typeIdentifier {
// NOTE: lproj is public.folder
return uti != "public.folder"

Choose a reason for hiding this comment

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

If someone looks at this code in three months, it's hard to say what it does. Which types of paths am I ignoring with this expression. Maybe it's worth adding a larger comment where you explain the rationale behind this line.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Thanks. Will do. Maybe as a doc-comment.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

done in 6933cde

@pepicrft
Copy link

Yea I worry about it too, but if we thought about it at first time, this should be the correct approach, isn't it?

Not making the most appropriate decision in the past doesn't justify that the "correct" approach should be introduced regardless of it breaking the contract with the projects that are already using the tool. What I would do is:

  1. Add tests that cover the most common file types.
  2. Check whether the behaviour is the same after your change.

If it's not, there's a decision to be made: either introducing a breaking change and going with a major bump, or finding a way to roll this out in a non-breaking manner. @yonaskolb is the person to help you with that.

@toshi0383
Copy link
Collaborator Author

  1. Add tests that cover the most common file types.
  2. Check whether the behaviour is the same after your change.

Thanks, will do👌

@toshi0383 toshi0383 added the WIP label Sep 18, 2018
@toshi0383
Copy link
Collaborator Author

Just found out how to list all recognized filetypes on mac. It lists all icons for each filetypes too.
https://discussions.apple.com/thread/3117503

I'll collect filetypes from these things.

            CFBundleTypeExtensions =             (
                xcodeproj,
                xcode,
                pbproj
            );
            CFBundleTypeIconFile = "xcode-project_Icon";
            CFBundleTypeName = "Xcode Project";
            CFBundleTypeRole = Editor;
            LSIsAppleDefaultForType = 1;
            LSItemContentTypes =             (
                "com.apple.xcode.project"
            );
            LSTypeIsPackage = 1;
            NSDocumentClass = Xcode3ProjectDocument;
            "_LSIconPath" = "Contents/Resources/xcode-project_Icon.icns";
        },
                conforms to:   com.apple.package, com.apple.dt.interfacebuilder.documen
t.storyboard
                tags:          .storyboardc
        --------------------------------------------------------
        type    id:            54184
                uti:           com.apple.dt.assetcatalog
                description:   Xcode Asset Catalog
                flags:         exported  active  apple-internal  trusted
                icon:
                conforms to:   public.directory
                tags:          .xcassets
        --------------------------------------------------------
        type    id:            54188
                uti:           com.apple.dt.stickers
                description:   Xcode Stickers Catalog
                flags:         exported  active  apple-internal  trusted
                icon:
                conforms to:   public.directory
                tags:          .xcstickers
        --------------------------------------------------------
        type    id:            54192
                uti:           com.apple.interfacebuilder.plugin

As a side note:
I'm not sure if we should depends on this database (which means dynamically executing and parsing this command output to get all these special filetypes). It looks like end-user can update these states using the lsregister command or something else.

}

$0.it("supports frameworks in sources") {
let directories = """
Sources:
- Foo.framework
- Foo.framework:
- Foo.swift
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

*.framework is now required to be a directory, not file.

@toshi0383
Copy link
Collaborator Author

@pepibumur @yonaskolb

  1. Add tests that cover the most common file types.

Added tests in b24a7bf .
File extensions are retrieved by this one-liner.

(for i in $(/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -dump | grep ' \.[a-zA-Z][a-zA-Z]*' | sed -n 's/.*: *\(.*\)/\1/p' | sort | uniq | sed "s,[ '],,g" | sed 's/,/ /g'); do echo $i; done) | grep '^\.' | grep -v '^\.\.*$' | sort | uniq

(Sorry for poor readability. The original output is not in any standard format and is hard to parse.)

  1. Check whether the behaviour is the same after your change.

The behavior is different for normal directory with dots. They had been treated as .resources BuildPhase (as shown in #396 ), but now as normal directories.
Other things like "special directory with dots" or "normal directory without dots" are not affected.

@toshi0383 toshi0383 removed the WIP label Sep 23, 2018
}
}

// MARK: Utilities
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Moved utility functions below the all test cases. What we are interested in most is the test cases themselves, not utilities.

@toshi0383
Copy link
Collaborator Author

And this is the script to determine if a file extension has a special meaning or not.
https://gist.github.com/toshi0383/41b7d3bcc27ae01246558114da6bcdd7

@keith keith removed their request for review September 24, 2018 21:36
@toshi0383
Copy link
Collaborator Author

@yonaskolb
Not sure why the test is failing. It passes locally with Xcode9.3 on HighSierra.

return false
}

if let uti = try! URL(fileURLWithPath: self.string)
Copy link
Owner

Choose a reason for hiding this comment

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

I'd like to get the performance tests in (coming shortly) so this can be tested for performance

@yonaskolb
Copy link
Owner

@toshi0383 Not sure why tests are failing either.
Could you add a changelog entry as well detailing the changes and mentioning the breaking change with normal directories with dots not being added to .resources anymore

@toshi0383
Copy link
Collaborator Author

Updated CHANGELOG in 9227503

@toshi0383
Copy link
Collaborator Author

Investigating CI failure. Maybe returned UTI is different on Mac VMs?

@toshi0383
Copy link
Collaborator Author

Path.string: TestDirectory/Sources/Hello.agilekeychain, uti: public.folder

So we need to figure out how to determine if an UTI is from System, or from third party app.

@toshi0383
Copy link
Collaborator Author

Closing for now.
Feel free to take over or reopen!👋🏻

@toshi0383 toshi0383 closed this Oct 18, 2022
@toshi0383 toshi0383 deleted the ts-filelikedir branch October 18, 2022 02:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Directory name containing dots is unexpectedly added to copy bundle resources build phase
4 participants