Skip to content

Commit 490ac4c

Browse files
committed
Proposal for new commands groups
1 parent 76471b3 commit 490ac4c

File tree

2 files changed

+126
-27
lines changed

2 files changed

+126
-27
lines changed

README.md

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ working directory:
124124

125125
1. get status of the project (check if there are any local/remote changes)
126126
```
127-
$ mergin status
127+
$ mergin project status
128128
```
129129
2. pull changes from Mergin Maps service
130130
```
@@ -141,6 +141,7 @@ If you plan to run `mergin` command multiple times and you wish to avoid logging
141141
you can use "login" command to get authorization token.
142142
It will ask for password and then output environment variable with auth token. The returned token
143143
is not permanent - it will expire after several hours.
144+
144145
```bash
145146
$ mergin --username john login
146147
Password: topsecret
@@ -150,25 +151,34 @@ export MERGIN_AUTH="Bearer ......."
150151
In Windows:
151152
SET MERGIN_AUTH=Bearer .......
152153
```
154+
153155
When setting the variable in Windows you do not quote the value.
154156

155157
When the MERGIN_AUTH env variable is set (or passed with `--auth-token` command line argument),
156158
it is possible to run other commands without specifying username/password.
157159

158-
159160
## Development
160161

161162
### Installing deps
162163

163164
Python 3.7+ required. Create `mergin/deps` folder where [geodiff](https://github.com/MerginMaps/geodiff) lib is supposed to be and install dependencies:
165+
164166
```bash
165167
rm -r mergin/deps
166168
mkdir mergin/deps
167169
pip install python-dateutil pytz
168170
pip install pygeodiff --target=mergin/deps
169171
```
170172

173+
To run `cli` from source code, install the package in editable mode:
174+
175+
```bash
176+
python setup.py dist
177+
cd dist && pip install {PACKAGE}.gz
178+
```
179+
171180
For using mergin client with its dependencies packaged locally run:
181+
172182
```bash
173183
pip install wheel
174184
python3 setup.py sdist bdist_wheel
@@ -179,6 +189,7 @@ For using mergin client with its dependencies packaged locally run:
179189
```
180190

181191
### Tests
192+
182193
For running test do:
183194

184195
```bash

mergin/cli.py

Lines changed: 113 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ def _print_unhandled_exception():
153153
@click.option("--username", envvar="MERGIN_USERNAME")
154154
@click.option("--password", cls=OptionPasswordIfUser, prompt=True, hide_input=True, envvar="MERGIN_PASSWORD")
155155
@click.pass_context
156-
def cli(ctx, url, auth_token, username, password):
156+
def cli(ctx, version, url, auth_token, username, password):
157157
"""
158158
Command line interface for the Mergin Maps client module.
159159
For user authentication on server there are two options:
@@ -164,10 +164,12 @@ def cli(ctx, url, auth_token, username, password):
164164
165165
Run `mergin --username <your_user> login` to see how to set the token variable manually.
166166
"""
167+
if (version):
168+
click.secho(f"v{__version__} / pygeodiff v{GeoDiff().version()}")
169+
return
167170
mc = get_client(url=url, auth_token=auth_token, username=username, password=password)
168171
ctx.obj = {"client": mc}
169172

170-
171173
@cli.command()
172174
@click.pass_context
173175
def login(ctx):
@@ -182,8 +184,17 @@ def login(ctx):
182184
hint = f'To set the MERGIN_AUTH variable run:\nexport MERGIN_AUTH="{token}"'
183185
click.secho(hint)
184186

187+
@cli.group()
188+
def project():
189+
"Commands related to projects"
190+
pass
185191

