@@ -85,7 +85,7 @@ def pretty_summary(summary):
85
85
)
86
86
87
87
88
- def get_token (url , username , password , show_token = False ):
88
+ def get_token (url , username , password , show_token = True ):
89
89
"""Get authorization token for given user and password."""
90
90
mc = MerginClient (url )
91
91
if not mc .is_server_compatible ():
@@ -97,24 +97,22 @@ def get_token(url, username, password, show_token=False):
97
97
click .secho ("Unable to log in: " + str (e ), fg = "red" )
98
98
return None
99
99
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:\n export MERGIN_AUTH="{ session ["token" ]} "' )
103
101
return session ["token" ]
104
102
105
103
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 ):
107
105
"""Return Mergin client."""
108
106
if auth_token is not None :
109
107
mc = MerginClient (url , auth_token = f"Bearer { auth_token } " )
110
108
# Check if the token has expired or is just about to expire
111
109
delta = mc ._auth_session ["expire" ] - datetime .now (timezone .utc )
112
110
if delta .total_seconds () > 5 :
113
- if show_token :
114
- click .secho (f'export MERGIN_AUTH="{ auth_token } "' )
115
111
return mc
116
112
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
118
116
mc = MerginClient (url , auth_token = f"Bearer { auth_token } " )
119
117
else :
120
118
click .secho (
@@ -139,40 +137,41 @@ def _print_unhandled_exception():
139
137
@click .option (
140
138
"--url" ,
141
139
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 () } " ,
144
142
)
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" )
146
144
@click .option ("--username" , envvar = "MERGIN_USERNAME" )
147
145
@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
- )
153
146
@click .pass_context
154
- def cli (ctx , url , auth_token , username , password , show_token ):
147
+ def cli (ctx , url , auth_token , username , password ):
155
148
"""
156
149
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.
160
155
"""
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 )
162
157
ctx .obj = {"client" : mc }
163
158
164
159
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
+
165
169
@cli .command ()
166
170
@click .argument ("project" )
167
171
@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." )
169
172
@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."""
176
175
mc = ctx .obj ["client" ]
177
176
if mc is None :
178
177
return
@@ -184,6 +183,9 @@ def create(ctx, project, public, namespace):
184
183
except (ValueError , AssertionError ) as e :
185
184
click .secho (f"Incorrect namespace/project format: { e } " , fg = "red" )
186
185
return
186
+ else :
187
+ # namespace not specified, use current user namespace
188
+ namespace = mc .username ()
187
189
try :
188
190
mc .create_project (project , is_public = public , namespace = namespace )
189
191
click .echo ("Remote project created" )
@@ -404,24 +406,6 @@ def show_file_changeset(ctx, path, version):
404
406
click .secho (json .dumps (info_dict , indent = 2 ))
405
407
406
408
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
-
425
409
@cli .command ()
426
410
@click .argument ("source_project_path" , required = True )
427
411
@click .argument ("cloned_project_name" , required = True )
@@ -447,8 +431,19 @@ def remove(ctx, project):
447
431
mc = ctx .obj ["client" ]
448
432
if mc is None :
449
433
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 ()
450
445
try :
451
- mc .delete_project (project )
446
+ mc .delete_project (f" { namespace } / { project } " )
452
447
click .echo ("Remote project removed" )
453
448
except Exception as e :
454
449
_print_unhandled_exception ()
0 commit comments