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

Implement Add-PoshGitToProfile command #361

Merged
merged 10 commits into from
Jan 16, 2017

Conversation

rkeithhill
Copy link
Collaborator

Offer to update their current/all host profile if posh-git not detected in their profile scripts. Note: we do not offer to update the "all users" profile scripts because that requires elevation and probably not worth it.

Add Pester tests for the new Utils.ps1 functions.

Offer to update their current/all host profile if posh-git not detected in their profile scripts.  Note: we do not offer to update the "all users" profile scripts because that requires elevation and probably not worth it.

Add Pester tests for the new Utils.ps1 functions.
Copy link
Owner

@dahlbyk dahlbyk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking great!

# Doesn't exist, so create it
New-Item -Path $profilePath -ItemType File
$profileContent = @()
$encoding = 'ascii'
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's go with utf8 here to make sure we can handle paths with non-ASCII characters.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check.


# Check if the location of this module file is in the PSModulePath
if (Test-InModulePath $ScriptRoot) {
$profileContent += "Import-Module posh-git"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we instead check Get-Module posh-git -ListAvailable to see if it finds this particular instance of the module? Or check that it will find any posh-git module and consider that good enough?

I'm almost tempted to just skip straight to always hard-coding the full module path.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would avoid hard-coding the module path as a "bad practice" for PowerShell modules. I can switch to using Get-Module -ListAvailable.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doh, that makes the Pester test a little harder. Oh well, hopefully not too much harder. :-)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK this is making the Pester tests a lot harder. For some reason, Mock Get-Module is not working. Will look at it more tomorrow.

@@ -1,5 +1,8 @@
param([switch]$WhatIf = $false)

# Dot source for Get-FileEncoding
. $PSScriptRoot\Utils.ps1
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$PSScriptRoot not supported in v2, right? Move $installDir here from below?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thought I caught that. We can just use Split-Path $MyInvocation.MyCommand.Path -Parent instead.

@@ -92,6 +92,57 @@ if (!$currentPromptDef -or ($currentPromptDef -eq $defaultPromptDef)) {
Set-Item Function:\prompt -Value $poshGitPromptScriptBlock
}

# If running interactive, check if user want's `import-module posh-git` added to their profile
if (!$NoProfileCheck -and ($MyInvocation.ScriptName.Length -eq 0)) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the Length check more idiomatic than !$MyInvocation.ScriptName?

Also, s/want's/wants above. :trollface:

@($content)[0] | Should BeExactly "Import-Module '$scriptRoot\posh-git.psd1'"
}
finally {
Remove-Item $profilePath -ErrorAction SilentlyContinue
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BeforeEach {
    $profilePath = [System.IO.Path]::GetTempFileName()
}
AfterEach {
    Remove-Item $profilePath -ErrorAction SilentlyContinue
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Heh, I started with that. Then wrote a few tests that didn't need $profilePath and removed Before/AfterEach. Then I moved those tests to a different Context. Fixed.

@@ -1,5 +1,9 @@
param([switch]$WhatIf = $false)

# Dot source for Get-FileEncoding
$scriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent
Copy link
Owner

@dahlbyk dahlbyk Jan 8, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have $installDir = Split-Path $MyInvocation.MyCommand.Path -Parent on L22. Rename this one and delete that line? (Or keep this name and fix uses of $installDir.)

@dahlbyk
Copy link
Owner

dahlbyk commented Jan 8, 2017

Minor nitpick, otherwise revisions look good. Just need to fix up how we detect if we should Import-Module posh-git!

However to get the Pester tests to work I had to put the Get-Module -List command in its own function and I mock that function.  Mocking Get-Module was resulting in some really weird bug about a write error trying to set PSEdition.
@dahlbyk
Copy link
Owner

dahlbyk commented Jan 9, 2017

Is this ready for a final review? (Go ahead and remove WIP from title if so.)

@dahlbyk dahlbyk mentioned this pull request Jan 9, 2017
13 tasks
@rkeithhill rkeithhill changed the title WIP check user profile during interactive import. Check user profile during interactive import. Jan 9, 2017
@rkeithhill
Copy link
Collaborator Author

Yes. Ready for final review.

@rkeithhill
Copy link
Collaborator Author

Hmm, hold off on this a bit. Joel says ScriptName is empty in implicit loading scenarios and he's right. Let's see if we can use Get-PSCallstack instead.

@rkeithhill rkeithhill changed the title Check user profile during interactive import. WIP Check user profile during interactive import. Jan 9, 2017
Committing this so I can test it on some other systems - via remoting.
@rkeithhill
Copy link
Collaborator Author

I'm becoming quite nervous about this PR. Using Get-PSCallstack has its issues as well. In general I thought a stack count of 2 would be reliably indicative of importing from the prompt e.g. here is a manual import call stack:

PS C:\Users\Keith> ipmo posh-git

Command          : posh-git.psm1
Location         : posh-git.psm1: line 95
Arguments        : {}
ScriptName       : C:\Users\Keith\Documents\WindowsPowerShell\Modules\posh-git\0.7.0\posh-git.psm1
ScriptLineNumber : 95
InvocationInfo   : System.Management.Automation.InvocationInfo
Position         : Get-PSCallstack | fl * | Out-String
FunctionName     : <ScriptBlock>

Command          : <ScriptBlock>
Location         : <No file>
Arguments        : {}
ScriptName       :
ScriptLineNumber : 1
InvocationInfo   : System.Management.Automation.InvocationInfo
Position         : ipmo posh-git
FunctionName     : <ScriptBlock>

And when the PowerShell console profile runs, the stack depth is three:

Command          : posh-git.psm1
Location         : posh-git.psm1: line 95
Arguments        : {}
ScriptName       : C:\Users\Keith\Documents\WindowsPowerShell\Modules\posh-git\0.7.0\posh-git.psm1
ScriptLineNumber : 95
InvocationInfo   : System.Management.Automation.InvocationInfo
Position         : Get-PSCallstack | fl * | Out-String
FunctionName     : <ScriptBlock>

Command          : profile.ps1
Location         : profile.ps1: line 9
Arguments        : {}
ScriptName       : C:\Users\Keith\Documents\WindowsPowerShell\profile.ps1
ScriptLineNumber : 9
InvocationInfo   : System.Management.Automation.InvocationInfo
Position         : Import-Module posh-git
FunctionName     : <ScriptBlock>

Command          : <ScriptBlock>
Location         : <No file>
Arguments        : {}
ScriptName       :
ScriptLineNumber : 1
InvocationInfo   : System.Management.Automation.InvocationInfo
Position         : . 'C:\Users\Keith\Documents\WindowsPowerShell\profile.ps1'
FunctionName     : <ScriptBlock>

But then I started to notice that the PowerShell in VSCode on my machine keep stalling during init. And of course it was stalling because of the query to modify the import. Sigh... There is something about the PowerShell extension custom host that results in a stack depth one less than expected when processing profiles e.g.:

Command          : posh-git.psm1
Location         : posh-git.psm1: line 96
Arguments        : {}
ScriptName       : C:\\Users\\Keith\\Documents\\WindowsPowerShell\\Modules\\posh-git\\0.7.0\\posh-git.psm1
ScriptLineNumber : 96
InvocationInfo   : System.Management.Automation.InvocationInfo
Position         : Get-PSCallstack | Fl * | Out-String
FunctionName     : <ScriptBlock>

Command          : profile.ps1
Location         : profile.ps1: line 10
Arguments        : {}
ScriptName       : C:\\Users\\Keith\\Documents\\WindowsPowerShell\\profile.ps1
ScriptLineNumber : 10
InvocationInfo   : System.Management.Automation.InvocationInfo
Position         : Get-GitStatus
FunctionName     : <ScriptBlock>

Another issue is that if posh-git hasn't been imported yet and you execute one of its commands, it will be auto-imported. That will cause the Modify Profile prompt to appear. That could be confusing.

How about we rejigger this work into a command like Add-PoshGitToProfile? It will result in a pretty simple install process e.g.:

Install-Module posh-git -Scope User
Add-PoshGitToProfile

Otherwise I'm worried there will be some unanticipated scenario (other custom hosts, remoting, etc) that will result in posh-git stalling the script waiting for input.

@rkeithhill
Copy link
Collaborator Author

Looking that the Docker instructions for getting going with the posh-docker PowerShell module see the section Set up tab completion in PowerShell. Their profile mod approach is simply:

Install-Module -Scope CurrentUser posh-docker -Force
Add-Content $PROFILE "`nImport-Module posh-docker"

I like the simplicity. They could have also mentioned that if you want posh-docker loaded in all hosts, then use:

Install-Module -Scope CurrentUser posh-docker -Force
Add-Content $PROFILE.CurrentUserAllHosts "`nImport-Module posh-docker"

And Add-Content seems to preserve the original file's encoding.

@dahlbyk
Copy link
Owner

dahlbyk commented Jan 11, 2017

If you're nervous, I'm nervous. Let's skip the magic. I appreciate the simplicity of Docker's approach, but wouldn't mind being a bit more helpful. How about:

Add-PoshGitToProfile [-AllHosts] [-Force]

  • -AllHosts would switch from CurrentUserCurrentHost to CurrentUserAllHosts.
  • -Force would skip our check if posh-git is already being imported by a profile.
  • We would keep our check to see if we can import by name or need to import the full path.
  • The Chocolatey install would replace its complexity with an import and Add-PoshGitToProfile

And Add-Content seems to preserve the original file's encoding.

And specifying -Encoding UTF8 seems to provide the encoding to use if the file doesn't exist. 💯

We'll still need to handle encoding (we don't today) in Chocolatey install/uninstall, but Add-Content seems sufficient for Add-PoshGitToProfile.

@rkeithhill
Copy link
Collaborator Author

I appreciate the simplicity of Docker's approach, but wouldn't mind being a bit more helpful.

Agreed. Everything else sounds good as well. I'm starting on it.

Now there is an Add-PoshGitToProfile command.  I have  a couple of Pester tests but I need to add a few more.
Not reliable on PS v2.  Add tests.
@rkeithhill rkeithhill changed the title WIP Check user profile during interactive import. Implement Add-PoshGitToProfile command Jan 12, 2017
@rkeithhill
Copy link
Collaborator Author

rkeithhill commented Jan 12, 2017

I'm ready to merge this. @dahlbyk Do you have time to review this?

@dahlbyk dahlbyk merged commit a99b031 into master Jan 16, 2017
@dahlbyk dahlbyk deleted the rkeithhill/modify-profile-on-interative-import branch January 16, 2017 05:47
@dahlbyk dahlbyk mentioned this pull request Feb 6, 2017
6 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants