git-glimpse-cli 0.1.0__tar.gz → 0.1.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: git-glimpse-cli
3
- Version: 0.1.0
3
+ Version: 0.1.2
4
4
  Summary: CLI tool to manage and update shared GitHub repos with GitGlimpse.
5
+ Author-email: sutaC <contact@sutac.pl>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/sutaC/git-glimpse-cli
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Operating System :: OS Independent
5
10
  Requires-Python: >=3.10
6
11
  Description-Content-Type: text/markdown
7
12
  License-File: LICENSE
@@ -60,12 +65,18 @@ pip install git-glimpse-cli
60
65
 
61
66
  GitGlimpse CLI uses holds your configuration at `~/.config/glimpsecli/config.json`, and local repository settings are stored at `./.shared-repo.json`.
62
67
 
68
+ Configuration hierarchy:
69
+
70
+ ```
71
+ Most important -> Local repo config -> Global cli config
72
+ ```
73
+
63
74
  ### Advanced Settings
64
75
 
65
- | Command | Description |
66
- | ------------------------ | --------------------------------------------------------------------------- |
67
- | `glimpse config debug` | Enables verbose debug mode, printing stack traces. |
68
- | `glimpse config set-url` | Overrides the default production server with a custom backend or localhost. |
76
+ | Command | Description |
77
+ | ---------------------- | --------------------------------------------------------------------------- |
78
+ | `glimpse config debug` | Enables verbose debug mode, printing stack traces. |
79
+ | `glimpse config url` | Overrides the default production server with a custom backend or localhost. |
69
80
 
70
81
  ## Development
71
82
 
@@ -77,7 +88,7 @@ GitGlimpse CLI uses holds your configuration at `~/.config/glimpsecli/config.jso
77
88
  source .venv/bin/activate
78
89
  pip install -e .
79
90
  ```
80
- 2. Point the CLI to your local development server:
91
+ 2. Point the CLI to your local development server (use `--local` to not propagate over your real global config):
81
92
  ```bash
82
- glimpse config set-url http://localhost:5000
93
+ glimpse config url http://localhost:5000 --local
83
94
  ```
@@ -48,12 +48,18 @@ pip install git-glimpse-cli
48
48
 
49
49
  GitGlimpse CLI uses holds your configuration at `~/.config/glimpsecli/config.json`, and local repository settings are stored at `./.shared-repo.json`.
50
50
 
51
+ Configuration hierarchy:
52
+
53
+ ```
54
+ Most important -> Local repo config -> Global cli config
55
+ ```
56
+
51
57
  ### Advanced Settings
52
58
 
53
- | Command | Description |
54
- | ------------------------ | --------------------------------------------------------------------------- |
55
- | `glimpse config debug` | Enables verbose debug mode, printing stack traces. |
56
- | `glimpse config set-url` | Overrides the default production server with a custom backend or localhost. |
59
+ | Command | Description |
60
+ | ---------------------- | --------------------------------------------------------------------------- |
61
+ | `glimpse config debug` | Enables verbose debug mode, printing stack traces. |
62
+ | `glimpse config url` | Overrides the default production server with a custom backend or localhost. |
57
63
 
58
64
  ## Development
59
65
 
@@ -65,7 +71,7 @@ GitGlimpse CLI uses holds your configuration at `~/.config/glimpsecli/config.jso
65
71
  source .venv/bin/activate
66
72
  pip install -e .
67
73
  ```
68
- 2. Point the CLI to your local development server:
74
+ 2. Point the CLI to your local development server (use `--local` to not propagate over your real global config):
69
75
  ```bash
70
- glimpse config set-url http://localhost:5000
76
+ glimpse config url http://localhost:5000 --local
71
77
  ```
@@ -1,7 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: git-glimpse-cli
3
- Version: 0.1.0
3
+ Version: 0.1.2
4
4
  Summary: CLI tool to manage and update shared GitHub repos with GitGlimpse.
5
+ Author-email: sutaC <contact@sutac.pl>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/sutaC/git-glimpse-cli
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Operating System :: OS Independent
5
10
  Requires-Python: >=3.10
6
11
  Description-Content-Type: text/markdown
7
12
  License-File: LICENSE
