jeskit 0.5.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.
@@ -0,0 +1,2 @@
1
+ __pycache__/
2
+ .env
jeskit-0.5.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Zaslon-Hivemind
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
jeskit-0.5.0/PKG-INFO ADDED
@@ -0,0 +1,110 @@
1
+ Metadata-Version: 2.5
2
+ Name: jeskit
3
+ Version: 0.5.0
4
+ Summary: A verbose and advanced orchestrator for developers.
5
+ Author: Zaslon-Hivemind
6
+ License: MIT
7
+ License-File: LICENSE
8
+ Requires-Python: >=3.11
9
+ Requires-Dist: rich>=13.0
10
+ Description-Content-Type: text/markdown
11
+
12
+ # Jeskit
13
+
14
+ ## What is Jeskit?
15
+
16
+ Jeskit is a command running/orchestration utility that is built using Python, and is constantly recieving new updates!
17
+ Unlike many other alternatives, Jeskit is meant to be **Verbose**, **Simple**, and **clean**!
18
+
19
+ And if it doesn't have a feature/has a bug? Report it directly to issues!
20
+ (See below)
21
+
22
+ ---
23
+
24
+ ## Jeskit is, and is NOT:
25
+
26
+ **IS:**
27
+ * Command runner
28
+ * Command orchestrator
29
+ * A simpler alternative to many other projects
30
+ * Written by (As of writing this) a beginner Dev as a hobby!
31
+
32
+ **IS NOT:**
33
+ * A compiler
34
+ * Full build system
35
+ * Another piece to rice on your arch linux rice to be posted onto r/linux (Unless you REALLY want to)
36
+ * Maintained by a developer that is equal to the skills of Linus Torvalds, Terry A. Davis, or literally any dev that has existed longer than I have.
37
+ * A large, complex, and huge project.
38
+
39
+ Please take this as a hint before writing anything that could get you ratio'd on twitter.
40
+
41
+ ---
42
+
43
+ ## How to install?
44
+
45
+ Just simply type:
46
+ `pip install jeskit`
47
+
48
+ Extra download methods will be supported soon.
49
+
50
+ ---
51
+
52
+ ## Usage guide:
53
+
54
+ As of writing this (v0.5 release), there is only two real commands:
55
+ * `run`
56
+ * `version`
57
+
58
+ we'll be running deep into run.
59
+
60
+ #### How to format jeskit.toml
61
+
62
+ first, create `jeskit.toml`, exactly as spelt. Then, fill it up with Jesits (Basically a command). There is only three parameters:
63
+ * Name: The title of your Jesit, which is a toml table formatted like this: `[jesits.command]`, change command as needed.
64
+ * command: This is the exact terminal command that your jeskit.toml will do. Fill it below as a key-pair value.
65
+ * depends_on: an optional field that says what your Jesit depends on. Note that only one dependency can be placed per jesit as of now.
66
+
67
+ If you need a better example, here is a template:
68
+
69
+ ```toml
70
+ [jesit.one]
71
+ command = "echo Hello World!"
72
+
73
+ [jesit.two]
74
+ command = "echo Goodbye World!"
75
+ depends_on = ["one"]
76
+ ```
77
+
78
+ #### How to run a Jesit
79
+
80
+ As stated, a Jesit is just a command for Jeskit to run. As for how to do it... Just type:
81
+ `jeskit run [command]`
82
+
83
+ As simple as that!
84
+
85
+ ## Current issues:
86
+ - If you check my todo, not everything is done! This will be fixed later.
87
+ - Note that I am a beginner in programming, and human, and of course, I may not understand every single thing about programming. So please be patient if you have an issue.
88
+ - Some cases give an unexpected error or a python traceback. Use this in a hacky way for now.
89
+
90
+ ## How to contribute?
91
+
92
+ **If you have a bug or an issue:**
93
+
94
+ Report it into issues, as a bug report.
95
+
96
+ **If you have an request or a feature:**
97
+
98
+ Report it into issues, as a feature request.
99
+
100
+ **If you wanna give advice, talk, or recommend any changes that isn't directly a bug-fix, or a feature:**
101
+
102
+ Open up a discussion!
103
+
104
+ **If you wanna do a pull request:**
105
+
106
+ Open a PR. Please do include a detailed report on what changed, why did it change, and for what good? I'll be much more liklier to accept these.
107
+
108
+ ## To friends that see this...
109
+
110
+ Dawg go back to scrolling on instagram reels.
jeskit-0.5.0/README.md ADDED
@@ -0,0 +1,99 @@
1
+ # Jeskit
2
+
3
+ ## What is Jeskit?
4
+
5
+ Jeskit is a command running/orchestration utility that is built using Python, and is constantly recieving new updates!
6
+ Unlike many other alternatives, Jeskit is meant to be **Verbose**, **Simple**, and **clean**!
7
+
8
+ And if it doesn't have a feature/has a bug? Report it directly to issues!
9
+ (See below)
10
+
11
+ ---
12
+
13
+ ## Jeskit is, and is NOT:
14
+
15
+ **IS:**
16
+ * Command runner
17
+ * Command orchestrator
18
+ * A simpler alternative to many other projects
19
+ * Written by (As of writing this) a beginner Dev as a hobby!
20
+
21
+ **IS NOT:**
22
+ * A compiler
23
+ * Full build system
24
+ * Another piece to rice on your arch linux rice to be posted onto r/linux (Unless you REALLY want to)
25
+ * Maintained by a developer that is equal to the skills of Linus Torvalds, Terry A. Davis, or literally any dev that has existed longer than I have.
26
+ * A large, complex, and huge project.
27
+
28
+ Please take this as a hint before writing anything that could get you ratio'd on twitter.
29
+
30
+ ---
31
+
32
+ ## How to install?
33
+
34
+ Just simply type:
35
+ `pip install jeskit`
36
+
37
+ Extra download methods will be supported soon.
38
+
39
+ ---
40
+
41
+ ## Usage guide:
42
+
43
+ As of writing this (v0.5 release), there is only two real commands:
44
+ * `run`
45
+ * `version`
46
+
47
+ we'll be running deep into run.
48
+
49
+ #### How to format jeskit.toml
50
+
51
+ first, create `jeskit.toml`, exactly as spelt. Then, fill it up with Jesits (Basically a command). There is only three parameters:
52
+ * Name: The title of your Jesit, which is a toml table formatted like this: `[jesits.command]`, change command as needed.
53
+ * command: This is the exact terminal command that your jeskit.toml will do. Fill it below as a key-pair value.
54
+ * depends_on: an optional field that says what your Jesit depends on. Note that only one dependency can be placed per jesit as of now.
55
+
56
+ If you need a better example, here is a template:
57
+
58
+ ```toml
59
+ [jesit.one]
60
+ command = "echo Hello World!"
61
+
62
+ [jesit.two]
63
+ command = "echo Goodbye World!"
64
+ depends_on = ["one"]
65
+ ```
66
+
67
+ #### How to run a Jesit
68
+
69
+ As stated, a Jesit is just a command for Jeskit to run. As for how to do it... Just type:
70
+ `jeskit run [command]`
71
+
72
+ As simple as that!
73
+
74
+ ## Current issues:
75
+ - If you check my todo, not everything is done! This will be fixed later.
76
+ - Note that I am a beginner in programming, and human, and of course, I may not understand every single thing about programming. So please be patient if you have an issue.
77
+ - Some cases give an unexpected error or a python traceback. Use this in a hacky way for now.
78
+
79
+ ## How to contribute?
80
+
81
+ **If you have a bug or an issue:**
82
+
83
+ Report it into issues, as a bug report.
84
+
85
+ **If you have an request or a feature:**
86
+
87
+ Report it into issues, as a feature request.
88
+
89
+ **If you wanna give advice, talk, or recommend any changes that isn't directly a bug-fix, or a feature:**
90
+
91
+ Open up a discussion!
92
+
93
+ **If you wanna do a pull request:**
94
+
95
+ Open a PR. Please do include a detailed report on what changed, why did it change, and for what good? I'll be much more liklier to accept these.
96
+
97
+ ## To friends that see this...
98
+
99
+ Dawg go back to scrolling on instagram reels.
@@ -0,0 +1,13 @@
1
+ ### NOTES UPDATED EVERY COMMIT!
2
+ ---
3
+
4
+ 9/22/26
5
+
6
+ K, Toml error has been fixed, and cli will be worked. If you didn't notice from this commit, a bunch of things have been revamped.
7
+ As for the error.py, that will come in a future case.
8
+
9
+ Right now, make CLI, polish, and prepare for a v0.5 release on pypi and github (publicly!)
10
+
11
+ K, good news again! This project is basically ready for a experimental phase, this means I'll put it on the backburner for a bit, however this project will NOT be abandonded.
12
+
13
+ Again, if you have any problems, let me know on GitHub! Read the README for more info!
@@ -0,0 +1,30 @@
1
+ # Roadmap
2
+ > **WARNING**: This will be prone to change!
3
+
4
+ ## Stage 1 — Core
5
+ - [X] Simple execution pipeline (Non-CLI)
6
+ - [x] Use `output.py`
7
+ - [x] Fix TOMLLibError whenever jeskit throws a tantrum that you did't write a `jeskit.toml` correctly
8
+ - [x] Utilize and populate `output` (Enough for v0.5)
9
+ - [x] Fix whatever sh*t is still there.
10
+ - [x] Functioning execution pipeline
11
+ - [X] Reformed Configuration Model (I don't know how I skipped a few... Oh well.) (And you certainly didn't add one huh?)
12
+ - [x] Task model
13
+ - [x] Do enough for v0.5
14
+
15
+ ## Stage 1.5 - Post-v0.5
16
+ - [ ] Extra cmds
17
+ - [ ] Dependency
18
+
19
+ ## Stage 2 — Developer UX
20
+ - [ ] CLI
21
+ - [ ] list
22
+ - [ ] plan
23
+ - [ ] Good errors
24
+ - [ ] Logging
25
+ - [ ] Actual documentation
26
+ - [ ] Tests
27
+
28
+ ## Stage 3 — One advanced feature
29
+ - [ ] Parallel execution
30
+ - [ ] Graphs
@@ -0,0 +1,26 @@
1
+ # Jeskit
2
+
3
+ Jeskit is a language-agnostic developer task runner
4
+ built around explicit dependency graphs. Built in Python.
5
+
6
+ ## Core responsibilities
7
+
8
+ 1. Define tasks
9
+ 2. Build dependency graphs
10
+ 3. Plan execution
11
+ 4. Execute commands
12
+ 5. Report results
13
+
14
+ ## It is NOT
15
+
16
+ - A compiler
17
+ - A package manager
18
+ - A CI/CD platform
19
+ - An IDE
20
+ - A replacement for language-specific build systems
21
+
22
+ ## Initial goal
23
+
24
+ Build a small, reliable Python CLI capable of reading a
25
+ TaskGraph configuration, resolving dependencies, executing
26
+ tasks in the correct order, and reporting failures clearly.
File without changes
@@ -0,0 +1,22 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "jeskit"
7
+ version = "0.5.0"
8
+ description = "A verbose and advanced orchestrator for developers."
9
+ readme = "README.md"
10
+ requires-python = ">=3.11"
11
+ license = { text = "MIT" }
12
+
13
+ authors = [
14
+ { name = "Zaslon-Hivemind" }
15
+ ]
16
+
17
+ dependencies = [
18
+ "rich>=13.0"
19
+ ]
20
+
21
+ [project.scripts]
22
+ jeskit = "jeskit.cli:main"
File without changes
@@ -0,0 +1,7 @@
1
+ # Official commands to be ported to cli.py, for ease of devlopment/routing.
2
+ from toml_parser import load_toml
3
+ from engine.runner import run_jesit
4
+
5
+ def cli_run(jesit: str):
6
+ jeskit = load_toml()
7
+ run_jesit(jesit, jeskit)
@@ -0,0 +1,59 @@
1
+ # Forgot to mention, this is supposed to be the verbosity, and containment center for rich. Please keep it here.
2
+ from ..models import ExecutionResult
3
+ from error import JeskitError, NotFoundJeskitTomlError, InvalidJeskitTomlError, UnknownJesitError, CircularDependencyError
4
+ from ..error import JeskitError, NotFoundJeskitTomlError, InvalidJeskitTomlError, UnknownJesitError, CircularDependencyError
5
+ from rich.console import Console
6
+ console = Console()
7
+
8
+ class GeneralConsoleOutput: # General things like help-guide, version, etc.
9
+ pass
10
+
11
+ class RunnerConsoleOutput: # For while `jeskit run` is being done.
12
+ @staticmethod
13
+ def finished_out(result: ExecutionResult):
14
+ if result.success:
15
+ console.print(
16
+ f"[bold green]✓[/bold green] "
17
+ f"Ran {result.name} successfully "
18
+ f"in {result.duration:.3f}s"
19
+ )
20
+ else:
21
+ console.print(
22
+ f"[bold red]✗[/bold red] "
23
+ f"Failed {result.name} "
24
+ f"after {result.duration:.3f}s"
25
+ )
26
+
27
+ class ErrorConsoleOutput: # Still error output.
28
+ @staticmethod
29
+ def error_out(error):
30
+ if error == NotFoundJeskitTomlError:
31
+ console.print(
32
+ "[bold red]Error:[/bold red] "
33
+ "Couldn't find jeskit.toml in your current directory."
34
+ )
35
+ console.print(
36
+ "[yellow]Suggested Fix:[/yellow] "
37
+ "Check that [bold]jeskit.toml[/bold] exists in your current directory."
38
+ )
39
+
40
+ elif error == InvalidJeskitTomlError:
41
+ console.print(
42
+ "[bold red]Error:[/bold red] "
43
+ "jeskit.toml contains invalid TOML syntax."
44
+ )
45
+
46
+ elif error == UnknownJesitError:
47
+ console.print(
48
+ "[bold red] Error: [/bold red]"
49
+ "the requested jesit was not found."
50
+ )
51
+ elif error == CircularDependencyError:
52
+ console.print(
53
+ "[bold red] Error: [/bold red]"
54
+ "the requested jesit is creating a circular deoendency! The jesit will not run.")
55
+
56
+ else:
57
+ console.print(
58
+ f"[bold red]Error:[/bold red] Unexpected Error!"
59
+ )
@@ -0,0 +1,21 @@
1
+ # Unlike runner, actually does the commands it's given. So no coordination.
2
+
3
+ import subprocess
4
+ from ..utils.timing_util import start_perftime, stop_perftime
5
+ from ..models import Jesit, ExecutionResult
6
+
7
+
8
+ def execute_cmd(jesit: Jesit) -> ExecutionResult:
9
+ start = start_perftime()
10
+
11
+ result = subprocess.run(
12
+ jesit.command,
13
+ shell=True,
14
+ )
15
+
16
+ return ExecutionResult(
17
+ name=jesit.name,
18
+ success=result.returncode == 0,
19
+ duration=stop_perftime(start),
20
+ return_code=result.returncode,
21
+ )
@@ -0,0 +1,56 @@
1
+ # Unlike the executor, this just coordinates something, first layer of the commands.
2
+
3
+ # Unlike the executor, this just coordinates something, first layer of the commands.
4
+
5
+ from .models import Jesit
6
+ from ..decor.output import RunnerConsoleOutput, ErrorConsoleOutput
7
+ from ..error import UnknownJesitError, UnknownJesitDependencyError, CircularDependencyError
8
+ from .executor import execute_cmd
9
+ import sys
10
+
11
+
12
+ def run_jesit(name: str, jesits: list[Jesit]) -> bool:
13
+ jesit_map = {jesit.name: jesit for jesit in jesits}
14
+
15
+ if name not in jesit_map:
16
+ ErrorConsoleOutput.error_out(UnknownJesitError)
17
+ sys.exit(1)
18
+
19
+ visited = set()
20
+ resolving = set()
21
+
22
+ def run(name: str) -> bool:
23
+ if name in resolving:
24
+ ErrorConsoleOutput.error_out(CircularDependencyError)
25
+ sys.exit(1)
26
+
27
+ if name in visited:
28
+ return True
29
+
30
+ if name not in jesit_map:
31
+ ErrorConsoleOutput.error_out(UnknownJesitDependencyError)
32
+ sys.exit(1)
33
+
34
+ resolving.add(name)
35
+
36
+ jesit = jesit_map[name]
37
+
38
+ for dependency in jesit.depends_on:
39
+ if not run(dependency):
40
+ resolving.remove(name)
41
+ return False
42
+
43
+ result = execute_cmd(jesit)
44
+
45
+ RunnerConsoleOutput.finished_out(result)
46
+
47
+ resolving.remove(name)
48
+
49
+ if not result.success:
50
+ return False
51
+
52
+ visited.add(name)
53
+
54
+ return True
55
+
56
+ return run(name)
@@ -0,0 +1,21 @@
1
+ # This is meant to just keep an list of errors, so that models.py isn't cluttered. Plus, will be used for exit codes maybe in the near future.
2
+
3
+ class JeskitError(Exception):
4
+ """Base exception for Jeskit."""
5
+
6
+
7
+ class InvalidJeskitTomlError(JeskitError):
8
+ """Raised when Jeskit.toml is malformed or invalid."""
9
+
10
+
11
+ class NotFoundJeskitTomlError(JeskitError):
12
+ """Raised when jeskit.toml is not found."""
13
+
14
+ class UnknownJesitError(JeskitError):
15
+ """Raised when a requested Jesit cannot be found."""
16
+
17
+ class UnknownJesitDependencyError(JeskitError):
18
+ """Raised when a Jesit's dependency cannot be found."""
19
+
20
+ class CircularDependencyError(JeskitError):
21
+ """Raised when a Jesit creates a circular dependency."""
File without changes
@@ -0,0 +1,5 @@
1
+ from .cli import main
2
+
3
+
4
+ if __name__ == "__main__":
5
+ main()
@@ -0,0 +1,38 @@
1
+ # ENTRY POINT!
2
+ import argparse
3
+ from .engine.runner import run_jesit
4
+ from .toml_parser import load_toml
5
+ from .commands import cli_run
6
+ import sys
7
+
8
+
9
+ def create_parser() -> argparse.ArgumentParser:
10
+ parser = argparse.ArgumentParser(
11
+ prog="jeskit",
12
+ description="A verbose orchestrator for devs alike!",
13
+ )
14
+
15
+ parser.add_argument(
16
+ "command",
17
+ help="Command to execute",
18
+ )
19
+
20
+ parser.add_argument(
21
+ "jesit",
22
+ nargs="?",
23
+ help="Jesit to run",
24
+ )
25
+
26
+ return parser
27
+
28
+
29
+ def main():
30
+ parser = create_parser()
31
+ args = parser.parse_args()
32
+
33
+ if args.command == "run":
34
+ cli_run(args.jesit)
35
+ sys.exit(0)
36
+
37
+ if args.command == "version":
38
+ print("Version: 0.5.0")
@@ -0,0 +1,7 @@
1
+ # Official commands to be ported to cli.py, for ease of devlopment/routing.
2
+ from .toml_parser import load_toml
3
+ from .engine.runner import run_jesit
4
+
5
+ def cli_run(jesit: str):
6
+ jeskit = load_toml()
7
+ run_jesit(jesit, jeskit)
File without changes
@@ -0,0 +1,59 @@
1
+ # Forgot to mention, this is supposed to be the verbosity, and containment center for rich. Please keep it here.
2
+ from ..models import ExecutionResult
3
+ from rich.console import Console
4
+ from error import JeskitError, NotFoundJeskitTomlError, InvalidJeskitTomlError, UnknownJesitError, CircularDependencyError
5
+ from ..error import JeskitError, NotFoundJeskitTomlError, InvalidJeskitTomlError, UnknownJesitError, CircularDependencyError
6
+ console = Console()
7
+
8
+ class GeneralConsoleOutput: # General things like help-guide, version, etc.
9
+ pass
10
+
11
+ class RunnerConsoleOutput: # For while `jeskit run` is being done.
12
+ @staticmethod
13
+ def finished_out(result: ExecutionResult):
14
+ if result.success:
15
+ console.print(
16
+ f"[bold green]✓[/bold green] "
17
+ f"Ran {result.name} successfully "
18
+ f"in {result.duration:.3f}s"
19
+ )
20
+ else:
21
+ console.print(
22
+ f"[bold red]✗[/bold red] "
23
+ f"Failed {result.name} "
24
+ f"after {result.duration:.3f}s"
25
+ )
26
+
27
+ class ErrorConsoleOutput: # Still error output.
28
+ @staticmethod
29
+ def error_out(error):
30
+ if error == NotFoundJeskitTomlError:
31
+ console.print(
32
+ "[bold red]Error:[/bold red] "
33
+ "Couldn't find jeskit.toml in your current directory."
34
+ )
35
+ console.print(
36
+ "[yellow]Suggested Fix:[/yellow] "
37
+ "Check that [bold]jeskit.toml[/bold] exists in your current directory."
38
+ )
39
+
40
+ elif error == InvalidJeskitTomlError:
41
+ console.print(
42
+ "[bold red]Error:[/bold red] "
43
+ "jeskit.toml contains invalid TOML syntax."
44
+ )
45
+
46
+ elif error == UnknownJesitError:
47
+ console.print(
48
+ "[bold red] Error: [/bold red]"
49
+ "the requested jesit was not found."
50
+ )
51
+ elif error == CircularDependencyError:
52
+ console.print(
53
+ "[bold red] Error: [/bold red]"
54
+ "the requested jesit is creating a circular deoendency! The jesit will not run.")
55
+
56
+ else:
57
+ console.print(
58
+ f"[bold red]Error:[/bold red] Unexpected Error!"
59
+ )
File without changes
@@ -0,0 +1,21 @@
1
+ # Unlike runner, actually does the commands it's given. So no coordination.
2
+
3
+ import subprocess
4
+ from ..utils.timing_util import start_perftime, stop_perftime
5
+ from ..models import Jesit, ExecutionResult
6
+
7
+
8
+ def execute_cmd(jesit: Jesit) -> ExecutionResult:
9
+ start = start_perftime()
10
+
11
+ result = subprocess.run(
12
+ jesit.command,
13
+ shell=True,
14
+ )
15
+
16
+ return ExecutionResult(
17
+ name=jesit.name,
18
+ success=result.returncode == 0,
19
+ duration=stop_perftime(start),
20
+ return_code=result.returncode,
21
+ )
@@ -0,0 +1,59 @@
1
+ # Unlike the executor, this just coordinates something, first layer of the commands.
2
+
3
+ # Unlike the executor, this just coordinates something, first layer of the commands.
4
+
5
+ from ..models import Jesit
6
+ from ..decor.output import RunnerConsoleOutput, ErrorConsoleOutput
7
+ from ..error import (
8
+ UnknownJesitError,
9
+ UnknownJesitDependencyError,
10
+ CircularDependencyError,
11
+ )
12
+ from .executor import execute_cmd
13
+ import sys
14
+
15
+ def run_jesit(name: str, jesits: list[Jesit]) -> bool:
16
+ jesit_map = {jesit.name: jesit for jesit in jesits}
17
+
18
+ if name not in jesit_map:
19
+ ErrorConsoleOutput.error_out(UnknownJesitError)
20
+ sys.exit(1)
21
+
22
+ visited = set()
23
+ resolving = set()
24
+
25
+ def run(name: str) -> bool:
26
+ if name in resolving:
27
+ ErrorConsoleOutput.error_out(CircularDependencyError)
28
+ sys.exit(1)
29
+
30
+ if name in visited:
31
+ return True
32
+
33
+ if name not in jesit_map:
34
+ ErrorConsoleOutput.error_out(UnknownJesitDependencyError)
35
+ sys.exit(1)
36
+
37
+ resolving.add(name)
38
+
39
+ jesit = jesit_map[name]
40
+
41
+ for dependency in jesit.depends_on:
42
+ if not run(dependency):
43
+ resolving.remove(name)
44
+ return False
45
+
46
+ result = execute_cmd(jesit)
47
+
48
+ RunnerConsoleOutput.finished_out(result)
49
+
50
+ resolving.remove(name)
51
+
52
+ if not result.success:
53
+ return False
54
+
55
+ visited.add(name)
56
+
57
+ return True
58
+
59
+ return run(name)
@@ -0,0 +1,21 @@
1
+ # This is meant to just keep an list of errors, so that models.py isn't cluttered. Plus, will be used for exit codes maybe in the near future.
2
+
3
+ class JeskitError(Exception):
4
+ """Base exception for Jeskit."""
5
+
6
+
7
+ class InvalidJeskitTomlError(JeskitError):
8
+ """Raised when Jeskit.toml is malformed or invalid."""
9
+
10
+
11
+ class NotFoundJeskitTomlError(JeskitError):
12
+ """Raised when jeskit.toml is not found."""
13
+
14
+ class UnknownJesitError(JeskitError):
15
+ """Raised when a requested Jesit cannot be found."""
16
+
17
+ class UnknownJesitDependencyError(JeskitError):
18
+ """Raised when a Jesit's dependency cannot be found."""
19
+
20
+ class CircularDependencyError(JeskitError):
21
+ """Raised when a Jesit creates a circular dependency."""
@@ -0,0 +1,14 @@
1
+ from dataclasses import dataclass
2
+
3
+ @dataclass
4
+ class Jesit:
5
+ name: str
6
+ command: str
7
+ depends_on: list[str]
8
+
9
+ @dataclass
10
+ class ExecutionResult:
11
+ name: str
12
+ success: bool
13
+ duration: float
14
+ return_code: int
@@ -0,0 +1,28 @@
1
+ import tomllib
2
+ import sys
3
+ from .models import Jesit
4
+ from .decor.output import ErrorConsoleOutput
5
+ from .error import NotFoundJeskitTomlError, InvalidJeskitTomlError
6
+
7
+ def load_toml(path="jeskit.toml") -> list[Jesit]:
8
+ try:
9
+ with open(path, "rb") as file:
10
+ data = tomllib.load(file)
11
+ except FileNotFoundError:
12
+ ErrorConsoleOutput.error_out(NotFoundJeskitTomlError)
13
+ sys.exit(1)
14
+ except tomllib.TOMLDecodeError:
15
+ ErrorConsoleOutput.error_out(InvalidJeskitTomlError)
16
+ sys.exit(1)
17
+
18
+ jesits = []
19
+ for name, config in data.get("jesits", {}).items():
20
+ jesits.append(
21
+ Jesit(
22
+ name=name,
23
+ command=config["command"],
24
+ depends_on=config.get("depends_on", []),
25
+ )
26
+ )
27
+
28
+ return jesits
File without changes
@@ -0,0 +1,8 @@
1
+ from time import perf_counter
2
+
3
+ def start_perftime() -> float:
4
+ return perf_counter()
5
+
6
+
7
+ def stop_perftime(start_time: float) -> float:
8
+ return perf_counter() - start_time
@@ -0,0 +1,6 @@
1
+ from toml_parser import load_toml
2
+ from engine.runner import run_jesit
3
+
4
+ jesit = load_toml()
5
+
6
+ print(jesit)