Depends on #989. For simplicity this proposal assumes it has been implemented.
To prevent ambiguity the term "project" in this proposal always refers to a Google Apps Script (GAS) project and "codebase" is used for a local project code folder/repository.
In most multi-developer workflows each developer has their own personal testing environment based on a shared codebase structure.
Unfortunately such a multi-developer workflow is currently not well-supported by clasp, as demonstrated by the discussion in #921.
Private remotes as proposed in #989 would solve a significant portion of the hassle, but the resulting workflow still has a couple of flaws and limitations:
create implicitly drags some default files into the codebase (#758).
create with git clone (#758) is unnatural when the codebase is already on your machine.
Some information for create such as --title and --type are not stored anywhere, so they can't be shared and tracked by version control to create consistent testing environments.
A combination of create, remote add, push and some juggling with files works, but is unnecessarily complicated and prone to mistakes.
The running theme here is that there's no easy way to reliably and consistently (re)create a GAS project based on the shared structure of a codebase, similar to something like Docker or "Infrastructure as Code".
You could turn to scripting, but that's a treacherous path of system differences and shoddy error handling.
This workflow is so common that I strongly believe it deserves first-party support. Scripting should only be necessary for truly custom scenarios.
To consistently (re)create GAS projects some extra information needs to be added to .clasp.json:
type: store after create/clone.
title:
Ask during create if not specified, suggest name of package.json or the name of the directory of .clasp.json.
Use title of cloned project during clone.
New subcommand: remote create
The existing create command is intended to create a new codebase with accompanying GAS project, like you would do on scripts.google.com.
We need a command that creates only a GAS project based on an existing codebase. I propose the following new subcommand:
clasp remote create <name>
This command should handle this workflow in three steps:
Add a new remote called <name> to the codebase (private by default).
Create a new (empty) GAS project based on .clasp.json.
Push the codebase to this new remote.
Options
All options for remote add should be propagated, except:
<scriptId> (newly created)
--pull (can't pull from a new project)
All options for create should be propagated, except:
--remote-name (covered by <name>)
--remote-default (covered by remote add's --default)
--type (read from .clasp.json)
--rootDir (using existing codebase)
--recycle or -r to reuse an existing GAS project with the same title
--title-suffix to add to the base title, e.g. "MyScript-dev". Defaults to the provided remote <name>, or an empty string if --title is explicitly specified.
Implementation notes
The title in .clasp.json can be overidden with --title(-suffix), this is not important for the consistency of the testing environment.
If --title is not explicitly specified the base title of the new GAS project should default to:
title in .clasp.json.
name in package.json.
The dirname of the folder that contains .clasp.json.
If --title-suffix is set to an empty string no dash should be added.
Error if a GAS project with the resolved full title already exists, unless --recycle is specified. This avoids accidental data loss.
--recycle should adjust the existing GAS project to the structure defined in .clasp.json, but preserve existing versions and deployments.
If --parentId is specified check if the inferred --type matches .clasp.json.
remote create felt more natural than create --empty as proposed in #758, since it explicitly signals creating only a new remote rather than a whole new codebase. Having create behave significantly differently in a folder with a .clasp.json seems undesirable and would probably be a breaking change.
Other considerations
Is sharing a codebase across projects with varying type-s a thing? If so, type could be moved/added to the remotes object with some form of shared default setting.
Depends on #989. For simplicity this proposal assumes it has been implemented.
In most multi-developer workflows each developer has their own personal testing environment based on a shared codebase structure. Unfortunately such a multi-developer workflow is currently not well-supported by clasp, as demonstrated by the discussion in #921.
Private remotes as proposed in #989 would solve a significant portion of the hassle, but the resulting workflow still has a couple of flaws and limitations:
create
implicitly drags some default files into the codebase (#758).create
withgit clone
(#758) is unnatural when the codebase is already on your machine.create
such as--title
and--type
are not stored anywhere, so they can't be shared and tracked by version control to create consistent testing environments.create
,remote add
,push
and some juggling with files works, but is unnecessarily complicated and prone to mistakes.The running theme here is that there's no easy way to reliably and consistently (re)create a GAS project based on the shared structure of a codebase, similar to something like Docker or "Infrastructure as Code".
You could turn to scripting, but that's a treacherous path of system differences and shoddy error handling. This workflow is so common that I strongly believe it deserves first-party support. Scripting should only be necessary for truly custom scenarios.
Usecases
Prior art
gcloud deployment-manager deployments create
.terraform apply
.docker compose up
.compose down
withremote remove --delete
.gh codespace create
.Configuration
To consistently (re)create GAS projects some extra information needs to be added to
.clasp.json
:type
: store aftercreate
/clone
.title
:create
if not specified, suggestname
ofpackage.json
or the name of the directory of.clasp.json
.clone
.New subcommand:
remote create
The existing
create
command is intended to create a new codebase with accompanying GAS project, like you would do on scripts.google.com. We need a command that creates only a GAS project based on an existing codebase. I propose the following new subcommand:This command should handle this workflow in three steps:
<name>
to the codebase (private by default)..clasp.json
.Options
remote add
should be propagated, except:<scriptId>
(newly created)--pull
(can't pull from a new project)create
should be propagated, except:--remote-name
(covered by<name>
)--remote-default
(covered byremote add
's--default
)--type
(read from.clasp.json
)--rootDir
(using existing codebase)--recycle
or-r
to reuse an existing GAS project with the same title--title-suffix
to add to the basetitle
, e.g. "MyScript-dev". Defaults to the provided remote<name>
, or an empty string if--title
is explicitly specified.Implementation notes
title
in.clasp.json
can be overidden with--title(-suffix)
, this is not important for the consistency of the testing environment.--title
is not explicitly specified the base title of the new GAS project should default to:title
in.clasp.json
.name
inpackage.json
.dirname
of the folder that contains.clasp.json
.--title-suffix
is set to an empty string no dash should be added.--recycle
is specified. This avoids accidental data loss.--recycle
should adjust the existing GAS project to the structure defined in.clasp.json
, but preserve existing versions and deployments.--parentId
is specified check if the inferred--type
matches.clasp.json
.remote create
felt more natural thancreate --empty
as proposed in #758, since it explicitly signals creating only a new remote rather than a whole new codebase. Havingcreate
behave significantly differently in a folder with a.clasp.json
seems undesirable and would probably be a breaking change.Other considerations
type
-s a thing? If so,type
could be moved/added to theremotes
object with some form of shared default setting.