qik 0.0.1__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.
qik-0.0.1/LICENSE ADDED
@@ -0,0 +1,27 @@
1
+ Copyright (c) 2024, Opus 10
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+
7
+ * Redistributions of source code must retain the above copyright
8
+ notice, this list of conditions and the following disclaimer.
9
+
10
+ * Redistributions in binary form must reproduce the above copyright
11
+ notice, this list of conditions and the following disclaimer in the
12
+ documentation and/or other materials provided with the distribution.
13
+
14
+ * Neither the name of the copyright holder nor the names of its
15
+ contributors may be used to endorse or promote products derived from
16
+ this software without specific prior written permission.
17
+
18
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
+ DISCLAIMED. IN NO EVENT SHALL OPUS 10 BE LIABLE FOR ANY
22
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
qik-0.0.1/PKG-INFO ADDED
@@ -0,0 +1,187 @@
1
+ Metadata-Version: 2.1
2
+ Name: qik
3
+ Version: 0.0.1
4
+ Summary: Run cached commands in your modular monorepo.
5
+ Home-page: https://github.com/Opus10/qik
6
+ License: BSD-3-Clause
7
+ Author: Opus 10 Engineering
8
+ Requires-Python: >=3.10.0,<4
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: License :: OSI Approved :: BSD License
11
+ Classifier: Operating System :: OS Independent
12
+ Classifier: Programming Language :: Python
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3 :: Only
18
+ Provides-Extra: dev
19
+ Provides-Extra: graph
20
+ Provides-Extra: s3
21
+ Provides-Extra: watch
22
+ Requires-Dist: boto3 (>=1) ; extra == "s3"
23
+ Requires-Dist: grimp (>=3.4.1) ; extra == "graph" or extra == "dev"
24
+ Requires-Dist: msgspec (>=0.18.6)
25
+ Requires-Dist: rich (>=13)
26
+ Requires-Dist: rustworkx (>=0.15.1) ; extra == "graph" or extra == "dev"
27
+ Requires-Dist: typing-extensions (>=4.11.0)
28
+ Requires-Dist: watchdog (>=4) ; extra == "watch" or extra == "dev"
29
+ Requires-Dist: xxhash (>=3.4.1)
30
+ Project-URL: Documentation, https://qik.readthedocs.io
31
+ Project-URL: Repository, https://github.com/Opus10/qik
32
+ Description-Content-Type: text/markdown
33
+
34
+ <p align="center" style="padding-bottom: 1rem">
35
+ <a href="https://qik.build"><img src="docs/static/logo.webp" alt="qik" width="40%"></a>
36
+ </p>
37
+
38
+ Qik (*quick*) is a cached command runner for modular monorepos. Like [make](https://www.gnu.org/software/make/), but with hash-based caching and advanced dependencies such as globs, imports, external packages, and much more.
39
+
40
+ Qik's command caching ensures you never do redundant work. Parametrize commands across modules, watch and re-run them reactively, or filter commands since a git hash. Qik can dramatically improve CI and local development time.
41
+
42
+ Although qik has special functionality with Python repos, any git-based project can use qik as a command runner.
43
+
44
+ [Read the docs here](https://qik.build).
45
+
46
+ ## Installation
47
+
48
+ ```bash
49
+ pip install qik
50
+ ```
51
+
52
+ For local development, we recommend installing most optional dependencies with:
53
+
54
+ ```bash
55
+ pip install qik[dev]
56
+ ```
57
+
58
+ Qik is compatible with Python 3.10 - 3.12, Linux, OSX, and WSL.
59
+
60
+ ## Quick Start
61
+
62
+ ### File and Glob Dependencies
63
+
64
+ Here we use the `pip-compile` executable from [pip-tools](https://github.com/jazzband/pip-tools) to lock PyPI distributions. Create `qik.toml` with the following:
65
+
66
+ ```toml
67
+ [commands.lock]
68
+ exec = "pip-compile > requirements.txt"
69
+ deps = ["requirements.in"]
70
+ cache = "repo"
71
+ ```
72
+
73
+ Running `qik lock` executes `pip-compile > requirements.txt`. Results are cached in your repo until `requirements.in` changes.
74
+
75
+ ### Distribution Dependencies
76
+
77
+ Change `deps` to re-run this command if we upgrade `pip-tools`:
78
+
79
+ ```toml
80
+ deps = ["requirements.in", {type = "dist", name = "pip-tools"}]
81
+ ```
82
+
83
+ Installing a different version of `pip-tools` will break the command cache.
84
+
85
+ ### Modular Commands
86
+
87
+ Parametrize commands over modules, for example, running the [ruff](https://docs.astral.sh/ruff/) code formatter:
88
+
89
+ ```toml
90
+ modules = ["a_module", "b_module", "c_module"]
91
+
92
+ [commands.format]
93
+ exec = "ruff format {module.path}"
94
+ deps = ["{module.path}/**.py"]
95
+ cache = "repo"
96
+ ```
97
+
98
+ Running `qik format` will parametrize `ruff format` in parallel over all available threads and configured modules. Use `-n` to adjust the number of threads and `-m` to supply modules:
99
+
100
+ ```bash
101
+ qik format -n 2 -m b_module -m c_module
102
+ ```
103
+
104
+ ### Import Dependencies
105
+
106
+ Some commands, such as [pyright](https://github.com/microsoft/pyright) type checking, should re-run whenever imports change:
107
+
108
+ ```toml
109
+ modules = ["a_module", "b_module", "c_module"]
110
+ plugins = ["qik.graph"]
111
+
112
+ [commands.check_types]
113
+ exec = "pyright {module.path}"
114
+ deps = [{type = "module", name = "{module.name}"}]
115
+ cache = "repo"
116
+ ```
117
+
118
+ Running `qik check_types` will parametrize `pyright` over all modules. Modular commands will be cached unless the module's files or dependencies change.
119
+
120
+ We use the `qik.graph` plugin, which provides commands that are automatically used for building and analyzing the import graph.
121
+
122
+ ### Command Dependencies
123
+
124
+ Command dependencies help order execution. For example, change `deps` of `command.check_types` to run type checking only after code has been successfully formatted:
125
+
126
+ ```toml
127
+ deps = [
128
+ {type = "module", name = "{module.name}"},
129
+ {type = "command", name = "format"}
130
+ ]
131
+ ```
132
+
133
+ ### Caching
134
+
135
+ We've shown examples of the `repo` cache, which stores metadata of the most recent runs in the repo. Qik offers both local and remote caches to store all command runs and their output.
136
+
137
+ To use these, first ensure commands have `artifacts` configured. For example, the `lock` command generates a `requirements.txt` file:
138
+
139
+ ```toml
140
+ [commands.lock]
141
+ exec = "pip-compile > requirements.txt"
142
+ deps = ["requirements.in"]
143
+ artifacts = ["requirements.txt"]
144
+ cache = "local"
145
+ ```
146
+
147
+ Above we're using the `local` cache. Versions of our `requirements.txt` will be stored in the `._qik/cache` folder. Qik supports [AWS S3](https://aws.amazon.com/pm/serv-s3/) as a [remote caching backend](caching.md).
148
+
149
+ ### Command Line Interface
150
+
151
+ The core CLI functionality is as follows:
152
+
153
+ - `qik` to run all commands.
154
+ - `qik <cmd_name> <cmd_name>` to run specific commands.
155
+ - `--watch` to reactively run selected commands.
156
+ - `-f` to run without the cache.
157
+ - `-m` to run against specific modules.
158
+ - `-n` to set the number of threads.
159
+ - `--ls` to list commands instead of running them.
160
+
161
+ Some runtime behavior is configurable via the CLI:
162
+
163
+ - `--cache` to set the default cache.
164
+ - `--cache-when` to configure when to cache. Use `finished` to cache all results. By default only `success` runs are cached.
165
+ - `--isolated` to not run dependent commands.
166
+
167
+ These options are useful for selecting commands:
168
+
169
+ - `--since` to select commands based on changes since a git SHA.
170
+ - `--cache-type` to select commands by their cache type.
171
+ - `--cache-status` to select commands by their cache status (`warm` or `cold`).
172
+ - `--fail` to return a non-zero exit code if any commands are selected.
173
+
174
+ Finally, use `-p` to set the qik [context](context.md).
175
+
176
+ ## Docs
177
+
178
+ [Read the qik docs here](https://qik.build) for more information on:
179
+
180
+ - Commands: A cookbook of common commands and creating module-specific commands.
181
+ - Dependencies: All dependencies, including global dependencies, constants, and file parts.
182
+ - Selectors: Selecting commands based on properties.
183
+ - Context: Using environment-based context and runtime profiles.
184
+ - Caching: How caching works and how to configure all cache types, including S3.
185
+ - Continuous Integration: Patterns for optimizing CI time.
186
+ - Plugins: How to create qik plugins, such as custom commands and cache backends.
187
+
qik-0.0.1/README.md ADDED
@@ -0,0 +1,153 @@
1
+ <p align="center" style="padding-bottom: 1rem">
2
+ <a href="https://qik.build"><img src="docs/static/logo.webp" alt="qik" width="40%"></a>
3
+ </p>
4
+
5
+ Qik (*quick*) is a cached command runner for modular monorepos. Like [make](https://www.gnu.org/software/make/), but with hash-based caching and advanced dependencies such as globs, imports, external packages, and much more.
6
+
7
+ Qik's command caching ensures you never do redundant work. Parametrize commands across modules, watch and re-run them reactively, or filter commands since a git hash. Qik can dramatically improve CI and local development time.
8
+
9
+ Although qik has special functionality with Python repos, any git-based project can use qik as a command runner.
10
+
11
+ [Read the docs here](https://qik.build).
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ pip install qik
17
+ ```
18
+
19
+ For local development, we recommend installing most optional dependencies with:
20
+
21
+ ```bash
22
+ pip install qik[dev]
23
+ ```
24
+
25
+ Qik is compatible with Python 3.10 - 3.12, Linux, OSX, and WSL.
26
+
27
+ ## Quick Start
28
+
29
+ ### File and Glob Dependencies
30
+
31
+ Here we use the `pip-compile` executable from [pip-tools](https://github.com/jazzband/pip-tools) to lock PyPI distributions. Create `qik.toml` with the following:
32
+
33
+ ```toml
34
+ [commands.lock]
35
+ exec = "pip-compile > requirements.txt"
36
+ deps = ["requirements.in"]
37
+ cache = "repo"
38
+ ```
39
+
40
+ Running `qik lock` executes `pip-compile > requirements.txt`. Results are cached in your repo until `requirements.in` changes.
41
+
42
+ ### Distribution Dependencies
43
+
44
+ Change `deps` to re-run this command if we upgrade `pip-tools`:
45
+
46
+ ```toml
47
+ deps = ["requirements.in", {type = "dist", name = "pip-tools"}]
48
+ ```
49
+
50
+ Installing a different version of `pip-tools` will break the command cache.
51
+
52
+ ### Modular Commands
53
+
54
+ Parametrize commands over modules, for example, running the [ruff](https://docs.astral.sh/ruff/) code formatter:
55
+
56
+ ```toml
57
+ modules = ["a_module", "b_module", "c_module"]
58
+
59
+ [commands.format]
60
+ exec = "ruff format {module.path}"
61
+ deps = ["{module.path}/**.py"]
62
+ cache = "repo"
63
+ ```
64
+
65
+ Running `qik format` will parametrize `ruff format` in parallel over all available threads and configured modules. Use `-n` to adjust the number of threads and `-m` to supply modules:
66
+
67
+ ```bash
68
+ qik format -n 2 -m b_module -m c_module
69
+ ```
70
+
71
+ ### Import Dependencies
72
+
73
+ Some commands, such as [pyright](https://github.com/microsoft/pyright) type checking, should re-run whenever imports change:
74
+
75
+ ```toml
76
+ modules = ["a_module", "b_module", "c_module"]
77
+ plugins = ["qik.graph"]
78
+
79
+ [commands.check_types]
80
+ exec = "pyright {module.path}"
81
+ deps = [{type = "module", name = "{module.name}"}]
82
+ cache = "repo"
83
+ ```
84
+
85
+ Running `qik check_types` will parametrize `pyright` over all modules. Modular commands will be cached unless the module's files or dependencies change.
86
+
87
+ We use the `qik.graph` plugin, which provides commands that are automatically used for building and analyzing the import graph.
88
+
89
+ ### Command Dependencies
90
+
91
+ Command dependencies help order execution. For example, change `deps` of `command.check_types` to run type checking only after code has been successfully formatted:
92
+
93
+ ```toml
94
+ deps = [
95
+ {type = "module", name = "{module.name}"},
96
+ {type = "command", name = "format"}
97
+ ]
98
+ ```
99
+
100
+ ### Caching
101
+
102
+ We've shown examples of the `repo` cache, which stores metadata of the most recent runs in the repo. Qik offers both local and remote caches to store all command runs and their output.
103
+
104
+ To use these, first ensure commands have `artifacts` configured. For example, the `lock` command generates a `requirements.txt` file:
105
+
106
+ ```toml
107
+ [commands.lock]
108
+ exec = "pip-compile > requirements.txt"
109
+ deps = ["requirements.in"]
110
+ artifacts = ["requirements.txt"]
111
+ cache = "local"
112
+ ```
113
+
114
+ Above we're using the `local` cache. Versions of our `requirements.txt` will be stored in the `._qik/cache` folder. Qik supports [AWS S3](https://aws.amazon.com/pm/serv-s3/) as a [remote caching backend](caching.md).
115
+
116
+ ### Command Line Interface
117
+
118
+ The core CLI functionality is as follows:
119
+
120
+ - `qik` to run all commands.
121
+ - `qik <cmd_name> <cmd_name>` to run specific commands.
122
+ - `--watch` to reactively run selected commands.
123
+ - `-f` to run without the cache.
124
+ - `-m` to run against specific modules.
125
+ - `-n` to set the number of threads.
126
+ - `--ls` to list commands instead of running them.
127
+
128
+ Some runtime behavior is configurable via the CLI:
129
+
130
+ - `--cache` to set the default cache.
131
+ - `--cache-when` to configure when to cache. Use `finished` to cache all results. By default only `success` runs are cached.
132
+ - `--isolated` to not run dependent commands.
133
+
134
+ These options are useful for selecting commands:
135
+
136
+ - `--since` to select commands based on changes since a git SHA.
137
+ - `--cache-type` to select commands by their cache type.
138
+ - `--cache-status` to select commands by their cache status (`warm` or `cold`).
139
+ - `--fail` to return a non-zero exit code if any commands are selected.
140
+
141
+ Finally, use `-p` to set the qik [context](context.md).
142
+
143
+ ## Docs
144
+
145
+ [Read the qik docs here](https://qik.build) for more information on:
146
+
147
+ - Commands: A cookbook of common commands and creating module-specific commands.
148
+ - Dependencies: All dependencies, including global dependencies, constants, and file parts.
149
+ - Selectors: Selecting commands based on properties.
150
+ - Context: Using environment-based context and runtime profiles.
151
+ - Caching: How caching works and how to configure all cache types, including S3.
152
+ - Continuous Integration: Patterns for optimizing CI time.
153
+ - Plugins: How to create qik plugins, such as custom commands and cache backends.
@@ -0,0 +1,106 @@
1
+ [build-system]
2
+ requires = ["poetry_core>=1.0.0"]
3
+ build-backend = "poetry.core.masonry.api"
4
+
5
+ [tool.coverage.run]
6
+ branch = true
7
+ source = ["qik"]
8
+
9
+ [tool.coverage.report]
10
+ exclude_lines = [
11
+ "pragma: no cover",
12
+ "raise AssertionError",
13
+ "raise NotImplementedError",
14
+ "pass",
15
+ "pytest.mark.skip",
16
+ "@(typing\\.)?overload",
17
+ "if TYPE_CHECKING:",
18
+ ]
19
+ show_missing = true
20
+ fail_under = 100
21
+
22
+ [tool.poetry]
23
+ name = "qik"
24
+ packages = [
25
+ { include = "qik" }
26
+ ]
27
+ exclude = [
28
+ "*/tests/"
29
+ ]
30
+ version = "0.0.1"
31
+ description = "Run cached commands in your modular monorepo."
32
+ authors = ["Opus 10 Engineering"]
33
+ classifiers = [
34
+ "Intended Audience :: Developers",
35
+ "Operating System :: OS Independent",
36
+ "Programming Language :: Python",
37
+ "Programming Language :: Python :: 3.10",
38
+ "Programming Language :: Python :: 3.11",
39
+ "Programming Language :: Python :: 3.12",
40
+ "Programming Language :: Python :: 3 :: Only",
41
+ ]
42
+ license = "BSD-3-Clause"
43
+ readme = "README.md"
44
+ homepage = "https://github.com/Opus10/qik"
45
+ repository = "https://github.com/Opus10/qik"
46
+ documentation = "https://qik.readthedocs.io"
47
+
48
+ [tool.poetry.scripts]
49
+ qik = "qik.cli:main"
50
+
51
+ [tool.poetry.dependencies]
52
+ python = ">=3.10.0,<4"
53
+ msgspec = ">=0.18.6"
54
+ xxhash = ">=3.4.1"
55
+ typing-extensions = ">=4.11.0"
56
+ rich = { version = ">=13" }
57
+ watchdog = { version = ">=4", optional = true }
58
+ grimp = { version = ">=3.4.1", optional = true }
59
+ rustworkx = { version = ">=0.15.1", optional = true }
60
+ boto3 = { version = ">=1", optional = true }
61
+
62
+ [tool.poetry.extras]
63
+ watch = ["watchdog"]
64
+ graph = ["grimp", "rustworkx"]
65
+ dev = ["watchdog", "grimp", "rustworkx"]
66
+ s3 = ["boto3"]
67
+
68
+ [tool.poetry.dev-dependencies]
69
+ git-tidy = "1.2.0"
70
+ pytest = "7.4.2"
71
+ pytest-cov = "4.1.0"
72
+ pytest-dotenv = "0.5.2"
73
+ tox = "4.11.3"
74
+ ruff = "0.3.7"
75
+ pyright = "1.1.360"
76
+ mkdocs = "1.5.3"
77
+ black = "24.4.0"
78
+ mkdocs-material = "9.5.18"
79
+ mkdocstrings-python = "1.9.2"
80
+ footing = "*"
81
+ setuptools = "*"
82
+ poetry-core = "*"
83
+ pytest-mock = "3.14.0"
84
+
85
+ [tool.pytest.ini_options]
86
+ xfail_strict = true
87
+ testpaths = ["qik/tests"]
88
+ norecursedirs = ".venv"
89
+
90
+ [tool.ruff]
91
+ lint.select = ["E", "F", "B", "I", "G", "C4"]
92
+ lint.ignore = ["E501"]
93
+ line-length = 99
94
+ target-version = "py310"
95
+
96
+ [tool.pyright]
97
+ exclude = [
98
+ "**/node_modules",
99
+ "**/__pycache__",
100
+ "src/experimental",
101
+ "src/typestubs",
102
+ "**/migrations/**",
103
+ "**/tests/**",
104
+ ]
105
+ pythonVersion = "3.10"
106
+ typeCheckingMode = "standard"
@@ -0,0 +1,3 @@
1
+ from qik.version import __version__
2
+
3
+ __all__ = ["__version__"]
qik-0.0.1/qik/arch.py ADDED
@@ -0,0 +1,40 @@
1
+ from __future__ import annotations
2
+
3
+ import platform
4
+ from typing import TYPE_CHECKING, Literal, TypeAlias
5
+
6
+ if TYPE_CHECKING:
7
+ ArchType: TypeAlias = Literal[
8
+ "win-64",
9
+ "win-32",
10
+ "linux-64",
11
+ "linux-aarch64",
12
+ "linux-ppc64le",
13
+ "linux-32",
14
+ "osx-arm64",
15
+ "osx-64",
16
+ ]
17
+
18
+
19
+ def get() -> ArchType:
20
+ """Get the architecture of a machine."""
21
+ system = platform.system()
22
+ arch = platform.architecture()[0]
23
+ machine = platform.machine()
24
+
25
+ if system == "Windows":
26
+ return "win-64" if arch == "64bit" else "win-32"
27
+ elif system == "Linux":
28
+ if machine == "x86_64":
29
+ return "linux-64"
30
+ elif machine == "aarch64":
31
+ return "linux-aarch64"
32
+ elif machine == "ppc64le":
33
+ return "linux-ppc64le"
34
+ elif arch == "32bit":
35
+ return "linux-32"
36
+ elif system == "Darwin":
37
+ if arch == "64bit":
38
+ return "osx-arm64" if machine == "arm64" else "osx-64"
39
+
40
+ return "unknown"