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

Add support for workspace profiles #190

Open
daviwil opened this issue May 18, 2016 · 31 comments
Open

Add support for workspace profiles #190

daviwil opened this issue May 18, 2016 · 31 comments
Labels

Comments

@daviwil
Copy link
Contributor

daviwil commented May 18, 2016

It'd be nice if we provided a way for the user to configure a startup script which gets run when VS Code opens their project folder. This would allow them to configure their session for the project they're developing without having to add anything extra to their profile. This would also allow registration of project-specific editor commands using the $psEditor API.

@daviwil daviwil added the Issue-Enhancement A feature request (enhancement). label May 18, 2016
@daviwil daviwil added this to the Backlog milestone May 18, 2016
@daviwil daviwil modified the milestones: July 2017, Future Jul 19, 2017
@daviwil daviwil changed the title Allow user to specify a startup script in their workspace configuration Add support for "workspace profiles" Jul 19, 2017
@daviwil
Copy link
Contributor Author

daviwil commented Jul 19, 2017

After thinking about this a bit, it seems like the most obvious way to approach this is to define the concept of a "workspace profile" that gets loaded in addition to the VS Code host profiles. When the user loads a folder in VS Code, we'll look for a file called .profile.ps1 (or better suggestion) in the root of the workspace path and then load that along with the other host profiles.

This will be useful when a project has certain modules it needs to load when the user loads up the project. This could also be useful to other editors so I won't be making it editor-specific (not placing the profile in the .vscode subfolder).

Thoughts? @rkeithhill

@daviwil daviwil changed the title Add support for "workspace profiles" Add support for workspace profiles Jul 19, 2017
@PowerSchill
Copy link
Contributor

I really like that idea. Would make development of modules and such much easier especially if I need to override installed modules with development versions.

@rkeithhill
Copy link
Collaborator

I like the idea. Do you want to load that file by a "conventional" name like .profile.ps1 or indirectly via a setting that defaults to ${workspaceRoot}/.profile.ps1. Not sure it's worth the extra level of indirection and there is some value in always being able to identify this file. And the extra level of indirection is something that could be added later if we find it is needed.

@dragonwolf83
Copy link

If it is going to be editor agnostic, it would make sense to continue the pattern to have a generic Workspace profile and a Host/Editor specific profile that can be used.

WorkspaceAllHosts    : {WorkspaceRoot}\Workspace.profile.ps1
WorkspaceCurrentHost : {WorkspaceRoot}\Workspace.VSCode_profile.ps1

WorkspaceAllHosts would work well to cover the module loading scenarios since most of them shouldn't care about the Host to run.

WorkspaceCurrentHost would cover the $psEditor commands that might be specific to an Editor that you wouldn't want to load up in another one.

@mattmcnabb
Copy link
Contributor

Like the idea, but not sure about using a generic file name like profile.ps1. I can imagine someone loading a project with a file named that and inadvertently running some code they didn't intend to. A safer way would be to include this in the .vscode folder, but i know you plan to leave this open for other editors. What if we had a project-level setting in there that would contain the path to the project profile script? That way you could choose to store it in the workspace root or any where else, and name it whatever you like.

@PowerSchill
Copy link
Contributor

@dragonwolf83 Considering that this setting would only be in VSCode I don't think you would need multiple values. For Example in Sublime Text you would need something to be stored in their project file.

@PowerSchill
Copy link
Contributor

I can see @mattmcnabb point. My PowerShell profile is a project so if I were using that workspace it would run every time. Let me offer a suggestion of the default profile to be workspace_profile.ps1. I think that would greatly reduce the conflict possibilities.

By default the workspace profile would be {WorkspaceRoot}\workspace_profile.ps1 but could be overriden in the project settings.

@rkeithhill
Copy link
Collaborator

Maybe this frickin' Linux stuff is starting to rub off on me but I'm strangely attracted to .profile.ps1. :-) That said ... considering all other PowerShell profiles do not start with a ., I'd go something like what @PowerSchill suggests. Is the term workspace editor agnostic?

@dragonwolf83
Copy link

@rkeithhill The workspace term is not used in all editors as many will use project but I think the definition of the term is clear enough that it can be safely used and understood.

@PowerSchill I don't see why it wouldn't work in Sublime Text if there is an Integrated Terminal with PowerShell Editor Services. The $PSEditor extension reads the Project/Workspace settings from the Editor and automatically loads $profile.WorkspaceCurrentHost and $profile.WorkspaceAllHosts if they exist.

