Skip to content

feat: specify add-on options in command args #543

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

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

AdrianGonz97
Copy link
Member

@AdrianGonz97 AdrianGonz97 commented Apr 22, 2025

partially implements #528 (although i'm moreso playing around with this idea atm)

While similar to #528, there's a minor difference when it comes to bailing/defaults:

# prompt for tailwind options
sv add tailwind

# installs tailwind with only the `forms` plugin
sv add tailwind=plugins:forms

# Rather than bailing on incomplete options, we'll apply defaults to incomplete items (just like we do today):
# installs tailwind with default options (which means no plugins are included)
sv add tailwind=

# installs drizzle with default options (postgres.js and no docker)
sv add drizzle=database:postgresql

I also had to configure our own formatHelp method to add a new help field that nicely displays the add-on options:

➜  boo sv add -h     
Usage: sv add [options] [add-on...]

applies specified add-ons into a project

Arguments:
  add-on                            add-ons to install

Add-On Options:
  tailwindcss                       plugins: typography, forms
  sveltekit-adapter                 adapter: auto, node, static, vercel, cloudflare-pages, netlify
  drizzle                           database: postgresql, mysql, sqlite
                                    client: postgres.js, neon, mysql2, planetscale, better-sqlite3, libsql, turso
                                    docker: yes, no
  lucia                             demo: yes, no
  paraglide                         languageTags: <user-input>
                                    demo: yes, no

Options:
  -C, --cwd <path>                  path to working directory (default: "...")
  --no-preconditions                skip validating preconditions
  --[no-]install <package-manager>  installs dependencies with a specified package manager (choices: npm, yarn, pnpm, bun, deno)

It would also be nice to have an example on how to apply them (e.g. Usage: sv add drizzle=database:postgresql,client:postgres.js,docker:yes), but I'm not exactly sure where that should go in the help text just yet.

Issues

Note

This has been resolved by requiring options to be listed with the <name>:<value> format (e.g. sv add addon=option:value)

I didn't notice this before, but the paraglide add-on is a bit of a nuisance when it comes to specifying its options. This is because one of its options prompts for arbitrary user input.

For example, how do we parse this?

sv add paraglide=en,es,de,no-demo
# ideally, we'll want to yank out `en,es,de` and `no-demo`

Since add-on options are delimited by ,'s and paraglide uses a , to delimit its own user input, how should we parse this? I'm not exactly sure yet, but this is an issue that occurs to this day with our current add-on option flags format: --paraglide=en,de,demo. I guess one option would be to choose a new delimiter for the paraglide add-on. Alternatively, we could change it to a ; for the add-on args (e.g. sv add paraglide=en,de;no-demo).

Copy link

changeset-bot bot commented Apr 22, 2025

⚠️ No Changeset found

Latest commit: 5d5ec5c

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Copy link

pkg-pr-new bot commented Apr 22, 2025

Open in StackBlitz

npx https://pkg.pr.new/sveltejs/cli/sv@543
npx https://pkg.pr.new/sveltejs/cli/svelte-migrate@543

commit: b2ecdaf

@AdrianGonz97 AdrianGonz97 marked this pull request as draft April 22, 2025 21:49
@benmccann
Copy link
Member

Ah, interesting catch on the paraglide add-on. The only other option I can think of is to do what CSV does when there's a comma and wrap that value in quotes:

sv add paraglide="en,es,de",no-demo

@AdrianGonz97
Copy link
Member Author

That's an interesting idea that could work!

Another idea that might work would be to eliminate the ambiguity of specifying options which would act as it's own separator as well:

sv add paraglide=languageTags:en,es,de,demo:no

sv add drizzle=database:postgres,client:postgres.js,docker:yes

However, it's a bit more verbose and can get awkward around the y/n prompts (e.g. docker:no, demo:yes, etc.)

@benmccann
Copy link
Member

Adding the option name in there does make things clearer. Though it's still a little hard to read since , can be used in multiple ways and still might not be a bad idea to switch to ; anyway:

sv add paraglide=languageTags:en,es,de;demo:no

sv add drizzle=database:postgres;client:postgres.js;docker:yes

@AdrianGonz97
Copy link
Member Author

AdrianGonz97 commented Apr 23, 2025

Sadly the quotes method (sv add paraglide="en,es",no-demo) won't work as shells strip the quotes from the args before we're able to parse them (e.g. it gets converted into sv add paraglide=en,es,no-demo).

You can view this in action by running node --eval "console.log(process.argv)" foo="bar" locally.

Though it's still a little hard to read since , can be used in multiple ways and still might not be a bad idea to switch to ; anyway:

Good point! Using a ; too will also make it notably easier to parse as well. Will give it a go


edit: Using a ; won't work either as it signifies the end of a command and the start of a new command in shells 😅 ironically, to get it to work with semis, we'd have to wrap the whole thing in quotes: sv add paraglide="languageTags:en,de;demo:yes"