@@ -60,12 +65,18 @@ pip install git-glimpse-cli
60
65
 
61
66
  GitGlimpse CLI uses holds your configuration at `~/.config/glimpsecli/config.json`, and local repository settings are stored at `./.shared-repo.json`.
62
67
 
68
+ Configuration hierarchy:
69
+
70
+ ```
71
+ Most important -> Local repo config -> Global cli config
72
+ ```
73
+
63
74
  ### Advanced Settings
64
75
 
65
- | Command | Description |
66
- | ------------------------ | --------------------------------------------------------------------------- |
67
- | `glimpse config debug` | Enables verbose debug mode, printing stack traces. |
68
- | `glimpse config set-url` | Overrides the default production server with a custom backend or localhost. |
76
+ | Command | Description |
77
+ | ---------------------- | --------------------------------------------------------------------------- |
78
+ | `glimpse config debug` | Enables verbose debug mode, printing stack traces. |
79
+ | `glimpse config url` | Overrides the default production server with a custom backend or localhost. |
69
80
 
70
81
  ## Development
71
82
 
@@ -77,7 +88,7 @@ GitGlimpse CLI uses holds your configuration at `~/.config/glimpsecli/config.jso
77
88
  source .venv/bin/activate
78
89
  pip install -e .
79
90
  ```
80
- 2. Point the CLI to your local development server:
91
+ 2. Point the CLI to your local development server (use `--local` to not propagate over your real global config):
81
92
  ```bash
82
- glimpse config set-url http://localhost:5000
93
+ glimpse config url http://localhost:5000 --local
83
94
  ```
