How to copy a folder, recursively, with progress feedback, while preserving all metadata on OS X? - macos

I need to copy a folder from one location to another while providing my users with a progress bar.
The only appropiate API that I can find that isn't deprecated is copyfile(3). I've implemented this and the results are nearly perfect, however I've since discovered that neither the Finder comments nor the tags associated with original are copied over. Not only do I need them to be copied, but I'm worried about what other metadata isn't being copied that I'm not yet aware of.
Note that I am setting all the appropriate flags on copyfile to copy over the metadata.
How can I achieve my goal without resorting to awful techniques such as an Applescript bridge to read/write the comments using the Finder at the end of the copy?
UPDATE
After much research I have discovered that both the comment and the tags are copied over in the file's extended attributes. However, the comment refuses to display in the Finder.
I saw it mentioned that the comment is also stored in the .DS_Store. As a test I deleted the .DS_Store file and then relaunched the Finder so that it would be regenerated. The comment still doesn't appear.
What needs to be done for the Finder to recognise this metadata?

Note: this answer assumes you are correct about comments etc. not being copied, this has not been verified.
copyfile is available in source form from Apple. You might need to tweak it a bit though to actually compile it. Once you've done that you can modify to add the features you wish.
HTH

Related

Delete unused ressources from Localizable.strings

I'm using BartyCrouch to maintain an up-to-date localized project. My project is currently translated in 4 different languages, and I'm going to add some new languages. My issue is that my base Localizable.strings file has about 200-300 resources, even though there are probably less than 100 currently used in the project.
I'm looking for the best way to remove the un-referenced localized strings in the project, all while keeping the currently localized values.
Is there any native solution or do I have to use a third party? And if so, is there anything automatic?
Well, I definitely didn't look hard enough. I think it's worth posting an answer instead of deleting the question because I don't think the answer is on Stackoverflow yet.
https://github.com/ijoshsmith/abandoned-strings
This little gem will do exactly this. Easy to use. Simply download the zip file, use the Terminal to go into the "AbandonedStrings" folder containing a single "main.swift" file.
Then, on the terminal, enter: ./main.swift /the/path/to/your/project
This will display a list of all the unused ressources.
Then, if you also want the script to delete them, simply add "write" at the end of the command.
Watch out though: it will delete all the Storyboard localized ressources, so commit your project before and simply discard the changes.

Cocoa document incrementally save big package

For the last 2 days I've been trying to make my single-file document into a package, but I can't get it to work. In the documentation it states the preferred way is to use NSFileWrapper. I've tried it but it's just such a unintuitive way of handling files.
I guess to update a file I need to delete the file wrapper from it's directory, create a completely new one and add it again to the directory. I haven't found anything that explicitly states it, but I guess I should update the file only when fileWrapperOfType:error: is called.
As NSFileWrapper keeps everything (at least once loaded) in memory, this means that I'll have the old version and the new version at the same time until the user (or autosave) saves the file.
It seems like NSFileWrapper shouldn't be used for big files, but I think it's better if all the files that are needed by the document are inside the package(can be copied to another Mac/iPhone/iPad without errors) and I don't want to limit the user on how many/how big the files can be.
When using a manual URL-based saving mechanism, I end up getting corrupt packages, as the destination directory is always a temporary one, and I couldn't find any information on how to merge them. Every time I manually save the document without any changes, an error occurs, as I don't write anything to the temporary directory. But I don't see a reason in writing/linking everything to the temporary directory, only for it to be copied/'un'-linked back to its destination.
As I can't seem to find the right answer, what is the best-practice for saving and restoring big packages with many/big files in them?

ctime, mtime, holding directory, windows, linux

Let's clarify this once and for all. I tried to Google this but it seems this information can't be found in one place.
When a file is created or removed, the holding directory mtime changes on Windows and Linux both. ctime also changes on Linux bot not on Windows because there ctime is create time.
If a file is reopened and written to, the holding directory does not change. However, both on Windows and Linux the file mtime changes, and on Linux the ctime changes too, on Windows the ctime is create time.
Is this correct? What caveats are there? Are there exceptions over, say Windows network shares? Or Samba?
Edit: those who have voted to close this as off-topic, please leave a comment on which site do you think this is on topic. There are tons of mtime/ctime questions on Stackoverflow and just because I didn't include PHP snippets that rely on this knowledge it doesn't mean there are none :/
Think of it this way:
A directory is a file that holds pointers (or 'links') to files.
As of that:
Changing the content of a file will not affect the directory (unless the file is first deleted and then created again with the same name, as mentioned by Gabor Garami above)
Adding, Deleting or Renaming files will change the content of the directory-file which will cause its ctime/mtime to change as you have described, depending on the OS

NSFileCoordinator correct usage

when writing a file using NSFileCoordinator i need to specify the correct NSFileCoordinatorWritingOptions. Although they are explained in detail, I am not sure when to use which one. The available options are:
NSFileCoordinatorWritingForDeleting
NSFileCoordinatorWritingForReplacing
NSFileCoordinatorWritingForMoving
NSFileCoordinatorWritingForMerging
For example, what option is the correct one if I want to create a file (a plist for example)?
Wich one when I modify a file?
Can someone explain the NSFileCoordinatorWritingOptions for a better understanding?
I agree, documentation is not complete on that front, and hard to understand. And no sample code is available even for basic operations like these.
I try to think of these options in the perspective of other apps that have that specific file open, that helps getting the whole picture.
Pass no option (0) to simply update the file and notify others of your changes.
Let's say you are deleting a file that TextEdit currently displays, by providing the NSFileCoordinatorWritingForDeleting option, you're telling TextEdit to close the file as it does not exist anymore (or it could propose to save it to another place if it's in memory). It acts because of deletion.
If you're overwriting a file (as opposed to updating a file), you want about that same behavior for other apps. That's NSFileCoordinatorWritingForReplacing.
NSFileCoordinatorWritingForMoving says other apps to track the file to it's new location, so that it can be later updated.
NSFileCoordinatorWritingForMerging asks other processes to first commit their changes so that you can then merge your own changes with those.
To answer your question, you should use NSFileCoordinatorWritingForReplacing when creating a new file (even when no file exists, as it was to appear in the mean time from another app, you'd be replacing it with your own, unrelated contents). And NSFileCoordinatorWritingForMerging should be used when updating an existing file with new data, as it allows integrating the latest changes to that file immediately (instead of doing later with conflict resolution).

VSS projects, do they have to be set as 'readonly' or can I make the files writetable?

In my working folder of a VSS project, is it alright if I make all the files/folders writable? i.e. not readonly?
It is ok, but why should you?
The read only state is a safeguard so you can't change code that is not locked. Avoiding possible merge troubles in the near future.
Edit: Ok in the comment you said that the build failed because the file was not writable. If so, then it is very strange. Especially if the error message said something about not able to access the file.
It was probably still locked by another process and changing the readonly flag removed the lock (or it just needed the delay). But as far as I know, compilers do work excelent with read only source files.
Possible problems:
Files on network drives. If the network is slow, the compiler can have trouble accessing the file.
File still open in (an other) editor. Normally this shouldn't be a problem, but you may never know.
Some code files are generated during the build. In this case they don't belong in the version system, their source (if any) does.

Resources