As long as $PSEditor is told when a project, folder, workspace or whatever is switched, it should be able to open a new runspace and load the correct $profile(s).

For example, I can see this being very useful in Visual Studio where I have scripts that automate Visual Studio in COM. I can open my project and have it run the PowerShell extension to run those commands or load a module that makes it easier to run those commands.

@mattmcnabb if you referring to my post on name profile.ps1. The PowerShell highlighting sucks on GitHub, the name I had was Workspace.profile.ps1. I tend to like dot notations rather than underscores as a personal preference.

@Jaykul is any of this useful in what you did with Jupyter? I think your feedback would be good on this.

@mattmcnabb
Copy link
Contributor

I'm just saying that if there's a chance that a user will update the extension and then open a workspace that contains a file matching whatever the naming convention may be, then there is a risk and this should be avoided. Any code that is automtically run at load should be explicitly agreed to by the user. If the path to this file is set by a setting in the .vscode/settings.json and the setting is off by default, then the user should be protected against inadvertently launching a script.

@rkeithhill
Copy link
Collaborator

rkeithhill commented Jul 19, 2017

@dragonwolf83

I tend to like dot notations rather than underscores as a personal preference.

Given that the existing host-specific profiles already use _ having a default of workspace_profile.ps1 makes the most sense to me. However, if this is controlled by an editor setting then you would be free to use .. :-)

@SeeminglyScience
Copy link
Collaborator

SeeminglyScience commented Jul 19, 2017

Definitely love this idea.

For security reasons would it be possible to have a prompt once per workspace? Similar to how VSCode handles workspace terminal customizations.

As for the file name, I'd like to throw ProjectName.profile.ps1 into the running. Similar to the InvokeBuild build script naming scheme.

@daviwil
Copy link
Contributor Author

daviwil commented Jul 20, 2017

