igor-makarov / xcake

:cake: Describe Xcode projects in a human readable format and (re)generate one on demand.
MIT License
632 stars 48 forks source link

Order of files included recursively is random #214

Closed PatrickKuijpers closed 4 years ago

PatrickKuijpers commented 4 years ago

I'm including all files in a single directory like so target.include_files = [target.name + "/**/*.*"] It seems to me that all files and (sub)directories in are ordered randomly. It would be great if this would happen in a bit more ordered way, I'd say alphabetically, by default. (and directories first, then separate files if possible)

I also added some additional files outside this dir. It seems these files are ordered in the order I define them, so that's great! Of course you could define every single file and directory by hand, resulting in a custom arranged dir/file structure, but I suppose I don't need to explain why this is cumbersome and error prone :)

PatrickKuijpers commented 4 years ago

Note: with 'random' I mean the ordering itself seems to be random. But this random ordering seems to be consistent each time I run xcake make, which gives me the feeling that it's not completely at random?

igor-makarov commented 4 years ago

According to my project the order is alphabetical.

Can you post the directory tree perhaps?

PatrickKuijpers commented 4 years ago

I've defined the source files in the Cakefile like this:

    target.include_files = [target.name + "/**/*.*"]
    target.include_files << "Cakefile"
    target.include_files << "CHANGELOG.md"
    target.include_files << "README.md"
    target.include_files << ".gitignore"
    target.include_files << "Docs/**/*.*"

This results in the following directory tree: Screenshot 2020-06-08 at 11 59 21

As you can see, the files I've defined in the Cakefile are created in that order, even the root directories themselves. But the files and directories inside both the target.name (Meld Een Vermoeden) and Docs directories are completely randomized

igor-makarov commented 4 years ago

Ok, I've checked and there is no defined order at the moment.
My suggestion is to sort the generated project before saving using the before_save hook:

project.before_save do |project|
  project.sort
end
PatrickKuijpers commented 4 years ago

That's a great and simple trick, thanks! The current result look much better already: Screenshot 2020-06-08 at 17 08 25

I've got 2 more questions:

1) If I may be really picky: it's ordering both files and directories now. I suppose there isn't an easy way to prioritise 'directories then files' over alphabetical order? If not, then no problem. If you do know, then I'd love to hear of course!

2) I've already got some other useful hooks after_save. Can I put your code inside this codeblock somehow?

Project.new do |c|
    after_save do
        # Re-install pods after each `xcake make`
        `pod install`

        # Schemes settings (like the selected executable) are lost after `xcake make` (and we don't know how to init these properly).
        # This will result in the app being unable to run, unless the executable is re-selected again.
        # To restore the lost settings we need to remove the local changes from git:
        `git checkout -- Meld\\ Een\\ Vermoeden.xcodeproj/xcshareddata/xcschemes/Meld\\ Een\\ Vermoeden-Debug.xcscheme`
        `git checkout -- Meld\\ Een\\ Vermoeden.xcodeproj/xcshareddata/xcschemes/Meld\\ Een\\ Vermoeden-Release.xcscheme`
    end
end

I've tried the following, but it fails, probably because project isn't the same as Project.new / c :)

Project.new do |c|
    before_save do
        c.sort
    end
    after_save do
        # etc
    end
end
igor-makarov commented 4 years ago

The sort order is corresponding to how macOS sorts directories by default - together with files.

You can't put the sort in after_save because for that you would need to reopen the saved project file. before_save is called, as expected, before saving the project to disk.

You need to call the sort on the generated project, which is different from the c argument you have in the provided snippet, like so:

before_save do |project|
    project.sort
end
nicolasrostan commented 1 year ago

To sort keeping the groups at the top:

before_save do |project|
    project.sort(:groups_position => :above)
end