dahlbyk/posh-git

Avoiding creating a C:\tools directory

jnm2 opened this issue · 24 comments

jnm2 commented

Is it possible to move C:\tools\poshgit to %appdata%\poshgit?

I'm using the Chocolatey package.

In the short term, you can change that path with $env:ChocolateyToolsLocation. (I would uninstall first.) See Get-ToolsLocation for details.

Beyond that, there's some discussion over in #328 about the future of distributing posh-git with Chocolatey. That may be a while yet, though, so I would not be opposed to switching from Get-ToolsLocation to installing posh-git elsewhere. Rather than %appdata%, I'm inclined to follow the suggestion from this comment of installing to a location that's discoverable by Get-Module -ListAvailable (i.e. a posh-git folder inside the first path from $Env:PSModulePath).

If you, or anyone, does decide to tackle this, keep in mind that the uninstaller should continue to correctly purge posh-git from Get-ToolsLocation as well.

Hi,
about the Chocolatey deliverable that installs in C:\tools.

I would ask to make an example out of InvokeBuild package: https://chocolatey.org/pack.... This is a build tool that I use at work, in the form of Powershell module. It installs correctly in the conventional directories where Powershell modules are discoverable.

These directories can be:

C:\Users\<user>\Documents\WindowsPowerShell
C:\Program Files\WindowsPowerShell
C:\Windows\System32\WindowsPowerShell\v1.0 (this is reserved to older scripts I believe)

Please check out this document from MSDN: https://msdn.microsoft.com/en-us/library/dd878350(v=vs.85).aspx#Anchor_1

To check if the module is correctly installed in the system, it should appear in Get-Module -ListAvailable command output.

The use case for this is that installing a module in the correct directories is important if you use 3rd party software that depends on these modules, as it wouldn't be discoverable by them otherwise.

For example I use the console emulator Cmder, which supposedly integrates with posh-git when emulating a Powershell terminal in a Git directory.
The integration works if you install posh-git with PowershellGet (Install-Module posh-git) but gives constant warnings ("the module cannot be located") if you install posh-git via Chocolatey.

For reference, here's Invoke-Build's Chocolatey tools. That package installs globally, but I'd be inclined to install to ($Env:PSModulePath -split ';')[0] (which is ~\Documents\WindowsPowerShell\Modules on my machine).

@ferventcoder does Chocolatey convention have a stance on this sort of install, vs using Get-ToolsLocation?

For example I use the console emulator Cmder, which supposedly integrates with posh-git when emulating a Powershell terminal in a Git directory.
The integration works if you install posh-git with PowershellGet (Install-Module posh-git) but gives constant warnings ("the module cannot be located") if you install posh-git via Chocolatey.

This surprises me. If you installed poshgit (via Chocolatey; note "poshgit" not "posh-git") from the Cmder shell, it should automatically import posh-git as part of your $PROFILE.

This surprises me. If you installed poshgit (via Chocolatey; note "poshgit" not "posh-git") from the Cmder shell, it should automatically import posh-git as part of your $PROFILE.

Tried on two different workstations but apparently it does not integrate, I see WARNINGS at the Cmder PS prompt.
What works instead, is to uninstall the posh-git Choco package, open Cmder in Powershell mode, get into any Git directory, at which point it will automatically offer to download and install posh-git (I assume it is using PowershellGet system? In any case, it is not Chocolatey for sure)

at which point it will automatically offer to download and install posh-git

This sounds very neat and magical. Can you tell where this module is installed? Or where it's coming from?

Cmder installs posh-git here:
C:\Users<user>\Documents\WindowsPowerShell\Modules
Browsing into their issue page, it seems that it uses PowershellGet to retrieve things: cmderdev/cmder#1345

pauby commented

For reference, here's Invoke-Build's Chocolatey tools. That package installs globally, but I'd be inclined to install to ($Env:PSModulePath -split ';')[0] (which is ~\Documents\WindowsPowerShell\Modules on my machine).

In the case of Chocolatey, installing to ~, installs to the Administrator / Elevated User account (as Chocolatey is run elevated). So in my case it installs to the 'Administrator'\Documents\WindowsPowerShell\Modules folder and therefore isn't available to my normal user account.

