stellar / stellar-cli

CLI for Stellar developers
72 stars 70 forks source link

Simplify/improve UX of `contract init` #1586

Closed Ifropc closed 4 weeks ago

Ifropc commented 2 months ago

The contract init command is very useful to quickstart the project, but as it's been shown recently it's very fragile and prone to breaking. The main culprit behind breakage is --with-example flag. Currently, it feels like the command tries to do too much, and therefore very easy to break by upstream dependencies. It's proposed to simplify the command, removing some of current functionality, with the possibility of bringing it back later (as another subcommand). There's also a proposal to add some QOL improvements to the command:

  1. Introduce a new --name switch that generates a contract with that name, so users don’t have to manually rename things. This also allows for developers to easily generate new contracts in an existing project without too much friction.
  2. Rename HelloContract to just Contract, so it’s generic and doesn’t require manual renaming whenever a new contract is generated. Also, a crate can only have one contract, so having a unique name doesn’t bring much.
  3. Remove --with-example; this switch is not really useful when developing real world contracts. That doesn’t mean users won’t have access to fully functional example contracts that can be executed by cloning the examples repo. That flag is de-facto just a git clone with some extra functionality, but proven to be quite hard to maintain.
  4. Remove --frontend-template; we’re pushing down a tech stack that we don’t necessarily want to promote. We can add something better later on, like a specific command for dapps. We should encourage people to use github tags on their repos for easier discovery. In addition, we may want to introduce stellar dapp init in the future, that will use one of the current templates.
  5. Copy contract template to the stellar-cli repo, detaching stellar-cli from examples. Now that we are removing --with-example, we don't need to clone examples repo for hello-world contract, it can simply live as a starter template in the cli repo.
chadoh commented 1 month ago

Regarding --frontend-template, the suggestion we came up with in a meeting is to, after getting rid of it from this command, encourage people to directly git clone whatever frontend template they want. Great, love it, super simple.

It strikes me that, after that's done, all that's left of stellar contract init is basically to degit stellar/soroban-examples. See https://github.com/Rich-Harris/degit

Differences between degit approach and proposed stellar contract init:

  1. degit would include all soroban-examples, rather than an explicitly opted-into subset
  2. degit would not provide a way to rename a/the contract, like the proposed --name arg
  3. Right now, soroban-examples is not set up as a Cargo workspace
  4. stellar contract init would include it in our main CLI tool, for discoverability and ease

(1 and 3 above seem like issues we can deal with at the level of stellar/soroban-examples. We can make it a workspace. We can remove some noise; move some examples to different repositories; make it more focused. Would we still feel a need to specify the subset of contracts? Is renaming a contract difficult enough to merit --name?)

A separate concern I have always had about the command, stellar contract init, is that it sounds like it would initialize a specific contract, not a new project.

I don't know what we should call it, but if we call it the right thing, then we can (basically? actually?) make it a wrapper around degit-rs and move it to the top level. stellar degit or stellar new or stellar new-project or stellar project or stellar from or ... what?

And if we do that, then it works for soroban-examples and also any other git repo. So, for frontend templates too.

Ifropc commented 1 month ago
  1. I personally don't think we want to clone soroban-examples and we should just stick to the simple hello-world. Not sure if having (just) hello-world in a separate repo is a good idea or not 🤔
  2. Based on team feedback, I think we all agreeing that we like workspace approach, and I think it makes sense to make init to init a workspace. Moreover, when you run init with different names, I think it should add new contract to the existing worspace (as such, it does just that: inits contract)

So the way I see this new command, it will:

  1. If is not being run in a Cargo worspace -> will init a new worspace from a template
  2. If IS run in a Cargo worspace -> simply add a new member to the worspace with a hello world contract from a template

WDYT?

fnando commented 1 month ago

Is renaming a contract difficult enough to merit --name?

Personally, I feel it's not about being difficult to rename files but more about being a boring task that can be easily automated without added complexity.

A separate concern I have always had about the command, stellar contract init, is that it sounds like it would initialize a specific contract, not a new project.

I think we need to decide what we want to tackle and promote. stellar new (and other variations) suggests something more generic, but everything we're doing is based on smart contracts, so stellar contract init seems the best place for it.

make it a wrapper around degit-rs and move it to the top level

Maybe this should be a community plugin instead? Given our goal of removing complexity in favor of git cloning, this seems equally (more?) complex.

janewang commented 1 month ago

Should init-ing into a workspace be stellar init or stellar workspace init instead of stellar contract init for clarity?

elizabethengelman commented 1 month ago

From the original issue description:

2. Renaming HelloContract -> Contract makes sense to me. I wonder if we should leave the directory and the package name hello_world still to indicate to users that they may have more than one contract in their project, and make it clear that this is an example. 4. I may be biased, but I still like the idea of conditionally including a frontend template! I also totally understand that it adds a lot of complexity. Maybe for now we can direct users to clone a fe template, but then in the future, perhaps this could be a separate subcommand. Like stellar contract init add-frontend or something like that? But that can be future work if we find it useful. 5. If I'm understanding this point correctly, I believe we are already doing this. We have the hello_world contract in the cli repo at cmd/soroban-cli/src/utils/contract-init-template.

other comments

A separate concern I have always had about the command, stellar contract init, is that it sounds like it would initialize a specific contract, not a new project.

I agree with this - I like Jane's suggestion stellar workspace init or maybe stellar project init. Perhaps that could initialize a new cargo workspace project with the hello world contract. Then we could have a new subcommand stellar project add-contract that adds a new contract to an existing workspace project.

for a brand-new project, the workflow could be

stellar project init ./path-to-my-project
cd path-to-my-project
stellar project add-contract --name my-cool-contract

Or, maybe we could have some way to combine those two steps into one for convenience, but also allow for them to be two separate commands for simplicity.

elizabethengelman commented 1 month ago

Also, just to keep things straight in my brain, I think that these are the things we're in agreement on: