dahlbyk / posh-git

A PowerShell environment for Git

Home Page:http://dahlbyk.github.io/posh-git/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Roadmap to 1.0

dahlbyk opened this issue Β· comments

First off, huge thanks to @rkeithhill for his recent help in pushing posh-git forward! He suggested adopting SemVer and using 1.0 for the forewarned dropping of support for PowerShell 2.0. We should also consider if 1.0 is a good time to drop support for versions prior to PowerShell 5.0. Before we do that, I think it makes sense to cut a "final" (modulo minor bug fixes) pre-1.0 release.

The 1.0 milestone also give us an opportunity to revisit the many ways that posh-git is currently distributed:

So... tentative roadmap:

posh-git 0.7

  • Fix Chocolatey package to install specific version (#358)
  • Close out existing PRs that are compatible with 2.0
    • In particular, finally merge #208, assuming it works with PowerShell 2.0 /cc @cmarcusreid
  • Close out trivial issues that I've just been ignoring for months or years πŸ˜’
  • Make prompt self-installing from the module (#217)

posh-git 1.0

  • Drop 2.0 support and warnings
  • Review exported commands - surface area seems too big (e.g. Invoke-NullCoalescing)
  • PowerShell Core support
  • ANSI support?
  • Remove profile.example.ps1
  • Update Chocolatey install/uninstall process
  • Spin off SSH Agent module (#338)
  • Close remaining Linux issues (#302)

cc @ferventcoder and @mwrock for Chocolatey input. Do you know of any other Chocolatey packages for PowerShell modules that are now available from the gallery? Would it make sense to try to restructure the package to just make sure PowerShell Gallery and the posh-git module are installed?

Update: Could Chocolatey package depend on https://chocolatey.org/packages/powershell-packagemanagement?

cc @shiftkey for GitHub Desktop implications. Do you have any telemetry for PowerShell versions used in the wild?

@dahlbyk I would consider PS-Get PowerShellGet separate and a release to the PowerShell Gallery means the module goes there.

If you also decide to continue releasing to Chocolatey's community repository, I would treat it differently and not just have it use PS-Get PowerShellGet. Some folks may want to install without any additional dependencies.

Side note: I've thought about adding the concept of choco install somemodule --source powershellgallery.

Note: While I say treat them separately, there is nothing from Chocolatey's end stopping you from building a package that is compatible with both PowerShell Gallery and Chocolatey and releasing to both the PS Gallery and Chocolatey's Community Repository.

I think it makes sense to use Chocolatey to support install on PS v2 and maybe v3/v4 as well. Although there is a PackageManagement/PowerShell install for v3/v4. I'd prefer we drop support for PSGet as it is just confusing with PowerShellGet and the latter is clearly the future for the distribution of PowerShell modules.

I'm not sure there is much to document WRT the git clone approach and I think we want to direct typical users to install from either Chocolatey for the PSGallery. These offer the benefit of providing an easy way to upgrade to a later release. For the power users, I think they'll know how to clone a GitHub repo and I'm hopeful the current README.md walks them through importing the module and configuring their prompt function.

Remove profile.example.ps1 and make prompt self-installing from the module
I'm not a big fan of the install.ps1 script approach. I used to do this with PSCX and got a fair amount of blowback from users but I'll concede that my users tended to be PowerShell "power users".

Profile scripts tend to personal / protected in nature. I mean PowerShell power users don't like you messing with their profile scripts. :-) They are also particular about which profile script imports a particular module. Some may want it in all AllUsersAllHosts, others in CurrentUserAllHosts and yet others in CurrentUserCurrentHost.

One thing we could do here, which is how I tend to "configure" my modules, is to provide a posh-git_config.ps1 file that looks like this:

Import-Module posh-git

# Set up a simple prompt that displays Git status summary info when inside of a Git repo.
function global:prompt {
    $origLastExitCode = $LASTEXITCODE

    # A UNC path has no drive so it's better to use the ProviderPath e.g. "\\server\share".
    # However for any path with a drive defined, it's better to use the Path property.
    # In this case, ProviderPath is "\LocalMachine\My"" whereas Path is "Cert:\LocalMachine\My".
    # The latter is more desirable.
    $pathInfo = $ExecutionContext.SessionState.Path.CurrentLocation
    $curPath = if ($pathInfo.Drive) { $pathInfo.Path } else { $pathInfo.ProviderPath }
    Write-Host $curPath -NoNewline

    # Write the Git status summary information to the host.
    Write-VcsStatus

    $global:LASTEXITCODE = $origLastExitCode
    "> "
}
# We could also provide several prompt variations in this file that are commented out.  The user could choose between them.

Then we could add a command like Add-PoshGitConfiguration that when run, gives the user the choice of which profile to modify, copies the file posh-git_config.ps1 to the user's $profile.CurrentUserAllHosts parent directory. Then the profile script is A) created if it doesn't exist and B) modifies the profile script to simply insert one line at the end:

. $PSScriptRoot\posh-git_config.ps1

On v2, this will need to be a bit different:

. "$(Split-Path $MyInvocation.MyCommand.Path -Parent)\posh-git_config.ps1

The command would direct the user to look at posh-git_config.ps1 and tweak their prompt as desired.

Keep in mind that many PowerShell users already have a prompt function so they are more likely to want to look at examples and integrate the posh-git status summary into their prompt function. They probably wouldn't use this command.

Regaring semver, I think it is beneficial for PowerShellGet users to be able to easily remember/type the version number in case they want to either install or import a specific version. Import-Module posh-git -Version 0.7.0 is easier to remember than Import-Module posh-git -Version 0.7.0.20161230.

We can encode the build date into another module field if wanted. Perhaps a BuildDate/SHA1 set of fields in the PrivateData field of the manifest?

I'd prefer we drop support for PSGet as it is just confusing with PowerShellGet and the latter is clearly the future for the distribution of PowerShell modules.

Edit - I meant PowerShellGet (not PSGet in my first statement, I specifically used "PS-Get" to separate the idea but I see the confusion). Edited.

Import-Module posh-git -Version 0.7.0 is easier to remember

Huge fan of this as well. The date on the end I think was either using a misunderstood package fix version notation as a release version notation or it was just easier to identify for someone (maybe me a long, long time ago).

I suspect that this might be hard sell and not easy thing to do - but I'd love to see posh-git implementing new way of tab-completing command elements (assuming you got v5.0+ route). TabExpansion is so v2... ;)

And a side note:

Then the profile script is A) created if it doesn't exist and B) modifies the profile script to simply insert one line at the end:

Please make sure if the profile is signed, you take that into account. To many "installers" in the wild tend to ignore that "at the end" may mean "in the part where there should not be any code".

There's a reasonable chance that v1.0.0 will support only v5 and higher (and cross-platform as well). v0.x could be maintained on a release branch to continue to support (bug fixes only) PowerShell v2 thru v4 for some time. For the v1.0.0 version, @lzybkr may help us switch over to Register-ArgumentCompleter. :-)

RE signed profile scripts - thanks for the heads up. In that case, I think the command would probably refuse to make the change but we could emit a warning that says something to the effect:

The profile script is signed and cannot be updated since that would render the script unloadable.  
Please add the command ". $PSScriptRoot\posh-git_config.ps1" to your profile and resign it.

Please make sure if the profile is signed, you take that into account. To many "installers" in the wild tend to ignore that "at the end" may mean "in the part where there should not be any code".

Also if you ensure the profile is signed, ensure the file is bigger than 4 bytes. Get-AuthenticodeSignature $profile on an empty file produces an error - chocolatey/choco#991

From a user POV, I think it makes sense to have https://www.powershellgallery.com/ as the canonical release channel.

Do releases on those package platforms include manual work? Maybe it's worth it to automate such stuff and put it into a central way (like CI) so that every source you can use to get posh-git is actually up to date.

Also does corss platform (as in Powershell Core) mean we need tests that run on different machines or does it "just work"? (haven't tried it yet)

I agree that PowerShell Gallery is the canonical release channel for PowerShell modules. I was thinking a release to the Chocolatey community repository as well as an alternative location (but not required)

I think it's fine to have alternative release channels, but IMHO they should not hold up releases to the canonical channel.

IMHO they should not hold up releases to the canonical channel.

I did not realize this was the case. Then by all means go for the canonical channel first.

I don't think it is that big of a deal to release both via the PSGallery and Chocolatey and for now, we need Chocolatey since there is no PowerShellGet support on PS v2.

ensure the file is bigger than 4 bytes

@ferventcoder Thanks for the tip!

Thanks, @ferventcoder. I have a feeling our Chocolatey strategy will depend on whether or not we end up taking on any other PS Gallery dependencies (e.g. TabExpansionPlusPlus). I suppose the other option would be to ship a "final" 1.0 version on Chocolatey that says "moved to PS Gallery". We'll see what makes sense.

Regaring semver, I think it is beneficial for PowerShellGet users to be able to easily remember/type the version number in case they want to either install or import a specific version. Import-Module posh-git -Version 0.7.0 is easier to remember than Import-Module posh-git -Version 0.7.0.20161230.

Agreed. Honestly, I never thought much about version numbers for Chocolatey releases because it always installed latest anyway. 😏

As for installing posh-git, I have zero attachment to install.ps1 or profile.example.ps1 - they're just what we came up with six years ago when nobody on Windows cared about Git. πŸ˜€ It sounds like what @rkeithhill is proposing is to essentially:

  1. Clean up install.ps1 and export it from the module.
  2. Rename profile.example.ps1 and simplify it a bit.

There are also discussions that could be had about whether it's posh-git's place to worry about ssh-agent in the first place. Between x-plat, Pageant, and Win32-OpenSSH, I almost wonder if 1.0 would be a good break point to spin those functions out into a separate project?

So I'm also pondering if there's some way to teach the posh-git module to install/repair itself without an explicit step, e.g.

> Install-Module posh-git -Scope CurrentUser
> Import-Module posh-git
Module import not found in user profiles.
Would you like to add an import to your profile?
[A] All Hosts  [C] Current Host  [N] None

We could also check here if either profile is signed and cannot be updated.


As for prompt, I wonder if we could simply export a default prompt as we do with TabExpansion? Or maybe even check if a custom prompt has already been defined, and just re-export that from the module (after checking/warning for absence of a Write-VcsStatus on import)?

We can do a Get-Command prompt and check the HelpURI. On v5 at least, it is populated when the built-in prompt function hasn't been overridden. I'm a little nervous though about "automatically" changing the profile. For instance, and many of the folks I work with don't have the Import-Module directly in any of their profile scripts. They dot source a posh-git_config.ps1 script that imports the module and configures their prompt.

I also think we have to be careful with auto-checks like this every time a module is imported. PS v5 is already notifying me that on some machines my profile scripts are slowing the PS load time. :-(

I guess my thought is that posh-git is close to useless without being loaded as part of a profile. Maybe we could only offer to modify the user's profile if $PSCommandPath is empty (or some equivalent "you seem to have manually imported the module" check)?

I will investigate how to detect if the import is running from a profile or not. If we can quickly assess that then sure, we could ask the user if they want their profile to be modified to import posh-git. I want to finish the prompt install first though. :-)

@dahlbyk

Do you have any telemetry for PowerShell versions used in the wild?

We still have a significant number of Posh-Git users running GitHub Desktop on Windows 7, and we don't touch their PowerShell environment if there is a suitable update available - so they could still be running PowerShell v2.

so they could still be running PowerShell v2.

It would not suck to know this in more detail, so I'm going to go ahead and put that on your backlog myself. 😜

But seriously, how much of a pain would it be for the GitHub Desktop team if we ended up with 0.* limping along for PS v2 and 1.* and beyond for everyone else? I suppose you could ship both and conditionally import?

I will investigate how to detect if the import is running from a profile or not. If we can quickly assess that then sure, we could ask the user if they want their profile to be modified to import posh-git. I want to finish the prompt install first though.

This is in progress: #361

It would not suck to know this in more detail, so I'm going to go ahead and put that on your backlog myself.

LOL, thanks buddy πŸ’– We don't actually track the PowerShell version you have installed - so I'm going by past anecdotes, the OS information I know about, and the fact that PowerShell updates aren't deployed automagically via Windows Update.

But seriously, how much of a pain would it be for the GitHub Desktop team if we ended up with 0.* limping along for PS v2 and 1.* and beyond for everyone else?

The current feature set of Posh-Git 0.* is fine for what we need in Git Shell. I'm also fine with you using 1.* to break the world.

For those who haven't seen it elsewhere, v0.7.0 shipped (changes). Some 1.0 planning is already happening over in #418.

Without revisiting this whole thread tonight, I expect the themes for 1.0 to be:

  1. PowerShell Core cross-platform support (and almost certainly dropping PS v2 support, and maybe v3/v4 too) (#302)

  2. Preferring ANSI strings over Write-Host (#304)

  3. Bust up Write-GitStatus to make overriding its components easier (#345)

    Aside: do we still need to keep the Write-VcsStatus layer of indirection? Should all of that code, and the default VCS-aware prompt, be moved into a common module on which posh-hg could depend?

  4. Simplifying how posh-git is configured (#344)

  5. Remove everything related to SSH agents (#338)

I am actually in favor of dropping support of Powershell < 5.0.

Since Windows 8 supports Powershell 5.0 and there's no point in holding to users who are running < Win8 os.

WMF 5.1 was released earlier this year for Windows 7 and Windows 2012 R2 as well: https://www.microsoft.com/en-us/download/details.aspx?id=54616. We can update the installed WMF 3.

OK I'm going to seriously propose dropping support for PS 2, 3 and 4 in the 1.0.0 release. We'll still keep around 0.7.x for these versions of PowerShell. posh-git 1.0.0 is all about supporting ANSI sequences and (cross-platform) PowerShell Core. This really only applies to PS v5 and higher.

I have several PR's pending that:

  1. Add 24-bit color support e.g. $GitPromptSettings.BranchColor.ForegroundColor = 0xffa000

  2. Convert $GitPromptSettings to a strongly typed class (using PS v5 class support) that also cleans up the API e.g. $GitPromptSettings.LocalStagedStatusSymbol.ForegroundColor. It does this by adding classes PoshGitCellColor and PoshGitTextSpan. The resulting display of $GitPromptSettings is better too IMO:

    image

  3. Refactor the one, huge Write-GitStatus function into a more fine-grained set of commands. So if say you wanted to rework your prompt as a right-to-left deal, it is quite a bit easier to do:

    image

    $status=Get-GitStatus;"$(Write-GitWorkingDirStatus $status)$(Write-GitIndexStatus $status)$(Write-GitBranchStatus $status) `e[38;2;255;160;0m$($status.Branch)`e[0m]"

    There's more work to do here to "clean-up" the experience but hopefully this gives you an idea of what we're shooting for.

OK bit more work on the refactoring of Write-GitStatus - added Write-GitBranchName. This makes the contrived example of a right-to-left style prompt feel more fleshed out:

$status=Get-GitStatus
"[$(Write-GitWorkingDirStatusSummary $status -NoLeadingSpace) " +
 "$(Write-GitWorkingDirStatus $status -NoLeadingSpace) || " +
 "$(Write-GitIndexStatus $status -NoLeadingSpace)/" +
 "$(Write-GitBranchStatus $status -NoLeadingSpace) " +
 "$(Write-GitBranchName $status -NoLeadingSpace)]"

Outputs:
image

BTW if anybody would like to try this out on Linux or macOS or PowerShell Core on Windows, checkout the rkeithhill/refactor-write-prompt branch from this repo. Please let me know if you find any issues

OK I'm going to seriously propose dropping support for PS 2, 3 and 4 in the 1.0.0 release.

I'm fine with this. Is PowerShellGet smart enough to fetch 0.x on older platforms if 1.x requires PS 5+?

That is a question I posted in the Slack channel - https://powershell.slack.com/messages/C22L60F5E

I haven't gotten an answer yet. @lzybkr would you happen to know?

BTW we should consider removing the chocolatey install support in 1.0.0. Everywhere there is PS 5.0 or higher, there is PowerShellGet - including Linux and macOS.

I don't think PowerShellGet has any smarts about installing something that won't work, and it might be annoying if it did, e.g. if you were installing to a location that might be shared across versions.

It seems reasonable to require users to specify a precise version to get support for <V5, or to just use chocolatey assuming that package is never updated.

@lzybkr Thanks. OK yeah, Install-Module has -RequiredVersion and -MaximumVersion that should help here. We'll need to update the README.md on master for the 0.7.x version to show how to install posh-git from the PSGallery for PS < v5 - for the brave few that tried the PkgMngmnt Preview on v3/v4.

Are there any usage stats for versions of PowerShell? Since v2 has been deprecated, I expect its usage to be low. And since v4 was a Win8 version, I suspect its usage is also very low. So what is of interest is the v3 usage share and how long we'll need to support v3.

BTW we should consider removing the chocolatey install support in 1.0.0. Everywhere there is PS 5.0 or higher, there is PowerShellGet - including Linux and macOS.

For 0.7.1, Chocolatey has 50% more downloads than PowerShell Gallery. It seems reasonable for the 1.0+ Chocolatey install/upgrade/uninstall to delegate to PowerShellGet for the exact package version.

Do we need to worry about someone trying to run the Chocolatey script from the repo on Linux/macOS? I mean there's no choco on those platforms. Just wondering if it's worth putting in a platform check or if it falls under the category of "sharp stick, don't poke yer eye out". :-)

Linux/macOS? I mean there's no choco on those platforms.

Not entirely true. Chocolatey has worked on Linux/macOS since 2014 (publicly available in March 2015), but it's only typically used for package maintenance. Installations won't run PowerShell on POSIX environments, so you have nothing to worry about.

FYI, all: we've shipped 1.0.0-beta1 to the PowerShell Gallery.

I've updated the task list here to reflect what I believe still needs to be resolved before we a final 1.0.0 release:

  • Remove profile.example.ps1
  • Convert Chocolatey install/uninstall to use PowerShellGet to install the version corresponding to the Chocolatey package
  • Spin off SSH Agent module (#338)
  • Close remaining Linux issues (#302)

@ferventcoder does Chocolatey have a mechanism to specify that a package only works for PowerShell 5+?

@dahlbyk yes, use dependencies with version ranges. Just like you would in NuGet. Take a dependency on the "powershell" package with a range or minimum version - https://docs.microsoft.com/en-us/nuget/reference/package-versioning#version-ranges-and-wildcards

If you don't want it to automatically upgrade folks to PowerShell v5, then consider something more along the lines of setting a requires in the install script itself and failing. https://ss64.com/ps/syntax-requires.html

I think we are about ready for a beta2 release. There are three PRs pending for this release: #529, #542 and #544.

ICYMI, 1.0.0-beta2 was pushed to the PowerShell Gallery earlier this week.

For anyone who cares about Chocolatey, there's an active discussion over in #473. In particular, the question was raised if posh-git should continue to automatically modify the current user's $PROFILE on install, if anyone has opinions they would like to share.

Is it still possible to define a different color for the git branch name depending if it is ahead/behind the remote?

Right now I have:

$GitPromptSettings.BranchColor.ForegroundColor = 'Green'

But I can't seem to find any other branch color settings.

Perhaps related: #212

Is it still possible to define a different color for the git branch name depending if it is ahead/behind the remote?

@Laoujin it is! Not necessarily intuitive, but branch names are displayed with the same color as the relevant ahead/behind symbol:

  • BranchGoneStatusSymbol
  • BranchIdenticalStatusSymbol
  • BranchAheadStatusSymbol
  • BranchBehindStatusSymbol
  • BranchBehindAndAheadStatusSymbol

You can set ForegroundColor on any of these. BranchColor is only used for branches that aren't set to track an upstream branch.

Thanks!

Silly me thought that would only change the symbol color so I hadn't tried it..

Are you going to continue to prevent TabExpansionPlusPlus from being installed? It would be nice to be able to add other tab completion things to my PS profile

UPDATE: Oh wait.. this is a bug w/ TabExpansionPlusPlus?

Are you going to continue to prevent TabExpansionPlusPlus from being installed? It would be nice to be able to add other tab completion things to my PS profile

UPDATE: Oh wait.. this is a bug w/ TabExpansionPlusPlus?

@tommck were you able to figure this out? I'm not aware of incompatibility, but please open a dedicated issue if you find otherwise.