パッケージに対応版です。もうちょっと効率的にできるかもしれませんが、とりあえず動くと思います。
'use strict';
ObjC.import('Cocoa');
var App = Application.currentApplication(); App.includeStandardAdditions = true;
function isPackage(fpath) {
return $.NSWorkspace.sharedWorkspace.isFilePackageAtPath(fpath);
}
function filtered(dir, pkgs, files) {
for (const f of files) {
if (isPackage($(dir).stringByAppendingPathComponent(f).js)) {
pkgs.push(f);
}
}
for (const p of pkgs.filter(x => ! /\//.test(x))) {
files = files.filter(f => ! f.startsWith(p + '/') && ! f.startsWith('.'));
}
return files;
}
function run() {
const dir1 = App.chooseFolder({withPrompt:'元フォルダを選択してください'}).toString();
const dir2 = App.chooseFolder({withPrompt:'先フォルダを選択してください'}).toString();
const filemanager = $.NSFileManager.defaultManager;
const files = ObjC.deepUnwrap(filemanager.enumeratorAtPath(dir1).allObjects.sortedArrayUsingSelector('localizedStandardCompare:'));
const pkgs = [];
for (const f of filtered(dir1, pkgs, files)) {
const old_fpath = $(dir1).stringByAppendingPathComponent(f);
const new_fpath = $(dir2).stringByAppendingPathComponent(f);
const isdir = Ref();
if (filemanager.fileExistsAtPathIsDirectory(old_fpath, isdir) && isdir[0] && !isPackage(old_fpath)) {
const err = $();
if (! filemanager.createDirectoryAtPathWithIntermediateDirectoriesAttributesError(new_fpath, true, $(), err)) {
throw new Error(err.localizedDescription.js);
}
} else {
const src = $.NSURL.fileURLWithPath(old_fpath);
const dst = $.NSURL.fileURLWithPath(new_fpath);
const err = $();
const opt = $.NSURLBookmarkCreationSuitableForBookmarkFile;
const bookmark = src.bookmarkDataWithOptionsIncludingResourceValuesForKeysRelativeToURLError(opt, $(), $(), err);
if (! err.isNil()) {
throw new Error(err.localizedDescription.js);
} else {
const err = $();
if (! $.NSURL.writeBookmarkDataToURLOptionsError(bookmark, dst, 0, err)) {
throw new Error(err.localizedDescription.js);
}
}
}
}
}