My suggestion is, by default, to installs to $env:ProgramFiles\WindowsPowerShell\Modules folder and that way it's available to all users on the system. This is what I've recently done with psscriptanalyzer, pscodehealth, plaster and platyps. I'm not suggesting my way is the 'right' way, I'm suggesting a better way, at least for me!

I will happily submit a PR if this is the way you want to do (as I have a template that pretty much works for all the modules I mentioned).

Two other points:

  1. You should be installing somewhere on the standard PS module paths not into c:\tools as nobody is going to pick that up unless they modify their PSModulePath and I'm not going to do that just for your module (being honest);

  2. Don't update the users profile with your module - very bad idea. I don't want you messing with my profile at all. I will sort that out. If you really want to do that to help the user out then add a parameter to the package to do that which the user can specify;

The above is meant to be helpful and not critical so hopefully it's taken the right way!

@pauby appreciate your input!

I'm somewhat settled that this isn't worth changing for v0.x, though I suppose changing this location might be a reasonable excuse to bump from 0.7.x to 0.8.0. If we do make this change, $env:ProgramFiles\WindowsPowerShell\Modules seems as good a place as any.

For v1.0 I'm strongly considering adding PowerShell 5+ as a Chocolatey dependency, and having the install/uninstall scripts just delegate to PowerShellGet using the PowerShell Gallery. Thoughts?

I will happily submit a PR if this is the way you want to do (as I have a template that pretty much works for all the modules I mentioned).

Maybe submit a PR against the v0 to discuss in more detail?

You should be installing somewhere on the standard PS module paths not into c:\tools as nobody is going to pick that up unless they modify their PSModulePath and I'm not going to do that just for your module (being honest);

Yeah, it's not intended that users would add C:\tools to their module path since we import the module for you from wherever it lives.

Don't update the users profile with your module - very bad idea. I don't want you messing with my profile at all. I will sort that out. If you really want to do that to help the user out then add a parameter to the package to do that which the user can specify;

I feel like you're probably the exception here. The vast majority of posh-git users aren't PowerShell developers, and I would guess a significant amount have nothing besides Import-Module posh-git in their profile. I'm certainly interested in making the install experience as tolerable for PowerShell Professionals™️ as possible (e.g. we skip touching profile if any profiles already mentions posh-git), but I do think it's a better general UX for us to keep adding to profile as part of the Chocolatey install.

pauby commented

For v1.0 I'm strongly considering adding PowerShell 5+ as a Chocolatey dependency, and having the install/uninstall scripts just delegate to PowerShellGet using the PowerShell Gallery. Thoughts?

I wouldn't add PS 5 as a package dependency in your Chocolatey .nuspec file. Most people won't be installing PS from Chocolatey (Core being an exception) as it comes installed out of the box. If you add PS 5 as a dependency everybody will have the Chocolatey PS 5 package installed by default even if it is already installed with their Windows 10. What I would do is do a check in the chocolateyInstall.ps1 file and then throw an exception if the correct version of PS is not installed. The user can then sort that out themselves.

Maybe submit a PR against the v0 to discuss in more detail?

Sure I'll submit a PR soon.

I feel like you're probably the exception here. The vast majority of posh-git users aren't PowerShell developers, and I would guess a significant amount have nothing besides Import-Module posh-git in their profile. I'm certainly interested in making the install experience as tolerable for PowerShell Professionals™️ as possible (e.g. we skip touching profile if any profiles already mentions posh-git), but I do think it's a better general UX for us to keep adding to profile as part of the Chocolatey install.

I'm a little confused as by definition GIT is a development tool and used by developers. So what do the non-developers use posh-git for??!?

Package should install themselves and let the users handle any specific configuration that they may want, by default. I wholeheartedly agree that if a user does want you to update their profile then they can give you the permission to do so (using a chocolatey parameter) but you shouldn't assume that's what they want.
I do disagree with you touching users profiles. As I said I am not wanting you to touch mine and

I'm a little confused as by definition GIT is a development tool and used by developers. So what do the non-developers use posh-git for??!?

Not non-developers. Non-PowerShell developers. People who use PowerShell as a shell (often for posh-git, often from GitHub for Windows initially), but have never written a script or module themselves.

As a PowerShell Professional™️ I would also like to have an option for scoping it to the current user to avoid the need to have an elevated shell.
I guess one could also just include the PowerShellGet and Packagemanagement modules for ps versions 3 and 4.

pauby commented

@bergmeister Chocolatey needs to run elevated so it can install packages. It would be difficult to scope a package installation to the current user. There are ways to do it but none of them are pretty.

Sorry, I did not know that, I am clearly not a Chocolatey Professional™️ 🤣 . I guess a simplistic installation script does the job in most cases.
To me it seems there is a bit of re-inventing the wheel for the installation part, is there no way of reusing PowerShellGet or does it not support taking a nupkg or something like that as an input?

pauby commented

That's cool. Chocolatey is still something new to a lot of people - but you should check it out :)

It does reinvent the wheel a little insomuch as we have another way to install a module. But the module is bundled with the package so it's an all-in-one package without the need for PowerShellGet or anything else. PowerShellGet is not installed by default in PS4 and below and with Chocolatey we are supporting PS back to v2.

As a PowerShell Professional™️ I would also like to have an option for scoping it to the current user to avoid the need to have an elevated shell.

If you're this picky, I'm inclined to let you use Install-Module and Add-PoshGitToProfile to specify scope yourself. I see Chocolatey very much as the "just get this working, I don't really care how" option.

I guess one could also just include the PowerShellGet and Packagemanagement modules for ps versions 3 and 4.

v1+ drops support for < 5 specifically so we can assume PowerShellGet is available.

To me it seems there is a bit of re-inventing the wheel for the installation part, is there no way of reusing PowerShellGet or does it not support taking a nupkg or something like that as an input?

Taking a nupkg, no (AFAIK), but you're absolutely right that the current Chocolatey installer replicates what Install-Module/Uninstall-Module could do for us. But what we have to fetch from GitHub does work, if not quite as well as it could. (There are a few other Chocolatey warnings we should resolve once we're settled on a path.)

pauby commented

Not non-developers. Non-PowerShell developers. People who use PowerShell as a shell (often for posh-git, often from GitHub for Windows initially), but have never written a script or module themselves.

But for them they can use Add-PoshGitToProfile to add it there rather than you doing it for everybody in the installation script. I also, dare I say, think you're treating your users a bit too simplistically. If they can you use another 'language'. If they can use Git. If they can use PowerShell. They can run a cmdlet to add posh-git to their profile.

As an aside, your code will not find where I am importing posh-git as I don't keep it in $PROFILE (it looks like your code only checks for that?). There's also a LOT of code around adding it. You're also distributing tests and other code that isn't relevant to the module - is this deliberate?

I know I've gone off on talking about the Chocolatey side of it but I've just noticed the other stuff and thought I'd point it out.

jnm2 commented

I see Chocolatey very much as the "just get this working, I don't really care how" option.

Agreed, except for the part where a C:\tools folder appears. 😇

pauby commented

I see Chocolatey very much as the "just get this working, I don't really care how" option.

I disagree entirely. As a Chocolatey user I very much care 'how'.

There's also a LOT of code around adding it. You're also distributing tests and other code that isn't relevant to the module - is this deliberate?

It's an accident of installing from a ZIP of the repo. This was one of the first Chocolatey packages ever written (not by me: #193) when Chocolatey and this project were much simpler. Until last year (#358 has some good context), the package always installed master!

Thus reconsidering for v1. 😀

But for them they can use Add-PoshGitToProfile to add it there rather than you doing it for everybody in the installation script. I also, dare I say, think you're treating your users a bit too simplistically. If they can you use another 'language'. If they can use Git. If they can use PowerShell. They can run a cmdlet to add posh-git to their profile.

I don't mean to; it's not a matter of "can". But this is the first I can recall in seven years as a Chocolatey package that someone has objected to modifying their profile. And for most of that time we didn't handle CurrentUser/AllUsers/CurrentHost/AllHosts. (Related: in a Chocolatey install script we actually can't: chocolatey/choco#1154.) Most people simply don't seem to care, and I'm not inclined to require that they care if we can provide a reasonable default.

That said, I'm sure there's a way to let the Chocolatey install respect an option to not touch $PROFILE. But I'm pretty firm that the default behavior should continue to be that choco install poshgit results in posh-git being imported in your current user/host profile. Maybe it makes sense to add a prompt in v1 to confirm profile should be modified?