The main reason why I suggested .profile.ps1 is because the naming doesn't stand out a whole lot in the project's root folder (i.e. it's not ugly looking). For some reason I'm aesthetically opposed to workspace_profile.ps1 as the standard name, just seems too long and clunky. If we go with something more specific than .profile.ps1, I'd probably go with @SeeminglyScience's recommendation of FolderName.profile.ps1 since the file name would at least match that of the project (and be more obvious in the process).

Regarding whether we'd have a separate "all editors" profile, I think I'd prefer to keep things simple and not require a project to have multiple files for all the possible editors that developers in the project might want to use. I think it'd be better if the profile script could modify it's behavior based on the editor it gets loaded in. The goal of PS Editor Services is to minimize the need for editor-specific behavior, so I think we've failed if it's absolutely necessary to have separate profiles per editor.

I'm also inclined to not allow this to be configured (at least at first). PowerShell doesn't let you customize it's profile paths :) The route I'd opt for is to have a standard naming convention so that you never have to look at the project's settings (across multiple editors...) to figure out what the workspace profile script is. I'd prefer to establish a standard name based on user feedback and then stick with that.

@daviwil
Copy link
Contributor Author

daviwil commented Jul 20, 2017

Forgot to mention the security aspect: I can definitely show an initial prompt to ask the user whether they want to load the workspace profile for this project.

@gwojan
Copy link

gwojan commented Jul 20, 2017

I would prefer the .profile.ps1 because on the *nix platforms it becomes just another hidden file right? That's a behavior I wish we could emulate on Windows.

Just my 2 cents worth... 😊

@SeeminglyScience
Copy link
Collaborator

@gwojan that's actually part of my problem with that name.

Do we really want this file to be hidden? I feel like it would be one of the first files you want to look at when opening someone else's project for the first time. Especially if it is registering editor commands.

@PowerSchill
Copy link
Contributor

To be honest as long as its a preference I don't really care as much since I can set it to what I want. But for the general public it is a bigger deal. I do kind of like the .profile but I also am very familiar with Linux/OSX systems so its normal for me. Considering that most users, I am guessing, are Windows users and are not familiar with it. Using other examples; InvokeBuild uses *.build.ps1 files and Pester uses *.test.ps1; I tend to think that maybe we should use *.profile.ps1.

With that said I am comfortable with any of the options stated.

@daviwil
Copy link
Contributor Author

daviwil commented Jul 20, 2017

Thanks for all the feedback! I think at first I'll go with ProjectName.profile.ps1 and then see what kind of feedback we get then potentially add a setting if people want more flexibilty.

@rkeithhill
Copy link
Collaborator

Sounds good. And if we need to add the setting, we can use "${workspaceRootFolderName}.profile.ps1.

@daviwil daviwil modified the milestones: July 2017, Future Oct 26, 2017
@lucdekens
Copy link

Not sure if this issue needs reviving or not, but I would really appreciate this feature.

I'm thinking primarily on folders that correspond with a repository.
With this feature, all contributors would have the same initialization/settings/environment when they start working on the repo.

I don't really care about the filename nor the location of the file, but the .vscode folder looks like an obvious choice when implemented for VSC only.

For VSC an enable/disable flag in the workspace settings would be a requirement for me.

@NReilingh
Copy link

Just wanted to chime in with what might be considered a novel workaround — since the PowerShell Integrated Console for a workspace always starts up with the workspace root as the working directory, you can add code to your Microsoft.VSCode_profile.ps1 that attempts to resolve to a file relative to the workspace root.

For example, you could do something like $WorkspaceProfiles = Resolve-Path .\*.profile.ps1 and then source the results if any exist.

@ghost ghost added the Needs: Maintainer Attention Maintainer attention needed! label Sep 3, 2019
@SydneyhSmith SydneyhSmith removed the Needs: Maintainer Attention Maintainer attention needed! label Sep 5, 2019
@chriskuech
Copy link

It looks like we just need to prepend const startEditorServices in process.ts with . <path-to-workspace-profile>;. Is my assessment correct?

In my opinion, adding an extension setting pointing to the profile is much preferred than a "magic" solution, as this feature would then be implicitly documented with the rest of the extension settings and subsequently much more discoverable.

@ghost ghost added the Needs: Maintainer Attention Maintainer attention needed! label Dec 13, 2019
@SeeminglyScience
Copy link
Collaborator

It looks like we just need to prepend const startEditorServices in process.ts with . <path-to-workspace-profile>;. Is my assessment correct?

Not exactly, the idea is that it would be a profile per workspace similar to VSCode's settings.json but for setting up PowerShell context. Adding something at the workspace level that gets invoked automatically is potentially dangerous. For this feature to be feasible I think one of these would need to be true:

  1. Disabled by default, cannot be overridden at the workspace level. This one isn't my preference because one of the main things I think this would be useful for is setting up PowerShell context for contributors of a public project. There's a lot of things you can do to set up intellisense like set up type accelerators, import non-public module functions into global, etc. This option limits the utility of that to folks who already have that enabled. It's also an either or type of thing, where ideally you'd want to enable this for some workspaces and disable for others.

  2. Enabled with prompt by default. Ideally when a workspace is entered, we'd check for a workspace profile and prompt the user to determine if they'd like to run it. Preferably with Yes/No/Always/Never options.

In my opinion, adding an extension setting pointing to the profile is much preferred than a "magic" solution, as this feature would then be implicitly documented with the rest of the extension settings and subsequently much more discoverable.

I don't see any problem with that. There could be a workspace overridable setting that specifies a profile path, though I would prefer a sensible default value as the "magic" option.

@chriskuech
Copy link

What if we break up the implementation into the two steps below to start unblocking and gaining traction?

  1. Read a specific profilePath from settings.json and load it into the session, such that no auto-execution of code is enabled by default--only enabled by explicitly updating settings.json.
  2. Automatically determine the profilePath from the environment and prompt the user asking whether to run the profile.

@SeeminglyScience
Copy link
Collaborator

  1. Read a specific profilePath from settings.json and load it into the session, such that no auto-execution of code is enabled by default--only enabled by explicitly updating settings.json.

I'm not really sure what problem that's solving to be honest. That makes them too individualized for what I'm picturing (imo). Also you could set this up currently in your $profile.CurrentUserCurrentHost pretty easy:

# $psEditor.Workspace.Path currently gives a malformed path in the
# preview version of the extension, but should be fixed next release.
$workspaceProfile = Join-Path $psEditor.Workspace.Path -ChildPath MyProfileName.ps1
if (Test-Path -LiteralPath $workspaceProfile) {
    . $workspaceProfile
}

If a feature is introduced to vscode-powershell that extends that functionality, I would personally prefer that it be more generalized.

Automatically determine the profilePath from the environment and prompt the user asking whether to run the profile.

That's more or less what I mean by option 2 in my post above. The setting to override it is the easy part, the harder (but probably still not too hard) part is setting up the prompt (particularly with the Always/Never options).

@chriskuech
Copy link

Right now there is no way to make linting work with custom modules, as you can in other language extensions. All I want is to make linting work automatically for repo contributors--defining a profile path in settings.json that gets checked in seems like a perfect candidate for this, as well as add the internal hook for adding more complex scenarios in the future.

My point is that these steps aren't mutually exclusive and breaking down the problem into smaller pieces will increase the likelihood of gaining traction towards implementing all the pieces.

If someone from the vscode-powershell team can confirm that this would be implemented by dot-sourcing the correct path in process.ts (and adding the necessary settings), then I can PR the change.

@SeeminglyScience
Copy link
Collaborator

SeeminglyScience commented Dec 13, 2019

Right now there is no way to make linting work with custom modules, as you can in other language extensions. All I want is to make linting work automatically for repo contributors--defining a profile path in settings.json that gets checked in seems like a perfect candidate for this

Would that be a workspace level setting or a user level setting? If the former, then that would still require the safe guards be in place. If the latter, then it's not automatic and (imo) doesn't provide significant value over having the above sample in your profile.

My point is that these steps aren't mutually exclusive and breaking down the problem into smaller pieces will increase the likelihood of gaining traction towards implementing all the pieces.

Yes and no. We have historically had a lot of half implemented features that never really went anywhere. I absolutely agree that this can be a fantastic feature, but I think there are some key parts to this feature that can't be skipped.

If someone from the vscode-powershell team can confirm that this would be implemented by dot-sourcing the correct path in process.ts (and adding the necessary settings), then I can PR the change.

Unfortunately that won't work. When the start up script is ran it creates a new runspace, this is how we are able to implement our own PSHost while still using powershell.exe/pwsh directly. That would potentially work for environment variables, but just about everything else would be lost.

The actual invocation would need to be done from PowerShellEditorServices (the language server vscode-powershell uses).

Here is where the profiles are executed. Though you may need to alter ProfilePathInfo since it is currently hard coded to the same four options as $profile is typically.

You can also implement the prompt from there potentially, but I can't remember if the LSP will be busy while the console is initializing. If it's not busy, you can send a showMessageRequest from the language server to determine if the profile should be invoked. If it is busy then it may be better to do as a separate request sent from vscode-powershell to PowerShellEditorServices after initialization.

As long as there is a prompt, and a sensible default file name (preferably {WorkspaceName}.profile.ps1), I think that's good enough for an initial implementation. I think the Never/Always options can come later.

@SydneyhSmith SydneyhSmith removed the Needs: Maintainer Attention Maintainer attention needed! label Dec 18, 2019
@ctmcisco
Copy link

I found myself needing this type of functionality. Also providing a nudge, almost, exactly 1 year from @SydneyhSmith nudge :).

