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

review quarkus cli command / flag structure #16033

Closed
maxandersen opened this issue Mar 25, 2021 · 28 comments · Fixed by #16407
Closed

review quarkus cli command / flag structure #16033

maxandersen opened this issue Mar 25, 2021 · 28 comments · Fixed by #16407
Assignees
Labels
area/cli Related to quarkus cli (not maven/gradle/etc.)
Projects
Milestone

Comments

@maxandersen
Copy link
Contributor

maxandersen commented Mar 25, 2021

current cli outline looks like this:

Usage: quarkus [-ehV] [--verbose] [COMMAND]
  -e, --errors    Produce execution error messages.
  -h, --help      Show this help message and exit.
  -V, --version   Print version information and exit.
      --verbose   Verbose mode.
Commands:
  build             Build your quarkus project
  clean             Clean current project
  create            Create a new quarkus project.
  create-jbang      Create a new quarkus jbang project.
  list              List installed (default) or installable extensions.
  platforms         List imported (default) or all available Quarkus platforms.
  add               Add extension(s) to current project.
  remove, rm        Remove an extension from this project.
  dev               Execute project in live coding dev mode
  create-extension  Creates the base of a Quarkus extension in different layout depending of the options and environment.

they currently can be grouped in following categories:

project creation

create, create-jbang, create-extension

imo. create-jbang should be a --jbang flag instead of its own command.

platform/extension query/manipulation

list,add,remove/rm
platforms

kinda core to what we would like the cli to do but feels a bit weird we have list/add/remove/rm for extensions but then a separate platform command.

dev time commands

build, clean, dev

force: they abstract away wether you are doing maven or gradle (in future jbang could be included here)

weakness: you cant express clean build - they always end up as two commands ..
missing remote dev

missing commands/ideas:

update - would check if quarkus has a newer release and update the corresponding build artifact.

validate/lint - be able to see if using out-of-platform-bounds artifacts.

@maxandersen maxandersen created this issue from a note in quarkus cli (To do) Mar 25, 2021
@maxandersen maxandersen added area/cli Related to quarkus cli (not maven/gradle/etc.) and removed triage/needs-triage labels Mar 25, 2021
@ebullient
Copy link
Contributor

create-jbang should be a --jbang flag instead of its own command.

By this light, we should also simplify create-extension to use an --extension flag

Usage: quarkus [-ehV] [--verbose] [COMMAND]
  -e, --errors    Produce execution error messages.
  -h, --help      Show this help message and exit.
  -V, --version   Print version information and exit.
      --verbose   Verbose mode.
Commands:
  build             Build your quarkus project
  clean             Clean current project
  create            Create a new quarkus project.
  list              List installed (default) or installable extensions.
  platforms         List imported (default) or all available Quarkus platforms.
  add               Add extension(s) to current project.
  remove, rm        Remove an extension from this project.
  dev               Execute project in live coding dev mode

Create options:

Usage: quarkus create [-ehV] [--verbose] [COMMAND]
  -e, --errors    Produce execution error messages.
  -h, --help      Show this help message and exit.
  -V, --version   Print version information and exit.
      --verbose   Verbose mode.
Create options:
     --jbang          Create a new quarkus jbang project. 
     --extension   Creates a Quarkus extension project.

.. more tomorrow (Will edit) ...

@maxandersen
Copy link
Contributor Author

Note, --jbang is an alternate build/layout like --gradle and --maven.

But extension is arguably different "thing".

@maxandersen maxandersen moved this from To do to In progress in quarkus cli Mar 26, 2021
@ebullient
Copy link
Contributor

ebullient commented Mar 26, 2021