186-
@cli.command()
192+
@cli.group()
193+
def file():
194+
"Commands related to files stored in project"
195+
pass
196+
197+
@project.command()
187198
@click.argument("project")
188199
@click.option("--public", is_flag=True, default=False, help="Public project, visible to everyone")
189200
@click.option(
@@ -212,7 +223,7 @@ def create(ctx, project, public, from_dir):
212223
_print_unhandled_exception()
213224

214225

215-
@cli.command()
226+
@project.command(name="list")
216227
@click.argument("namespace")
217228
@click.option(
218229
"--name",
@@ -227,7 +238,7 @@ def create(ctx, project, public, from_dir):
227238
"Available attrs: namespace, name, created, updated, disk_usage, creator",
228239
)
229240
@click.pass_context
230-
def list_projects(ctx, name, namespace, order_params):
241+
def project_list(ctx, name, namespace, order_params):
231242
"""List projects on the server."""
232243

233244
mc = ctx.obj["client"]
@@ -244,7 +255,7 @@ def list_projects(ctx, name, namespace, order_params):
244255
)
245256

246257

247-
@cli.command()
258+
@project.command()
248259
@click.argument("project")
249260
@click.argument("directory", type=click.Path(), required=False)
250261
@click.option("--version", default=None, help="Version of project to download")
@@ -276,7 +287,7 @@ def download(ctx, project, directory, version):
276287
_print_unhandled_exception()
277288

278289

279-
@cli.command()
290+
@project.command()
280291
@click.argument("project")
281292
@click.argument("usernames", nargs=-1)
282293
@click.option("--permissions", help="permissions to be granted to project (reader, writer, owner)")
@@ -290,7 +301,7 @@ def share_add(ctx, project, usernames, permissions):
290301
mc.add_user_permissions_to_project(project, usernames, permissions)
291302

292303

293-
@cli.command()
304+
@project.command()
294305
@click.argument("project")
295306
@click.argument("usernames", nargs=-1)
296307
@click.pass_context
@@ -303,7 +314,7 @@ def share_remove(ctx, project, usernames):
303314
mc.remove_user_permissions_from_project(project, usernames)
304315

305316

306-
@cli.command()
317+
@project.command()
307318
@click.argument("project")
308319
@click.pass_context
309320
def share(ctx, project):
@@ -331,12 +342,12 @@ def share(ctx, project):
331342
click.echo("{:20}\t{:20}".format(username, "reader"))
332343

333344

