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.
Files changed (32) hide show
  1. {plain_dev-0.35.0 → plain_dev-0.37.0}/PKG-INFO +3 -3
  2. {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/CHANGELOG.md +21 -0
  3. {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/README.md +2 -2
  4. plain_dev-0.37.0/plain/dev/alias.py +152 -0
  5. {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/cli.py +4 -1
  6. {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/core.py +3 -1
  7. {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/precommit/cli.py +9 -2
  8. {plain_dev-0.35.0 → plain_dev-0.37.0}/pyproject.toml +1 -1
  9. {plain_dev-0.35.0 → plain_dev-0.37.0}/.gitignore +0 -0
  10. {plain_dev-0.35.0 → plain_dev-0.37.0}/LICENSE +0 -0
  11. {plain_dev-0.35.0 → plain_dev-0.37.0}/README.md +0 -0
  12. {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/__init__.py +0 -0
  13. {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/contribute/README.md +0 -0
  14. {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/contribute/__init__.py +0 -0
  15. {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/contribute/cli.py +0 -0
  16. {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/debug.py +0 -0
  17. {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/default_settings.py +0 -0
  18. {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/entrypoints.py +0 -0
  19. {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/gunicorn_logging.json +0 -0
  20. {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/mkcert.py +0 -0
  21. {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/pdb.py +0 -0
  22. {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/poncho/__init__.py +0 -0
  23. {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/poncho/color.py +0 -0
  24. {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/poncho/compat.py +0 -0
  25. {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/poncho/manager.py +0 -0
  26. {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/poncho/printer.py +0 -0
  27. {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/poncho/process.py +0 -0
  28. {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/precommit/__init__.py +0 -0
  29. {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/process.py +0 -0
  30. {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/services.py +0 -0
  31. {plain_dev-0.35.0 → plain_dev-0.37.0}/plain/dev/utils.py +0 -0
  32. {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.35.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 --database default`
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 --database default`
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(["plain", "preflight"], env=self.plain_env).returncode:
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
- "--database",
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("Running Plain checks (without database)", "plain", "preflight")
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")
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "plain.dev"
3
- version = "0.35.0"
3
+ version = "0.37.0"
4
4
  description = "A single command that runs everything you need for local development."
5
5
  authors = [{name = "Dave Gaeddert", email = "dave.gaeddert@dropseed.dev"}]
6
6
  license = "BSD-3-Clause"
File without changes
File without changes
File without changes
File without changes
File without changes