Skip to content

Commit

Permalink
Initial revamp of build process and project structure
Browse files Browse the repository at this point in the history
  • Loading branch information
gouline committed Jan 4, 2024
1 parent 9982f90 commit f4e0bb7
Show file tree
Hide file tree
Showing 24 changed files with 308 additions and 860 deletions.
27 changes: 18 additions & 9 deletions .github/workflows/master.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,34 @@ on:

jobs:
build:
runs-on: ubuntu-latest
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3

- uses: actions/setup-python@v4
with:
python-version: "3.8.18"

- name: Requirements
run: make requirements

- name: Build
run: make build

# TODO: enable when issues fixed
# - name: Lint check
# run: make lint
- name: Formatting check (black)
run: make check-fmt

- name: Imports ordering check (isort)
run: make check-imports

- name: Lint Python check (pylint)
run: make check-lint-python

# - name: Type check
# run: make type
- name: Type check (mypy)
run: make check-type

# - name: Test
# run: make test
- name: Test
run: make test

- name: Publish a Python distribution to PyPI
if: github.event_name == 'release'
Expand Down
27 changes: 18 additions & 9 deletions .github/workflows/pull_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,13 @@ on:

jobs:
validate:
runs-on: ubuntu-latest
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3

- uses: actions/setup-python@v4
with:
python-version: "3.8.18"

- uses: actions/cache@v2
with:
Expand All @@ -24,12 +28,17 @@ jobs:
- name: Build
run: make build

# TODO: enable when issues fixed
# - name: Lint check
# run: make lint
- name: Formatting check (black)
run: make check-fmt

- name: Imports ordering check (isort)
run: make check-imports

- name: Lint Python check (pylint)
run: make check-lint-python

# - name: Type check
# run: make type
- name: Type check (mypy)
run: make check-type

# - name: Test
# run: make test
- name: Test
run: make test
1 change: 0 additions & 1 deletion CODEOWNERS

This file was deleted.

57 changes: 41 additions & 16 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,35 +1,60 @@
build: clean
python3 setup.py sdist bdist_wheel
python3 -m build
.PHONY: build

clean:
rm -rf build dist
.PHONY: clean

requirements:
pip3 install -r requirements.txt
pip3 install -r requirements-test.txt
python3 -m pip install \
-r requirements.txt \
-r requirements-test.txt
.PHONY: requirements

lint:
fix-fmt:
black .
.PHONY: fix-fmt

fix-imports:
isort .
.PHONY: fix-imports

fix: fix-fmt fix-imports
.PHONY: fix

check-fmt:
black --check .
.PHONY: check-fmt

check-imports:
isort --check .
.PHONY: check-imports

check-lint-python:
pylint molot
.PHONY: lint
.PHONY: check-lint-python

type:
check-type:
mypy molot
.PHONY: type
.PHONY: check-type

check: check-fmt check-imports check-lint-python check-type
.PHONY: check

# TODO: implement tests
# test:
# python3 -m unittest tests
# .PHONY: test
test:
python3 -m unittest tests
.PHONY: test

check: build
dist-check: build
twine check dist/*
.PHONY: check
.PHONY: dist-check

upload: check
dist-upload: check
twine upload dist/*
.PHONY: upload
.PHONY: dist-upload

dev-install: build
pip3 uninstall -y molot && pip3 install dist/molot-*-py3-none-any.whl
python3 -m pip uninstall -y molot \
&& python3 -m pip install dist/molot-*-py3-none-any.whl
.PHONY: dev-install
143 changes: 143 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
# Molot

[![GitHub Actions](https://github.com/gouline/molot/actions/workflows/master.yml/badge.svg)](https://github.com/gouline/molot/actions/workflows/master.yml)
[![PyPI](https://img.shields.io/pypi/v/molot)](https://pypi.org/project/molot/)
[![Downloads](https://pepy.tech/badge/molot)](https://pepy.tech/project/molot)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/gouline/molot/blob/master/LICENSE)
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)

Simple execution orchestrator.

## Requirements

Molot requires Python 3.8 or above.

## Usage

Create a new orchestration file, e.g. `build.py` for a build orchestration. Make it executable `chmod +x build.py` to make it easier to run.

```py
#!/usr/bin/env python3
from molot import * # pylint: disable=wildcard-import,unused-wildcard-import

# Your targets and environment arguments here

evaluate()
```

Pylint comment silences editor warnings about wildcard imports, you can alternatively import everything individually.

Now you're ready to run the build script to see the help message:

```shell
./build.py
```

To only see a list of targets and environment arguments, call the built-in `list` target:

```shell
./build.py list
```

Not very exciting so far, let's learn how to add your own targets and environment arguments.

### Targets

Any piece of work that your build needs to perform is defined as a target. Here's a trivial example of a target that executes `ls`.

```py
@target(
name="ls",
description="lists current directory items",
group="greetings",
depends=["target1", "target2"]
)
def ls():
shell("ls")
```

Parameters explained:

* `name` - unique name to reference the target (optional; function name is used by default)
* `description` - short description of what the target does displayed in the help message (optional)
* `group` - grouping to list target under (optional; listed under "ungrouped" by default)
* `depends` - list of other targets that must be executed first (optional)

Since all the parameters are optional, the shortest definition of the same target can be as follows:

```py
@target()
def ls():
shell("ls")
```

Here's how you run your new target:

```shell
./build.py ls
```

#### Dependency Resolution

Now we can define another target `hello` that depends on `ls`:

```py
@target(description="say hello", depends=["ls"])
def hello():
print("hello")
```

There is basic dependency resolution that checks for circular dependencies and finds all transitive dependency targets to execute before running the one that you called. When you call:

```shell
./build.py hello
```

What actually happens is equivalent to calling:

```shell
./build.py ls hello
```

### Environment Arguments

Environment arguments ar a cross between environment variables and arguments. Values can be passed as the former and then overriden as the latter.

Here's how you define one:

```py
ENV = envarg("ENV", default="dev", description="build environment")
```

Parameters explained:

* `name` - unique name for the argument
* `default` - default value if none is supplied (optional; `None` by default)
* `description` - short description of what the argument is displayed in the help message (optional)
* `sensitive` - indicates the value is sensitive and should be masked (optional)

The argument is evaluated right there (not inside of targets), so you can use that variable straightaway.

It can be set as a regular environment variable:

```shell
ENV=dev ./build.py sometarget
```

Alternatively, it can be passed as an argument:

```shell
./build.py sometarget --arg ENV=prod
```

Finally, you can pass .env file to load:

```shell
./build.py sometarget --dotenv /path/to/.env
```

If both are passed simultaneously, then argument takes precedence over the environment variable.

## Examples

See [example](./example) for a basic orchestration that showcases most features.
Loading

0 comments on commit f4e0bb7

Please sign in to comment.