334-
@cli.command()
345+
@file.command("download")
335346
@click.argument("filepath")
336347
@click.argument("output")
337348
@click.option("--version", help="Project version tag, for example 'v3'")
338349
@click.pass_context
339-
def download_file(ctx, filepath, output, version):
350+
def file_download(ctx, filepath, output, version):
340351
"""
341352
Download project file at specified version. `project` needs to be a combination of namespace/project.
342353
If no version is given, the latest will be fetched.
@@ -368,7 +379,7 @@ def num_version(name):
368379
return int(name.lstrip("v"))
369380

370381

371-
@cli.command()
382+
@project.command()
372383
@click.pass_context
373384
def status(ctx):
374385
"""Show all changes in project files - upstream and local."""
@@ -469,10 +480,10 @@ def pull(ctx):
469480
_print_unhandled_exception()
470481

471482

472-
@cli.command()
483+
@project.command()
473484
@click.argument("version")
474485
@click.pass_context
475-
def show_version(ctx, version):
486+
def version(ctx, version):
476487
"""Displays information about a single version of a project. `version` is 'v1', 'v2', etc."""
477488
mc = ctx.obj["client"]
478489
if mc is None:
@@ -488,11 +499,11 @@ def show_version(ctx, version):
488499
pretty_diff(version_info_dict["changes"])
489500

490501

491-
@cli.command()
502+
@file.command()
492503
@click.argument("path")
493504
@click.pass_context
494-
def show_file_history(ctx, path):
495-
"""Displays information about a single version of a project."""
505+
def history(ctx, path):
506+
"""Displays history for file in specified path"""
496507
mc = ctx.obj["client"]
497508
if mc is None:
498509
return
@@ -511,12 +522,12 @@ def show_file_history(ctx, path):
511522
click.secho(" {:5} {:10} {}".format(version, version_data["change"], diff_info))
512523

513524

514-
@cli.command()
525+
@file.command()
515526
@click.argument("path")
516527
@click.argument("version")
517528
@click.pass_context
518529
def show_file_changeset(ctx, path, version):
519-
"""Displays information about project changes."""
530+
"""Displays file changes."""
520531
mc = ctx.obj["client"]
521532
if mc is None:
522533
return
@@ -528,7 +539,7 @@ def show_file_changeset(ctx, path, version):
528539
click.secho(json.dumps(info_dict, indent=2))
529540

530541

531-
@cli.command()
542+
@project.command()
532543
@click.argument("source_project_path", required=True)
533544
@click.argument("cloned_project_name", required=True)
534545
@click.argument("cloned_project_namespace", required=False)
@@ -561,7 +572,7 @@ def clone(ctx, source_project_path, cloned_project_name, cloned_project_namespac
561572
_print_unhandled_exception()
562573

563574

564-
@cli.command()
575+
@project.command()
565576
@click.argument("project", required=True)
566577
@click.pass_context
567578
def remove(ctx, project):
@@ -608,7 +619,7 @@ def resolve_unfinished_pull(ctx):
608619
_print_unhandled_exception()
609620

610621

611-
@cli.command()
622+
@project.command()
612623
@click.argument("project_path")
613624
@click.argument("new_project_name")
614625
@click.pass_context
@@ -642,7 +653,7 @@ def rename(ctx, project_path: str, new_project_name: str):
642653
_print_unhandled_exception()
643654

644655

645-
@cli.command()
656+
@project.command()
646657
@click.pass_context
647658
def reset(ctx):
648659
"""Reset local changes in project."""
@@ -660,11 +671,11 @@ def reset(ctx):
660671
_print_unhandled_exception()
661672

662673

663-
@cli.command()
674+
@file.command("list")
664675
@click.argument("project")
665676
@click.option("--json", is_flag=True, default=False, help="Output in JSON format")
666677
@click.pass_context
667-
def list_files(ctx, project, json):
678+
def file_list(ctx, project, json):
668679
"""List files in a project."""
669680

670681
mc = ctx.obj["client"]
@@ -681,6 +692,83 @@ def list_files(ctx, project, json):
681692
for file in project_files:
682693
click.echo(" {:40}\t{:6.1f} MB".format(file["path"], file["size"] / (1024 * 1024)))
683694

695+
@cli.group()
696+
@click.pass_context
697+
def user():
698+
"""User management"""
699+
pass
700+
701+
@user.command()
702+
@click.pass_context
703+
def register():
704+
"Register user"
705+
pass
706+
707+
@project.group()
708+
@click.pass_context
709+
def collaborators():
710+
pass
711+
712+
@collaborators.command(name="list")
713+
@click.pass_context
714+
def collaborators_list(ctx):
715+
"List project collaborators"
716+
pass
717+
718+
@collaborators.command()
719+
@click.pass_context
720+
def add():
721+
"Add project collaborator"
722+
pass
723+
724+
@collaborators.command()
725+
@click.pass_context
726+
def update():
727+
"Update project collaborator"
728+
pass
729+
730+
@collaborators.command()
731+
@click.pass_context
732+
def remove():
733+
"Update project collaborator"
734+
pass
735+
736+
@cli.group()
737+
def workspace():
738+
"Workspace management"
739+
pass
740+
741+
@workspace.group()
742+
@click.pass_context
743+
def members():
744+
"Workspace members management"
745+
pass
746+
747+
@members.command()
748+
@click.pass_context
749+
def get():
750+
"Get workspace member"
751+
pass
752+
753+
@members.command()
754+
@click.pass_context
755+
def add():
756+
"Add workspace member"
757+
pass
758+
759+
@workspace.command()
760+
@click.pass_context
761+
def update():
762+
"Create workspace"
763+
pass
764+
765+
@members.command()
766+
@click.pass_context
767+
def remove():
768+
"Remove workspace member"
769+
pass
770+
771+
684772

685773
if __name__ == "__main__":
686774
cli()

0 commit comments

Comments
 (0)