diff --git a/config.schema.json b/config.schema.json index 8df58d0..8df178a 100644 --- a/config.schema.json +++ b/config.schema.json @@ -19,25 +19,189 @@ "type:": "array", "description": "the packages to be installed, by their package name", "items": { - "type": "string" + "type": "string", + "pattern": "^[a-z0-9-._]+(?=[a-z0-9]$)" } }, - "presets": { + "repos": { + "type": "object", + "properties": { + "enabled_repos": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": false, + "description": "The repos to set up", + "properties": { + "name": { + "type": "string", + "description": "The repositories to set up", + "pattern": "^(core|extra|core-testing|extra-testing|multilib|multilib-testing|[a-z0-9-]+(?=[a-z0-9]$))" + }, + "setup_cmds": { + "type": "array", + "description": "The commands to run to set it up (optional if any of the explicitly supported ones)", + "items": { + "type": "string", + "description": "Command to run" + } + }, + "mirrors": { + "type": "object", + "description": "Configure the mirrors to use", + "properties": { + "use_default": { + "type": "boolean", + "description": "Whether to use the default mirrors or not", + "default": true + }, + "extra_mirrors": { + "type": "array", + "description": "Any extra mirrors you want to add. At least one mirror needs to be put here if use_default is false. Order matters", + "items": { + "type": "string" + } + } + } + } + } + } + }, + "reflector": { + "type": "object", + "description": "Use reflector to update the mirrors", + "properties": { + "enabled": { + "type": "boolean", + "default": false + }, + "interval": { + "type": "number", + "description": "The number of days to elapse between reflector reruns" + }, + "countries": { + "type": "array", + "description": "The countries in which the should be located (only applies for the main arch repos)", + "items": { + "type": "string", + "pattern": "^[A-Z][a-z]*[a-z]$" + }, + "maxItems": 5, + "minItems": 1 + } + }, + "required": [ + "enabled" + ], + "additionalProperties": false + }, + "additionalProperties": false + } + }, + "bundles": { "type": "array", + "description": "Bundled packages, installing all the recommended extra software for them (such as hyprland and nvim)", "maxItems": 1, "items": { - "type": "string" + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "The bundle name", + "pattern": "^[a-z0-9-._]+(?=[a-z0-9]$)" + }, + "ignored_pkgs": { + "type": "array", + "description": "List of packages from the bundle that should not be installed", + "items": { + "type": "string", + "pattern": "^[a-z0-9-._]+(?=[a-z0-9]$)" + } + } + }, + "additionalProperties": false, + "required": [ + "name" + ] } } - } + }, + "additionalProperties": false }, "users": { "type": "array", - "properties": {} + "description": "Users to add, including groups. Users will be diffed and removed if they are removed from here. No files are deleted", + "items": { + "type": "object", + "properties": { + "username": { + "type": "string", + "pattern": "^[a-zA-Z0-9\\-._]{2,19}(?=[a-zA-Z0-9]$)" + }, + "groups": { + "type": "array", + "description": "The groups to add the user to. Groups are created if they don't exist. User's own group doesn't have to be listed explicitly", + "items": { + "type": "string", + "pattern": "^[a-zA-Z0-9\\-._]{2,19}(?=[a-zA-Z0-9]$)" + } + }, + "sudo_user": { + "type": "boolean", + "default": false, + "description": "Whether a user can use sudo or not. Same as appending them to the `wheel` group" + }, + "home_dir": { + "type": "boolean", + "description": "Whether to create a home directory for the user or not", + "default": false + } + }, + "required": [ + "username" + ], + "additionalProperties": false + } }, "boot": { "type": "object", - "properties": {} + "description": "Settings for the bootloader, such as theme, using os-prober, etc", + "properties": { + "bootloader": { + "type": "string", + "description": "The bootloader to use (more coming eventually)", + "pattern": "^(grub)" + }, + "esp_dir": { + "type": "string", + "description": "The directory for the bootloader files. Has to end in slash", + "pattern": "^(^(~|\\.|\\.\\.)?\\/)?([\\w\\/.-]+(?!.*[^\\w\\/.-]+))\\/$" + }, + "theme": { + "type": "object", + "description": "Configuration for the bootloader theme", + "properties": { + "folder": { + "type": "string", + "description": "Where the folder for the theme is found. Can be relative to the config repo or file system and has to end in slash", + "pattern": "^(^(~|\\.|\\.\\.)?\\/)?([\\w\\/.-]+(?!.*[^\\w\\/.-]+))\\/$" + } + }, + "additionalProperties": false, + "required": [ + "folder" + ] + }, + "os_prober": { + "type": "boolean", + "description": "Whether to enable OS prober to search for other operating systems" + } + }, + "additionalProperties": false, + "required": [ + "bootloader", + "esp_dir" + ] }, "themes": { "type": "object", @@ -45,16 +209,20 @@ }, "git": { "type": "object", - "description": "Options", + "description": "Automatically set up credential manager and clone repos", "properties": { "creds": { "type": "object", "description": "Which git services to log into", "properties": { - "ssh_cert": { - "type": "string" + "manager": { + "type": "string", + "description": "The git credential manager to use. Set to none if you don't want one (default)", + "pattern": "^(git-credential-manager|none)", + "default": "none" } - } + }, + "additionalProperties": false }, "repos": { "type": "array", @@ -64,17 +232,23 @@ "properties": { "url": { "type": "string", - "description": "git clone URL", - "pattern": "^(https?:\\/\\/([a-z0-9-]+\\.)+[a-z]+(\\/[a-zA-Z0-9-.]+)+)|(([a-z]+@[a-z0-9-]+\\.)+[a-z]+:([a-zA-Z0-9.-]+\\/)+[a-zA-Z0-9.-]+)" + "description": "git clone URL (ssh or HTTP(S))", + "pattern": "^((https?):\\/\\/(([a-z0-9-]+)((?=\\.))\\.)+[a-z]+(?=\\/)\\/([\\w\\-?.=]+(?=\\/[\\w\\-?.=])\\/)*([\\w\\-?&.=\\/]+(?=[\\w\\-.=\\/]$)))|([a-zA-Z0-9\\-._]+(?=[a-zA-Z0-9])[a-zA-Z0-9])@(([a-z0-9\\-]+(?=\\.))\\.)+[a-z]+(?=:):([a-zA-Z0-9\\-._]+(?=\\/)\\/)+([a-zA-Z0-9\\-._]+(?=[a-zA-Z0-9]$))" }, "clone_path": { "type": "string", "description": "The location on the local system where to put it. Must be absolute path. Parent folders will be created if they don't exist", - "pattern": "^~?\\/([0-9a-zA-Z.-_]+\\/)*" + "pattern": "^(^(~|\\.|\\.\\.)?\\/)?([\\w\\/.-]+(?!.*[^\\w\\/.-]+))\\/$" } - } + }, + "additionalProperties": false, + "required": [ + "url", + "clone_path" + ] } - } + }, + "additionalProperties": false } }, "template_data": { @@ -93,20 +267,89 @@ } }, "required": [ - "properties", + "name", "data" ], "additionalProperties": false } }, "cmds": { - "type": "array", - "description": "Commands to run on first install", - "items": { - "type": "string" - } - }, - "additionalProperties": false + "type": "object", + "properties": { + "once": { + "type": "array", + "description": "Commands to run on only once (uses the name property to determine if it needs to run)", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "This name is used to track if a command was run before." + }, + "cmd": { + "type": "string" + }, + "hook": { + "type": "string", + "description": "Where in the execution of archmgr to run", + "default": "end", + "pattern": "^(pre-pkg|post-pkg|pre-git|post-git|end)" + }, + "user": { + "type": "string", + "default": "root", + "pattern": "^[a-zA-Z0-9\\-._]{2,19}(?=[a-zA-Z0-9]$)", + "description": "The user to run as. Be aware that only the current user's password is available, unless capture_output is set to false" + }, + "capture_output": { + "type": "boolean", + "default": true, + "description": "Whether or not to hide the output from the user" + } + }, + "additionalProperties": false, + "required": [ + "name", + "cmd" + ] + } + }, + "always": { + "type": "array", + "description": "Commands to run on each apply", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Used to indicate to user what command is executing. If omitted, will be truncated cmd" + }, + "cmd": { + "type": "string" + }, + "hook": { + "type": "string", + "description": "Where in the execution of archmgr to run", + "default": "end", + "pattern": "^(pre-pkg|post-pkg|pre-git|post-git|end)" + }, + "user": { + "type": "string", + "default": "root", + "pattern": "^[a-zA-Z0-9\\-._]{2,19}(?=[a-zA-Z0-9]$)", + "description": "The user to run as. Be aware that only the current user's password is available, unless capture_output is set to false" + }, + "capture_output": { + "type": "boolean", + "default": true, + "description": "Whether or not to hide the output from the user" + } + } + } + } + }, + "additionalProperties": false + } }, "required": [ "pkgs", diff --git a/config.yml b/config.yml index 1e15cc9..2cbab90 100644 --- a/config.yml +++ b/config.yml @@ -4,10 +4,15 @@ requires: - path/to/other/configs/relative/to/this # Reads the other configs after finishing this one pkgs: - named: + individual: - pkg_name - presets: - - hyprland + bundles: + - name: hyprland + repos: + reflector: + enabled: false + countries: + - Switzerland users: - username: username @@ -17,14 +22,13 @@ users: boot: bootloader: grub + esp_dir: /boot/ theme: - src: git # (expects a git clone url) or repo (for this repo) or url (for a valid URL openable using wget) - url: path/to/theme - build: none # or make TODO: More options + folder: ~/.path/to/theme/ os_prober: False # Also copies over the /etc/default/grub config or equivalent for other supported bootloaders -# TODO: Desktops, login managers, full disk encryption etc configuration? + # TODO: Desktops, login managers, full disk encryption etc configuration? themes: gtk: theme_name @@ -35,20 +39,20 @@ themes: git: creds: - ssh_cert: gen # or none manager: git-credential-manager # or none - login: - - service: github # Service name - type: oauth # Set to ssh for it to not be managed by cred manager - url: https://github.com repos: - - url: https://github.com/... + - url: https://github.com/janishutz/janishutz + clone_path: ~/projects/ # Project location will be clone_path/ + - url: git@git.janishutz.com:janishutz/nvim clone_path: ~/projects/ # Project location will be clone_path/ template_data: - name: template_data_name data: the_data -# TODO: Think about how to handle this appropriately with diffing and stuff cmds: - - "command to run" + always: + - cmd: "cmd to run every time archmgr is run" + once: + - name: "cmd1" + cmd: "cmd to run on first execution of archmgr (or if not executed previously)" diff --git a/notes.md b/notes.md index ad7e430..e24e384 100644 --- a/notes.md +++ b/notes.md @@ -20,3 +20,13 @@ - [ ] Autocompletion - [ ] Basic arch install how? -> Probably manual (or semi-automatic) - [ ] Mounts? + + +# REGEX +TODO: Improve the below (especially file can be shortened with positive lookahead) +- File: `^(^(~|\\.|\\.\\.)?\\/)?([\\w\\/.-]+(?!.*[^\\w\\/.-]+))` +- Folder: `^(^(~|\\.|\\.\\.)?\\/)?([\\w\\/.-]+(?!.*[^\\w\\/.-]+))\\/$` +- URL (just domain): `^(https?):\\/\\/(([a-z0-9-]+)((?=\\.))\\.)+[a-z]+(?=[a-z]$)` +- Full URL: `^(https?):\\/\\/(([a-z0-9-]+)((?=\\.))\\.)+[a-z]+(?=\\/)\\/([\\w\\-?.=]+(?=\\/[\\w\\-?.=])\\/)*([\\w\\-?&.=\\/]+(?=[\\w\\-.=\\/]$))` +- UNIX username and groups: `^[a-zA-Z0-9\\-._]{2,19}(?=[a-zA-Z0-9]$)` +- Git SSH: `([a-zA-Z0-9\\-._]+(?=[a-zA-Z0-9])[a-zA-Z0-9])@(([a-z0-9\\-]+(?=\\.))\\.)+[a-z]+(?=:):([a-zA-Z0-9\\-._]+(?=\\/)\\/)+([a-zA-Z0-9\\-._]+(?=[a-zA-Z0-9]$))`