@AdrianGonz97
Copy link
Member Author

I've updated the PR to now use the addon=<name>:<value> format for specifying options. This solves the paraglide issue and seems to be working nicely

@manuel3108
Copy link
Member

Generally, this seems like the perfect solution. We should have found that way earlier. It's way more descriptive and more clear what you are actually trying to achieve. Also the first tests seemed pretty successful.

But this currently fails for me

pnpm dlx https://pkg.pr.new/sveltejs/cli/sv@543 add drizzle=database:postgresql,client:postgres.js --no-install

Probably because it does not know if the comma should separate an option or an option value (like for tailwind forms). Alternatively, this might be on of those things that's only happening on windows.

The same goes for this one:

pnpm dlx https://pkg.pr.new/sveltejs/cli/sv@543 add paraglide=languageTags:en,de,demo:no --no-install

Alternatively, I'm just not aware of the correct syntax.

It would also be nice to have an example on how to apply them (e.g. Usage: sv add drizzle=database:postgresql,client:postgres.js,docker:yes), but I'm not exactly sure where that should go in the help text just yet.

I wouldn't necessarily deem this as obligatory. Based on the docs Ben drafted, this should be pretty clear how to use them.

@AdrianGonz97
Copy link
Member Author

AdrianGonz97 commented Apr 24, 2025

But this currently fails for me

pnpm dlx https://pkg.pr.new/sveltejs/cli/sv@543 add drizzle=database:postgresql,client:postgres.js --no-instal

Running this line works perfectly for me on linux, so I'm going to guess it's Windows 🙃. Will take a closer look in a few.

@manuel3108
Copy link
Member

manuel3108 commented Apr 24, 2025

Here is a stack trace if you want:

