Skip to content
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

Out-File should create missing parent folders #13553

Closed
Joe-Zer0 opened this issue Aug 31, 2020 · 13 comments
Closed

Out-File should create missing parent folders #13553

Joe-Zer0 opened this issue Aug 31, 2020 · 13 comments
Labels
Issue-Question ideally support can be provided via other mechanisms, but sometimes folks do open an issue to get a Resolution-Answered The question is answered. WG-Cmdlets-Utility cmdlets in the Microsoft.PowerShell.Utility module

Comments

@Joe-Zer0
Copy link

Summary of the new feature/enhancement

It would be nice for Out-File to create missing parent folders. Possibly require the -Force flag for this to take effect.

Currently to safely output to a file in a different folder, it's safest to preface your command with a New-Item -Force command.

Proposed technical implementation details (optional)

@Joe-Zer0 Joe-Zer0 added the Issue-Enhancement the issue is more of a feature request than a bug label Aug 31, 2020
@iSazonov iSazonov added WG-Cmdlets-Utility cmdlets in the Microsoft.PowerShell.Utility module Issue-Question ideally support can be provided via other mechanisms, but sometimes folks do open an issue to get a and removed Issue-Enhancement the issue is more of a feature request than a bug labels Sep 1, 2020
@Joe-Zer0
Copy link
Author

Joe-Zer0 commented Sep 2, 2020

Adding more detail. To me this is what I would expect to happen with the -Force flag. This could possible be classified as a bug, although I labeled it as an enhancement to be safe.

Current Behavior

❯ tree
+ C:\temp
❯ 'example error' | Out-File 'logs/error-log.txt' -Force
Out-File: Could not find a part of the path 'C:\temp\logs\error-log.txt'.

Desired Behavior

❯ tree
+ C:\temp
❯ 'example error' | Out-File 'logs/error-log.txt' -Force
❯ tree
+ C:\temp
  + logs
    - error-log.txt
❯ cat .\logs\error-log.txt
example error

@mklement0
Copy link
Contributor

While desired-state functionality is a wonderful thing, the problem is that (a) users have come to expect -Force to have a specific meaning with respect to Out-File (to override a read-only attribute on Windows) and (b) to overload a single flag with multiple, unrelated behaviors is problematic.

It's not as concise, but you can use New-Item's -Force flag:

'foo' | Out-File "$(New-Item -Force -Type Directory logs)/error-log.txt"

@Joe-Zer0
Copy link
Author

Joe-Zer0 commented Sep 2, 2020

I can understand where overloading the functionality of the Force flag could be problematic. I propose adding a new flag to achieve this functionality. While the statement you provided above works, it hurts readability. I feel like it's reasonable for the end user to expect that Out-File has the ability to create the file (and parent directories) that it's trying to write to. I also feel like this would desired functionality by end users. Of course this is just my opinion, but if others agree, I think this would be a valuable feature to add.

@mklement0
Copy link
Contributor

Understood, but at this point I suggest you close this issue, and create a new one, using the "Feature Request/Idea" template, in which you can:

  • present the proposal along with suggesting a specific (switch) parameter name.

  • also consider how and which additional file-creating cmdlets - notably Set-Content, which is the faster choice if the input objects already are strings - could be covered.

@Joe-Zer0
Copy link
Author

Joe-Zer0 commented Sep 2, 2020

This thread was created by selecting Feature Request/Idea. My initial comment recommended the Force flag since it matches the functionality of New-Item. I'm not familiar enough with this repository to feel comfortable recommending anything more specific than the desire for Out-File to be capable of generating parent folders. I'm open to suggestions, and I'd happily create a new topic to propose that.

@mklement0
Copy link
Contributor

Sorry - I missed that you had indeed used the right template - it was @iSazonov who removed the Issue-Enhancement label and replaced with Issue-Question (which is the default for the bug template).

My sense was that the -Force aspect of your suggestion - which I think we now agree was a dead end - created a distraction, so I proposed creating a new "Feature Request/Idea" post - which I still recommend: you can simply mention the aspect of perhaps needing to cover additional cmdlets, soliciting input from others.

@Joe-Zer0
Copy link
Author

Joe-Zer0 commented Sep 2, 2020

Ok, thank you, I will try that. Do you have any suggestion what the flag should be named? I'm not aware or anything with similar functionality to take cues from.

@mklement0
Copy link
Contributor

@Joe-Zer0, good question re name for the switch (flag) - I don't think there is a precedent (except in New-Item -Type Directory, where the already ruled-out -Force serves that purpose) and I can't think of anything that strikes the right balance between concision and descriptiveness - something like -CreateDirectoryOnDemand feels clunky.

Perhaps that's an indication that the functionality doesn't really belong there, which is my personal sense.

But I don't want to discourage you from creating a proposal - feel free to create it and see what others say.

@vexx32
Copy link
Collaborator

vexx32 commented Sep 6, 2020

-Force isn't required for New-Item -Type Directory (though it is if you're doing -Type File and targeting a file path that contains nonexistent directories).

But yeah, personally I'm kind of feeling this doesn't belong in Out-File itself.

@mklement0
Copy link
Contributor

@vexx32, -Force is required if you want desired-state functionality, which is what this issue is about.

That is, if you want New-Item -Type Directory to either create the target directory on demand (and return information about it) or return information about an existing target directory at the specified path, -Force is required.

However, you bring up a good point: with New-Item -Type File (-Type File being the default), creating the parent directory on demand does work; thus, @Joe-Zer0's command could have been rewritten as:

# Replace any existing logs/error-log.txt file
#  *or* 
# create the /logs/ subdir. on demand an create the 'error-log.txt' file in it.
New-Item -Force 'logs/error-log.txt' -Value 'example error'

@Joe-Zer0
Copy link
Author

Joe-Zer0 commented Sep 8, 2020

I was previously using "if Test-Path" prior to my output redirection. Since this doesn't seem to be getting much traction, I decided to adapt some sample code that @mklement0 posted. It's a bit cleaner that having extra if statements. I also switched back to the redirection operator since I had no use for any Out-File flags.

random command > $(New-Item logs/error-log.txt -Force)

This is a fairly clean method of redirecting output while ensuring the destination file exist. Thanks for both of your help and feedback!

@Joe-Zer0 Joe-Zer0 closed this as completed Sep 8, 2020
@mklement0
Copy link
Contributor

@Joe-Zer0, that's a nice idiom, thanks for sharing.

You can even make it (ever so slightly) shorter by using (...) rather than $(...).
In case you're curious about the difference and when to use which, see this SO answer.

@Joe-Zer0
Copy link
Author

Joe-Zer0 commented Sep 8, 2020

@mklement0
Thanks for that SO link. I've recently been realizing I've been using $() more than I should. That helps me with understanding when it's actually necessary.

@iSazonov iSazonov added the Resolution-Answered The question is answered. label Sep 9, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Issue-Question ideally support can be provided via other mechanisms, but sometimes folks do open an issue to get a Resolution-Answered The question is answered. WG-Cmdlets-Utility cmdlets in the Microsoft.PowerShell.Utility module
Projects
None yet
Development

No branches or pull requests

4 participants