{"id":15400491,"url":"https://github.com/whisperity/dotfiles-framework","last_synced_at":"2025-04-16T02:25:38.528Z","repository":{"id":148837212,"uuid":"342549225","full_name":"whisperity/dotfiles-framework","owner":"whisperity","description":"Framework for installing \"dotfiles\" packages into your environment","archived":false,"fork":false,"pushed_at":"2024-09-30T08:57:35.000Z","size":156,"stargazers_count":2,"open_issues_count":5,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-29T04:11:20.907Z","etag":null,"topics":["dotfile","dotfiles","environment","environment-variables","package","package-management","package-manager","prompt","shell","shell-prompt","shell-scripts","synchronisation","synchronization"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/whisperity.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-02-26T11:02:55.000Z","updated_at":"2024-09-30T08:57:39.000Z","dependencies_parsed_at":"2024-10-19T06:43:58.436Z","dependency_job_id":null,"html_url":"https://github.com/whisperity/dotfiles-framework","commit_stats":{"total_commits":36,"total_committers":1,"mean_commits":36.0,"dds":0.0,"last_synced_commit":"096824922028f781659194b3eb6a9b9bd0cf2832"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/whisperity%2Fdotfiles-framework","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/whisperity%2Fdotfiles-framework/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/whisperity%2Fdotfiles-framework/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/whisperity%2Fdotfiles-framework/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/whisperity","download_url":"https://codeload.github.com/whisperity/dotfiles-framework/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249184100,"owners_count":21226307,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dotfile","dotfiles","environment","environment-variables","package","package-management","package-manager","prompt","shell","shell-prompt","shell-scripts","synchronisation","synchronization"],"created_at":"2024-10-01T15:54:02.213Z","updated_at":"2025-04-16T02:25:38.511Z","avatar_url":"https://github.com/whisperity.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"`.`-files\n=========\n\n\u003e **Note:** This repository contains the management code for installing\n\u003e packages, and not the actual \"dotfiles\" themselves.\n\u003e See [Dotfiles](http://github.com/whisperity/Dotfiles).\n\n\n\nSynopsis\n--------\n\n**dotfiles** repositories are commonly used for synchronising files related to\n\\*nix shell environments.\nIn addition to offering a synchronisation source, this piece of software also\nhelps set up some more sought utilities and tools.\n\n```bash\nusage: dotfiles [-h] [-l | -i | -u] [package [package ...]]\n```\n\n\n\nUsage\n-----\n\nThe `dotfiles.py` main script handles installing the environment.\nSpecify the packages to install.\n\nIf no packages are specified, the list and description of packages will be\nshown.\nIf package names are specified, the default action is to **install** the\npackages.\n\nListing status for a particular package is possible if `--list` is explicitly\nspecified: `dotfiles --list foo bar`.\n\n\n:warning: **Note:** This tool is intended to be used when a new user\nprofile is created, such as when a new machine is installed.\n\n\n\n### Package globber\n\nMultiple packages belonging to a package \"group\" can be selected by saying\n`group.*` or `group.__ALL__`.\n\n\n\n### Package sources\n\nMultiple package sources can be given to Dotfiles.\nTo edit the package configuration, use the built-in editor by calling\n\n```bash\ndotfiles --edit-sources\n```\n\nwhich will allow you to manually add, remove, move the sources.\n\nThe package sources are forming a priority list.\nWhen installing a package `foo`, it will be installed from the first source it\nis found.\n\n\n\n#### Default sources\n\nBy default, the manager framework will use the following _2_ package sources,\nin order:\n\n 1. Your `~/Dotfiles/packages/` directory.\n 2. The author's own [Dotfiles](http://github.com/whisperity/Dotfiles)\n    repository.\n\n\n\n### Uninstalling packages\nTo uninstall packages, specify `--uninstall` before the package names:\n\n```bash\ndotfiles --uninstall foo\n```\n\n\n\nPackage description details\n---------------------------\n\nPackages are present across a number of source root directories, where an\narbitrary hierarchy can be present.\n\nA package is any directory which contains a (valid) `package.json` file.\nSubpackages are translated from filesystem hierarchy to logical hierarchy via\n`.`, i.e. `tools/system/package.json` denotes the `tools.system` package.\n\nPackage descriptor files are [YAML](http://yaml.org)s which contain the\ndirectives describing installation and handling of the package.\nAny other file is disregarded by the tool unless explicitly used, e.g. being\nthe source of a copy operation.\n\nThe user-specific package source root configuration is parsed and expanded\nat the start of the invocation into special directories under `~/.cache` and\n`~/.local/share`.\nWhen a package name `foo` is requested, every package source is queried in the\norder configured, until one source is found, or it is realised the package\ndoes not exist.\nThis resolution order is true for every package name lookup, so it applies to\ndependency queries, too.\n\n\n\n### Configuration directives\n\n#### `description` (string)\n\nContains a free form textual description for the package which is printed in\nthe \"help\" when `dotfiles.py` is invoked without any arguments.\n\n\n\n#### `dependencies` (list of other package names)\n\nThe _logical_ names of packages which must be installed before the installation\nof the current package could begin.\n\n\n\n#### `depend on parent` (boolean, default: `true`)\n\nWhether the package should implicitly depend on the parent (e.g. for\n`tools.system`, parent is `tools`), assuming the parent is a valid package.\n\n\n\n#### `support` (boolean, default: `false`)\n\n_Support_ packages are packages which have all the necessary directives to\nperform an installation, but are **NOT** meant to do persistent changes to the\nuser's environment and files.\n\nSupport packages can be depended upon, but may not be directly installed by\nthe user.\nA support package's \"installed\" status will not be saved.\nSupport packages may not have _`uninstall`_ actions.\n\nPackages with `internal` in their name (such as `internal.mypkg`) will\nautomatically be considered as _support packages_.\n\n\n\n#### Conditions (`if` and `if not`)\n\nThe **package descriptor** might take the `if` and `if not` keys, which specifies\na list of strings, each associated with a condition.\n(See the table below for the options.)\n\nConditions for the entire package **require** satisfaction, without which the\npackage will **NOT** be visible to the installer.\n\n```yaml\ndescription: A package that can only be installed if 'sudo'.\nif:\n  - superuser\ninstall:\n  - action: shell\n    command: \"sudo echo 'Hey root!'\"\n```\n\n**Action directives** may specify a list of conditions, with the `$if` and\n`$if not` meta-arguments.\nThe conditions in the `$if` list (positive conditions) must **all** be\nsatisfied, and none of the conditions in the `$if not` (negative conditions)\nlist may be satisfied for the action to execute.\nIf the conditions aren't as described for the action, the action will be\nskipped, but the rest of the actions will be executed.\n`$if` and `$if not` can both be specified on the same action.\nIf neither is specified, the action is not conditional, and will always\nexecute.\n\n```yaml\n    - action: print\n      $if:\n        - superuser\n      text: \"I have sudo!\"\n    - action: print\n      $if not:\n        - superuser\n      text: \"I do not have sudo!\"\n    - action: print\n      $if:\n        - superuser\n      $if not:\n        - superuser\n      text: \"Impossible to execute... hopefully.\"\n```\n\nThe contents of the package-level and the action-level condition lists are the\nsame:\n\n| Condition   | Semantics                                                                                             |\n|:-----------:|:------------------------------------------------------------------------------------------------------|\n| `os-darwin` | Executes the action only if the package is being installed for _Apple macOS_ systems.                 |\n| `superuser` | Turns one action into a conditional action which is only executed if the user presents `sudo` rights. |\n\n\n\n### Action directives\n\nThe installation of a package consists of two separate phases.\nBefore the installation of the first package, a **temporary** `$SESSION_DIR` is\ncreated where temporary resources may be shared between packages.\nThis directory is deleted at the end of execution of all installs.\nThe usage of this feature is discouraged unless absolutely necessary.\n\nAction directives are laid out in the package descriptor YAML file as\nshown below.\nEach phase has a **list** of key-value tuples, which will be executed _in the\norder_ they are added.\nEach tuple must have an **`action`** argument which defines the type/kind of\nthe action to run.\n\nThe rest of the arguments to specify are specific to the _`action`_ type\nidentifier.\nAll the arguments that are not _meta-arguments_ (starting with `$`) are\nspecific to the _`action`_ type identifier.\n\n\n```yaml\nprepare:\n    - action: shell\n      command: echo \"True\"\n```\n\n\n\n#### `prepare` (optional)\n\nFirst, the package's configuration and external dependencies are obtained.\nThis is called the _preparation phase_.\n\nAt the beginning of this phase, the executing environment switches into a\ntemporary directory.\nIn most directives, `$TEMPORARY_DIR` can be used to refer to this directory\nwhen specifying a path.\n\n\n| Action          | Arguments                    | Semantics                                                                                                    | Failure condition                                     |\n|:---------------:|------------------------------|:-------------------------------------------------------------------------------------------------------------|:------------------------------------------------------|\n| `copy resource` | `path` (string)              | Copy the file or directory from the package's resources (where `package.yaml` is) to the temporary directory | `path` is invalid or OS-level permission error occurs |\n| `git clone`     | `repository` (URL string)    | Obtain a clone of the repository by calling `git`                                                            | `git clone` process fails                             |\n| `print`         | `text` (string)              | Emit the message `text` to the user on the standard output.                                                  |                                                       |\n| `shell`         | `command` (string)           | Execute `command` in a shell                                                                                 | Non-zero return                                       |\n| `shell all`     | `commands` (list of strings) | Execute every command in order                                                                               | At least one command returns non-zero                 |\n| `shell any`     | `commands` (list of strings) | Execute the commands in order until one succeeds                                                             | None of the commands returns zero                     |\n\n\n\n#### `install`\n\nThe installation starts from the `packages/foo/bar/` directory (for package\n`foo.bar`).\nThis phase is the _main_ phase where changes to the user's files should be\ndone.\n\nIn most directives, `$TEMPORARY_DIR` can be used to refer to the _`prepare`_\nphase's directory when specifying a path.\n(This may only be done if there was a _`prepare`_ phase for the package!)\n\n`$PACKAGE_DIR` refers to the directory where the package's metadata file\n(`package.yaml`) and additional resources are.\n\n\n| Action      | Arguments                                                                                                                                                     | Semantics                                                                                                                                                                           | Failure condition                                  |\n|:-----------:|---------------------------------------------------------------------------------------------------------------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:---------------------------------------------------|\n| `copy`      | `file` (string), `to` (string)                                                                                                                                | Copies `file` to the `to` path                                                                                                                                                      | OS-level error                                     |\n| `copy`      | `files` (list of string), `to` (string), `from` (string, default: `$PACKAGE_DIR`), `prefix` (string, default: empty)                                          | As if `copy` was done for all element of `files` understood relative to `from`; `to` must be the destination directory, optionally prepending `prefix` to each destination filename | OS-level error, `to` isn't an existing directory   |\n| `copy tree` | `dir` (string), `to` (string)                                                                                                                                 | Copies the contents of `dir` to the `to` directory, `to` is created by this call                                                                                                    | OS-level error, `to` is  an existing directory     |\n| `make dirs` | `dirs` (list of strings)                                                                                                                                      | Creates the directories specified, and their parents if they don't exist                                                                                                            | OS-level error happens at creating a directory     |\n| `remove`    | `file` (string), `ignore missing` (boolean, default: `true`)                                                                                                  | Same as `remove` for _Uninstall_, but saves the original in the backup for later restoration                                                                                        | _see failure conditions for `remove` in Uninstall_ |\n| `remove`    | `files` (list of string), `ignore missing` (boolean, default: `true`)                                                                                         | Same as `remove` for _Uninstall_, but saves the original in the backup for later restoration                                                                                        | _see failure conditions for `remove` in Uninstall_ |\n| `remove`    | `where` (string), `file` or `files`, `ignore missing` as above                                                                                                | Same as `remove` for _Uninstall_, but saves the original in the backup for later restoration                                                                                        | _see failure conditions for `remove` in Uninstall_ |\n| `replace`   | `at` (string), `with file` (string), `with files` (list of strings), `from` (string, default: empty), `prefix` (string, default: empty)                       | Does the same as `copy` but also prepares restoring (at uninstall) the original target files if they existed                                                                        | _see failure conditions for `copy`_                |\n| `print`     | `text` (string)                                                                                                                                               | Emit the message `text` to the user on the standard output.                                                                                                                         |                                                    |\n| `shell`     | `command` (string)                                                                                                                                            | Execute `command` in a shell                                                                                                                                                        | Non-zero return                                    |\n| `shell all` | `commands` (list of strings)                                                                                                                                  | Execute every command in order                                                                                                                                                      | At least one command returns non-zero              |\n| `shell any` | `commands` (list of strings)                                                                                                                                  | Execute the commands in order until one succeeds                                                                                                                                    | None of the commands returns zero                  |\n| `symlink`   | `file` (string), `to` (string), `relative` (boolean, default: `false`)                                                                                        | Same as `copy`, but creates a symbolic link instead; if `relative` is `true`, the symbolic link will be created relatively from its target location.                                | _see failure conditions for `copy`_                |\n| `symlink`   | `files` (list of strings), `to` (string), `from` (string, default: `$PACKAGE_DIR`), `prefix` (string, default: empty), `relative` (boolean, default: `false`) | Same as `copy`, but create symbolic links instead; if `relative` is `true`, the symbolic links will be created relatively from their target location.                               | _see failure conditions for `copy`_                |\n\n\n\n#### `uninstall`\n\nUninstall starts from the directory that corresponds to `$PACKAGE_DIR`, but\ncontains the files that were present in this directory at installation, not\nwhat are *currently* present on the system.\nThis means that the state of `package.yaml` and the resource files are kept\nintact even if the `packages/` directory on the system is updated.\n\nIn `uninstall` mode, `$PACKAGE_DIR` refers to this archived directory.\n\n:warning: **Note!** The \"original\" `$PACKAGE_DIR` is **not accessible** during\n_`uninstall`_.\n\n\n| Action        | Arguments                                                             | Semantics                                                                                                                                     | Failure condition                                   |\n|:-------------:|-----------------------------------------------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------|\n| `remove`      | `file` (string), `ignore missing` (boolean, default: `true`)          | Removes the specified `file` if it exists, raising an error if `ignore missing` is `false`; `file` must be an absolute path                   | OS-level error happens at removal                   |\n| `remove`      | `files` (list of strings, `ignore missing` (boolean, default: `true`) | Removes all files specified, all files must be specified as an absolute path                                                                  | OS-level error happens at removal                   |\n| `remove`      | `where` (string), `file` or `files`, `ignore missing` as above        | As above, but `file` or `files` may be a relative path, understood relative to `where`, `where` must be an existing directory's absolute path | OS-level error, `where` isn't an existing directory |\n| `remove dirs` | `dirs` (list of strings)                                              | Removes the specified directory, if it is empty                                                                                               | OS-level error happens at removing a directory      |\n| `remove tree` | `dir` (string)                                                        | Removes the tree (all subdirectories and files) under `dir`                                                                                   | OS-level error, `dir` isn't an existing directory   |\n| `restore`     | `file` (string)                                                       | Restores the version of the `file` (which must be an absolute path) that was present when the package was installed, if such version exists   | OS-level error                                      |\n| `restore`     | `files` (list of strings)                                             | Calls `restore` for each file in `files`                                                                                                      | OS-level error                                      |\n| `print`       | `text` (string)                                                       | Emit the message `text` to the user on the standard output.                                                                                   |                                                     |\n| `shell`       | `command` (string)                                                    | Execute `command` in a shell                                                                                                                  | Non-zero return                                     |\n| `shell all`   | `commands` (list of strings)                                          | Execute every command in order                                                                                                                | At least one command returns non-zero               |\n| `shell any`   | `commands` (list of strings)                                          | Execute the commands in order until one succeeds                                                                                              | None of the commands returns zero                   |\n\n\n\n##### Automatic `uninstall` actions for `install` directives\n\nCertain _`install`_ directives can automatically be mapped to _`uninstall`_\nactions.\nAt the uninstall of a package, the corresponding actions are executed in\n**reverse order** (compared to the order of `install` directives).\n\nIf automatic uninstall actions were generated for a package's install, they\nare executed **after** the manually written _`uninstall`_ directives are\nexecuted.\n\n\n| `install` action     | `uninstall` action  | Comment                                                                                                                                                               |\n|:--------------------:|:-------------------:|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `copy`               | `remove`            | `file` and `files` are translated in a reasonable manner, `where` is not filled automatically, paths containing environment variables are kept as such for uninstall! |\n| `copy tree(dir, to)` | `remove tree(to)`   |                                                                                                                                                                       |\n| `make dirs(dirs)`    | `remove dirs(dirs)` |                                                                                                                                                                       |\n| `remove`             | `restore`           | `file` and `files` are translated in a reasonable manner, `where` is not filled automatically, paths containing environment variables are kept as such for uninstall! |\n| `replace`            | `restore`           | `with file` and `with files` are translated in a reasonable manner, `at` is ignored as paths are translated into absolute paths but retain environment variables      |\n| `symlink`            | `remove`            | _see details for `copy`_                                                                                                                                              |\n\n\n\n### Transformers\n\nAutomatic transformation of the executed actions might be beneficial in some\ncircumstances.\nAll transformers are enabled with the `--X` flag, followed by the\ntransformer's name (with dashes).\n\n\n\n#### Explicitly disallowing transformers per-action\n\nTo forbid a transformer from running for an action, add its name set to `false`\nunder the `$transform` meta-argument.\n\n```yaml\ninstall:\n  - action: copy\n    file: foo\n    to: bar\n    $transform:\n      copies as symlinks: false\n```\n\n#### `copies-as-symlinks`\n\nInstead of executing `copy`-like directives during **`install`** normally, use\nthe `symlink` action to set up **symbolic links**.\nThe links will target the original files in the package source.\nThis allows easy versioning of configuration file changes if the source is a\nversioned repository, as the original package source tree will have the files\nmodified.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwhisperity%2Fdotfiles-framework","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwhisperity%2Fdotfiles-framework","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwhisperity%2Fdotfiles-framework/lists"}