@ghost ghost added the Needs: Maintainer Attention Maintainer attention needed! label Dec 14, 2020
@SydneyhSmith SydneyhSmith removed the Needs: Maintainer Attention Maintainer attention needed! label Jan 5, 2021
@SydneyhSmith SydneyhSmith removed this from the Future milestone Jan 26, 2021
@egerlach
Copy link

egerlach commented Jan 7, 2023

I'm not an expert at this by any stretch of the imagination, but would a half-measure be a way to specify the HostProfileId when starting up PSES? Honestly, I don't even know what that parameter does specifically (I tried to read the code but quickly got lost), but it sounds like it might change the Profile Host Id from Microsoft.VSCode to something custom for the workspace.

While that doesn't quite get 100% there, it's one setup step to put the appropriate .ps1 file in your PowerShell directory where it would get picked up. This also avoids the security concerns about running arbitrary code on first load of a workspace with the option set.

Again, I don't know if that would work and I don't know nearly enough about the extension or PSES. I don't know if the dots I'm seeing connect into a picture or a mess, thus why I'm just leaving this here for more experienced minds to ponder.

@ilsaloving
Copy link

It would not be appropriate to put this in User as the point is to have a custom profile for the workspace/project you are working on.

As far as security goes, I don't think this should be a consideration. VSC already has a mechanism for trusting the files in a workspace/folder, so you either trust them or you don't. Anything more should fall to the developer. If people really feel this is necessary, a simple workspace setting checkbox for loading profile scripts or not should be sufficient.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests