create-pywire-app 0.1.3__tar.gz → 0.1.4__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.
- {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/PKG-INFO +1 -1
- {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/pyproject.toml +8 -2
- create_pywire_app-0.1.4/src/create_pywire_app/__init__.py +8 -0
- create_pywire_app-0.1.4/src/create_pywire_app/_version.py +34 -0
- {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/main.py +101 -5
- {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/blog/explicit/about.wire +2 -1
- {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/blog/explicit/blog-posts.wire +5 -11
- {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/blog/explicit/home.wire +5 -2
- {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/blog/path-based/index.wire +5 -2
- {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/blog/path-based/posts_index.wire +5 -2
- {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/blog/path-based/posts_slug.wire +3 -9
- {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/common/__error__.wire +1 -2
- {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/counter/explicit/home.wire +6 -4
- {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/counter/path-based/index.wire +6 -4
- {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/saas/explicit/auth-layout.wire.j2 +2 -1
- {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/saas/explicit/dashboard-pages.wire +2 -1
- {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/saas/explicit/landing.wire +2 -1
- {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/saas/explicit/login.wire +2 -1
- {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/saas/explicit/pricing.wire +1 -1
- {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/saas/path-based/dashboard__layout__.wire.j2 +2 -1
- {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/saas/path-based/dashboard_index.wire +0 -1
- {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/saas/path-based/dashboard_settings.wire +0 -1
- {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/saas/path-based/index.wire +0 -1
- {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/saas/path-based/login.wire +0 -1
- {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/saas/path-based/pricing.wire +2 -1
- create_pywire_app-0.1.3/src/create_pywire_app/__init__.py +0 -0
- {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/.gitignore +0 -0
- {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/LICENSE +0 -0
- {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/README.md +0 -0
- {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/blog/explicit/layout.wire.j2 +0 -0
- {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/blog/path-based/__layout__.wire.j2 +0 -0
- {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/blog/path-based/posts__layout__.wire.j2 +0 -0
- {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/common/.gitignore +0 -0
- {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/common/Dockerfile +0 -0
- {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/common/README.md.j2 +0 -0
- {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/common/extensions.json +0 -0
- {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/common/main-explicit.py.j2 +0 -0
- {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/common/main-path.py.j2 +0 -0
- {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/common/pyproject.toml.j2 +0 -0
- {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/common/render.yaml.j2 +0 -0
- {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/counter/explicit/layout.wire.j2 +0 -0
- {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/counter/path-based/__layout__.wire.j2 +0 -0
- {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/saas/explicit/public-layout.wire.j2 +0 -0
- {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/saas/models.py +0 -0
- {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/saas/path-based/__layout__.wire.j2 +0 -0
- {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/tests/test_smoke.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "create-pywire-app"
|
|
3
|
-
|
|
3
|
+
dynamic = ["version"]
|
|
4
4
|
description = "Init wizard for new pywire projects"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.11"
|
|
@@ -14,7 +14,7 @@ dependencies = [
|
|
|
14
14
|
create-pywire-app = "create_pywire_app.main:main"
|
|
15
15
|
|
|
16
16
|
[build-system]
|
|
17
|
-
requires = ["hatchling"]
|
|
17
|
+
requires = ["hatchling", "hatch-vcs"]
|
|
18
18
|
build-backend = "hatchling.build"
|
|
19
19
|
|
|
20
20
|
|
|
@@ -44,3 +44,9 @@ include = [
|
|
|
44
44
|
exclude = [
|
|
45
45
|
"src/create_pywire_app/templates",
|
|
46
46
|
]
|
|
47
|
+
|
|
48
|
+
[tool.hatch.version]
|
|
49
|
+
source = "vcs"
|
|
50
|
+
|
|
51
|
+
[tool.hatch.build.hooks.vcs]
|
|
52
|
+
version-file = "src/create_pywire_app/_version.py"
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# file generated by setuptools-scm
|
|
2
|
+
# don't change, don't track in version control
|
|
3
|
+
|
|
4
|
+
__all__ = [
|
|
5
|
+
"__version__",
|
|
6
|
+
"__version_tuple__",
|
|
7
|
+
"version",
|
|
8
|
+
"version_tuple",
|
|
9
|
+
"__commit_id__",
|
|
10
|
+
"commit_id",
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
TYPE_CHECKING = False
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from typing import Tuple
|
|
16
|
+
from typing import Union
|
|
17
|
+
|
|
18
|
+
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
|
19
|
+
COMMIT_ID = Union[str, None]
|
|
20
|
+
else:
|
|
21
|
+
VERSION_TUPLE = object
|
|
22
|
+
COMMIT_ID = object
|
|
23
|
+
|
|
24
|
+
version: str
|
|
25
|
+
__version__: str
|
|
26
|
+
__version_tuple__: VERSION_TUPLE
|
|
27
|
+
version_tuple: VERSION_TUPLE
|
|
28
|
+
commit_id: COMMIT_ID
|
|
29
|
+
__commit_id__: COMMIT_ID
|
|
30
|
+
|
|
31
|
+
__version__ = version = '0.1.4'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 1, 4)
|
|
33
|
+
|
|
34
|
+
__commit_id__ = commit_id = None
|
|
@@ -8,11 +8,14 @@ from pathlib import Path
|
|
|
8
8
|
from typing import Any, Dict, List, Optional
|
|
9
9
|
|
|
10
10
|
import questionary
|
|
11
|
+
import tomllib
|
|
11
12
|
from jinja2 import Environment, PackageLoader, select_autoescape
|
|
12
13
|
from rich.console import Console
|
|
13
14
|
from rich.markdown import Markdown
|
|
14
15
|
from rich.panel import Panel
|
|
15
16
|
|
|
17
|
+
from create_pywire_app import __version__
|
|
18
|
+
|
|
16
19
|
console = Console()
|
|
17
20
|
|
|
18
21
|
LOGO = r"""
|
|
@@ -27,11 +30,56 @@ LOGO = r"""
|
|
|
27
30
|
"""
|
|
28
31
|
|
|
29
32
|
|
|
33
|
+
def get_local_version(path: Path) -> Optional[str]:
|
|
34
|
+
"""Try to read version from a local pyproject.toml file."""
|
|
35
|
+
try:
|
|
36
|
+
if path.exists():
|
|
37
|
+
with open(path, "rb") as f:
|
|
38
|
+
data = tomllib.load(f)
|
|
39
|
+
return data.get("project", {}).get("version")
|
|
40
|
+
except Exception:
|
|
41
|
+
pass
|
|
42
|
+
return None
|
|
43
|
+
|
|
44
|
+
|
|
30
45
|
def get_version() -> str:
|
|
46
|
+
return __version__
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def resolve_pywire_version(pywire_dep: str) -> Optional[str]:
|
|
50
|
+
"""Resolve the actual pywire version that will be installed.
|
|
51
|
+
|
|
52
|
+
Args:
|
|
53
|
+
pywire_dep: Dependency spec (e.g., 'pywire', 'pywire==0.1.4', 'pywire @ /path')
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
Resolved version string or None if resolution fails
|
|
57
|
+
"""
|
|
58
|
+
# For local paths, we can't resolve via uv pip compile
|
|
59
|
+
if "@" in pywire_dep:
|
|
60
|
+
return None
|
|
61
|
+
|
|
31
62
|
try:
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
63
|
+
# Use uv pip compile to resolve the version without installing
|
|
64
|
+
process = subprocess.run(
|
|
65
|
+
["uv", "pip", "compile", "-", "--quiet"],
|
|
66
|
+
input=pywire_dep,
|
|
67
|
+
text=True,
|
|
68
|
+
capture_output=True,
|
|
69
|
+
check=True,
|
|
70
|
+
timeout=10,
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
# Parse the output for pywire==<version>
|
|
74
|
+
import re
|
|
75
|
+
match = re.search(r'pywire==([^\s]+)', process.stdout)
|
|
76
|
+
if match:
|
|
77
|
+
return match.group(1)
|
|
78
|
+
|
|
79
|
+
except (subprocess.CalledProcessError, subprocess.TimeoutExpired, FileNotFoundError):
|
|
80
|
+
pass
|
|
81
|
+
|
|
82
|
+
return None
|
|
35
83
|
|
|
36
84
|
|
|
37
85
|
class TemplateRenderer:
|
|
@@ -277,6 +325,19 @@ class ProjectGenerator:
|
|
|
277
325
|
|
|
278
326
|
|
|
279
327
|
def main():
|
|
328
|
+
# Fix for macOS when running with redirected stdin (e.g. via pipe)
|
|
329
|
+
# KqueueSelector fails with /dev/tty on macOS, so we force SelectSelector.
|
|
330
|
+
if sys.platform == "darwin":
|
|
331
|
+
import asyncio
|
|
332
|
+
import selectors
|
|
333
|
+
|
|
334
|
+
class MacOSEventLoopPolicy(asyncio.DefaultEventLoopPolicy):
|
|
335
|
+
def new_event_loop(self):
|
|
336
|
+
selector = selectors.SelectSelector()
|
|
337
|
+
return asyncio.SelectorEventLoop(selector)
|
|
338
|
+
|
|
339
|
+
asyncio.set_event_loop_policy(MacOSEventLoopPolicy())
|
|
340
|
+
|
|
280
341
|
console.clear()
|
|
281
342
|
|
|
282
343
|
# Parse arguments
|
|
@@ -291,16 +352,51 @@ def main():
|
|
|
291
352
|
|
|
292
353
|
if use_local:
|
|
293
354
|
pywire_dep = "pywire @ /Users/rholmdahl/projects/pywire-workspace/pywire"
|
|
294
|
-
#
|
|
355
|
+
# Try to resolve actual local version for display
|
|
356
|
+
# In a workspace structure, we might be in src/create_pywire_app, so up 3 levels is create-pywire-app, then up 1 is workspace
|
|
357
|
+
# actually let's try a safer relative resolution based on known structure
|
|
358
|
+
# /Users/rholmdahl/projects/pywire-workspace/create-pywire-app/src/create_pywire_app/main.py
|
|
359
|
+
# -> create-pywire-app (repo root) = parents[2]
|
|
360
|
+
# -> pywire-workspace = parents[3]
|
|
361
|
+
workspace_root = Path(__file__).resolve().parents[3]
|
|
362
|
+
local_pywire_path = workspace_root / "pywire"
|
|
363
|
+
|
|
364
|
+
# Try reading _version.py first (generated by hatch-vcs)
|
|
365
|
+
local_pywire_version_file = local_pywire_path / "src" / "pywire" / "_version.py"
|
|
366
|
+
pywire_version_display = "Local (Source)"
|
|
367
|
+
|
|
368
|
+
if local_pywire_version_file.exists():
|
|
369
|
+
# Basic regex search for version string to avoid importing it
|
|
370
|
+
import re
|
|
371
|
+
content = local_pywire_version_file.read_text()
|
|
372
|
+
match = re.search(r'version = ["\']([^"\']+)["\']', content)
|
|
373
|
+
if match:
|
|
374
|
+
pywire_version_display = f"{match.group(1)} (Local)"
|
|
375
|
+
|
|
376
|
+
if pywire_version_display == "Local (Source)":
|
|
377
|
+
# Fallback to toml if needed, though with hatch-vcs pyproject.toml won't have it.
|
|
378
|
+
# but check anyway? hatch-vcs usually cleans it.
|
|
379
|
+
# If completely failing, just stick with "Local (Source)"
|
|
380
|
+
pass
|
|
381
|
+
|
|
295
382
|
elif args.pywire_version:
|
|
296
383
|
pywire_dep = f"pywire=={args.pywire_version}"
|
|
384
|
+
pywire_version_display = args.pywire_version
|
|
297
385
|
else:
|
|
298
386
|
pywire_dep = "pywire" # Latest
|
|
387
|
+
pywire_version_display = "Latest"
|
|
388
|
+
|
|
389
|
+
# Resolve the actual version if not local
|
|
390
|
+
if not use_local and pywire_version_display == "Latest":
|
|
391
|
+
with console.status("[dim]Resolving version...", spinner="dots"):
|
|
392
|
+
resolved_version = resolve_pywire_version(pywire_dep)
|
|
393
|
+
if resolved_version:
|
|
394
|
+
pywire_version_display = resolved_version
|
|
299
395
|
|
|
300
396
|
tool_version = get_version()
|
|
301
397
|
|
|
302
398
|
console.print(LOGO)
|
|
303
|
-
console.print(f"[dim]v{tool_version} •
|
|
399
|
+
console.print(f"[dim]v{tool_version} • PyWire {pywire_version_display}[/dim]\n")
|
|
304
400
|
|
|
305
401
|
if use_local:
|
|
306
402
|
console.print("[yellow]WARNING: Using local pywire dependency[/yellow]")
|
|
@@ -31,15 +31,9 @@ if path.detail:
|
|
|
31
31
|
"select title, body from posts where slug = ?",
|
|
32
32
|
(slug,),
|
|
33
33
|
).fetchone()
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
post_body_html = markdown.markdown(post["body"])
|
|
38
|
-
else:
|
|
39
|
-
post_title = "Post not found"
|
|
40
|
-
post_body_html = "<p>We couldn't find that post.</p>"
|
|
41
|
-
|
|
42
|
-
---html---
|
|
34
|
+
|
|
35
|
+
--- html ---
|
|
36
|
+
|
|
43
37
|
<main>
|
|
44
38
|
<!-- List view: /posts -->
|
|
45
39
|
<section $if={path.list}>
|
|
@@ -54,8 +48,8 @@ if path.detail:
|
|
|
54
48
|
|
|
55
49
|
<!-- Detail view: /posts/{slug} -->
|
|
56
50
|
<article $if={path.detail}>
|
|
57
|
-
<h1>{post_title}</h1>
|
|
58
|
-
<div>{
|
|
51
|
+
<h1>{post_title if post else "Post not found"}</h1>
|
|
52
|
+
<div>{!html markdown.markdown(post["body"]) if post else "<p>We couldn't find that post.</p>"}</div>
|
|
59
53
|
<p><a href="/posts">← Back to all posts</a></p>
|
|
60
54
|
</article>
|
|
61
55
|
</main>
|
|
@@ -48,11 +48,14 @@ posts = cursor.execute(
|
|
|
48
48
|
"select slug, title from posts order by id desc"
|
|
49
49
|
).fetchall()
|
|
50
50
|
|
|
51
|
-
---html---
|
|
51
|
+
--- html ---
|
|
52
|
+
|
|
52
53
|
<section>
|
|
53
54
|
<h1>Blog + Portfolio (Explicit)</h1>
|
|
54
55
|
<p>Routes are declared with <code>!path</code> and files are named semantically.</p>
|
|
55
56
|
<ul>
|
|
56
|
-
|
|
57
|
+
<li $for={post in posts} $key={post["slug"]}>
|
|
58
|
+
<a href="/posts/{row["slug"]}">{row["title"]}</a>
|
|
59
|
+
</li>
|
|
57
60
|
</ul>
|
|
58
61
|
</section>
|
|
@@ -45,11 +45,14 @@ posts = cursor.execute(
|
|
|
45
45
|
"select slug, title from posts order by id desc"
|
|
46
46
|
).fetchall()
|
|
47
47
|
|
|
48
|
-
---html---
|
|
48
|
+
--- html ---
|
|
49
|
+
|
|
49
50
|
<section>
|
|
50
51
|
<h1>Blog + Portfolio</h1>
|
|
51
52
|
<p>Markdown posts backed by SQLite.</p>
|
|
52
53
|
<ul>
|
|
53
|
-
|
|
54
|
+
<li $for={post in posts} $key={post["slug"]}>
|
|
55
|
+
<a href="/posts/{row["slug"]}">{row["title"]}</a>
|
|
56
|
+
</li>
|
|
54
57
|
</ul>
|
|
55
58
|
</section>
|
|
@@ -12,10 +12,13 @@ posts = cursor.execute(
|
|
|
12
12
|
"select slug, title from posts order by id desc"
|
|
13
13
|
).fetchall()
|
|
14
14
|
|
|
15
|
-
---html---
|
|
15
|
+
--- html ---
|
|
16
|
+
|
|
16
17
|
<section>
|
|
17
18
|
<h1>All posts</h1>
|
|
18
19
|
<ul>
|
|
19
|
-
|
|
20
|
+
<li $for={post in posts} $key={post["slug"]}>
|
|
21
|
+
<a href="/posts/{row["slug"]}">{row["title"]}</a>
|
|
22
|
+
</li>
|
|
20
23
|
</ul>
|
|
21
24
|
</section>
|
|
@@ -14,15 +14,9 @@ post = cursor.execute(
|
|
|
14
14
|
(slug,),
|
|
15
15
|
).fetchone()
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
title = post["title"]
|
|
19
|
-
body_html = markdown.markdown(post["body"])
|
|
20
|
-
else:
|
|
21
|
-
title = "Post not found"
|
|
22
|
-
body_html = "<p>We couldn't find that post.</p>"
|
|
17
|
+
--- html ---
|
|
23
18
|
|
|
24
|
-
---html---
|
|
25
19
|
<article>
|
|
26
|
-
<h1>{title}</h1>
|
|
27
|
-
<div>{
|
|
20
|
+
<h1>{post["title"] if post else "Post not found"}</h1>
|
|
21
|
+
<div>{!html markdown.markdown(post["body"]) if post else "<p>We couldn't find that post.</p>"}</div>
|
|
28
22
|
</article>
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
!path "/"
|
|
2
2
|
!layout "layout.wire"
|
|
3
3
|
|
|
4
|
-
count = 0
|
|
5
|
-
|
|
4
|
+
count = wire(0)
|
|
5
|
+
|
|
6
|
+
--- html ---
|
|
7
|
+
|
|
6
8
|
<div class="container">
|
|
7
9
|
<h1>Counter (Explicit Routing)</h1>
|
|
8
10
|
<p>This page uses explicit routing via <code>!path</code>.</p>
|
|
9
|
-
<p>Count is: {count}</p>
|
|
10
|
-
<button @click={count += 1}>Increment</button>
|
|
11
|
+
<p>Count is: {count.value}</p>
|
|
12
|
+
<button @click={count.value += 1}>Increment</button>
|
|
11
13
|
</div>
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
count = 0
|
|
2
|
-
|
|
1
|
+
count = wire(0)
|
|
2
|
+
|
|
3
|
+
--- html ---
|
|
4
|
+
|
|
3
5
|
<div class="container">
|
|
4
6
|
<h1>Counter</h1>
|
|
5
7
|
<p>Edit <code>pages/index.wire</code> to watch hot reload in action.</p>
|
|
6
|
-
<p>Count is: {count}</p>
|
|
7
|
-
<button @click={count += 1}>Increment</button>
|
|
8
|
+
<p>Count is: {count.value}</p>
|
|
9
|
+
<button @click={count.value += 1}>Increment</button>
|
|
8
10
|
</div>
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/saas/models.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|