Skip to content

Commit 79edc12

Browse files
erpaswonder-sk
authored andcommitted
Changes after review.
Added `login` command that shows how to set the token environment variable. Fixed #95.
1 parent 8d0cd2c commit 79edc12

File tree

1 file changed

+42
-47
lines changed

1 file changed

+42
-47
lines changed

mergin/cli.py

Lines changed: 42 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ def pretty_summary(summary):
8585
)
8686

8787

88-
def get_token(url, username, password, show_token=False):
88+
def get_token(url, username, password, show_token=True):
8989
"""Get authorization token for given user and password."""
9090
mc = MerginClient(url)
9191
if not mc.is_server_compatible():
@@ -97,24 +97,22 @@ def get_token(url, username, password, show_token=False):
9797
click.secho("Unable to log in: " + str(e), fg="red")
9898
return None
9999
if show_token:
100-
click.secho(f'export MERGIN_AUTH="{session["token"]}"')
101-
else:
102-
click.secho(f"auth_token created (use --show_token option to see the token).")
100+
click.secho(f'To set the MERGIN_AUTH variable run:\nexport MERGIN_AUTH="{session["token"]}"')
103101
return session["token"]
104102

105103

106-
def get_client(url=None, auth_token=None, username=None, password=None, show_token=False):
104+
def get_client(url=None, auth_token=None, username=None, password=None):
107105
"""Return Mergin client."""
108106
if auth_token is not None:
109107
mc = MerginClient(url, auth_token=f"Bearer {auth_token}")
110108
# Check if the token has expired or is just about to expire
111109
delta = mc._auth_session["expire"] - datetime.now(timezone.utc)
112110
if delta.total_seconds() > 5:
113-
if show_token:
114-
click.secho(f'export MERGIN_AUTH="{auth_token}"')
115111
return mc
116112
if username and password:
117-
auth_token = get_token(url, username, password, show_token=show_token)
113+
auth_token = get_token(url, username, password)
114+
if auth_token is None:
115+
return None
118116
mc = MerginClient(url, auth_token=f"Bearer {auth_token}")
119117
else:
120118
click.secho(
@@ -139,40 +137,41 @@ def _print_unhandled_exception():
139137
@click.option(
140138
"--url",
141139
envvar="MERGIN_URL",
142-
default="https://public.cloudmergin.com",
143-
help="Mergin server URL. Default is: https://public.cloudmergin.com",
140+
default=MerginClient.default_url(),
141+
help=f"Mergin server URL. Default is: {MerginClient.default_url()}",
144142
)
145-
@click.option("--auth_token", envvar="MERGIN_AUTH", help="Mergin authentication token string")
143+
@click.option("--auth-token", envvar="MERGIN_AUTH", help="Mergin authentication token string")
146144
@click.option("--username", envvar="MERGIN_USERNAME")
147145
@click.option("--password", cls=OptionPasswordIfUser, prompt=True, hide_input=True, envvar="MERGIN_PASSWORD")
148-
@click.option(
149-
"--show_token",
150-
is_flag=True,
151-
help="Flag for echoing the authentication token. Useful for setting the MERGIN_AUTH environment variable.",
152-
)
153146
@click.pass_context
154-
def cli(ctx, url, auth_token, username, password, show_token):
147+
def cli(ctx, url, auth_token, username, password):
155148
"""
156149
Command line interface for the Mergin client module.
157-
For user authentication on server, username and password need to be given either as environment variables
158-
(MERGIN_USERNAME, MERGIN_PASSWORD), or as options (--username, --password).
159-
To set MERGIN_AUTH variable, run the command with --show_token option to see the token and how to set it manually.
150+
For user authentication on server there are two options:
151+
1. authorization token environment variable (MERGIN_AUTH) is defined, or
152+
2. username and password need to be given either as environment variables (MERGIN_USERNAME, MERGIN_PASSWORD),
153+
or as command options (--username, --password).
154+
Run `mergin --username <your_user> login` to see how to set the token variable manually.
160155
"""
161-
mc = get_client(url=url, auth_token=auth_token, username=username, password=password, show_token=show_token)
156+
mc = get_client(url=url, auth_token=auth_token, username=username, password=password)
162157
ctx.obj = {"client": mc}
163158

164159

160+
@cli.command()
161+
@click.pass_context
162+
def login(ctx):
163+
"""Login to the service and see how to set the token environment variable."""
164+
mc = ctx.obj["client"]
165+
if mc is not None:
166+
click.secho("Login successful!", fg="green")
167+
168+
165169
@cli.command()
166170
@click.argument("project")
167171
@click.option("--public", is_flag=True, default=False, help="Public project, visible to everyone")
168-
@click.option("--namespace", help="Namespace for the new project. Default is current Mergin user namespace.")
169172
@click.pass_context
170-
def create(ctx, project, public, namespace):
171-
"""
172-
Create a new project on Mergin server.
173-
`project` can be a combination of namespace/project. Namespace can also be specified as an option, however if
174-
namespace is specified as a part of `project` argument, the option is ignored.
175-
"""
173+
def create(ctx, project, public):
174+
"""Create a new project on Mergin server. `project` needs to be a combination of namespace/project."""
176175
mc = ctx.obj["client"]
177176
if mc is None:
178177
return
@@ -184,6 +183,9 @@ def create(ctx, project, public, namespace):
184183
except (ValueError, AssertionError) as e:
185184
click.secho(f"Incorrect namespace/project format: {e}", fg="red")
186185
return
186+
else:
187+
# namespace not specified, use current user namespace
188+
namespace = mc.username()
187189
try:
188190
mc.create_project(project, is_public=public, namespace=namespace)
189191
click.echo("Remote project created")
@@ -404,24 +406,6 @@ def show_file_changeset(ctx, path, version):
404406
click.secho(json.dumps(info_dict, indent=2))
405407

406408

407-
@cli.command()
408-
@click.argument("directory", required=False)
409-
def modtime(directory):
410-
"""
411-
Show files modification time info. For debug purposes only.
412-
"""
413-
directory = os.path.abspath(directory or os.getcwd())
414-
strip_len = len(directory) + 1
415-
for root, dirs, files in os.walk(directory, topdown=True):
416-
for entry in dirs + files:
417-
abs_path = os.path.abspath(os.path.join(root, entry))
418-
click.echo(abs_path[strip_len:])
419-
# click.secho('atime %s' % datetime.fromtimestamp(os.path.getatime(abs_path)), fg="cyan")
420-
click.secho("mtime %s" % datetime.fromtimestamp(os.path.getmtime(abs_path)), fg="cyan")
421-
# click.secho('ctime %s' % datetime.fromtimestamp(os.path.getctime(abs_path)), fg="cyan")
422-
click.echo()
423-
424-
425409
@cli.command()
426410
@click.argument("source_project_path", required=True)
427411
@click.argument("cloned_project_name", required=True)
@@ -447,8 +431,19 @@ def remove(ctx, project):
447431
mc = ctx.obj["client"]
448432
if mc is None:
449433
return
434+
if "/" in project:
435+
try:
436+
namespace, project = project.split("/")
437+
assert namespace, "No namespace given"
438+
assert project, "No project name given"
439+
except (ValueError, AssertionError) as e:
440+
click.secho(f"Incorrect namespace/project format: {e}", fg="red")
441+
return
442+
else:
443+
# namespace not specified, use current user namespace
444+
namespace = mc.username()
450445
try:
451-
mc.delete_project(project)
446+
mc.delete_project(f"{namespace}/{project}")
452447
click.echo("Remote project removed")
453448
except Exception as e:
454449
_print_unhandled_exception()

0 commit comments

Comments
 (0)