plain.dev 0.35.0__tar.gz → 0.37.0__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.
- {plain_dev-0.35.0 → plain_dev-0.37.0}/PKG-INFO +3 -3
- {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/CHANGELOG.md +21 -0
- {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/README.md +2 -2
- plain_dev-0.37.0/plain/dev/alias.py +152 -0
- {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/cli.py +4 -1
- {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/core.py +3 -1
- {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/precommit/cli.py +9 -2
- {plain_dev-0.35.0 → plain_dev-0.37.0}/pyproject.toml +1 -1
- {plain_dev-0.35.0 → plain_dev-0.37.0}/.gitignore +0 -0
- {plain_dev-0.35.0 → plain_dev-0.37.0}/LICENSE +0 -0
- {plain_dev-0.35.0 → plain_dev-0.37.0}/README.md +0 -0
- {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/__init__.py +0 -0
- {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/contribute/README.md +0 -0
- {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/contribute/__init__.py +0 -0
- {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/contribute/cli.py +0 -0
- {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/debug.py +0 -0
- {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/default_settings.py +0 -0
- {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/entrypoints.py +0 -0
- {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/gunicorn_logging.json +0 -0
- {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/mkcert.py +0 -0
- {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/pdb.py +0 -0
- {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/poncho/__init__.py +0 -0
- {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/poncho/color.py +0 -0
- {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/poncho/compat.py +0 -0
- {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/poncho/manager.py +0 -0
- {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/poncho/printer.py +0 -0
- {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/poncho/process.py +0 -0
- {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/precommit/__init__.py +0 -0
- {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/process.py +0 -0
- {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/services.py +0 -0
- {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/utils.py +0 -0
- {plain_dev-0.35.0 → plain_dev-0.37.0}/tests/settings.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: plain.dev
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.37.0
|
4
4
|
Summary: A single command that runs everything you need for local development.
|
5
5
|
Author-email: Dave Gaeddert <dave.gaeddert@dropseed.dev>
|
6
6
|
License-Expression: BSD-3-Clause
|
@@ -56,7 +56,7 @@ This will:
|
|
56
56
|
The `plain dev` command does several things:
|
57
57
|
|
58
58
|
- Sets `PLAIN_CSRF_TRUSTED_ORIGINS` to localhost by default
|
59
|
-
- Runs `plain preflight` to check for any issues
|
59
|
+
- Runs `plain preflight check` to check for any issues
|
60
60
|
- Executes any pending model migrations
|
61
61
|
- Starts `gunicorn` with `--reload`
|
62
62
|
- Serves HTTPS on port 8443 by default (uses the next free port if 8443 is taken and no port is specified)
|
@@ -113,7 +113,7 @@ Runs:
|
|
113
113
|
- Custom commands defined in `pyproject.toml` at `tool.plain.pre-commit.run`
|
114
114
|
- `plain code check`, if [`plain.code`](https://plainframework.com/docs/plain-code/plain/code/) is installed
|
115
115
|
- `uv lock --locked`, if using uv
|
116
|
-
- `plain preflight
|
116
|
+
- `plain preflight check`
|
117
117
|
- `plain migrate --check`
|
118
118
|
- `plain makemigrations --dry-run --check`
|
119
119
|
- `plain build`
|
@@ -1,5 +1,26 @@
|
|
1
1
|
# plain-dev changelog
|
2
2
|
|
3
|
+
## [0.37.0](https://github.com/dropseed/plain/releases/plain-dev@0.37.0) (2025-09-29)
|
4
|
+
|
5
|
+
### What's changed
|
6
|
+
|
7
|
+
- Added a `p` alias prompt that suggests setting up a shell alias for `uv run plain` to make command execution faster ([d913b44](https://github.com/dropseed/plain/commit/d913b44fab), [6632529](https://github.com/dropseed/plain/commit/663252925b))
|
8
|
+
|
9
|
+
### Upgrade instructions
|
10
|
+
|
11
|
+
- No changes required
|
12
|
+
|
13
|
+
## [0.36.0](https://github.com/dropseed/plain/releases/plain-dev@0.36.0) (2025-09-25)
|
14
|
+
|
15
|
+
### What's changed
|
16
|
+
|
17
|
+
- The `plain preflight` command has been updated to use `plain preflight check` with a `--quiet` flag for cleaner output in development workflows ([b0b610d](https://github.com/dropseed/plain/commit/b0b610d461))
|
18
|
+
- Pre-commit hooks now use the updated preflight check syntax ([b0b610d](https://github.com/dropseed/plain/commit/b0b610d461))
|
19
|
+
|
20
|
+
### Upgrade instructions
|
21
|
+
|
22
|
+
- No changes required
|
23
|
+
|
3
24
|
## [0.35.0](https://github.com/dropseed/plain/releases/plain-dev@0.35.0) (2025-09-22)
|
4
25
|
|
5
26
|
### What's changed
|
@@ -39,7 +39,7 @@ This will:
|
|
39
39
|
The `plain dev` command does several things:
|
40
40
|
|
41
41
|
- Sets `PLAIN_CSRF_TRUSTED_ORIGINS` to localhost by default
|
42
|
-
- Runs `plain preflight` to check for any issues
|
42
|
+
- Runs `plain preflight check` to check for any issues
|
43
43
|
- Executes any pending model migrations
|
44
44
|
- Starts `gunicorn` with `--reload`
|
45
45
|
- Serves HTTPS on port 8443 by default (uses the next free port if 8443 is taken and no port is specified)
|
@@ -96,7 +96,7 @@ Runs:
|
|
96
96
|
- Custom commands defined in `pyproject.toml` at `tool.plain.pre-commit.run`
|
97
97
|
- `plain code check`, if [`plain.code`](https://plainframework.com/docs/plain-code/plain/code/) is installed
|
98
98
|
- `uv lock --locked`, if using uv
|
99
|
-
- `plain preflight
|
99
|
+
- `plain preflight check`
|
100
100
|
- `plain migrate --check`
|
101
101
|
- `plain makemigrations --dry-run --check`
|
102
102
|
- `plain build`
|
@@ -0,0 +1,152 @@
|
|
1
|
+
import os
|
2
|
+
import subprocess
|
3
|
+
import sys
|
4
|
+
from functools import cached_property
|
5
|
+
from pathlib import Path
|
6
|
+
|
7
|
+
import click
|
8
|
+
|
9
|
+
|
10
|
+
class AliasManager:
|
11
|
+
"""Manages the 'p' alias for 'uv run plain'."""
|
12
|
+
|
13
|
+
MARKER_FILE = Path.home() / ".plain" / "dev" / ".alias_prompted"
|
14
|
+
ALIAS_COMMAND = "uv run plain"
|
15
|
+
ALIAS_NAME = "p"
|
16
|
+
|
17
|
+
@cached_property
|
18
|
+
def shell(self):
|
19
|
+
"""Detect the current shell."""
|
20
|
+
shell = os.environ.get("SHELL", "")
|
21
|
+
if "zsh" in shell:
|
22
|
+
return "zsh"
|
23
|
+
elif "bash" in shell:
|
24
|
+
return "bash"
|
25
|
+
elif "fish" in shell:
|
26
|
+
return "fish"
|
27
|
+
return None
|
28
|
+
|
29
|
+
@cached_property
|
30
|
+
def shell_config_file(self):
|
31
|
+
"""Get the appropriate shell configuration file."""
|
32
|
+
home = Path.home()
|
33
|
+
|
34
|
+
if self.shell == "zsh":
|
35
|
+
return home / ".zshrc"
|
36
|
+
elif self.shell == "bash":
|
37
|
+
# Check for .bash_aliases first (Ubuntu/Debian convention)
|
38
|
+
if (home / ".bash_aliases").exists():
|
39
|
+
return home / ".bash_aliases"
|
40
|
+
return home / ".bashrc"
|
41
|
+
elif self.shell == "fish":
|
42
|
+
return home / ".config" / "fish" / "config.fish"
|
43
|
+
|
44
|
+
return None
|
45
|
+
|
46
|
+
def _command_exists(self, command):
|
47
|
+
"""Check if a command exists in the system."""
|
48
|
+
try:
|
49
|
+
result = subprocess.run(
|
50
|
+
["which", command], capture_output=True, text=True, check=False
|
51
|
+
)
|
52
|
+
return result.returncode == 0
|
53
|
+
except Exception:
|
54
|
+
return False
|
55
|
+
|
56
|
+
def _alias_exists(self):
|
57
|
+
"""Check if the 'p' alias already exists."""
|
58
|
+
# First check if 'p' is already a command
|
59
|
+
if self._command_exists(self.ALIAS_NAME):
|
60
|
+
return True
|
61
|
+
|
62
|
+
# Check if alias is defined in shell
|
63
|
+
try:
|
64
|
+
# Try to run the alias to see if it exists
|
65
|
+
result = subprocess.run(
|
66
|
+
[self.shell, "-i", "-c", f"alias {self.ALIAS_NAME}"],
|
67
|
+
capture_output=True,
|
68
|
+
text=True,
|
69
|
+
check=False,
|
70
|
+
timeout=2,
|
71
|
+
)
|
72
|
+
return result.returncode == 0
|
73
|
+
except (subprocess.TimeoutExpired, Exception):
|
74
|
+
return False
|
75
|
+
|
76
|
+
def _add_alias_to_shell(self):
|
77
|
+
"""Add the alias to the shell configuration file."""
|
78
|
+
if not self.shell_config_file or not self.shell_config_file.exists():
|
79
|
+
return False
|
80
|
+
|
81
|
+
alias_line = f'alias {self.ALIAS_NAME}="{self.ALIAS_COMMAND}"'
|
82
|
+
comment = "# Added by Plain"
|
83
|
+
|
84
|
+
# Check if alias already in file
|
85
|
+
try:
|
86
|
+
with open(self.shell_config_file) as f:
|
87
|
+
content = f.read()
|
88
|
+
if alias_line in content:
|
89
|
+
return True
|
90
|
+
except Exception:
|
91
|
+
return False
|
92
|
+
|
93
|
+
# Add alias to file
|
94
|
+
try:
|
95
|
+
with open(self.shell_config_file, "a") as f:
|
96
|
+
f.write(f"\n{comment}\n{alias_line}\n")
|
97
|
+
|
98
|
+
click.secho(
|
99
|
+
f"✓ Added '{self.ALIAS_NAME}' alias to {self.shell_config_file.name}. Restart your shell!",
|
100
|
+
fg="green",
|
101
|
+
)
|
102
|
+
return True
|
103
|
+
except Exception as e:
|
104
|
+
click.secho(
|
105
|
+
f"Failed to add alias to {self.shell_config_file.name}: {e}", fg="red"
|
106
|
+
)
|
107
|
+
return False
|
108
|
+
|
109
|
+
def check_and_prompt(self):
|
110
|
+
"""Check if alias exists and prompt user to set it up if needed."""
|
111
|
+
# Only suggest if project uses uv (has uv.lock file)
|
112
|
+
if not Path("uv.lock").exists():
|
113
|
+
return
|
114
|
+
|
115
|
+
# Don't prompt if already configured
|
116
|
+
if self._alias_exists():
|
117
|
+
return
|
118
|
+
|
119
|
+
# Don't prompt if we've asked before
|
120
|
+
if self.MARKER_FILE.exists():
|
121
|
+
return
|
122
|
+
|
123
|
+
# Don't prompt for certain commands
|
124
|
+
if "--help" in sys.argv or "-h" in sys.argv:
|
125
|
+
return
|
126
|
+
|
127
|
+
# Mark that we've asked (do this first so we don't ask again even if they Ctrl+C)
|
128
|
+
self.MARKER_FILE.parent.mkdir(parents=True, exist_ok=True)
|
129
|
+
self.MARKER_FILE.touch()
|
130
|
+
|
131
|
+
click.echo()
|
132
|
+
click.secho("💡 Tip: ", fg="yellow", bold=True, nl=False)
|
133
|
+
click.echo(
|
134
|
+
f"Set up `{self.ALIAS_NAME}` as an alias to run commands faster (e.g., `{self.ALIAS_NAME} dev` instead of `uv run plain dev`)."
|
135
|
+
)
|
136
|
+
click.echo()
|
137
|
+
|
138
|
+
# Check if shell is supported
|
139
|
+
if not self.shell or not self.shell_config_file:
|
140
|
+
click.echo("To set this up manually, add to your shell config:")
|
141
|
+
click.echo(f' alias {self.ALIAS_NAME}="{self.ALIAS_COMMAND}"')
|
142
|
+
click.echo()
|
143
|
+
return
|
144
|
+
|
145
|
+
# Offer to set it up
|
146
|
+
prompt_text = f"Would you like to add this to {self.shell_config_file.name}?"
|
147
|
+
if click.confirm(prompt_text, default=False):
|
148
|
+
click.echo()
|
149
|
+
if self._add_alias_to_shell():
|
150
|
+
sys.exit(0) # Completely exit
|
151
|
+
|
152
|
+
click.echo()
|
@@ -9,6 +9,7 @@ import click
|
|
9
9
|
from plain.cli import register_cli
|
10
10
|
from plain.runtime import APP_PATH, PLAIN_TEMP_PATH
|
11
11
|
|
12
|
+
from .alias import AliasManager
|
12
13
|
from .core import ENTRYPOINT_GROUP, DevProcess
|
13
14
|
from .services import ServicesProcess
|
14
15
|
|
@@ -119,7 +120,6 @@ class DevGroup(click.Group):
|
|
119
120
|
)
|
120
121
|
def cli(ctx, port, hostname, log_level, start, stop):
|
121
122
|
"""Start local development"""
|
122
|
-
|
123
123
|
if ctx.invoked_subcommand:
|
124
124
|
return
|
125
125
|
|
@@ -170,6 +170,9 @@ def cli(ctx, port, hostname, log_level, start, stop):
|
|
170
170
|
)
|
171
171
|
return
|
172
172
|
|
173
|
+
# Check and prompt for alias setup
|
174
|
+
AliasManager().check_and_prompt()
|
175
|
+
|
173
176
|
dev.setup(port=port, hostname=hostname, log_level=log_level)
|
174
177
|
returncode = dev.run()
|
175
178
|
if returncode:
|
@@ -260,7 +260,9 @@ class DevProcess(ProcessManager):
|
|
260
260
|
sys.exit(1)
|
261
261
|
|
262
262
|
def run_preflight(self):
|
263
|
-
if subprocess.run(
|
263
|
+
if subprocess.run(
|
264
|
+
["plain", "preflight", "check", "--quiet"], env=self.plain_env
|
265
|
+
).returncode:
|
264
266
|
click.secho("Preflight check failed!", fg="red")
|
265
267
|
sys.exit(1)
|
266
268
|
|
@@ -63,7 +63,8 @@ def cli(install):
|
|
63
63
|
"Running preflight checks",
|
64
64
|
"plain",
|
65
65
|
"preflight",
|
66
|
-
"
|
66
|
+
"check",
|
67
|
+
"--quiet",
|
67
68
|
)
|
68
69
|
check_short("Checking Plain migrations", "plain", "migrate", "--check")
|
69
70
|
check_short(
|
@@ -74,7 +75,13 @@ def cli(install):
|
|
74
75
|
"--check",
|
75
76
|
)
|
76
77
|
else:
|
77
|
-
check_short(
|
78
|
+
check_short(
|
79
|
+
"Running Plain checks (without database)",
|
80
|
+
"plain",
|
81
|
+
"preflight",
|
82
|
+
"check",
|
83
|
+
"--quiet",
|
84
|
+
)
|
78
85
|
click.secho("--> Skipping migration checks", bold=True, fg="yellow")
|
79
86
|
|
80
87
|
print_event("Running plain build")
|
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
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|