sum-cli 3.0.0__py3-none-any.whl → 3.1.0__py3-none-any.whl

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.
sum/setup/scaffold.py CHANGED
@@ -17,7 +17,6 @@ from typing import cast
17
17
 
18
18
  from sum.exceptions import SetupError, ThemeNotFoundError, ThemeValidationError
19
19
  from sum.setup.remote_themes import parse_theme_spec, resolve_remote_theme
20
- from sum.system_config import ConfigurationError, get_system_config
21
20
  from sum.utils.environment import find_monorepo_root
22
21
  from sum.utils.project import (
23
22
  ProjectNaming,
@@ -366,23 +365,20 @@ def _copy_seeders_and_content(
366
365
  shutil.copytree(content_profile_dir, target_content, ignore=ignore)
367
366
 
368
367
 
369
- def _configure_ci_workflows(project_path: Path) -> None:
368
+ def _configure_ci_workflows(project_path: Path, git_provider: str | None) -> None:
370
369
  """Keep only the CI workflow directory for the configured git provider.
371
370
 
372
371
  Boilerplate contains both .github/workflows/ and .gitea/workflows/.
373
- This removes the one that doesn't match the configured git_provider.
372
+ This removes the one that doesn't match the git_provider.
373
+
374
+ Args:
375
+ project_path: Path to the project.
376
+ git_provider: "github", "gitea", or None (defaults to github).
374
377
  """
375
378
  github_dir = project_path / ".github"
376
379
  gitea_dir = project_path / ".gitea"
377
380
 
378
- # Determine provider from config, defaulting to github if config unavailable
379
- try:
380
- config = get_system_config()
381
- provider = config.agency.git_provider
382
- except ConfigurationError:
383
- # Config not available (e.g., running in test without config)
384
- # Default to GitHub workflows
385
- provider = "github"
381
+ provider = git_provider or "github"
386
382
 
387
383
  if provider == "gitea":
388
384
  # Remove GitHub workflows, keep Gitea
@@ -399,6 +395,7 @@ def scaffold_project(
399
395
  clients_dir: Path,
400
396
  theme_slug: str = DEFAULT_THEME_SLUG,
401
397
  seed_profile: str = "starter",
398
+ git_provider: str | None = None,
402
399
  ) -> Path:
403
400
  try:
404
401
  naming = validate_project_name(project_name)
@@ -460,7 +457,7 @@ def scaffold_project(
460
457
  _rename_project_package_dir(project_path, naming)
461
458
  _replace_placeholders(project_path, naming)
462
459
  _create_env_from_example(project_path)
463
- _configure_ci_workflows(project_path)
460
+ _configure_ci_workflows(project_path, git_provider)
464
461
  _copy_theme_to_active(project_path, theme_source_dir, theme_slug)
465
462
  _write_theme_config(project_path, theme_slug, theme_manifest.version)
466
463
  _copy_seeders_and_content(
@@ -15,6 +15,7 @@ from __future__ import annotations
15
15
 
16
16
  import shutil
17
17
  from dataclasses import dataclass
18
+ from datetime import UTC, datetime
18
19
  from pathlib import Path
19
20
 
20
21
  from sum.exceptions import SeedError, SetupError
@@ -38,6 +39,7 @@ from sum.setup.infrastructure import (
38
39
  )
39
40
  from sum.setup.scaffold import scaffold_project
40
41
  from sum.setup.venv import VenvManager
42
+ from sum.site_config import GitConfig, SiteConfig
41
43
  from sum.system_config import SystemConfig, get_system_config
42
44
  from sum.utils.django import DjangoCommandExecutor
43
45
  from sum.utils.environment import ExecutionMode
@@ -69,9 +71,9 @@ class SiteSetupConfig:
69
71
  seed_profile: str | None = "starter"
70
72
  content_path: str | None = None
71
73
  superuser_username: str = "admin"
72
- skip_git: bool = False
73
74
  skip_systemd: bool = False
74
75
  skip_caddy: bool = False
76
+ git_config: GitConfig | None = None # None means --no-git
75
77
 
76
78
 
77
79
  class SiteOrchestrator:
@@ -147,6 +149,11 @@ class SiteOrchestrator:
147
149
  site_slug,
148
150
  setup_config.theme_slug,
149
151
  setup_config.seed_profile,
152
+ git_provider=(
153
+ setup_config.git_config.provider
154
+ if setup_config.git_config
155
+ else None
156
+ ),
150
157
  )
151
158
  # Copy .env to app directory (Django reads from app/.env, not site root)
152
159
  self._copy_env_to_app()
@@ -212,7 +219,7 @@ class SiteOrchestrator:
212
219
  repo_url = setup_git_for_site(
213
220
  self._app_dir,
214
221
  site_slug,
215
- skip_remote=setup_config.skip_git,
222
+ git_config=setup_config.git_config,
216
223
  )
217
224
  if repo_url:
218
225
  self._done(current_step, total_steps, f"Repository created: {repo_url}")
@@ -246,7 +253,19 @@ class SiteOrchestrator:
246
253
  start_site_service(site_slug, self.sys_config)
247
254
  self._done(current_step, total_steps, "Service started")
248
255
 
249
- # Step 18: Write credentials file
256
+ # Step 18: Write site config
257
+ current_step += 1
258
+ self._progress(current_step, total_steps, "Writing site config")
259
+ site_config = SiteConfig(
260
+ slug=site_slug,
261
+ theme=setup_config.theme_slug,
262
+ created=datetime.now(UTC),
263
+ git=setup_config.git_config,
264
+ )
265
+ site_config.save(self._site_dir)
266
+ self._done(current_step, total_steps, "Site config saved")
267
+
268
+ # Step 19: Write credentials file
250
269
  current_step += 1
251
270
  self._progress(current_step, total_steps, "Saving credentials")
252
271
  creds_path = write_credentials_file(
@@ -317,6 +336,7 @@ class SiteOrchestrator:
317
336
  if not config.skip_systemd:
318
337
  steps.append("start_systemd_service")
319
338
 
339
+ steps.append("write_site_config")
320
340
  steps.append("write_credentials_file")
321
341
 
322
342
  return len(steps)
@@ -330,7 +350,11 @@ class SiteOrchestrator:
330
350
  OutputFormatter.progress(step, total, message, "✅")
331
351
 
332
352
  def _scaffold_to_app_dir(
333
- self, site_slug: str, theme_slug: str, seed_profile: str | None = None
353
+ self,
354
+ site_slug: str,
355
+ theme_slug: str,
356
+ seed_profile: str | None = None,
357
+ git_provider: str | None = None,
334
358
  ) -> None:
335
359
  """Scaffold project code to the app directory.
336
360
 
@@ -358,6 +382,7 @@ class SiteOrchestrator:
358
382
  clients_dir=self._site_dir,
359
383
  theme_slug=theme_slug,
360
384
  seed_profile=seed_profile or "starter",
385
+ git_provider=git_provider,
361
386
  )
362
387
 
363
388
  # Rename from site_slug to app
sum/site_config.py ADDED
@@ -0,0 +1,129 @@
1
+ """Per-site configuration stored at /srv/sum/<site>/.sum/config.yml."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass
6
+ from datetime import datetime
7
+ from pathlib import Path
8
+
9
+ import yaml
10
+ from sum.exceptions import SumCliError
11
+
12
+
13
+ class SiteConfigError(SumCliError):
14
+ """Site configuration error."""
15
+
16
+ pass
17
+
18
+
19
+ @dataclass
20
+ class GitConfig:
21
+ """Git configuration for a site."""
22
+
23
+ provider: str # "github" or "gitea"
24
+ org: str
25
+ url: str | None = None # Required for gitea
26
+ ssh_port: int = 22
27
+ token_env: str = "GITEA_TOKEN"
28
+
29
+
30
+ @dataclass
31
+ class SiteConfig:
32
+ """Per-site configuration."""
33
+
34
+ slug: str
35
+ theme: str
36
+ created: datetime
37
+ git: GitConfig | None # None if --no-git
38
+
39
+ @classmethod
40
+ def load(cls, site_dir: Path) -> SiteConfig:
41
+ """Load site config from .sum/config.yml."""
42
+ config_path = site_dir / ".sum" / "config.yml"
43
+ if not config_path.exists():
44
+ raise SiteConfigError(
45
+ f"Site config not found: {config_path}\n"
46
+ f"This site may have been created before site configs were introduced."
47
+ )
48
+
49
+ try:
50
+ with open(config_path) as f:
51
+ data = yaml.safe_load(f)
52
+ except yaml.YAMLError as exc:
53
+ raise SiteConfigError(
54
+ f"Invalid YAML in site config: {config_path}\n{exc}"
55
+ ) from exc
56
+
57
+ if not isinstance(data, dict):
58
+ raise SiteConfigError(
59
+ f"Site config is empty or not a mapping: {config_path}"
60
+ )
61
+
62
+ try:
63
+ site_data = data["site"]
64
+ slug = site_data["slug"]
65
+ theme = site_data["theme"]
66
+ created_raw = site_data["created"]
67
+ except KeyError as exc:
68
+ raise SiteConfigError(
69
+ f"Missing required field '{exc.args[0]}' in site config: {config_path}"
70
+ ) from exc
71
+
72
+ try:
73
+ created_dt = datetime.fromisoformat(created_raw)
74
+ except (TypeError, ValueError) as exc:
75
+ raise SiteConfigError(
76
+ f"Invalid datetime format for 'site.created' in: {config_path}"
77
+ ) from exc
78
+
79
+ git_data = data.get("git")
80
+ git_config = None
81
+ if git_data:
82
+ try:
83
+ git_config = GitConfig(
84
+ provider=git_data["provider"],
85
+ org=git_data["org"],
86
+ url=git_data.get("url"),
87
+ ssh_port=git_data.get("ssh_port", 22),
88
+ token_env=git_data.get("token_env", "GITEA_TOKEN"),
89
+ )
90
+ except KeyError as exc:
91
+ raise SiteConfigError(
92
+ f"Missing required git field '{exc.args[0]}' in: {config_path}"
93
+ ) from exc
94
+
95
+ return cls(
96
+ slug=slug,
97
+ theme=theme,
98
+ created=created_dt,
99
+ git=git_config,
100
+ )
101
+
102
+ def save(self, site_dir: Path) -> None:
103
+ """Save site config to .sum/config.yml."""
104
+ config_dir = site_dir / ".sum"
105
+ config_dir.mkdir(parents=True, exist_ok=True)
106
+ config_path = config_dir / "config.yml"
107
+
108
+ data: dict = {
109
+ "site": {
110
+ "slug": self.slug,
111
+ "theme": self.theme,
112
+ "created": self.created.isoformat(),
113
+ },
114
+ "git": None,
115
+ }
116
+
117
+ if self.git:
118
+ git_data: dict = {
119
+ "provider": self.git.provider,
120
+ "org": self.git.org,
121
+ }
122
+ if self.git.provider == "gitea":
123
+ git_data["url"] = self.git.url
124
+ git_data["ssh_port"] = self.git.ssh_port
125
+ git_data["token_env"] = self.git.token_env
126
+ data["git"] = git_data
127
+
128
+ with open(config_path, "w") as f:
129
+ yaml.dump(data, f, default_flow_style=False, sort_keys=False)
sum/system_config.py CHANGED
@@ -33,43 +33,6 @@ class AgencyConfig:
33
33
  """Agency identification settings."""
34
34
 
35
35
  name: str
36
- # Git provider: "github" (default) or "gitea"
37
- git_provider: str = "github"
38
- # GitHub-specific (required when git_provider=github)
39
- github_org: str | None = None
40
- # Gitea-specific (required when git_provider=gitea)
41
- gitea_url: str | None = None
42
- gitea_org: str | None = None
43
- gitea_token_env: str = "GITEA_TOKEN" # env var name containing API token
44
-
45
- def __post_init__(self) -> None:
46
- """Validate provider-specific fields."""
47
- if self.git_provider not in ("github", "gitea"):
48
- raise ConfigurationError(
49
- f"Invalid git_provider '{self.git_provider}'. Must be 'github' or 'gitea'."
50
- )
51
-
52
- if self.git_provider == "github":
53
- if not self.github_org:
54
- raise ConfigurationError(
55
- "github_org is required when git_provider is 'github'"
56
- )
57
- elif self.git_provider == "gitea":
58
- if not self.gitea_url:
59
- raise ConfigurationError(
60
- "gitea_url is required when git_provider is 'gitea'"
61
- )
62
- if not self.gitea_org:
63
- raise ConfigurationError(
64
- "gitea_org is required when git_provider is 'gitea'"
65
- )
66
-
67
- @property
68
- def org(self) -> str:
69
- """Get the organization name for the configured provider."""
70
- if self.git_provider == "gitea":
71
- return self.gitea_org or ""
72
- return self.github_org or ""
73
36
 
74
37
 
75
38
  @dataclass
sum/utils/environment.py CHANGED
@@ -1,10 +1,10 @@
1
1
  from __future__ import annotations
2
2
 
3
- from enum import Enum
3
+ from enum import StrEnum
4
4
  from pathlib import Path
5
5
 
6
6
 
7
- class ExecutionMode(str, Enum):
7
+ class ExecutionMode(StrEnum):
8
8
  MONOREPO = "monorepo"
9
9
  STANDALONE = "standalone"
10
10
 
sum/utils/validation.py CHANGED
@@ -7,7 +7,7 @@ import re
7
7
  import subprocess
8
8
  import sys
9
9
  from dataclasses import dataclass
10
- from enum import Enum
10
+ from enum import StrEnum
11
11
  from pathlib import Path
12
12
  from typing import cast
13
13
 
@@ -16,7 +16,7 @@ from sum.utils.django import DjangoCommandExecutor
16
16
  from sum.utils.environment import ExecutionMode, find_monorepo_root
17
17
 
18
18
 
19
- class ValidationStatus(str, Enum):
19
+ class ValidationStatus(StrEnum):
20
20
  OK = "ok"
21
21
  FAIL = "fail"
22
22
  SKIP = "skip"
@@ -0,0 +1,230 @@
1
+ Metadata-Version: 2.4
2
+ Name: sum-cli
3
+ Version: 3.1.0
4
+ Summary: SUM Platform CLI: single control plane for site lifecycle management
5
+ Author: Mark Ashton
6
+ License-Expression: BSD-3-Clause
7
+ Project-URL: Homepage, https://github.com/markashton480/sum-platform
8
+ Project-URL: Repository, https://github.com/markashton480/sum-platform
9
+ Project-URL: Issues, https://github.com/markashton480/sum-platform/issues
10
+ Project-URL: Documentation, https://github.com/markashton480/sum-platform/tree/main/docs/dev/cli.md
11
+ Keywords: sum,cli,django,wagtail
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3 :: Only
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Topic :: Software Development :: Build Tools
19
+ Classifier: Topic :: Software Development :: Code Generators
20
+ Requires-Python: >=3.12
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: click>=8.1.7
24
+ Requires-Dist: pyyaml>=6.0
25
+ Provides-Extra: gitea
26
+ Requires-Dist: httpx>=0.27.0; extra == "gitea"
27
+ Dynamic: license-file
28
+
29
+ # SUM CLI (v3.1)
30
+
31
+ [![PyPI](https://img.shields.io/pypi/v/sum-cli.svg)](https://pypi.org/project/sum-cli/)
32
+
33
+ The SUM CLI is the single control plane for deploying and managing SUM Platform client sites on staging and production servers.
34
+
35
+ ## Install
36
+
37
+ ```bash
38
+ pip install sum-cli
39
+ sum-platform --version
40
+ ```
41
+
42
+ ### With Gitea Support
43
+
44
+ If using Gitea instead of GitHub for repository hosting:
45
+
46
+ ```bash
47
+ pip install sum-cli[gitea]
48
+ ```
49
+
50
+ ## Initial Setup
51
+
52
+ Before using the CLI, configure your infrastructure settings:
53
+
54
+ ```bash
55
+ sudo sum-platform setup
56
+ ```
57
+
58
+ This interactive command creates `/etc/sum/config.yml` with your staging/production server settings.
59
+
60
+ ## Commands
61
+
62
+ | Command | Description | Requires Sudo |
63
+ |---------|-------------|---------------|
64
+ | `setup` | Configure infrastructure settings | Yes |
65
+ | `init` | Create new site at `/srv/sum/<name>/` | Yes |
66
+ | `update` | Pull updates, migrate, restart | No (staging) |
67
+ | `backup` | Database and media backup | No |
68
+ | `promote` | Deploy staging site to production | No |
69
+ | `check` | Validate project setup | No |
70
+ | `themes` | List available themes | No |
71
+
72
+ ## Creating Sites
73
+
74
+ ### With GitHub
75
+
76
+ ```bash
77
+ sudo sum-platform init acme --git-provider github --git-org acme-corp
78
+ ```
79
+
80
+ ### With Gitea
81
+
82
+ ```bash
83
+ sudo sum-platform init acme --git-provider gitea --git-org clients \
84
+ --gitea-url https://gitea.agency.com
85
+ ```
86
+
87
+ ### With Gitea (Custom SSH Port)
88
+
89
+ ```bash
90
+ sudo sum-platform init acme --git-provider gitea --git-org clients \
91
+ --gitea-url https://gitea.agency.com --gitea-ssh-port 2222
92
+ ```
93
+
94
+ ### Without Git
95
+
96
+ ```bash
97
+ sudo sum-platform init acme --no-git
98
+ ```
99
+
100
+ ### Additional Init Options
101
+
102
+ ```bash
103
+ sudo sum-platform init acme --git-provider github --git-org acme-corp \
104
+ --theme theme_a \
105
+ --profile sage-stone \
106
+ --content-path /path/to/custom/content
107
+ ```
108
+
109
+ ## Managing Sites
110
+
111
+ ```bash
112
+ # Update a deployed site (pull, migrate, restart)
113
+ sum-platform update acme
114
+
115
+ # Backup database and media
116
+ sum-platform backup acme --include-media
117
+
118
+ # Promote staging to production
119
+ sum-platform promote acme --domain acme.example.com
120
+
121
+ # Validate project setup
122
+ sum-platform check acme
123
+
124
+ # List available themes
125
+ sum-platform themes
126
+ ```
127
+
128
+ ## Configuration
129
+
130
+ ### Global Config (`/etc/sum/config.yml`)
131
+
132
+ Infrastructure settings only. Created via `sum-platform setup`.
133
+
134
+ ```yaml
135
+ agency:
136
+ name: Your Agency Name
137
+
138
+ staging:
139
+ server: staging.example.com
140
+ domain_pattern: "{slug}.staging.example.com"
141
+ base_dir: /srv/sum
142
+
143
+ production:
144
+ server: prod.example.com
145
+ ssh_host: 10.0.0.1
146
+ base_dir: /srv/sum
147
+
148
+ templates:
149
+ dir: /opt/your-ops/infra
150
+ systemd: systemd/sum-site-gunicorn.service.template
151
+ caddy: caddy/Caddyfile.template
152
+
153
+ defaults:
154
+ theme: theme_a
155
+ seed_profile: starter
156
+ deploy_user: deploy
157
+ postgres_port: 5432
158
+ ```
159
+
160
+ ### Site Config (`/srv/sum/<site>/.sum/config.yml`)
161
+
162
+ Per-site configuration. Auto-created when you run `init`.
163
+
164
+ **GitHub site:**
165
+ ```yaml
166
+ site:
167
+ slug: acme
168
+ theme: theme_a
169
+ created: 2026-02-03T14:30:00Z
170
+
171
+ git:
172
+ provider: github
173
+ org: acme-corp
174
+ ```
175
+
176
+ **Gitea site:**
177
+ ```yaml
178
+ site:
179
+ slug: acme
180
+ theme: theme_a
181
+ created: 2026-02-03T14:30:00Z
182
+
183
+ git:
184
+ provider: gitea
185
+ org: clients
186
+ url: https://gitea.agency.com
187
+ ssh_port: 2222
188
+ token_env: GITEA_TOKEN
189
+ ```
190
+
191
+ **No-git site:**
192
+ ```yaml
193
+ site:
194
+ slug: acme
195
+ theme: theme_a
196
+ created: 2026-02-03T14:30:00Z
197
+
198
+ git: null
199
+ ```
200
+
201
+ ## Git Provider Setup
202
+
203
+ ### GitHub
204
+
205
+ Requires the GitHub CLI (`gh`) to be installed and authenticated:
206
+
207
+ ```bash
208
+ gh auth login
209
+ ```
210
+
211
+ ### Gitea
212
+
213
+ Set the API token environment variable:
214
+
215
+ ```bash
216
+ export GITEA_TOKEN=your-token-here
217
+ ```
218
+
219
+ Or use a custom environment variable name:
220
+
221
+ ```bash
222
+ sudo sum-platform init acme --git-provider gitea --git-org clients \
223
+ --gitea-url https://gitea.agency.com --gitea-token-env MY_GITEA_TOKEN
224
+ ```
225
+
226
+ ## Development Install (monorepo)
227
+
228
+ ```bash
229
+ pip install -e ./cli
230
+ ```
@@ -1,8 +1,9 @@
1
1
  sum/__init__.py,sha256=4Hqvsw_wQrS-HCr8d7k9lsTk-whfS-XuLIja6cwe_K8,27
2
- sum/cli.py,sha256=NxUiTZMlsfMonKBTXDvZJUISiZ1kZLzBuR_tAoLTc6c,952
2
+ sum/cli.py,sha256=iYsjVSOBXgWpAvYW_DBbtuVAh3AJMHlTBttkRr21FGQ,986
3
3
  sum/config.py,sha256=LucWpecznyXfYGKFfMzlYc_YGgQz6YYgEYss1ohqtU0,1500
4
4
  sum/exceptions.py,sha256=bcTxqy_MXysc3-_CtLITuA0mea3PJv2gSmm6Opdx038,1172
5
- sum/system_config.py,sha256=9e7qRqqG5qnj-fM7lgiHl4hJ7Rx5ZCCQ5XKFg22l_gM,10358
5
+ sum/site_config.py,sha256=sPCICpXvT-X4-jwVo90ZMxNmLbQRcQ5sPouvlKXwJP8,3890
6
+ sum/system_config.py,sha256=8gej6_7Wlhip0OSvaetm_WKYfM45Z40et47WhO5_ruE,8874
6
7
  sum/themes_registry.py,sha256=86SJjNHne2t24G5x3FQglL2toqo06-WBGujV598d4w4,5565
7
8
  sum/boilerplate/.env.example,sha256=Y3GajiSPEQA3_uCFxzUwWwJEataGgZRySktb6UgaQD8,5038
8
9
  sum/boilerplate/.gitignore,sha256=ko-akHlkIhaS9vqz78zAlwMfp0W5z1TE52dBmoFdSu8,397
@@ -36,37 +37,36 @@ sum/boilerplate/static/client/.gitkeep,sha256=oljA0ouMsVDR4goUYUlxPrm_uxOCM7fAYo
36
37
  sum/boilerplate/templates/overrides/.gitkeep,sha256=OsCO3X-nPRZHK3_hxkn8B1KZRVmwaXwUfJbHD8ywk90,174
37
38
  sum/boilerplate/tests/__init__.py,sha256=h4W89xW2hAKb5WX3DGURe7gmvJbsv2n2aG5hyYvv07A,46
38
39
  sum/boilerplate/tests/test_health.py,sha256=cSptlBMzz8ppTEW0xHSiTGKdZVCHkGI-0HUTj6U0IhA,1794
39
- sum/commands/__init__.py,sha256=2GDI4K46anO4InrXQwZ5iqmRM3vdhi0SUnSk9b2MQbQ,262
40
+ sum/commands/__init__.py,sha256=xu_gWw3cG6n9NYUof3hMlZQwfScLjaJL8V4L9E1xmlM,268
40
41
  sum/commands/backup.py,sha256=2_qhP5yHUSXxif0M1MgVn78dHF7T6GDlBmuw07ZtrX0,9071
41
42
  sum/commands/check.py,sha256=OQhHMtnF54ojySYeveToIAB-YvpRnAFuHQuCLZRNT-s,4332
42
- sum/commands/init.py,sha256=LmpfNkN9vWro2-TulLNw_UiX5tcZ1DUfaqRTXbNbMI0,7477
43
- sum/commands/promote.py,sha256=SCoJgSYe40qJ8CQSymUktNoXHfJXrHeH8EONE9FcNyk,25436
44
- sum/commands/run.py,sha256=9EwL51_GaIW7Ksy9AxKxjK7fKpJtjjBUop0gpxXHg-U,2953
43
+ sum/commands/init.py,sha256=2wM3ZbmmXK-y8mpOA_RU-N3I-wjmWJ1VXq9SWHMzADw,10303
44
+ sum/commands/promote.py,sha256=1BonaU_QyMRMaCPlkV9NlMPsEDItZsYV0_F9gzVxOJc,25957
45
+ sum/commands/setup.py,sha256=LG_zt8Nxheaac-Fx3tPg62J40e_A_zFSnhBV7kH_300,4509
45
46
  sum/commands/themes.py,sha256=DrPD0R9kig9DeyTXFPvsDL12qGhRFs_06N5g0BAPM3k,1307
46
47
  sum/commands/update.py,sha256=AXYa0BugWuYWJpj0vx5N5Ni0D0ZS_NsZeUhk3v3HwLc,9157
47
- sum/docs/USER_GUIDE.md,sha256=nRO1vH6SxhPnpjaUcNxRJvIDIaWWMdyEmiK91WLWVss,14698
48
48
  sum/setup/__init__.py,sha256=dm8Qq819REBxcZxOYQ6sjYOGAYdnMyZHMR8PFgMrNu0,457
49
49
  sum/setup/auth.py,sha256=kBBLZKZjt8EUgK4_UV2QFmlQ0Z2RbekCQzkSBYxMJVA,5899
50
50
  sum/setup/database.py,sha256=gsMa8aqxyfOBcJ1u13hbUPYSVMpFbP-S2gesVOK1UpE,1630
51
51
  sum/setup/deps.py,sha256=snciWZg7TtFlullkxZGs2Acjx1jzrbiG8wFy2rb4Vw8,3018
52
- sum/setup/git_ops.py,sha256=Kqg8DrePhRWfLFWVmvrP_8AP8LulP3ho9CRmrBvt4EM,14482
52
+ sum/setup/git_ops.py,sha256=RTbgFoJd0Y_N2c_DIsFLL0bvySD771zpLS-Ir5ZsV5M,14858
53
53
  sum/setup/infrastructure.py,sha256=lI2kI_odt4JyF6wa0uAmysozGSyDmD6X70rROcNOdJ8,18065
54
- sum/setup/orchestrator.py,sha256=MThyN6DvXyi-cI6icgeFJ3Plt0AXqOVQ6ECEfpP3ACM,12338
54
+ sum/setup/orchestrator.py,sha256=NkJCvsGbdPEridQ2XO7AbAFT1tDJNLca_6HZrp0UM5I,12339
55
55
  sum/setup/remote_themes.py,sha256=xc5sY-QwaIiLsP_LqSRE57Kk1hWre1SKxflzhu7cx0c,11685
56
- sum/setup/scaffold.py,sha256=hp3BzypaBHIGk8zN2STHDZ37BpD283eW0MZc4XnWBsc,17360
56
+ sum/setup/scaffold.py,sha256=MIuS2hBjBbtTobLCG1YXpokn4OVTYCkeEhF2AD_VLbw,17183
57
57
  sum/setup/seed.py,sha256=db_5lEVfYbH51h2GuJjWS9lTjUzg88jQF-AodUS-uFQ,3086
58
- sum/setup/site_orchestrator.py,sha256=iRTkBYdBWJ03DjTXzO0Y6HqHACEry27LP9VR-rpsn8M,16553
58
+ sum/setup/site_orchestrator.py,sha256=YeCXkezDb0HiNiaLVkHwvLixxU6CZmtWLM4bCxCoDUo,17486
59
59
  sum/setup/venv.py,sha256=YttFbI-EZY0w5TFCeAwwO-OFQ1ZviWwa5PnWXXP3Q9s,3150
60
60
  sum/utils/__init__.py,sha256=acO546Z2ktZ5TuGcPzR7xMwCFUJ7VIOjzuwh5qKqcIA,630
61
61
  sum/utils/django.py,sha256=rqQj6Bwcw_8ihm_tPx6U1AcEtp3kXOVtzfLxC2IN_Yg,3280
62
- sum/utils/environment.py,sha256=ek7dRYJyg0z1dHgbZCiEWh6cKxIKUeIXdoDYxn-shao,2508
62
+ sum/utils/environment.py,sha256=Vm9nIeBkKztNQuKwNpa9h0nEyhyD7T5UeVlcHdACixs,2509
63
63
  sum/utils/output.py,sha256=jeFHKX1chjJowhNH3NadlNZp8rUvRuuizdwrdDoW49c,2379
64
64
  sum/utils/project.py,sha256=27CveU5U0QhgQK_tuI6cGCN9KUskpdwv1_q8t5R_QFY,3375
65
65
  sum/utils/prompts.py,sha256=iHDMWpMOj1_xbDE0XB3qF2yw4-EDPG8YbG-uGMXRmnI,1153
66
- sum/utils/validation.py,sha256=15PNw1lhrRSnyH7BaN_N44qI4rXWx4i-44ps-0fylYU,11533
67
- sum_cli-3.0.0.dist-info/licenses/LICENSE,sha256=RSHp5Au98mOtEsT8N4WMxqxsa-AtcVQCfr3SqoffQoU,1519
68
- sum_cli-3.0.0.dist-info/METADATA,sha256=7gtkSOHAUzk7wjxjmcA7d0uIiN0qpOjAlswiuF31wsY,3503
69
- sum_cli-3.0.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
70
- sum_cli-3.0.0.dist-info/entry_points.txt,sha256=cp92-F73mckmgEqj6RKxJ2SII7JfK26A9Kx_LLZElGc,45
71
- sum_cli-3.0.0.dist-info/top_level.txt,sha256=xfyDwB6SQERSuYZSfSORQMz5pIuI4MJo-_OMLhQp6ck,4
72
- sum_cli-3.0.0.dist-info/RECORD,,
66
+ sum/utils/validation.py,sha256=6kTMpPt1K0ZxAj24qkvV-fxdMnmCQqLNI42uHkxd6lM,11534
67
+ sum_cli-3.1.0.dist-info/licenses/LICENSE,sha256=RSHp5Au98mOtEsT8N4WMxqxsa-AtcVQCfr3SqoffQoU,1519
68
+ sum_cli-3.1.0.dist-info/METADATA,sha256=36oFrddsZ1sn2-rteo-zjlH3del_1HK0SNfSbUhVQ_Q,4966
69
+ sum_cli-3.1.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
70
+ sum_cli-3.1.0.dist-info/entry_points.txt,sha256=cp92-F73mckmgEqj6RKxJ2SII7JfK26A9Kx_LLZElGc,45
71
+ sum_cli-3.1.0.dist-info/top_level.txt,sha256=xfyDwB6SQERSuYZSfSORQMz5pIuI4MJo-_OMLhQp6ck,4
72
+ sum_cli-3.1.0.dist-info/RECORD,,