■  Error: Unable to process 'src/lib/server/db/schema.ts'. Reason: unreachable state...
│      at Object.file (file:///C:/Users/manue/AppData/Local/pnpm-cache/dlx/549e25a5f22fa51d3cd0c210a4923d430768b3b4648911fef330d82ee1b55e7b/19668831d42-56e70/node_modules/.pnpm/sv@https+++pkg.pr.new+sveltejs+cli+sv@543/node_modules/sv/dist/install-iBxCFLH9.js:1067:35)
│      at Object.run (file:///C:/Users/manue/AppData/Local/pnpm-cache/dlx/549e25a5f22fa51d3cd0c210a4923d430768b3b4648911fef330d82ee1b55e7b/19668831d42-56e70/node_modules/.pnpm/sv@https+++pkg.pr.new+sveltejs+cli+sv@543/node_modules/sv/dist/bin.js:1299:6)
│      at runAddon (file:///C:/Users/manue/AppData/Local/pnpm-cache/dlx/549e25a5f22fa51d3cd0c210a4923d430768b3b4648911fef330d82ee1b55e7b/19668831d42-56e70/node_modules/.pnpm/sv@https+++pkg.pr.new+sveltejs+cli+sv@543/node_modules/sv/dist/install-iBxCFLH9.js:1108:14)
│      at applyAddons (file:///C:/Users/manue/AppData/Local/pnpm-cache/dlx/549e25a5f22fa51d3cd0c210a4923d430768b3b4648911fef330d82ee1b55e7b/19668831d42-56e70/node_modules/.pnpm/sv@https+++pkg.pr.new+sveltejs+cli+sv@543/node_modules/sv/dist/install-iBxCFLH9.js:1023:50)
│      at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
│      at async runAddCommand (file:///C:/Users/manue/AppData/Local/pnpm-cache/dlx/549e25a5f22fa51d3cd0c210a4923d430768b3b4648911fef330d82ee1b55e7b/19668831d42-56e70/node_modules/.pnpm/sv@https+++pkg.pr.new+sveltejs+cli+sv@543/node_modules/sv/dist/bin.js:7071:79)
│      at async file:///C:/Users/manue/AppData/Local/pnpm-cache/dlx/549e25a5f22fa51d3cd0c210a4923d430768b3b4648911fef330d82ee1b55e7b/19668831d42-56e70/node_modules/.pnpm/sv@https+++pkg.pr.new+sveltejs+cli+sv@543/node_modules/sv/dist/bin.js:6837:25
│      at async runCommand (file:///C:/Users/manue/AppData/Local/pnpm-cache/dlx/549e25a5f22fa51d3cd0c210a4923d430768b3b4648911fef330d82ee1b55e7b/19668831d42-56e70/node_modules/.pnpm/sv@https+++pkg.pr.new+sveltejs+cli+sv@543/node_modules/sv/dist/bin.js:3899:3)

The second paraglide option actually installs the demo, even though it's explicitly set to no. But this one does not throw an error

This was referenced Apr 24, 2025
@manuel3108
Copy link
Member

As discussed on discord and partially in #533 the issue I was encountering did only happen on Windows while using PowerShell (others were able to reproduce this as well). The best / most simple workaround is to qoute all option args like this pnpm dlx https://pkg.pr.new/sveltejs/cli/sv@543 add drizzle="database:postgresql,client:postgres.js" --no-instal which then works as expected.

I would suggest that we go forward with this and update the recently introduced docs. Also, we should probably quote all add-on option values in the docs to avoid future confusion for windows users.

@benmccann
Copy link
Member

The same goes for this one:
pnpm dlx https://pkg.pr.new/sveltejs/cli/sv@543 add paraglide=languageTags:en,de,demo:no --no-install

Is that what the command ended up being? Or is a semi-colon between de and demo? That might also be your problem with the other one as well rather than a Windows issue

I would suggest that we go forward with this and update the recently introduced docs. Also, we should probably quote all add-on option values in the docs to avoid future confusion for windows users.

I was going to say that I'd hate to make non-Windows users do that, but maybe it doesn't actually matter since I imagine very few people will be specifying long strings of options except inside scripts, so that's probably fine actually

@manuel3108
Copy link
Member

Is that what the command ended up being? Or is a semi-colon between de and demo? That might also be your problem with the other one as well rather than a Windows issue

Currently it's commas everywhere.

I was going to say that I'd hate to make non-Windows users do that, but maybe it doesn't actually matter since I imagine very few people will be specifying long strings of options except inside scripts, so that's probably fine actually

Yeah, I do think this only affects a very small minority, so I'm not super concerned as well. And the quotes shouldn't break anything on *nix systems

@benmccann
Copy link
Member

paraglide=languageTags:en,de,demo:no looks hard to read for me , is used both within and between questions. What about something like like query parameters such as paraglide=languageTags:en,de&demo:no?

@AdrianGonz97
Copy link
Member Author

Unfortunately using an & to separate questions won't work either since & is a preexisting shell control operator (used to run processes in the background), similar to the issue with using ;. The workaround would also be to wrap the question values in quotes:

sv add paraglide="languageTags:en,de&demo:no"

@benmccann
Copy link
Member

darn. I'd feared that. Quotes aren't the worst option though. I wonder if + would need quotes as well?

sv add paraglide=languageTags:en,de+demo:no

@AdrianGonz97
Copy link
Member Author

Ooh, + could work. It doesn't seem to require the quotes on unix-like systems (windows users will need to use the quotes anyway, so we don't need to worry about them).

@svelte-docs-bot
Copy link

@benmccann
Copy link
Member

I think some of the new docs I added in https://github.com/sveltejs/cli/tree/main/documentation/docs/30-add-ons will need to be updated, but otherwise this is looking pretty good

@AdrianGonz97
Copy link
Member Author

AdrianGonz97 commented May 6, 2025

So it looks like the + separator works pretty well in Windows too without needing to wrap the whole thing in quotes (@manuel3108 if you could confirm this as well, just in case my machine's not just another anomaly 😄).

Adding quotes should only be necessary for add-on options that use arbitrary strings or lists (like languageTags in paraglide or plugins in tailwindcss).

typical usage (no quotes required, should work on Windows without issue):

sv add drizzle=database:postgresql+client:postgres.js+docker:yes
sv add lucia=demo:yes
sv add sveltekit-adapter=adapter:node
sv add tailwind=plugins:none # `sv add tailwind=` is also the equivalent

quotes required for arbitrary strings or multiselect prompts:

sv add paraglide="languageTags:en,de+demo:no"
sv add tailwind="plugins:typography,forms"

I wonder if should we just default to not using quotes in the docs until it's necessary? or should we just always wrap them for the sake of consistency?

@benmccann
Copy link
Member

I think we could probably include quotes only where needed. But we should just be careful that if it's a place you could include a comma that we demonstrate it that way and don't use a simpler example

Copy link
Member

@manuel3108 manuel3108 left a comment

Choose a reason for hiding this comment

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

Can confirm everything is working correctly for me, as you already expected.
I agree with the decision regarding the docs, i think that makes sense

```

### demo

Whether to generate an optional demo page showing how to use paraglide.

```bash
npx sv add --paraglide=demo
npx sv add paraglide="demo:yes"
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
npx sv add paraglide="demo:yes"
npx sv add paraglide=demo:yes

@@ -27,5 +27,5 @@ Which plugin to use:
- `forms` — [`@tailwindcss/forms`](https://github.com/tailwindlabs/tailwindcss-forms)

```bash
npx sv add --tailwindcss=typography
npx sv add tailwindcss="plugins:typography"
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
npx sv add tailwindcss="plugins:typography"
npx sv add tailwindcss=plugins:typography

// need to transform the boolean back to `no-{id}` or `{id}`
existingOption = existingOption ? questionId : `no-${questionId}`;
// need to transform the boolean back to `yes` or `no`
existingOption = existingOption ? 'yes' : `no`;
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
existingOption = existingOption ? 'yes' : `no`;
existingOption = existingOption ? 'yes' : 'no';

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.

3 participants