Compare commits

...

3 Commits

Author SHA1 Message Date
janishutz 2fd69cc595 feat(init): Templates handling 2026-04-25 16:43:53 +02:00
janishutz 541a876307 feat(config): Schema validator, initial config merger setup 2026-04-23 11:31:01 +02:00
janishutz 5126e0373f feat(PKGBUILD): First setup 2026-04-23 11:30:31 +02:00
17 changed files with 128 additions and 7 deletions
+28
View File
@@ -0,0 +1,28 @@
# Maintainer: Janis Hutz <development@janishutz.com>
pkgname=archmgr-git
pkgver=0.0.0
pkgrel=1
pkgdesc='A nixos-like declarative config and package manager for Arch Linux'
arch=('any')
url="https://github.com/janishutz/archmgr"
license=('GPL3')
depends=('python', 'python-pyaml')
makedepends=('git')
provides=('archmgr')
conflicts=('archmgr')
source=("$pkgname"::git+${url}.git)
sha256sums=('SKIP') # TODO: Add?
pkgver() {
cd "${pkgname}"
# TODO: For the non-git pkgbuild, need to use different output
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
}
package() {
cd "${pkgname}"
# TODO: Need to finish
}
+2
View File
@@ -9,6 +9,7 @@ import commands.init as init
import commands.pull as pull import commands.pull as pull
import commands.push as push import commands.push as push
import commands.prepare as setup import commands.prepare as setup
from config import load_config
if __name__ == "__main__": if __name__ == "__main__":
args, ap = cliargs.add_cli_args() args, ap = cliargs.add_cli_args()
@@ -29,6 +30,7 @@ if __name__ == "__main__":
\\___/ \\___/
""") """)
print(load_config("config.yml"))
try: try:
if args.cmd == "commit": if args.cmd == "commit":
commit.commit(args.force, args.no_render) commit.commit(args.force, args.no_render)
+14 -5
View File
@@ -1,19 +1,28 @@
import os import os
import shutil
import commands.util.git as git import commands.util.git as git
from commands.util.input_mgr import confirm
def init(force: bool = False): def init(force: bool = False):
dir = os.getcwd() dir = os.getcwd()
script_dir = os.path.dirname(os.path.realpath(__file__))
if force: if force:
[os.remove(dir) for dir in os.listdir(dir)] if confirm(False, "Do you really want to IRREVERSIBLY DELETE the contents of this folder and redo setup?"):
[os.remove(file) for file in os.listdir(dir)]
git.init(dir) git.init(dir)
os.mkdir(dir + "/config") os.mkdir(dir + "/config")
os.mkdir(dir + "/etc") os.mkdir(dir + "/db")
with open(dir + "/config.yaml") as file: os.mkdir(dir + "/system")
file.write("") os.mkdir(dir + "/includes")
shutil.copy(script_dir + "/templates/config/config.yml", dir + "/config.yml")
shutil.copy(script_dir + "/templates/config/system/", dir + "/includes/system/")
shutil.copy(script_dir + "/templates/config/templates/", dir + "/includes/templates/")
shutil.copy(script_dir + "/templates/README.md", dir + "/README.md")
print("Initialized a new archmgr repository") print("Initialized a new archmgr repository")
# TODO: For the files, store the permissions in a db
# TODO: Warn user to not delete .config/archmgr repo # TODO: Warn user to not delete .config/archmgr repo
# TODO: Set up that repo (where to put it? /usr/share?) # TODO: Set up that repo (where to put it? /usr/share?)
# TODO: Consider collecting function # TODO: Consider collecting function -> If no files present, will only collect the pkgs, else also the files
# TODO: Config folder instead of single config file # TODO: Config folder instead of single config file
# TODO: Also store the folder name of the config folder in that repo (needs to be easily changeable for user!) # TODO: Also store the folder name of the config folder in that repo (needs to be easily changeable for user!)
+25
View File
@@ -88,6 +88,12 @@
}, },
"maxItems": 5, "maxItems": 5,
"minItems": 1 "minItems": 1
},
"count": {
"type": "number",
"description": "The number of mirrors to add to the list",
"maximum": 20,
"minimum": 3
} }
}, },
"required": [ "required": [
@@ -273,6 +279,25 @@
"additionalProperties": false "additionalProperties": false
} }
}, },
"symlinks": {
"type": "array",
"description": "Symlinks to create",
"items": {
"type": "object",
"properties": {
"destination": {
"type": "string",
"description": "The directory the link should point to",
"pattern": "^(^(~|\\.|\\.\\.)?\\/)?([\\w\\/.-]+(?!.*[^\\w\\/.-]+))"
},
"location": {
"type": "string",
"description": "What to call the link",
"pattern": "^(^(~|\\.|\\.\\.)?\\/)?([\\w\\/.-]+(?!.*[^\\w\\/.-]+))"
}
}
}
},
"cmds": { "cmds": {
"type": "object", "type": "object",
"properties": { "properties": {
+31
View File
@@ -0,0 +1,31 @@
from typing import Any, cast
import yaml
from config import validator
from config.merger import merge_configs
def _load_config_file(file: str):
with open(file, "r") as f:
parsed = yaml.load(f, Loader=yaml.FullLoader)
return parsed
def load_config(file: str):
# Load and validate initial config
try:
loaded_conf = _load_config_file(file)
except Exception:
return {}
if not validator.validate(loaded_conf):
return {}
conf = cast(dict[str, Any], loaded_conf)
requires = cast(list[str], conf["requires"])
conf.pop("requires")
# Recursively load files
for conf_file in requires:
conf = merge_configs(conf, load_config(conf_file))
return conf
+6
View File
@@ -0,0 +1,6 @@
def merge_configs(config: dict, new_config: dict):
if len(new_config) == 0 or len(config) == 0:
return config
# Merge configs
return config
+18 -2
View File
@@ -1,2 +1,18 @@
def validate(): import json
pass import jsonschema
with open("config.schema.json") as file:
schema = json.load(file)
def validate(config):
try:
jsonschema.validate(config, schema)
except jsonschema.SchemaError:
print("Schema invalid")
return False
except jsonschema.ValidationError:
print("Config invalid")
return False
return True
+1
View File
@@ -1,3 +1,4 @@
pyyaml
pylette pylette
argcomplete argcomplete
inquirer inquirer
+3
View File
@@ -0,0 +1,3 @@
# archmgr data folder
archmgr is a nixos-inspired package and config manager for Arch Linux.
To function, it needs both a configuration file (or multiple) and
View File
View File
View File
View File
View File
View File