It is.. but you could also think of it as a variant of what is being created.. you still end up with a project in the end.
(it's just a project that creates an extension, instead of a project that creates a CLI something or a project that does the usual rest things, or.. )

@maxandersen
Copy link
Contributor Author

lets say we unified on create, how would you indicate wether you want a quarkus project created or quarkus extension created ?

@aloubyansky
Copy link
Member

What we should think of is a set options that create-extension (and another create flavors) need. If they have different options, I think they are good candidates to become subcommands instead of options of create.

@ebullient
Copy link
Contributor

Coming back to this after letting it percolate for a bit.... (also some simplifications after talking w/ Max)

Usage: qs [-hV] [--verbose] [COMMAND]
  -h, --help      Show this help message and exit.
  -V, --version   Print version information and exit.
      --verbose   Verbose mode.
Commands:
  create            Create a new quarkus project
  create-cli        Create a new quarkus command line project
  create-extension  Create a new quarkus extension project

  build             Build the current project
  clean             Clean the current  project
  dev               Run the current project dev mode (live coding)

  list              List extensions and platforms
  add               Add extension(s) to current project
  remove, rm        Remove extension(s) from this project

Lots of room for improvement w/ list. Wondering about pinning/filtering based on platform version (even if platform version then still appears in the resulting list.. ). Starts to make the existence/selection of a platform meaningful w.r.t. where extensions come from...

Usage: qs list [-Bhi] [-s=PATTERN] [--include=all] [--name | --concise | --full | --origins]
List platforms and/or extensions.

Options
  -B, --batch-mode       run command in non-interactive batch mode
  -h, --help             display this help message

Filters
      --include=[all | extensions | platforms]
                         List platforms and extensions (default), only extensions, or only platforms
  -i, --installable      Display installable platforms and/or extensions
  -s, --search=PATTERN   Search for platforms or extensions that match the specified Java Pattern.

Output
      --name             Display name only. (default)
      --concise          Display name and description.
      --full             Display concise format and version related columns.
      --origins          Display extensions including their platform origins.

I don't have an impulse to change add/remove, though part of me is thinking about tucking under a dependency command (dep add, dep remove, dep tree, .. ?!)

Usage: qs add [-Bh] EXTENSION...
Add extension(s) to current project.

      EXTENSION...   extensions to add to project
  -B, --batch-mode   run command in batch mode
  -h, --help         display this help message
Usage: qs remove [-Bh] EXTENSION...
Remove an extension from this project.
      EXTENSION...   extensions to remove
  -B, --batch-mode   run command in batch mode
  -h, --help         display this help message

@aloubyansky
Copy link
Member

Nice. A thing to keep in mind is commands like add and list depend on the context. E.g. if it's an application, it's what's described. What if I create-extension and do add? It could certainly still add a dependency on an extension, it's not unreasonable. But in that case it would have to update the deployment module as well.

@ebullient
Copy link
Contributor

it could certainly help make sure you add the right dependency in the right place (as you don't always need them in both places, ... ). But there are a few cases where I need the extension dependency in one or the other (but not both), so yes, extensions are trickier.

We could either say add/remove isn't supported for extension projects, or figure out a middle ground (e.g. advice on what needs to be added where to add the dependency on the other extension)

@aloubyansky
Copy link
Member

Just in case, if a runtime extension artifact depends on a runtime artifact of another extension, it should be mirrored in the deployment deps. And the other way around.

@ebullient
Copy link
Contributor

Micrometer uses some extensions in the test scope (so only in deployment, not at runtime at all).

Micrometer also uses other extensions optionally: so the optional dependency is in the runtime module, and maybe only the spi is in deployment (there are other checks in place to ensure paths aren't exercised if the other extension isn't there).

@maxandersen
Copy link
Contributor Author

What does create-cli actually do ? Just create quarkus project without default resteasy ?

@maxandersen
Copy link
Contributor Author

I kinda have mixed feelings that list works for both platform and extensions.

not sure what implications are of the multiple platform notion.

Wondering if list should be for extensions and a more generic query command to get info from the registry data ?

@ebullient
Copy link
Contributor

ebullient commented Apr 8, 2021

create-cli creates a client project.. --without-jbang would be the option to remove the jbang wrapper.

elevates the nature of using quarkus to create cli projects (where jbang wrapper would be included by default)

@ebullient
Copy link
Contributor

I can see the mixed feelings re: platforms and extensions.

In my head: platforms are a limiter on the extensions that are available (they are essentially an extension constraint).

I see the following output for list (MAKING THIS UP):

> qs list
Active/Enabled/Installed/? Platforms
 io.quarkus:quarkus-bom::pom:999-SNAPSHOT

Extensions
 quarkus-tika                                       
 quarkus-neo4j                                     
 quarkus-scala                                     
 quarkus-jgit 

Or:

> qss list -i --origins
Active/Enabled/Installed/? Platforms
 io.quarkus:quarkus-bom::pom:999-SNAPSHOT

Available Extensions
 Logging JSON                                       999-SNAPSHOT                      io.quarkus:quarkus-bom::pom:999-SNAPSHOT
 Logging Sentry                                     999-SNAPSHOT                      io.quarkus:quarkus-bom::pom:999-SNAPSHOT
 Logging GELF                                       999-SNAPSHOT                      io.quarkus:quarkus-bom::pom:999-SNAPSHOT

There is a linkage between platform(s) and extensions. Reminding people which platform their project is using isn't a bad thing.

@maxandersen
Copy link
Contributor Author

create-cli creates a client project.. --without-jbang would be the option to remove the jbang wrapper.

so create-cli replaces create-jbang ?

Not a big fan as jbang projects using quarkus is just as able to be non-cli as a standard quarkus app.

like qs create --jbang resteasy,openshift should be as doable as qs create resteasy,openshift just like qs create-cli --jbang picocli,jackson and qs create-cli --gradle picocli,jackson would both create a cli - just that with jbang lots of the ceromony is removed and deps are in the source files.

@ebullient
Copy link
Contributor

ebullient commented Apr 8, 2021

ok. If --jbang is shorthand for "create a jbang wrapper" .. then that should be the option (applicable wherever).

I guess up for debate if create-cli constructs a project that is unique/different (which create-extension undeniably does)

@ebullient
Copy link
Contributor

ebullient commented Apr 9, 2021

Above draft PR will let you play with options as I've messed with them so far.. and we can keep going more interactively.
(proper capitalization of nouns could use some work.. those are nits for later.. lets see how it flows.. )

Usage: q [-ehV] [--verbose] [COMMAND]
  -e, --errors    Produce execution error messages.
  -h, --help      Show this help message and exit.
  -V, --version   Print version information and exit.
      --verbose   Verbose mode.
Commands:
  create            Create a Quarkus project
  create-cli        Create a Quarkus command-line project
  create-extension  Create a Quarkus extension project
  build             Build the current project
  clean             Clean the current project
  dev               Run the current project in dev mode (live coding)
  list              List platform(s) and extensions
  add               Add extension(s) to current project.
  remove, rm        Remove an extension from this project.

create:

Create a Quarkus project
Usage: quarkus create [-B | -h] [[-g=GROUP-ID] [-a=ARTIFACT-ID] [-v=VERSION]]
                      [--jbang | --maven | --gradle | --grade-kotlin-dsl]
                      [--java | --kotlin | --scala] [-0 | -x=<example>
                      [-x=<example>]...] [EXTENSION...]
By default, this command will create a new 'code-with-quarkus' directory
containing a Java project that will use maven to build a quarkus application
with groupId='org.acme', artifactId='code-with-quarkus', and version='1.0.0
-SNAPSHOT'.

      [EXTENSION...]        Extension(s) to add to the project

Common options
  -B, --batch-mode          run command in batch mode
  -h, --help                display this help message

Project identifiers (Default artifactId: code-with-quarkus)
  -g, --group-id=GROUP-ID   The groupId for maven and gradle artifacts
                              Default: org.acme
  -a, --artifact-id=ARTIFACT-ID
                            The artifactId for maven and gradle artifacts
  -v, --version=VERSION     The initial project version
                              Default: 1.0.0-SNAPSHOT

Build tool (Default: Maven)
      --jbang               Use jbang
      --maven               Use Maven
      --gradle              Use Gradle
      --grade-kotlin-dsl    Use Gradle with Kotlin DSL

Target language (Default: Java)
      --java                Use Java
      --kotlin              Use Kotlin
      --scala               Use Scala

Example code
  -0, --no-examples         Do not include examples
  -x, --example=<example>   Example to include in the project

create-cli:

Create a Quarkus command-line project
Usage: quarkus create-cli [-a=ARTIFACT-ID] [-g=GROUP-ID] [-v=VERSION] [-B | -h]
                          [--jbang | --maven | --gradle | --grade-kotlin-dsl]
                          [--java | --kotlin | --scala] [EXTENSION...]
By default, this command will create a new 'cli-with-quarkus' directory
containing Java project that will use jbang to build a quarkus application.

      [EXTENSION...]        Extensions to add to project

Common options
  -B, --batch-mode          run command in batch mode
  -h, --help                display this help message

Project identifiers (Default artifactId: cli-with-quarkus)
  -g, --group-id=GROUP-ID   The groupId for maven and gradle artifacts
                              Default: org.acme
  -a, --artifact-id=ARTIFACT-ID
                            The artifactId for maven and gradle artifacts
  -v, --version=VERSION     The initial project version
                              Default: 1.0.0-SNAPSHOT

Build tool (Default: jbang)
      --jbang               Use jbang
      --maven               Use Maven
      --gradle              Use Gradle
      --grade-kotlin-dsl    Use Gradle with Kotlin DSL

Target language (Default: Java)
      --java                Use Java
      --kotlin              Use Kotlin
      --scala               Use Scala

@ebullient
Copy link
Contributor

ebullient commented Apr 14, 2021

I personally find create extension challenging because it presents a lot of options for naming things without enough context about what the values are used for. If you use maven archetypes a lot, some of the things may feel more obvious, but for people that loathe them (like me), it's a bit mysterious.

Here is an attempt with a LOT of help / context:

create-extension --help
Create a Quarkus extension project
Usage: quarkus create-extension [--without-devmode-test] [--without-it-tests]
                                [--without-tests] [--without-unit-test]
                                [--bom-artifact-id=BOM-ARTIFACT-ID]
                                [--bom-group-id=BOM-GROUP-ID]
                                [--bom-version=BOM-VERSION]
                                [--extension-name=EXTENSION-NAME] [-g=GROUP-ID]
                                [-N=NAMESPACE-ID]
                                [--namespace-name=NAMESPACE-NAME]
                                [-p=PACKAGE-NAME] [-q=QUARKUS-VERSION]
                                [-v=VERSION] [-B | -h] EXTENSION-ID

Quarkus extensions are built from multiple modules: runtime, deployment, and
integration-test. This command will generate a multi-module project by applying
naming conventions to the specified EXTENSION-ID.

      EXTENSION-ID          Identifier used to generate module artifactIds

Common options
  -B, --batch-mode          run command in batch mode
  -h, --help                display this help message

Extension group and version
  -g, --group-id=GROUP-ID   The groupId for extension artifacts
                              Default: org.acme
  -v, --version=VERSION     The initial project version
                              Default: 1.0.0-SNAPSHOT

Quarkus version
  -q, --quarkus-version=QUARKUS-VERSION
                            The target Quarkus version
      --bom-group-id=BOM-GROUP-ID
                            The groupId of the Quarkus platform BOM
      --bom-artifact-id=BOM-ARTIFACT-ID
                            The artifactId of the Quarkus platform BOM
      --bom-version=BOM-VERSION
                            The version of the Quarkus platform BOM

Generated artifacts
      --extension-name=EXTENSION-NAME
                            Extension name
  -N, --namespace-id=NAMESPACE-ID
                            A common prefix for all module artifactIds
      --namespace-name=NAMESPACE-NAME
                            A common prefix for all module names
  -p, --package-name=PACKAGE-NAME
                            Base package for generated classes

Generated code (Optional)
      --without-unit-test   Do not generate unit tests
      --without-it-tests    Do not generate integration tests
      --without-devmode-test
                            Do not generate dev mode tests
      --without-tests       Do not generate any tests

Default Naming conventions

 EXTENSION-NAME: EXTENSION-ID converted to Capitalized Words
 NAMESPACE-NAME: NAMESPACE-ID converted to Capitalized Words

Module Naming Conventions

 parent:
    artifactId: [NAMESPACE-ID][EXTENSION-ID]-parent
    name:       [NAMESPACE-NAME][EXTENSION-NAME] - Parent
 runtime:
    artifactId: [NAMESPACE-ID][EXTENSION-ID]
    name:       [NAMESPACE-NAME][EXTENSION-NAME] - Runtime
 deployment:
    artifactId: [NAMESPACE-ID][EXTENSION-ID]-deployment
    name:       [NAMESPACE-NAME][EXTENSION-NAME] - Deployment
 integration-tests:
    artifactId: [NAMESPACE-ID][EXTENSION-ID]-integration-tests
    name:       [NAMESPACE-NAME][EXTENSION-NAME] - Integration Tests

Package and Class Naming Conventions

 Package name: [GROUP-ID][EXTENSION-ID] with any dashes replaced by dots
 Class name prefix: EXTENSION-ID converted to CamelCase

As an example, specifying 'hello-world' as the EXTENSION-ID and 'org.acme' as
the GROUP-ID will generate a project containing the following modules:

  hello-world:
    groupId:    org.acme
    artifactId: hello-world-parent
    version:    1.0.0-SNAPSHOT
    name:       Hello World - Parent
  hello-world/runtime:
    groupId:    org.acme
    artifactId: hello-world
    version:    1.0.0-SNAPSHOT
    name:       Hello World - Runtime
    package name: org.acme.hello.world.runtime
  hello-world/deployment:
    groupId:    org.acme
    artifactId: hello-world-deployment
    version:    1.0.0-SNAPSHOT
    name:       Hello World - Deployment
    package names: org.acme.hello.world.deployment, org.acme.hello.world.test
  hello-world/integration-test:
    groupId:    org.acme
    artifactId: hello-world-integration-tests
    version:    1.0.0-SNAPSHOT
    name:       Hello World - Integration Tests
    package name: org.acme.hello.world.it

Generated classes will use 'HelloWorld' as a class name prefix.

@ebullient
Copy link
Contributor

Trying to use shared option groups (e.g. the GAV groups for create and create-cli) is a little awkward when it comes to specify defaults because we use a different default "code-with-quarkus" vs. "cli-with-quarkus" .. I'm tempted to simplify and either use "code-with-quarkus" always.

@ebullient
Copy link
Contributor

@ia3andy @mkouba .. see above

@aloubyansky
Copy link
Member

Trying to use shared option groups (e.g. the GAV groups for create and create-cli) is a little awkward when it comes to specify defaults because we use a different default "code-with-quarkus" vs. "cli-with-quarkus" .. I'm tempted to simplify and either use "code-with-quarkus" always.

That makes sense, IMO, especially if it allows reusing some options and code.

@mkouba
Copy link
Contributor

mkouba commented Apr 15, 2021

So I wonder whether it would make sense to turn such complicated commands (create-extension...) into a wizard-like multi-step process? IIRC jboss forge supported something similar, or? @gastaldi

@mkouba
Copy link
Contributor

mkouba commented Apr 15, 2021

picocli interactive options might also help...

@ebullient
Copy link
Contributor

create-extension does have interactive prompting for options you don't specify..
Also, just by the bye -- I was messing with the existing create extension behavior, and the way it determines the layout and makes assumptions as a result is.. REALLY confusing. So that's something I also want to sort out.

See more conversation in the PR? @gsmet made some comments..

@mkouba
Copy link
Contributor

mkouba commented Apr 15, 2021

create-extension does have interactive prompting for options you don't specify..

Does it? I can't see it anywhere but it could be that I just need more caffeine ;-)

@ia3andy
Copy link
Contributor

ia3andy commented Apr 15, 2021

@ebullient there are 3 differents cases handled:

  • in quarkus or quarkus/extensions: quarkus layout
  • in an empty dir: standalone layout
  • in an empty dir with io.quarkiverse.xxx as groupId: quarkiverse layout

Is it that confusing?

@ebullient
Copy link
Contributor

It is how it is determined and what attributes are (or are not) required that is magical/confusing.

@ia3andy
Copy link
Contributor

ia3andy commented Apr 15, 2021

If too confusing, we could make the layout part of the options or different subcommands create-extension quarkus-core/standalone/quarkiverse or something, I am not against it.

quarkus cli automation moved this from In progress to Done May 27, 2021
@quarkus-bot quarkus-bot bot modified the milestone: 2.0 - main May 27, 2021
@gsmet gsmet modified the milestones: 2.1 - main, 2.0.0.CR2 May 27, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/cli Related to quarkus cli (not maven/gradle/etc.)
Projects
No open projects
Development

Successfully merging a pull request may close this issue.

6 participants