Skip to content

Create new project#755

Merged
adam-fowler merged 9 commits into
swiftlang:mainfrom
matthewbastien:create-new-project
Apr 23, 2024
Merged

Create new project#755
adam-fowler merged 9 commits into
swiftlang:mainfrom
matthewbastien:create-new-project

Conversation

@matthewbastien

Copy link
Copy Markdown
Member

Implementation of the feature request #754.

The workflow is as follows:

  1. User runs the command Swift: New Project
  2. A prompt appears to select the project type. Available project types are retrieved by parsing the output of swift package init --help.
  3. An open folder dialog appears to select the root folder for the new project.
  4. A quick input appears to enter a name for the project.
  5. The project folder is created on disk and swift package init is executed to create the project based on the given inputs.
  6. A modal appears asking whether or not the user would like to open the newly created folder in the current window or a new one. An automatic action for this step can be configured with the swift.openAfterCreateProject setting. This is essentially the same modal used by the Git: Clone command.

I've also added a fairly basic test to make sure that the parsing of swift package init --help is functioning as intended.

Feedback is greatly appreciated! This is my first commit to this project and I definitely don't know all the ins and outs to the code base.

Comment thread src/commands.ts Outdated
*/
export function register(ctx: WorkspaceContext) {
ctx.subscriptions.push(
vscode.commands.registerCommand("swift.createProject", () => createProject(ctx)),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

createProject() has a few instances where it returns undefined. What's the experience for the user in these cases? Should createProject be providing guidance/errors to the user in the form of notifications?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The places where createProject() returns undefined correspond to the user cancelling dialogs. I don't think we need any notifications in this case.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

👍 What's the behaviour from vscode for exceptions (e.g. the execSwift or mkdir fail)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

It pops up a modal with the error message from the exception.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Have you verified what the message is for say mkdir failing? Would be good to make sure it is human readable.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Good question! I tried it out myself and it looks like the error message is fairly self explanatory:

Screenshot 2024-04-22 at 1 05 31 PM

@adam-fowler adam-fowler left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

In general looks pretty good, I've added a few comments

Comment thread package.json Outdated
{
"title": "Swift",
"properties": {
"swift.openAfterCreateProject": {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can we add an order value to this to define where it appears in the settings menu

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Done. I put it at the end of the settings since I can't imagine this being a high runner use case.

Comment thread src/utilities/utilities.ts Outdated
/**
* A wrapper around {@link vscode.Progress} that allows for delaying progress reporting.
*/
class ProgressWrapper<T> implements vscode.Progress<T> {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can we move the progress UI code to a separate file in the UI folder.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Done.

Comment thread src/commands.ts
Comment thread src/commands.ts Outdated
// Prompt the user whether or not they want to open the newly created project
const isWorkspaceOpened = !!vscode.workspace.workspaceFolders;
const config = vscode.workspace.getConfiguration("swift");
const openAfterCreate = config.get<string>("openAfterCreateProject");

@adam-fowler adam-fowler Apr 20, 2024

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can we add configuration settings to configuration.ts

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Done.

Comment thread src/commands.ts

// Use swift package manager to initialize the swift project
await withDelayedProgress(
{

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Given there is no progress reported here, any reason you can't use WorkspaceContext.statusItem.showStatusWhileRunning()

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I'd expect that 99% of the time we would never even show the notification. In my testing it never showed up unless I reduced the timeout. However, if it does take longer than expected, I want it to be a prominent notification rather than something hidden away in the status bar. That way users know that something is actually happening in the background.

That being said, this does add extra code that will need to be maintained. I'm not too strongly attached to this opinion and can just use showStatusWhileRunning() instead if that makes more sense to you.

Comment thread src/commands.ts Outdated
*/
export function register(ctx: WorkspaceContext) {
ctx.subscriptions.push(
vscode.commands.registerCommand("swift.createProject", () => createProject(ctx)),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Have you verified what the message is for say mkdir failing? Would be good to make sure it is human readable.

*/
public async getProjectTemplates(): Promise<SwiftProjectTemplate[]> {
const { stdout } = await execSwift(["package", "init", "--help"], "default");
const lines = stdout.split(/\r?\n/g);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This is some funky way to get project templates, but yeah can't see any other way of doing it.

I almost wonder if it is worthwhile rolling our own outside of SwiftPM. Would love to give users the ability to create their own templates. Maybe using Mustache templating to allow users to add in customisation. But that'd be for another task I think.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yeah I agree. I'd honestly like an option in Swift Package Manager to get these as JSON rather than doing the crazy command line parsing. However, we still need to support Swift versions <6.

@adam-fowler

Copy link
Copy Markdown
Contributor

@swift-server-bot test this please

@adam-fowler

Copy link
Copy Markdown
Contributor

@swift-server-bot add to allowlist

@adam-fowler

Copy link
Copy Markdown
Contributor

CI is returning a bunch of errors for older versions of swift. New features can probably be gated on the last three versions of swift. Get it working for 5.8 if it works for all the earlier swift versions as well you are done. Otherwise Add a new contextKey newProjectAvailable in contextKeys.ts and use the contextKey to control availability of the command. At startup you can check the swift version and set it to false if the swift version is less than 5.8

Comment thread package.json Outdated

@award999 award999 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

a few minor comments :)

Comment thread src/commands.ts Outdated
Comment thread src/commands.ts
@matthewbastien

Copy link
Copy Markdown
Member Author

CI is returning a bunch of errors for older versions of swift. New features can probably be gated on the last three versions of swift. Get it working for 5.8 if it works for all the earlier swift versions as well you are done. Otherwise Add a new contextKey newProjectAvailable in contextKeys.ts and use the contextKey to control availability of the command. At startup you can check the swift version and set it to false if the swift version is less than 5.8

The output of swift package init --help changes pretty drastically in versions <5.8.0. I've added the context key for enablement of the command, but we still need to support users being able to create a project in cases where the Swift extension is not activated yet (e.g. when no workspace is open). As such, I've also added a swift.isActivated context key to detect this. An error is shown to the user if they try to use the create project command with an unsupported swift version.

@adam-fowler adam-fowler left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think we are good here

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.

4 participants