# ExtMake - `make` wrapper with `include git=...` and more
ExtMake is a loose wordplay on a "**make** with an ability to include
**ext**ernal Makefiles".
While `make` supports the `include` directive, it can only include files from a
local file system. ExtMake adds an ability to include files from Git
repositories and stays out of the way for everything else. You can see ExtMake
as a preprocessor or a wrapper around `make`.
Features:
- backward-comptible syntax: any valid `Makefile` is valid for `extmake`
- no new syntax except for the added support of `git=...` extension for the
`include` directive
- straightforward implementation reuses `make` for everything else
- forward-compatible: ability to eject the configuration into a single
self-contained `Makefile`
## Motivation
Makefiles are often (ab?)used for task automation in the projects not related
to C. But they are hardly reusable and often get copy-pasted between projects.
Tools for project templating - for example, Cookicutter or Copier in the Python
ecosystem - may be used to facilitate this, but have their drawbacks. Instead,
why not apply the same approach as in all other code - declare a dependency and
load a reusable implementation from a "library"? This is the problem ExtMake is
set to solve, with a touch of simplicity and minimalism.
## Example
File `pytest.mk` in a GitHub repository "example/test":
test:
poetry run pytest --cov-report term --cov=myproj tests/
File `Makefile`:
include git=git@github.com:example/test.git;rev=1.0.0;path=pytest.mk
build:
poetry build
all: test build
Usage:
extmake all
## Installation
Install from PyPI:
pip install extmake
If you prefer so, you can safely alias `extmake` to `make`. ExtMake will
process regular Makefiles by simply proxying them to `make`, albeit with some
overhead.
## Dependencies
- Make
- Git
## Usage
### extmake
`extmake` is a wrapper over `make` and proxies all inputs and outputs almost
unchanged. As such, usage in the command line is exactly the same as with a
regular `make`.
To avoid ambiguity, `extmake` may remind the user that they use the `extmake`
wrapper in case of errors, for example. A dedicated message is added to the
stdout in this case, keeping the rest of the original `make` output intact.
### extmake-edit
To keep the `extmake` usage transparent with regard to `make`, all commands
specific to ExtMake are available through `extmake-edit`.
`extmake-edit` may be used to debug the Makefile resolution, or eject from
ExtMake, altogether.
For usage, run:
extmake-edit --help
### Syntax
The `include` directive is supported by `make` natively and interprets the
arguments as file paths. On top of that, ExtMake can interpret the argument as
a reference to a Git repository. For simplicity, a single Git reference is
allowed for each `include` directive.
include git=URL[;key=value]...
The argument is a [DSN](https://en.wikipedia.org/wiki/Data_source_name)
formatted as a series of `key=value` pairs separated by a semicolon `;`.
Following keys are supported:
- `git`: a Git repository URL, such that can be used with `git clone`; this
is the only mandatory key
- `rev`: a Git commit reference, such as a branch name, a tag name, or a SHA;
defaults to `master`
- `path`: a path within a repository pointing to the file to be included;
defaults to `Makefile`
As with the original `include` directive, included resources are inserted
verbatim at the location of the directive. Issues such as conflicting target
names, for example, are not controlled and `make` is left to do its job and
report any further syntax warning or errors.
Nested includes are supported.
### Best practices
- To keep the builds reproducible, it is best to set the `rev` to a tag
- If you don't use tags for the `rev`, you can run `extmake-edit update`
to force the update of the dependencies
- `*.mk` is a common naming convention for the files that are to be included
### Using public or private Git servers
ExtMake uses Git to clone the repository and will effectively reuse the SSH
config to authenticate with a private server, for example.
For example, in a file `~/.ssh/config`:
Host gitlab.example.com
HostName gitlab.example.com
User git
IdentityFile ~/.ssh/my_rsa
### Eject
At any time you can stop using ExtMake. Ejecting will resolve all includes and
generate a single complete Makefile with all included content embedded into it:
extmake-edit eject [--file FILE]
## Troubleshooting
- For better performance, both the dependencies and the resolved `Makefiles`
are cached in the user data directory (somewhere in user `$HOME`, depending
on the OS). In case of problems, try clearing the cache with `extmake-edit
cache clear`.
- Feel free to [report a bug](https://github.com/candidtim/extmake/issues).
## Future features
- A command to list all dependencies
- A hint about the use of ExtMake in case of errors raised by `make`.
- Better error handling: when `make` or `git` are not available, all internal
errors.
- PyPI distribution.
- Resolve included target names, allow overrides.
- Add the `#super make TARGET` directive (or interpret `make super.TARGET`?)
- A command to generate an override, like `extmake-edit override TARGET`.
- Allow overriding the variables defined in the included files with `?=`.
- Update policy to control how often the cloned repositories are updated.
E.g., `update=manual|always` in the DSN.
Raw data
{
"_id": null,
"home_page": "https://github.com/candidtim/extmake/",
"name": "extmake",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.10,<4.0",
"maintainer_email": "",
"keywords": "make,wrapper,include,git,dependency",
"author": "candidtim",
"author_email": "timcandid@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/b3/a9/26b88fed4a9c29c5d2d45d21d2951b428e14fc3f8b867e1b824f517e00a4/extmake-1.0.0.tar.gz",
"platform": null,
"description": "# ExtMake - `make` wrapper with `include git=...` and more\n\nExtMake is a loose wordplay on a \"**make** with an ability to include\n**ext**ernal Makefiles\".\n\nWhile `make` supports the `include` directive, it can only include files from a\nlocal file system. ExtMake adds an ability to include files from Git\nrepositories and stays out of the way for everything else. You can see ExtMake\nas a preprocessor or a wrapper around `make`.\n\nFeatures:\n\n - backward-comptible syntax: any valid `Makefile` is valid for `extmake`\n - no new syntax except for the added support of `git=...` extension for the\n `include` directive\n - straightforward implementation reuses `make` for everything else\n - forward-compatible: ability to eject the configuration into a single\n self-contained `Makefile`\n\n## Motivation\n\nMakefiles are often (ab?)used for task automation in the projects not related\nto C. But they are hardly reusable and often get copy-pasted between projects.\nTools for project templating - for example, Cookicutter or Copier in the Python\necosystem - may be used to facilitate this, but have their drawbacks. Instead,\nwhy not apply the same approach as in all other code - declare a dependency and\nload a reusable implementation from a \"library\"? This is the problem ExtMake is\nset to solve, with a touch of simplicity and minimalism.\n\n## Example\n\nFile `pytest.mk` in a GitHub repository \"example/test\":\n\n test:\n poetry run pytest --cov-report term --cov=myproj tests/\n\nFile `Makefile`:\n\n include git=git@github.com:example/test.git;rev=1.0.0;path=pytest.mk\n\n build:\n poetry build\n\n all: test build\n\nUsage:\n\n extmake all\n\n## Installation\n\nInstall from PyPI:\n\n pip install extmake\n\nIf you prefer so, you can safely alias `extmake` to `make`. ExtMake will\nprocess regular Makefiles by simply proxying them to `make`, albeit with some\noverhead.\n\n## Dependencies\n\n - Make\n - Git\n\n## Usage\n\n### extmake\n\n`extmake` is a wrapper over `make` and proxies all inputs and outputs almost\nunchanged. As such, usage in the command line is exactly the same as with a\nregular `make`.\n\nTo avoid ambiguity, `extmake` may remind the user that they use the `extmake`\nwrapper in case of errors, for example. A dedicated message is added to the\nstdout in this case, keeping the rest of the original `make` output intact.\n\n### extmake-edit\n\nTo keep the `extmake` usage transparent with regard to `make`, all commands\nspecific to ExtMake are available through `extmake-edit`.\n\n`extmake-edit` may be used to debug the Makefile resolution, or eject from\nExtMake, altogether.\n\nFor usage, run:\n\n extmake-edit --help\n\n### Syntax\n\nThe `include` directive is supported by `make` natively and interprets the\narguments as file paths. On top of that, ExtMake can interpret the argument as\na reference to a Git repository. For simplicity, a single Git reference is\nallowed for each `include` directive.\n\n include git=URL[;key=value]...\n\nThe argument is a [DSN](https://en.wikipedia.org/wiki/Data_source_name)\nformatted as a series of `key=value` pairs separated by a semicolon `;`.\nFollowing keys are supported:\n\n - `git`: a Git repository URL, such that can be used with `git clone`; this\n is the only mandatory key\n - `rev`: a Git commit reference, such as a branch name, a tag name, or a SHA;\n defaults to `master`\n - `path`: a path within a repository pointing to the file to be included;\n defaults to `Makefile`\n\nAs with the original `include` directive, included resources are inserted\nverbatim at the location of the directive. Issues such as conflicting target\nnames, for example, are not controlled and `make` is left to do its job and\nreport any further syntax warning or errors.\n\nNested includes are supported.\n\n### Best practices\n\n - To keep the builds reproducible, it is best to set the `rev` to a tag\n - If you don't use tags for the `rev`, you can run `extmake-edit update`\n to force the update of the dependencies\n - `*.mk` is a common naming convention for the files that are to be included\n\n### Using public or private Git servers\n\nExtMake uses Git to clone the repository and will effectively reuse the SSH\nconfig to authenticate with a private server, for example.\n\nFor example, in a file `~/.ssh/config`:\n\n Host gitlab.example.com\n HostName gitlab.example.com\n User git\n IdentityFile ~/.ssh/my_rsa\n\n### Eject\n\nAt any time you can stop using ExtMake. Ejecting will resolve all includes and\ngenerate a single complete Makefile with all included content embedded into it:\n\n extmake-edit eject [--file FILE]\n\n## Troubleshooting\n\n - For better performance, both the dependencies and the resolved `Makefiles`\n are cached in the user data directory (somewhere in user `$HOME`, depending\n on the OS). In case of problems, try clearing the cache with `extmake-edit\n cache clear`.\n\n - Feel free to [report a bug](https://github.com/candidtim/extmake/issues).\n\n## Future features\n\n - A command to list all dependencies\n - A hint about the use of ExtMake in case of errors raised by `make`.\n - Better error handling: when `make` or `git` are not available, all internal\n errors.\n - PyPI distribution.\n - Resolve included target names, allow overrides.\n - Add the `#super make TARGET` directive (or interpret `make super.TARGET`?)\n - A command to generate an override, like `extmake-edit override TARGET`.\n - Allow overriding the variables defined in the included files with `?=`.\n - Update policy to control how often the cloned repositories are updated.\n E.g., `update=manual|always` in the DSN.\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "ExtMake - `make` wrapper with `include git=...` and more",
"version": "1.0.0",
"project_urls": {
"Bug Tracker": "https://github.com/candidtim/extmake/issues",
"Documentation": "https://github.com/candidtim/extmake/blob/master/README.md",
"Homepage": "https://github.com/candidtim/extmake/",
"Repository": "https://github.com/candidtim/extmake/"
},
"split_keywords": [
"make",
"wrapper",
"include",
"git",
"dependency"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "2c5ae033db0e04954e8413739e84f8ede56644a6333d4b458ef806fe932d7025",
"md5": "a5a8f1b495afba157b4cab3838faddd4",
"sha256": "d49fc7bc870e0274736c3806b0b8a83d106f7a42b6187cd15713e13fc61e4161"
},
"downloads": -1,
"filename": "extmake-1.0.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "a5a8f1b495afba157b4cab3838faddd4",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10,<4.0",
"size": 10355,
"upload_time": "2024-02-25T23:45:57",
"upload_time_iso_8601": "2024-02-25T23:45:57.745258Z",
"url": "https://files.pythonhosted.org/packages/2c/5a/e033db0e04954e8413739e84f8ede56644a6333d4b458ef806fe932d7025/extmake-1.0.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "b3a926b88fed4a9c29c5d2d45d21d2951b428e14fc3f8b867e1b824f517e00a4",
"md5": "a4f77c2409451cdcf21a87c563228ed8",
"sha256": "3ccec8724966a488dc470f8a7cb54b43ba5cb6310f395db05ebdc4c42704184c"
},
"downloads": -1,
"filename": "extmake-1.0.0.tar.gz",
"has_sig": false,
"md5_digest": "a4f77c2409451cdcf21a87c563228ed8",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10,<4.0",
"size": 10588,
"upload_time": "2024-02-25T23:46:00",
"upload_time_iso_8601": "2024-02-25T23:46:00.275470Z",
"url": "https://files.pythonhosted.org/packages/b3/a9/26b88fed4a9c29c5d2d45d21d2951b428e14fc3f8b867e1b824f517e00a4/extmake-1.0.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-02-25 23:46:00",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "candidtim",
"github_project": "extmake",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "extmake"
}