`new` fails when `--output` is an existing directory
raysarebest opened this issue · 2 comments
Describe the bug
I have an existing project in Node.js that I haven't touched in several years, so I'd like to rewrite it in Swift using Vapor. However, while I've cleaned the directory it lives in of any code/tooling-related files, I'd like to keep around a handful of metadata files (README.md
, etc) and the existing git repository. I was hoping that I'd be able to just set my existing project directory as the --output
of running vapor new
and Vapor would set up a new project template in that folder, but I get an error every time. For example, when I run this command:
vapor new myproject --output existing-directory --no-git
I get the following output:
Cloning template...
Error: Error Domain=NSCocoaErrorDomain Code=516 "The file “existing-directory” couldn’t be saved in the folder “working-directory” because a file with the same name already exists." UserInfo={NSFilePath=/Users/me/Developer/working-directory/existing-directory, NSUnderlyingError=0x600000d30e70 {Error Domain=NSPOSIXErrorDomain Code=17 "File exists"}}
To Reproduce
Steps to reproduce the behavior:
mkdir existing
vapor new example --output existing
(with or without--no-git
)- See error
Expected behavior
A new Vapor project to be set up in the directory existing
Environment
- Vapor Framework version: N/A, didn't get that far yet
- Vapor Toolbox version: 18.6.0
- OS version: Ventura 13.2
TBH I think this is probably something we won't tackle and will be out of scope for the toolbox. Whilst we could have a hardcoded list of 'approved' files that we shouldn't overwrite - what do we do with other files? Overwrite them and cause a potential loss of data? Use the existing files? That might lead to a new project that doesn't compile causing confusion for users. IMO we should keep it as it currently is.
Will close this as won't fix
but feel free to reopen or continue discussion if you feel strongly about it!
I think it ultimately should be supported, as it was very surprising to me as a first-time user that it required a non-existent directory, though I agree that a list of files (either allow or deny) is not the way to go. In my opinion, if this were to be supported, it should do one of four things (in the order that makes the most sense to me, descending):
- Add a flag to let the user specify up-front in the event of a conflict whether they want to be asked per-file, always use the existing file in the
output
tree, always overwrite the existing file with the template file, or throw an error and clean up any files it added - Ask the user what it should do for each file where there's a conflict
- Throw an error when it encounters a file that doesn't exist (while using existing directories), and ideally clean up added files
- Add all files in the template, while favoring the file that already exists in the
output
tree if one exists
That said, I already took a crack at implementing the 1st option before you commented, and while I got it working fine on macOS, I got a bunch of build errors and potentially found a bug or two in swift-corelibs-foundation that makes me think the cleanest solution would involve some updates from over there
At the very least, I think it should be documented somewhere that output
needs to be a directory that doesn't exist yet, as I couldn't find that at the time I was attempting what I described