Skip to content

Commit

Permalink
Implemented the dev.py commands as package level commands to simplify…
Browse files Browse the repository at this point in the history
… usage (#1)

* Started to implement the commands as separate package level commands

* Added pre-commit hooks

* Added more rules to pre-commit

* Refactored dev.py commands to package level stand alone commands

* Removed config from from pre-commit

* Fixed bugs and typos on new commands

* Better type checking

* Fixed local-install command and updated readme with new changes
  • Loading branch information
josu-dev authored Sep 24, 2023
1 parent b237e7b commit 748dc94
Show file tree
Hide file tree
Showing 20 changed files with 1,781 additions and 617 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ __pycache__/
# poetry
dist/
poetry.toml
poetry.lock
.pytest_cache/

# others
Expand Down
25 changes: 25 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: 'v4.4.0'
hooks:
- id: check-yaml
- id: end-of-file-fixer
- id: trailing-whitespace
- id: no-commit-to-branch

- repo: https://github.com/pycqa/isort
rev: '5.12.0'
hooks:
- id: isort

- repo: https://github.com/psf/black
rev: '23.9.1'
hooks:
- id: black

- repo: https://github.com/pycqa/flake8
rev: '6.1.0'
hooks:
- id: flake8
args: ['--extend-ignore=E203,E501,W503']
stages: [pre-push]
9 changes: 2 additions & 7 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,15 @@
"editor.defaultFormatter": "ms-python.black-formatter",
"editor.tabSize": 4
},
"black-formatter.args": [
"--line-length=79"
],
"files.exclude": {
"**/__pycache__": true
"**/__pycache__": true,
"**/.venv": true
},
"files.insertFinalNewline": true,
"files.trimFinalNewlines": true,
"files.trimTrailingWhitespace": true,
"flake8.args": [
"--ignore=E501,W503"
],
"isort.args": [
"--profile=black"
],
"python.analysis.typeCheckingMode": "strict"
}
160 changes: 81 additions & 79 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,141 +1,143 @@
# Flask live tailwindcss

A simple package for adding a dev server to your flask app that automatically compiles your tailwindcss of the templates on save and reloads your browser to sync the changes.
A simple package for adding a dev server to your flask app that automatically compiles the tailwindcss of the templates on file save and triggers a browser reload to sync the changes on the fly.

> **Note:** This package is intended to use with [poetry](https://python-poetry.org/). If you are not using poetry, you can still use this package by installing the dependencies manually.


## Integrate with poetry

### Installation
## Installation

```bash
# using poetry
poetry add --group=dev flask-livetw

# using pip
pip install flask-livetw
```

### Initialization

Simply go to your project root folder, run the following command and follow along the steps.
## Initialization

To start using this package, simply go to your project root folder, run the following command and follow along the steps.

```bash
poetry run flask-livetw
# using poetry
poetry shell
flask-livetw init

# using pip
"activate your virtual environment like you normally do"
flask-livetw init
```

> **Note 1:** If want to skip the questions, you can use the `-Y` or `--yes` flag.
> **Note 1:** To skip requirements check use the `-Y` or `--yes` flag.
>
> **Note 2:** If you want to use default values for the setup, you can use the `-D` or `--default` flag.
>
> **Note 3:** You can use the `-h` or `--help` flag to see the available options.
## Integrate with pip
> **Note 2:** To use default values for the initialization use the `-D` or `--default` flag.
### Installation
### Default values

```bash
pip install flask-livetw
```
```py
FLASK_ROOT = "src"

### Initialization
STATIC_FOLDER = "src/static"

Simply go to your project root folder, run the following command and follow along the steps.
TEMPLATE_FOLDER = "src/templates"
TEMPLATE_GLOB = "src/templates/**/*.html"
ROOT_LAYOUT_FILE = "src/templates/layout.html"

```bash
python -m flask_livetw
```
LIVE_RELOAD_FILE = "src/static/.dev/live_reload.js"

After the initialization, you need to install the dependencies manually.
GLOBALCSS_FILE = "src/static/.dev/global.css"
TAILWIND_FILE = "src/static/.dev/tailwind.css"
MINIFIED_TAILWIND_FILE = "src/static/tailwind_min.css"

```bash
pip install pytailwindcss python-dotenv websockets
UPDATE_GITIGNORE = False
```

Example as file system tree:

```txt
project_root
├── src
│ ├── static
│ │ ├── .dev
│ │ │ ├── global.css
│ │ │ ├── live_reload.js
│ │ │ └── tailwind.css
│ │ ├── tailwind_min.css
│ │ ...
│ └── templates
│ ├── layout.html
│ ...
├── .gitignore
├── pyproject.toml
...
```

## Usage

### Development
## Commands

When developing your app, you can use the following command to start the dev server.
In order to use the commands, you need to activate your virtual environment first.

```bash
./dev.py dev
```
# using poetry
poetry shell

> **Note:** You can use the `-h` or `--help` flag to see the available options.
# using pip
"activate your virtual environment like you normally do"
```

### Building
Each command has its own help page, you can use the `-h` or `--help` flag to see the available options.

When you are done developing, you can use the following command to build your app.
### dev

```bash
./dev.py build
flask-livetw dev
```

> **Note:** You can use the `-h` or `--help` flag to see the available options.
By default the command starts:

## Default values
- a flask server in debug mode
- a live reload websocket server
- a tailwindcss in watch mode

### Package cli
### build

```py
DEFAULT_FLASK_ROOT = "src"
Builds the tailwindcss of the templates as a single css file.

DEFAULT_STATIC_FOLDER = "src/static"
```bash
flask-livetw build
```

DEFAULT_TEMPLATE_FOLDER = "src/templates"
DEFAULT_TEMPLATE_GLOB = "src/templates/**/*.html"
By default the builded tailwindcss file will be minified.

DEFAULT_ROOT_LAYOUT_FILE = "src/templates/layout.html"
DEFAULT_LIVE_RELOAD_FILE = "src/static/.dev/live_reload.js"
DEFAULT_GLOBALCSS_FILE = ".dev/global.css"
DEFAULT_TWCSS_FILE = "src/static/.dev/tailwindcss.css"
DEFAULT_MINIFIED_TWCSS_FILE = "src/static/tailwindcss_min.css"
### local-install

DEFAULT_UPDATE_GITIGNORE = False
```bash
flask-livetw local-install
```

Example as file system tree:

```txt
project_root
├── src
│ ├── static
│ │ ├── .dev
│ │ │ ├── global.css
│ │ │ ├── live_reload.js
│ │ │ └── tailwindcss.css
│ │ ├── tailwindcss_min.css
│ │ ...
│ └── templates
│ ├── layout.html
│ ...
├── .gitignore
├── dev.py
├── pyproject.toml
...
```
This command creates a local script that mimics the `flask-livetw` command and installs the necessary dependencies.

### Dev server
After the installation, you can use the `dev` and `build` commands as follows:

```py
LRWS_HOST = "127.0.0.1"
LRWS_PORT = 5678
TW_INPUT_PATH = "package_test/static/.dev/global.css"
TW_OUTPUT_PATH = "src/static/.dev/tailwindcss.css"
TW_OUTPUT_PATH_BUILD = "src/static/tailwindcss_min.css"
```bash
./dev.py dev
./dev.py build
```


## Contributing

Contributions are welcome, feel free to submit a pull request or an issue.

## Credits

## Packages used

- [pytailwindcss](https://github.com/timonweb/pytailwindcss)
- [python-dotenv](https://github.com/theskumar/python-dotenv)
- [tomli](https://github.com/hukkin/tomli)
- [websockets](https://github.com/python-websockets/websockets)


## License

[MIT](./LICENSE)
1 change: 0 additions & 1 deletion flask_livetw/__main__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from flask_livetw.main import main


if __name__ == "__main__":
raise SystemExit(main())
112 changes: 112 additions & 0 deletions flask_livetw/build_app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
from __future__ import annotations

import argparse
import dataclasses
import shlex
import subprocess
from typing import Sequence

from flask_livetw.config import Config
from flask_livetw.util import Term, pkgprint

MINIFY_ON_BUILD = True


@dataclasses.dataclass
class BuildConfig:
input: str
output: str
minify: bool


def minify_tailwind(config: BuildConfig) -> int:
input_arg = f"-i {config.input}"

output_arg = f"-o {config.output}"

minify_arg = "--minify" if config.minify else ""

command = f"tailwindcss {input_arg} {output_arg} {minify_arg}"

pkgprint("Minifying tailwindcss for production...")

build_result = subprocess.run(shlex.split(command))

if build_result.returncode != 0:
pkgprint(f"Tailwind build for production {Term.R}fail{Term.END}")
return build_result.returncode

pkgprint(f"Tailwind build for production {Term.G}ready{Term.END}")
return build_result.returncode


def build(cli_args: argparse.Namespace) -> int:
config = Config.from_pyproject_toml()

build_config = BuildConfig(
input=cli_args.input or config.full_globalcss_file,
output=cli_args.output or config.full_tailwind_minified_file,
minify=cli_args.minify,
)

return minify_tailwind(build_config)


def add_command_args(parser: argparse.ArgumentParser) -> None:
parser.add_argument(
"-i",
"--input",
dest="input",
type=str,
help="Input path, accepts glob patterns.",
)
parser.add_argument(
"-o", "--output", dest="output", type=str, help="Output path."
)
build_minify_group = parser.add_mutually_exclusive_group()
build_minify_group.add_argument(
"--minify", dest="minify", action="store_true", help="Minify output."
)
build_minify_group.add_argument(
"--no-minify",
dest="minify",
action="store_false",
help="Do not minify output.",
)
parser.set_defaults(minify=MINIFY_ON_BUILD)


def add_command(
subparser: argparse._SubParsersAction[argparse.ArgumentParser],
) -> None:
parser = subparser.add_parser(
name="build",
description="""
Build the tailwindcss of the project as a single minified css file.
""",
help="Build tailwindcss for production.",
allow_abbrev=True,
formatter_class=argparse.MetavarTypeHelpFormatter,
)

add_command_args(parser)


def main(args: Sequence[str] | None = None) -> int:
parser = argparse.ArgumentParser(
description="""
Build the tailwindcss of the project as a single css file.
""",
allow_abbrev=True,
formatter_class=argparse.MetavarTypeHelpFormatter,
)

add_command_args(parser)

parsed_args = parser.parse_args(args)

return build(parsed_args)


if __name__ == "__main__":
raise SystemExit(main())
Loading

0 comments on commit 748dc94

Please sign in to comment.