pauby commented

I don't mean to; it's not a matter of "can". But this is the first I can recall in seven years as a Chocolatey package that someone has objected to modifying their profile

You'll probably find that most people don't know you're modifying the profile. There is nothing in the Chocolatey description or output from the package install to say it. If you removed updating the profile you'd probably have no complaints either!

Have a look at https://chocolatey.org/packages/invoke-build and see the notes in the description around adding to your profile.

That said, I'm sure there's a way to let the Chocolatey install respect an option to not touch $PROFILE. But I'm pretty firm that the default behavior should continue to be that choco install poshgit results in posh-git being imported in your current user/host profile.

I've outline the reasons you should do this in the PR I submitted (#578) rather add an option to modify the profile.

Maybe it makes sense to add a prompt in v1 to confirm profile should be modified?

If you add a prompt the installation will not be silent which is what Chocolatey prefers to have.

I don't mean to; it's not a matter of "can". But this is the first I can recall in seven years as a Chocolatey package that someone has objected to modifying their profile

You'll probably find that most people don't know you're modifying the profile. There is nothing in the Chocolatey description or output from the package install to say it. If you removed updating the profile you'd probably have no complaints either!

Right. My point is that they don't need to know as long as it works. They probably don't know that Chocolatey itself also modifies their profile to support choco tab expansion.

pauby commented

Right. My point is that they don't need to know as long as it works.

I respectfully disagree. You need to let them know what you're doing as modifying people's 'stuff' is not okay.

I really don't like this whole idea of 'hey this stuff works you don't need to know how'. That's why consumer IT is in such a mess. I agree that the user 'doesn't need to know if they don't want to know' but give them the choice. And don't start modifying things outside of your module without gaining their consent. You are not in a position to decide what the user does and does not need to know. (There really is no way to write that without it sounding confrontational :))

They probably don't know that Chocolatey itself also modifies their profile to support choco tab expansion.

Chocolatey doesn't do this (I never thought it did but I just checked with the team).

And don't start modifying things outside of your module without gaining their consent. You are not in a position to decide what the user does and does not need to know. (There really is no way to write that without it sounding confrontational :))

With respect, you're thinking from a PowerShell Module standpoint, not a Chocolatey "application" standpoint. Application installers nearly always change their environment on install, otherwise $Env:PATH would never get modified. Sometimes it's an option (e.g. the Git for Windows installer), but even then someone made a judgement call as to which option should be used when installed with Chocolatey. And that selection is optimized for user experience (running git from a shell should work) rather than control. That's the lens through which I view posh-git's Chocolatey experience.

They probably don't know that Chocolatey itself also modifies their profile to support choco tab expansion.

Chocolatey doesn't do this (I never thought it did but I just checked with the team).

Unless I'm missing something, you were told wrong: Add-ChocolateyProfile is called in Initialize-Chocolatey, which is called from chocolateyInstall.ps1, which is invoked by install.ps1.

pauby commented

With respect, you're thinking from a PowerShell Module standpoint, not a Chocolatey "application" standpoint. Application installers nearly always change their environment on install, otherwise $Env:PATH would never get modified.

I'm not actually thinking of module vs Chocolatey. I'm thinking user consent / understanding / knowing what you're going to do vs modifying files that the user has no way to stop and no way to know it's being done. If you had a Chocolatey parameter (to allow / disallow profile modification) then you'd first of all need to tell people (there is the consent) and you are giving people an choice.

In my case you're not modifying the file I keep all my profile in so it makes troubleshooting any issues a problem as I won't be looking in $PROFILE (as all it does it dot sources a central profile ps1 file - this is not unusual). A parameter would allow me to stop that from happening.

But to look at it from a module (ie. PS Gallery) vs, Chocolatey (or other method) you have one set of behaviours from PS Gallery and another from Chocolatey. This will again cause that misunderstanding for people going from one to the other. Let them know it's different and how.

As an aside this thread has move away from using C:\Tools so I'm not sure if it would be more appropriate to start a new issue which might allows others to come in too. I'll leave that to your call.

Unless I'm missing something, you were told wrong: Add-ChocolateyProfile is called in Initialize-Chocolatey, which is called from chocolateyInstall.ps1, which is invoked by install.ps1.

@gep13 can you comment on this?