@@ -28,7 +28,7 @@ def request_api(
28
28
  Response from api.
29
29
  """
30
30
  if not token:
31
- token = helpers.get_token()
31
+ token = helpers.fget_token()
32
32
  url = f"{config.get_api_url()}{endpoint}"
33
33
  with Progress(SpinnerColumn(), TextColumn("[progress.description]{task.description}"), transient=True) if not quiet else nullcontext() as progress:
34
34
  if progress:
@@ -52,7 +52,6 @@ def request_api(
52
52
  error = response.json().get("error")
53
53
  if error: print(f"[dim]Error reason: {error}[/dim]")
54
54
  except JSONDecodeError: pass
55
- config.cliconf_save(token="")
56
55
  print("[yellow]Your session has expired. Please run 'glimpse login' again [/yellow].")
57
56
  raise typer.Exit(1)
58
57
  elif response.status_code == 403:
@@ -0,0 +1,126 @@
1
+ from functools import partial
2
+ from typing import TypedDict
3
+ from pathlib import Path
4
+ import json
5
+
6
+ CLI_CONFIG_DIR = Path.home() / ".config" / "glimpsecli"
7
+ CLI_CONFIG_FILE = CLI_CONFIG_DIR / "config.json"
8
+ CONFIG_FILENAME = ".shared-repo.json"
9
+ DEFAULT_API_URL = "https://gitglimpse.sutac.pl"
10
+
11
+ class CliConfig(TypedDict, total=False):
12
+ token: str
13
+ api_url: str
14
+ debug: bool
15
+
16
+ class RepoConfig(CliConfig, total=False):
17
+ repo_id: str
18
+
19
+ # --- repository config
20
+ def _repoconf_load() -> RepoConfig | None:
21
+ """Loads repository config from file.
22
+
23
+ Args:
24
+ path: Path to directory holding config file.
25
+
26
+ Returns:
27
+ RepoConfig if avaliable, else None.
28
+ """
29
+ config_path = Path(".") / CONFIG_FILENAME
30
+ if not config_path.exists():
31
+ return None
32
+ try:
33
+ with open(config_path, "r") as f:
34
+ return json.load(f)
35
+ except Exception:
36
+ return None
37
+
38
+ def repoconf_remove() -> None:
39
+ """Removes repository config file if exists.
40
+
41
+ Args:
42
+ path: Path to directory holding config file.
43
+ """
44
+ config_path = Path(".") / CONFIG_FILENAME
45
+ config_path.unlink(missing_ok=True)
46
+
47
+
48
+ # --- cli config
49
+ def _cliconf_load() -> CliConfig | None:
50
+ """Loads cli configfrom file.
51
+
52
+ Returns:
53
+ CliConfig if avaliable, else None.
54
+ """
55
+ if not CLI_CONFIG_FILE.exists():
56
+ return None
57
+ try:
58
+ with open(CLI_CONFIG_FILE, "r") as f:
59
+ return json.load(f)
60
+ except Exception:
61
+ return None
62
+
63
+ def cliconf_remove() -> None:
64
+ """Removes cli config file."""
65
+ CLI_CONFIG_FILE.unlink(missing_ok=True)
66
+
67
+ # --- conf update
68
+ def conf_save(
69
+ new_conf: CliConfig | RepoConfig | dict,
70
+ local = False
71
+ ) -> None:
72
+ """Save configuration in ethier local or global context.
73
+
74
+ Args:
75
+ local: If True saves config to local context, else saves in global context.
76
+ """
77
+ if local:
78
+ conf = _repoconf_load() or {}
79
+ conf_file = Path(".") / CONFIG_FILENAME
80
+ else:
81
+ CLI_CONFIG_DIR.mkdir(parents=True, exist_ok=True)
82
+ conf = _cliconf_load() or {}
83
+ conf_file = CLI_CONFIG_FILE
84
+ for key, val in new_conf.items():
85
+ if val is not None:
86
+ conf[key] = val
87
+ elif key in conf:
88
+ conf.pop(key)
89
+ with open(conf_file, "w") as f:
90
+ json.dump(conf, f, indent=2)
91
+
92
+ # --- config getters
93
+ def get_api_url() -> str:
94
+ """Returns active api url."""
95
+ if conf := _repoconf_load():
96
+ if user_url := conf.get("api_url"):
97
+ return user_url.rstrip("/")
98
+ if conf := _cliconf_load():
99
+ if user_url := conf.get("api_url"):
100
+ return user_url.rstrip("/")
101
+ return DEFAULT_API_URL
102
+
103
+ def get_debug_mode() -> bool:
104
+ """Returns True if debug is enabled in user config, else False."""
105
+ if conf := _repoconf_load():
106
+ if debug := conf.get("debug") is not None:
107
+ return debug
108
+ if conf := _cliconf_load():
109
+ return conf.get("debug", False)
110
+ return False
111
+
112
+ def get_repo_id() -> str | None:
113
+ """Returns current repo_id."""
114
+ if conf := _repoconf_load():
115
+ return conf.get("repo_id")
116
+ return None
117
+
118
+ def get_token() -> str | None:
119
+ """Returns current user cli token."""
120
+ if conf := _repoconf_load():
121
+ if token := conf.get("token"):
122
+ return token
123
+ if conf := _cliconf_load():
124
+ if token := conf.get("token"):
125
+ return token
126
+ return None
@@ -5,7 +5,6 @@ from rich import print
5
5
  import typer
6
6
  import time
7
7
 
8
-
9
8
  def get_or_prompt_url(url: str | None = None, detect: bool = True) -> str:
10
9
  """Helper to get GitHub repository url.
11
10
 
@@ -38,7 +37,7 @@ def finalize_init(repo_id: str) -> None:
38
37
  repo_id: Repository GitGlimpse id.
39
38
  """
40
39
  # Add repo id to local file
41
- config.repoconf_save(repo_id)
40
+ config.conf_save({"repo_id": repo_id}, local=True)
42
41
  print("[dim]Created local .shared-repo.json configuration file for this repository.[/dim]")
43
42
  # Auto-add to .gitignore
44
43
  gitignore = Path(".gitignore")
@@ -65,7 +64,7 @@ def poll_build_status(token: str, repo_id: str) -> None:
65
64
  task_id = progress.add_task(description="Connecting to server...", total=None)
66
65
  last_status = None
67
66
  while True:
68
- poll_response = api.request_api(f"/repos/build/{repo_id}/status", token=token, quiet=True)
67
+ poll_response = api.request_api(f"/cli/repos/build/{repo_id}/status", token=token, quiet=True)
69
68
  status = poll_response.json().get("status")
70
69
  if status != last_status:
71
70
  progress.update(task_id, description=f"Build status: {utils.enrich_status(status)}")
@@ -79,19 +78,18 @@ def poll_build_status(token: str, repo_id: str) -> None:
79
78
  print(f"Build has finished with status: {utils.enrich_status(status)}")
80
79
  print(f"View details at: {config.get_api_url()}/repos/details/{repo_id}")
81
80
 
82
- def get_repo_config() -> config.RepoConfig:
81
+ def fget_repo_id() -> str:
83
82
  """Helper for getting repository config."""
84
- conf = config.repoconf_load()
85
- if not conf:
83
+ repo_id = config.get_repo_id()
84
+ if not repo_id:
86
85
  print("[yellow]Not initialised. Run 'glimpse init' first.[/yellow]")
87
86
  raise typer.Exit(1)
88
- return conf
87
+ return repo_id
89
88
 
90
- def get_token() -> str:
89
+ def fget_token() -> str:
91
90
  """Helper for getting api token."""
92
- conf = config.cliconf_load() or {}
93
- token = conf.get("token")
94
- if not conf or not token:
91
+ token = config.get_token()
92
+ if not token:
95
93
  print("[yellow]Not logged in. Run 'glimpse login' first.[/yellow]")
96
94
  raise typer.Exit(code=1)
97
95
  return token
@@ -33,17 +33,19 @@ def login(
33
33
  prompt="Enter your CLI token",
34
34
  hide_input=True,
35
35
  help="Your personal access cli token from dashboard."),
36
- force: bool = typer.Option(False, "--force", "-f", help="Overwrite existing session without prompting.")
36
+ force: bool = typer.Option(False, "--force", "-f", help="Overwrite existing session without prompting."),
37
+ local: bool = typer.Option(False, "--local", "-l", help="Save config to local repository only.")
37
38
  ):
38
39
  """Authenticate cli with server."""
39
- conf = config.cliconf_load()
40
- if not force and conf and conf.get("token"):
40
+ if local: old_token = (config._repoconf_load() or {}).get("token")
41
+ else: old_token = (config._cliconf_load() or {}).get("token")
42
+ if not force and old_token:
41
43
  print("[yellow]You are already logged in.[/yellow]")
42
44
  if not typer.confirm("Do you want to overwrite your existing session?"):
43
45
  print("[dim]Login cancelled.[/dim]")
44
46
  raise typer.Exit(0)
45
47
  response = api.request_api("/cli/user", token=token)
46
- config.cliconf_save(token)
48
+ config.conf_save({"token": token}, local)
47
49
  username = response.json().get("username")
48
50
  print(f"[bold green]Success![/bold green] Authenticated as [cyan]{username}[/cyan].")
49
51
 
@@ -57,13 +59,16 @@ def whoami():
57
59
 
58
60
  # --- logout
59
61
  @app.command()
60
- def logout():
62
+ def logout(
63
+ local: bool = typer.Option(False, "--local", "-l", help="Alter config in local repository only.")
64
+ ):
61
65
  """Clear stored local credentials."""
62
- conf = config.cliconf_load()
63
- if not conf or not conf.get("token"):
66
+ if local: token = (config._repoconf_load() or {}).get("token")
67
+ else: token = (config._cliconf_load() or {}).get("token")
68
+ if not token:
64
69
  print("[yellow]You are not currently logged in.[/yellow]")
65
70
  raise typer.Exit(0)
66
- config.cliconf_save(token="")
71
+ config.conf_save({"token": None})
67
72
  print("[bold green]Logged out successfully.[/bold green]\nStored credentials removed.")
68
73
 
69
74
  # --- init
@@ -76,8 +81,8 @@ def init_link(
76
81
  detect: bool = typer.Option(True, help="Do you want to detect repository url automatically.")
77
82
  ):
78
83
  """Link current Git repository to existing one on GitGlimpse."""
79
- token = helpers.get_token()
80
- if config.repoconf_load():
84
+ token = helpers.fget_token()
85
+ if config.get_repo_id():
81
86
  print("Shared repository already initialised.")
82
87
  raise typer.Exit(0)
83
88
  url = helpers.get_or_prompt_url(url, detect)
@@ -100,8 +105,8 @@ def init_new(
100
105
  detect: bool = typer.Option(True, help="Do you want to detect repository url automatically.")
101
106
  ):
102
107
  """Upload and register current Git repository to GitGlimpse."""
103
- token = helpers.get_token()
104
- if config.repoconf_load():
108
+ token = helpers.fget_token()
109
+ if config.get_repo_id():
105
110
  print("Shared repository already initialised.")
106
111
  raise typer.Exit(0)
107
112
  url = helpers.get_or_prompt_url(url, detect)
@@ -172,14 +177,14 @@ def limits():
172
177
  @app.command()
173
178
  def status():
174
179
  """Display status info of current repository."""
175
- token = helpers.get_token()
176
- conf = helpers.get_repo_config()
177
- response = api.request_api(f"/cli/repos/build/{conf['repo_id']}/status", token=token)
180
+ token = helpers.fget_token()
181
+ repo_id = helpers.fget_repo_id()
182
+ response = api.request_api(f"/cli/repos/build/{repo_id}/status", token=token)
178
183
  data = response.json()
179
184
  build_status = data.get("status", "")
180
- print(f"Repository id: [dark_cyan]{conf['repo_id']}[/dark_cyan]")
185
+ print(f"Repository id: [dark_cyan]{repo_id}[/dark_cyan]")
181
186
  print(f"Build status: {utils.enrich_status(build_status)}")
182
- print(f"Repository details: {config.get_api_url()}/repos/details/{conf['repo_id']}")
187
+ print(f"Repository details: {config.get_api_url()}/repos/details/{repo_id}")
183
188
 
184
189
  # --- remove
185
190
  @app.command()
@@ -187,11 +192,11 @@ def remove(
187
192
  force: bool = typer.Option(False, "--force", "-f", help="Remove without prompting.")
188
193
  ):
189
194
  """Remove current repository from GitGlimpse."""
190
- token = helpers.get_token()
191
- conf = helpers.get_repo_config()
192
- print(f"[dim]Current repository id: '{conf['repo_id']}'[/dim]")
195
+ token = helpers.fget_token()
196
+ repo_id = helpers.fget_repo_id()
197
+ print(f"[dim]Current repository id: '{repo_id}'[/dim]")
193
198
  if not force: typer.confirm(f"Are you sure, you want to remove this repository from GitGlimpse?", abort=True)
194
- api.request_api(f"/cli/repos/remove/{conf['repo_id']}", method="POST", token=token, handle_codes=[204])
199
+ api.request_api(f"/cli/repos/remove/{repo_id}", method="POST", token=token, handle_codes=[204])
195
200
  config.repoconf_remove()
196
201
  print("Removed repository from GitGlimpse.")
197
202
 
@@ -201,13 +206,13 @@ def build(
201
206
  force: bool = typer.Option(False, "--force", "-f", help="Schedule without prompting.")
202
207
  ):
203
208
  """Schedule a build for current repository."""
204
- token = helpers.get_token()
205
- conf = helpers.get_repo_config()
209
+ token = helpers.fget_token()
210
+ repo_id = helpers.fget_repo_id()
206
211
  if not force:
207
212
  print("Ensure that you pushed recent changes to GitHub.")
208
213
  typer.confirm("Continue?", abort=True)
209
- print(f"[dim]Scheduling a build for current repository (id: '{conf['repo_id']}')[/dim]")
210
- response = api.request_api(f"/cli/repos/build/{conf['repo_id']}", method="POST", token=token, handle_codes=[202, 420, 425])
214
+ print(f"[dim]Scheduling a build for current repository (id: '{repo_id}')[/dim]")
215
+ response = api.request_api(f"/cli/repos/build/{repo_id}", method="POST", token=token, handle_codes=[202, 420, 425])
211
216
  if response.status_code == 420:
212
217
  print(f"[yellow]You have reached your usage limits.[/yellow]")
213
218
  try:
@@ -219,36 +224,56 @@ def build(
219
224
  print(f"[yellow]This repository already has a pending build.[/yellow]")
220
225
  raise typer.Exit(1)
221
226
  # response.status_code == 202
222
- helpers.poll_build_status(token, conf['repo_id'])
227
+ helpers.poll_build_status(token, repo_id)
223
228
 
224
229
  # --- config
225
230
  config_app = typer.Typer(help="Configure your cli.", no_args_is_help=True)
226
231
  app.add_typer(config_app, name="config")
227
232
 
228
- @config_app.command("set-url")
229
- def config_set_url(
230
- url: str = typer.Argument(..., help="Api base url (e.g., http://localhost:8000 or https://gitglimpse.sutac.pl)")
233
+ @config_app.command("list")
234
+ def config_list(
235
+ sensitive: bool = typer.Option(False, "--show-sensitive", help="Display sensitive data."),
236
+ local: bool = typer.Option(None, "--local/--global", help="Display only local or global config.")
237
+ ):
238
+ """Get current cli config."""
239
+ sensitive_keys = ["token", "repo_id"]
240
+ lconf = config._repoconf_load() or {}
241
+ gconf = config._cliconf_load() or {}
242
+ if local is None:
243
+ print("[bold]Current cli config[/bold]")
244
+ elif local:
245
+ print("[bold]Current LOCAL cli config[/bold]")
246
+ else:
247
+ print("[bold]Current GLOBAL cli config[/bold]")
248
+ if local != False:
249
+ for key, val in lconf.items():
250
+ val = f"[dim][{key.upper()}][/dim]" if not sensitive and key in sensitive_keys else val
251
+ print(f"{key}: {val}")
252
+ if local != True:
253
+ for key, val in gconf.items():
254
+ if local is None and key in lconf: continue
255
+ val = f"[dim][{key.upper()}][/dim]" if not sensitive and key in sensitive_keys else val
256
+ print(f"{key}: {val}")
257
+
258
+ @config_app.command("url")
259
+ def config_url(
260
+ url: str = typer.Argument(..., help="Api base url (e.g., http://localhost:8000 or https://gitglimpse.sutac.pl)"),
261
+ local: bool = typer.Option(False, "--local", "-l", help="Save config to local repository only.")
231
262
  ):
232
263
  """Set the active api server url."""
233
- config.cliconf_save(api_url=url)
264
+ config.conf_save({"api_url": (url if url else None)}, local)
234
265
  if url:
235
266
  print(f"Api url updated to: {url}")
236
267
  else:
237
268
  print("Api url unset.")
238
269
 
239
- @config_app.command("get-url")
240
- def config_get_url():
241
- """Get the active api server url."""
242
- conf = config.cliconf_load() or {}
243
- url = conf.get("api_url")
244
- if url: print(url)
245
-
246
270
  @config_app.command("debug")
247
271
  def config_debug(
248
- enabled: bool = typer.Argument(..., help="True to enable debug mode, False to disable.")
249
- ):
272
+ enabled: bool = typer.Argument(..., help="True to enable debug mode, False to disable."),
273
+ local: bool = typer.Option(False, "--local", "-l", help="Save config to local repository only.")
274
+ ):
250
275
  """Enable or disable verbose debug output and full crash stack traces."""
251
- config.cliconf_save(debug=enabled)
276
+ config.conf_save({"debug": enabled}, local)
252
277
  status = "[bold green]enabled[/bold green]" if enabled else "[bold yellow]disabled[/bold yellow]"
253
278
  print(f"Debug mode {status}.")
254
279
 
@@ -4,15 +4,27 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "git-glimpse-cli"
7
- version = "0.1.0"
7
+ authors = [
8
+ { name="sutaC", email="contact@sutac.pl" },
9
+ ]
10
+ version = "0.1.2"
8
11
  description = "CLI tool to manage and update shared GitHub repos with GitGlimpse."
9
12
  readme = "README.md"
10
13
  requires-python = ">=3.10"
14
+ classifiers = [
15
+ "Programming Language :: Python :: 3",
16
+ "Operating System :: OS Independent",
17
+ ]
11
18
  dependencies = [
12
19
  "httpx>=0.28.1",
13
20
  "rich>=15.0.0",
14
21
  "typer>=0.27.2"
15
22
  ]
23
+ license = "MIT"
24
+ license-files = ["LICEN[CS]E*"]
25
+
26
+ [project.urls]
27
+ Homepage = "https://github.com/sutaC/git-glimpse-cli"
16
28
 
17
29
  [project.scripts]
18
- glimpse = "glimpsecli.main:cli"
30
+ glimpse = "glimpsecli.main:cli"
@@ -1,116 +0,0 @@
1
- from typing import TypedDict
2
- from pathlib import Path
3
- import json
4
- import os
5
-
6
- CLI_CONFIG_DIR = Path.home() / ".config" / "glimpsecli"
7
- CLI_CONFIG_FILE = CLI_CONFIG_DIR / "config.json"
8
- CONFIG_FILENAME = ".shared-repo.json"
9
- DEFAULT_API_URL = "https://gitglimpse.sutac.pl"
10
-
11
- # --- repository config
12
- class RepoConfig(TypedDict):
13
- repo_id: str
14
-
15
- def repoconf_save(repo_id: str, path: Path = Path(".")) -> None:
16
- """Saves repository config to file.
17
-
18
- Args:
19
- repo_id: Repository GitGlimpse id.
20
- path: Path to directory holding config file.
21
- """
22
- config_path = path / CONFIG_FILENAME
23
- conf: RepoConfig = {"repo_id": repo_id}
24
- with open(config_path, "w") as f:
25
- json.dump(conf, f, indent=2)
26
-
27
- def repoconf_load(path: Path = Path(".")) -> RepoConfig | None:
28
- """Loads repository config from file.
29
-
30
- Args:
31
- path: Path to directory holding config file.
32
-
33
- Returns:
34
- RepoConfig if avaliable, else None.
35
- """
36
- config_path = path / CONFIG_FILENAME
37
- if not config_path.exists():
38
- return None
39
- try:
40
- with open(config_path, "r") as f:
41
- return json.load(f)
42
- except Exception:
43
- return None
44
-
45
- def repoconf_remove(path: Path = Path(".")) -> None:
46
- """Removes repository config file if exists.
47
-
48
- Args:
49
- path: Path to directory holding config file.
50
- """
51
- config_path = path / CONFIG_FILENAME
52
- config_path.unlink(missing_ok=True)
53
-
54
- # --- cli config
55
- class CliConfig(TypedDict, total=False):
56
- token: str
57
- api_url: str
58
- debug: bool
59
-
60
- def cliconf_save(
61
- token: str | None = None,
62
- api_url: str | None = None,
63
- debug: bool | None = None
64
- ) -> None:
65
- """Saves or updates cli config safely.
66
-
67
- Args:
68
- token: GitGlimpse api token.
69
- """
70
- CLI_CONFIG_DIR.mkdir(parents=True, exist_ok=True)
71
- conf = cliconf_load() or {}
72
- if token is not None:
73
- if token: conf["token"] = token
74
- elif "token" in conf: conf.pop("token")
75
- if api_url is not None:
76
- if api_url: conf["api_url"] = api_url.rstrip("/")
77
- elif "api_url" in conf: conf.pop("api_url")
78
- if debug is not None:
79
- conf["debug"] = debug
80
- with open(CLI_CONFIG_FILE, "w") as f:
81
- json.dump(conf, f, indent=2)
82
-
83
- def cliconf_load() -> CliConfig | None:
84
- """Loads cli configfrom file.
85
-
86
- Returns:
87
- CliConfig if avaliable, else None.
88
- """
89
- if not CLI_CONFIG_FILE.exists():
90
- return None
91
- try:
92
- with open(CLI_CONFIG_FILE, "r") as f:
93
- return json.load(f)
94
- except Exception:
95
- return None
96
-
97
- def cliconf_remove() -> None:
98
- """Removes cli config file."""
99
- CLI_CONFIG_FILE.unlink(missing_ok=True)
100
-
101
- def get_api_url() -> str:
102
- """Resolves active api url
103
-
104
- Returns:
105
- Active api url.
106
- """
107
- if conf := cliconf_load():
108
- if user_url := conf.get("api_url"):
109
- return user_url.rstrip("/")
110
- return DEFAULT_API_URL
111
-
112
- def get_debug_mode() -> bool:
113
- """Returns True if debug is enabled in user config, else False."""
114
- if conf := cliconf_load():
115
- return conf.get("debug", False)
116
- return False
File without changes