mirror of
https://github.com/TheLocehiliosan/yadm
synced 2024-10-27 20:34:27 +00:00
Compare commits
80 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
0a5e7aa353 | ||
|
040dd461bd | ||
|
e4bb8a79a4 | ||
|
2d4dcd05ef | ||
|
5981f6329e | ||
|
0f8538d3e3 | ||
|
67c684473d | ||
|
8f390cf085 | ||
|
36fda72bec | ||
|
a89e5cee89 | ||
|
075cd1b06b | ||
|
19b7a30668 | ||
|
6304553ab3 | ||
|
24ee841372 | ||
|
87ff97bbd6 | ||
|
f163130609 | ||
|
d49005ce6c | ||
|
2cc64a2fa0 | ||
|
2989734359 | ||
|
7573e18a89 | ||
|
beb83077d8 | ||
|
6a49e849c8 | ||
|
222182b296 | ||
|
0d67c44343 | ||
|
a9e7e7679b | ||
|
abf6ea4b61 | ||
|
f59d903769 | ||
|
bd0039a650 | ||
|
82c0b6d02e | ||
|
a4adadcc8c | ||
|
287249df91 | ||
|
c5e4e4eda2 | ||
|
46f72c2768 | ||
|
ebb6715aad | ||
|
39d0c791ce | ||
|
3445763731 | ||
|
718e99c826 | ||
|
50bf8716cd | ||
|
82bfd5e773 | ||
|
b7c5294bd9 | ||
|
0b75e71237 | ||
|
487f030405 | ||
|
b0e0856658 | ||
|
027c7359ac | ||
|
3d3432516f | ||
|
5ae553b078 | ||
|
32bc9abb0c | ||
|
8186705059 | ||
|
f28d4bc1c6 | ||
|
f11974140e | ||
|
71cb08a5f3 | ||
|
1aa9839096 | ||
|
a9fc8b1374 | ||
|
0ae8931e01 | ||
|
2379d63068 | ||
|
42c74efbac | ||
|
2f00dabcdb | ||
|
4caf5f681e | ||
|
4843e1fa14 | ||
|
bacc948bba | ||
|
31e2ce56bc | ||
|
3d82aff3e8 | ||
|
0cac436219 | ||
|
ec307ce4f8 | ||
|
de34cd2e8c | ||
|
a37eabba98 | ||
|
85e05d311a | ||
|
0ecb9c4f2f | ||
|
344b740d9b | ||
|
9aaefa60fe | ||
|
6c57bdd8fb | ||
|
ed4a60257d | ||
|
9beed3307f | ||
|
f8abcd756b | ||
|
db78669479 | ||
|
1544413c91 | ||
|
73af421667 | ||
|
5adb486727 | ||
|
c144d9f3bb | ||
|
77d2da4e9b |
5
.github/CONTRIBUTING.md
vendored
5
.github/CONTRIBUTING.md
vendored
@ -212,6 +212,11 @@ these principles when making changes.
|
|||||||
```text
|
```text
|
||||||
$ make test
|
$ make test
|
||||||
```
|
```
|
||||||
|
If you don't use `docker` but an OCI engine akin to `podman`, you can set it through the `OCI` switch for every target
|
||||||
|
|
||||||
|
```text
|
||||||
|
$ make test OCI=podman
|
||||||
|
```
|
||||||
|
|
||||||
5. Create a feature branch, based off the `develop` branch.
|
5. Create a feature branch, based off the `develop` branch.
|
||||||
|
|
||||||
|
25
.github/workflows/stale.yml
vendored
Normal file
25
.github/workflows/stale.yml
vendored
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
---
|
||||||
|
name: Close Stale Issues
|
||||||
|
on: # yamllint disable-line rule:truthy
|
||||||
|
schedule:
|
||||||
|
- cron: "30 1 * * *" # Daily
|
||||||
|
jobs:
|
||||||
|
Stale:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/stale@v4
|
||||||
|
with:
|
||||||
|
close-issue-message: >-
|
||||||
|
This issue was closed because it has been labeled as stale for 7
|
||||||
|
days with no activity.
|
||||||
|
days-before-close: 7
|
||||||
|
days-before-stale: 60
|
||||||
|
exempt-all-assignees: true
|
||||||
|
exempt-issue-labels: in develop, 1, 2, 3
|
||||||
|
exempt-pr-labels: in develop, 1, 2, 3
|
||||||
|
stale-issue-label: stale
|
||||||
|
stale-issue-message: >-
|
||||||
|
This issue has been labeled as stale because it has been open 60
|
||||||
|
days with no activity. Remove stale label or comment or this will
|
||||||
|
be closed in 7 days.
|
||||||
|
stale-pr-label: stale
|
22
CHANGES
22
CHANGES
@ -1,3 +1,25 @@
|
|||||||
|
3.2.2
|
||||||
|
* Support spaces in distro/distro-family (#432)
|
||||||
|
* Fix zsh hanging when tab completing add/checkout (#417)
|
||||||
|
* Add yadm-untracked script to contributed files (#418)
|
||||||
|
* Fix documentation typos (#425)
|
||||||
|
* Support docker-like OCI engines for dev testing (#431)
|
||||||
|
|
||||||
|
3.2.1
|
||||||
|
* Fix Bash 3 bad array subscript bug (#411)
|
||||||
|
|
||||||
|
3.2.0
|
||||||
|
* Support architecture for alternates/templates (#202, #203, #393)
|
||||||
|
* Support distro_family for alternates/templates (#213)
|
||||||
|
* Support setting multiple classes (#185, #304)
|
||||||
|
* Support environment variables in default template processor (#347)
|
||||||
|
* Update version command to include Bash & Git versions (#377)
|
||||||
|
|
||||||
|
3.1.1
|
||||||
|
* Fix clone support for older versions of Git (#348)
|
||||||
|
* Fix support for multiple GPG recipients (#342)
|
||||||
|
* Find symlinks in bootstrap-in-dir (#340)
|
||||||
|
|
||||||
3.1.0
|
3.1.0
|
||||||
* Use `git clone` directly during clone (#289, #323)
|
* Use `git clone` directly during clone (#289, #323)
|
||||||
* Fix compatibility bug with Git completions (#318, #321)
|
* Fix compatibility bug with Git completions (#318, #321)
|
||||||
|
11
CONTRIBUTORS
11
CONTRIBUTORS
@ -11,11 +11,18 @@ Tin Lai
|
|||||||
Espen Henriksen
|
Espen Henriksen
|
||||||
Cameron Eagans
|
Cameron Eagans
|
||||||
Klas Mellbourn
|
Klas Mellbourn
|
||||||
|
James Clark
|
||||||
|
Glenn Waters
|
||||||
|
Nicolas signed-log FORMICHELLA
|
||||||
Tomas Cernaj
|
Tomas Cernaj
|
||||||
|
Joshua Cold
|
||||||
jonasc
|
jonasc
|
||||||
|
Nicolas stig124 FORMICHELLA
|
||||||
Chad Wade Day, Jr
|
Chad Wade Day, Jr
|
||||||
Sébastien Gross
|
Sébastien Gross
|
||||||
David Mandelberg
|
David Mandelberg
|
||||||
|
Paulo Köch
|
||||||
|
Oren Zipori
|
||||||
Daniel Gray
|
Daniel Gray
|
||||||
Paraplegic Racehorse
|
Paraplegic Racehorse
|
||||||
japm48
|
japm48
|
||||||
@ -23,19 +30,23 @@ Siôn Le Roux
|
|||||||
Mateusz Piotrowski
|
Mateusz Piotrowski
|
||||||
Uroš Golja
|
Uroš Golja
|
||||||
Satoshi Ohki
|
Satoshi Ohki
|
||||||
|
Jonas
|
||||||
Franciszek Madej
|
Franciszek Madej
|
||||||
Daniel Wagenknecht
|
Daniel Wagenknecht
|
||||||
Stig Palmquist
|
Stig Palmquist
|
||||||
Patrick Hof
|
Patrick Hof
|
||||||
con-f-use
|
con-f-use
|
||||||
|
Samisafool
|
||||||
Bram Ceulemans
|
Bram Ceulemans
|
||||||
Travis A. Everett
|
Travis A. Everett
|
||||||
Sheng Yang
|
Sheng Yang
|
||||||
Jared Smartt
|
Jared Smartt
|
||||||
Adam Jimerson
|
Adam Jimerson
|
||||||
|
dessert1
|
||||||
addshore
|
addshore
|
||||||
Tim Condit
|
Tim Condit
|
||||||
Thomas Luzat
|
Thomas Luzat
|
||||||
Russ Allbery
|
Russ Allbery
|
||||||
Brayden Banks
|
Brayden Banks
|
||||||
Alexandre GV
|
Alexandre GV
|
||||||
|
Felipe S. S. Schneider
|
||||||
|
25
Makefile
25
Makefile
@ -1,5 +1,6 @@
|
|||||||
PYTESTS = $(wildcard test/test_*.py)
|
PYTESTS = $(wildcard test/test_*.py)
|
||||||
IMAGE = yadm/testbed:2020-12-29
|
IMAGE = docker.io/yadm/testbed:2022-01-07
|
||||||
|
OCI = docker
|
||||||
|
|
||||||
.PHONY: all
|
.PHONY: all
|
||||||
all:
|
all:
|
||||||
@ -94,7 +95,7 @@ test:
|
|||||||
py.test -v $(testargs); \
|
py.test -v $(testargs); \
|
||||||
else \
|
else \
|
||||||
$(MAKE) -s require-docker && \
|
$(MAKE) -s require-docker && \
|
||||||
docker run \
|
$(OCI) run \
|
||||||
--rm -t$(shell test -t 0 && echo i) \
|
--rm -t$(shell test -t 0 && echo i) \
|
||||||
-v "$(CURDIR):/yadm:ro" \
|
-v "$(CURDIR):/yadm:ro" \
|
||||||
$(IMAGE) \
|
$(IMAGE) \
|
||||||
@ -117,7 +118,7 @@ test:
|
|||||||
.PHONY: testhost
|
.PHONY: testhost
|
||||||
testhost: require-docker .testyadm
|
testhost: require-docker .testyadm
|
||||||
@echo "Starting testhost"
|
@echo "Starting testhost"
|
||||||
@docker run \
|
@$(OCI) run \
|
||||||
-w /root \
|
-w /root \
|
||||||
--hostname testhost \
|
--hostname testhost \
|
||||||
--rm -it \
|
--rm -it \
|
||||||
@ -129,7 +130,7 @@ testhost: require-docker .testyadm
|
|||||||
scripthost: require-docker .testyadm
|
scripthost: require-docker .testyadm
|
||||||
@echo "Starting scripthost \(recording script\)"
|
@echo "Starting scripthost \(recording script\)"
|
||||||
@printf '' > script.gz
|
@printf '' > script.gz
|
||||||
@docker run \
|
@$(OCI) run \
|
||||||
-w /root \
|
-w /root \
|
||||||
--hostname scripthost \
|
--hostname scripthost \
|
||||||
--rm -it \
|
--rm -it \
|
||||||
@ -159,7 +160,7 @@ testenv:
|
|||||||
|
|
||||||
.PHONY: image
|
.PHONY: image
|
||||||
image:
|
image:
|
||||||
@docker build -f test/Dockerfile . -t "$(IMAGE)"
|
@$(OCI) build -f test/Dockerfile . -t "$(IMAGE)"
|
||||||
|
|
||||||
|
|
||||||
.PHONY: man
|
.PHONY: man
|
||||||
@ -175,7 +176,7 @@ man-ps:
|
|||||||
@groff -man -Tps ./yadm.1 > yadm.ps
|
@groff -man -Tps ./yadm.1 > yadm.ps
|
||||||
|
|
||||||
yadm.md: yadm.1
|
yadm.md: yadm.1
|
||||||
@groff -man -Tascii ./yadm.1 | col -bx | sed 's/^[A-Z]/## &/g' | sed '/yadm(1)/d' > yadm.md
|
@groff -man -Tutf8 -Z ./yadm.1 | grotty -c | col -bx | sed 's/^[A-Z]/## &/g' | sed '/yadm(1)/d' > yadm.md
|
||||||
|
|
||||||
.PHONY: contrib
|
.PHONY: contrib
|
||||||
contrib: SHELL = /bin/bash
|
contrib: SHELL = /bin/bash
|
||||||
@ -192,9 +193,9 @@ install:
|
|||||||
@[ -n "$(PREFIX)" ] || { echo "PREFIX is not set"; exit 1; }
|
@[ -n "$(PREFIX)" ] || { echo "PREFIX is not set"; exit 1; }
|
||||||
@{\
|
@{\
|
||||||
set -e ;\
|
set -e ;\
|
||||||
bin="$(PREFIX)/bin" ;\
|
bin="$(DESTDIR)$(PREFIX)/bin" ;\
|
||||||
doc="$(PREFIX)/share/doc/yadm" ;\
|
doc="$(DESTDIR)$(PREFIX)/share/doc/yadm" ;\
|
||||||
man="$(PREFIX)/share/man/man1" ;\
|
man="$(DESTDIR)$(PREFIX)/share/man/man1" ;\
|
||||||
install -d "$$bin" "$$doc" "$$man" ;\
|
install -d "$$bin" "$$doc" "$$man" ;\
|
||||||
install -m 0755 yadm "$$bin" ;\
|
install -m 0755 yadm "$$bin" ;\
|
||||||
install -m 0644 yadm.1 "$$man" ;\
|
install -m 0644 yadm.1 "$$man" ;\
|
||||||
@ -204,11 +205,11 @@ install:
|
|||||||
|
|
||||||
.PHONY: sync-clock
|
.PHONY: sync-clock
|
||||||
sync-clock:
|
sync-clock:
|
||||||
docker run --rm --privileged alpine hwclock -s
|
$(OCI) run --rm --privileged alpine hwclock -s
|
||||||
|
|
||||||
.PHONY: require-docker
|
.PHONY: require-docker
|
||||||
require-docker:
|
require-docker:
|
||||||
@if ! command -v "docker" > /dev/null 2>&1; then \
|
@if ! command -v $(OCI) > /dev/null 2>&1; then \
|
||||||
echo "Sorry, this make target requires docker to be installed."; \
|
echo "Sorry, this make target requires docker to be installed, to use another docker-compatible engine, like podman, re-run the make command adding OCI=podman"; \
|
||||||
false; \
|
false; \
|
||||||
fi
|
fi
|
||||||
|
16
README.md
16
README.md
@ -3,7 +3,7 @@
|
|||||||
[![Latest Version][releases-badge]][releases-link]
|
[![Latest Version][releases-badge]][releases-link]
|
||||||
[![Homebrew Version][homebrew-badge]][homebrew-link]
|
[![Homebrew Version][homebrew-badge]][homebrew-link]
|
||||||
[![OBS Version][obs-badge]][obs-link]
|
[![OBS Version][obs-badge]][obs-link]
|
||||||
[![Arch Version][aur-badge]][aur-link]
|
[![Arch Version][arch-badge]][arch-link]
|
||||||
[![License][license-badge]][license-link]<br />
|
[![License][license-badge]][license-link]<br />
|
||||||
[![Master Update][master-date]][master-commits]
|
[![Master Update][master-date]][master-commits]
|
||||||
[![Develop Update][develop-date]][develop-commits]
|
[![Develop Update][develop-date]][develop-commits]
|
||||||
@ -56,23 +56,23 @@ The star count helps others discover yadm.
|
|||||||
[Git]: https://git-scm.com/
|
[Git]: https://git-scm.com/
|
||||||
[GnuPG]: https://gnupg.org/
|
[GnuPG]: https://gnupg.org/
|
||||||
[OpenSSL]: https://www.openssl.org/
|
[OpenSSL]: https://www.openssl.org/
|
||||||
[aur-badge]: https://img.shields.io/aur/version/yadm.svg
|
[arch-badge]: https://img.shields.io/archlinux/v/extra/any/yadm
|
||||||
[aur-link]: https://aur.archlinux.org/packages/yadm
|
[arch-link]: https://archlinux.org/packages/extra/any/yadm/
|
||||||
[dev-pages-badge]: https://img.shields.io/github/workflow/status/TheLocehiliosan/yadm/Test%20Site/dev-pages?label=dev-pages
|
[dev-pages-badge]: https://img.shields.io/github/actions/workflow/status/TheLocehiliosan/yadm/test.yml?branch=dev-pages
|
||||||
[develop-badge]: https://img.shields.io/github/workflow/status/TheLocehiliosan/yadm/Tests/develop?label=develop
|
[develop-badge]: https://img.shields.io/github/actions/workflow/status/TheLocehiliosan/yadm/test.yml?branch=develop
|
||||||
[develop-commits]: https://github.com/TheLocehiliosan/yadm/commits/develop
|
[develop-commits]: https://github.com/TheLocehiliosan/yadm/commits/develop
|
||||||
[develop-date]: https://img.shields.io/github/last-commit/TheLocehiliosan/yadm/develop.svg?label=develop
|
[develop-date]: https://img.shields.io/github/last-commit/TheLocehiliosan/yadm/develop.svg?label=develop
|
||||||
[dotfiles]: https://en.wikipedia.org/wiki/Hidden_file_and_hidden_directory
|
[dotfiles]: https://en.wikipedia.org/wiki/Hidden_file_and_hidden_directory
|
||||||
[gh-pages-badge]: https://img.shields.io/github/workflow/status/TheLocehiliosan/yadm/Test%20Site/gh-pages?label=gh-pages
|
[gh-pages-badge]: https://img.shields.io/github/actions/workflow/status/TheLocehiliosan/yadm/test.yml?branch=gh-pages
|
||||||
[git-crypt]: https://github.com/AGWA/git-crypt
|
[git-crypt]: https://github.com/AGWA/git-crypt
|
||||||
[homebrew-badge]: https://img.shields.io/homebrew/v/yadm.svg
|
[homebrew-badge]: https://img.shields.io/homebrew/v/yadm.svg
|
||||||
[homebrew-link]: https://formulae.brew.sh/formula/yadm
|
[homebrew-link]: https://formulae.brew.sh/formula/yadm
|
||||||
[license-badge]: https://img.shields.io/github/license/TheLocehiliosan/yadm.svg
|
[license-badge]: https://img.shields.io/github/license/TheLocehiliosan/yadm.svg
|
||||||
[license-link]: https://github.com/TheLocehiliosan/yadm/blob/master/LICENSE
|
[license-link]: https://github.com/TheLocehiliosan/yadm/blob/master/LICENSE
|
||||||
[master-badge]: https://img.shields.io/github/workflow/status/TheLocehiliosan/yadm/Tests/master?label=master
|
[master-badge]: https://img.shields.io/github/actions/workflow/status/TheLocehiliosan/yadm/test.yml?branch=master
|
||||||
[master-commits]: https://github.com/TheLocehiliosan/yadm/commits/master
|
[master-commits]: https://github.com/TheLocehiliosan/yadm/commits/master
|
||||||
[master-date]: https://img.shields.io/github/last-commit/TheLocehiliosan/yadm/master.svg?label=master
|
[master-date]: https://img.shields.io/github/last-commit/TheLocehiliosan/yadm/master.svg?label=master
|
||||||
[obs-badge]: https://img.shields.io/badge/OBS-v3.1.0-blue
|
[obs-badge]: https://img.shields.io/badge/OBS-v3.2.2-blue
|
||||||
[obs-link]: https://software.opensuse.org//download.html?project=home%3ATheLocehiliosan%3Ayadm&package=yadm
|
[obs-link]: https://software.opensuse.org//download.html?project=home%3ATheLocehiliosan%3Ayadm&package=yadm
|
||||||
[releases-badge]: https://img.shields.io/github/tag/TheLocehiliosan/yadm.svg?label=latest+release
|
[releases-badge]: https://img.shields.io/github/tag/TheLocehiliosan/yadm.svg?label=latest+release
|
||||||
[releases-link]: https://github.com/TheLocehiliosan/yadm/releases
|
[releases-link]: https://github.com/TheLocehiliosan/yadm/releases
|
||||||
|
@ -7,6 +7,20 @@ zstyle -T ':completion:*:yadm:argument-1:descriptions:' format && \
|
|||||||
zstyle -T ':completion:*:yadm:*:yadm' group-name && \
|
zstyle -T ':completion:*:yadm:*:yadm' group-name && \
|
||||||
zstyle ':completion:*:yadm:*:yadm' group-name ''
|
zstyle ':completion:*:yadm:*:yadm' group-name ''
|
||||||
|
|
||||||
|
function _yadm-add(){
|
||||||
|
local -a yadm_options yadm_path
|
||||||
|
yadm_path="$(yadm rev-parse --show-toplevel)"
|
||||||
|
yadm_options=($(yadm status --porcelain=v1 |
|
||||||
|
awk -v yadm_path=${yadm_path} '{printf "%s/%s:%s\n", yadm_path, $2, $1}' ))
|
||||||
|
|
||||||
|
_describe 'command' yadm_options
|
||||||
|
_files
|
||||||
|
}
|
||||||
|
|
||||||
|
function _yadm-checkout(){
|
||||||
|
_yadm-add
|
||||||
|
}
|
||||||
|
|
||||||
_yadm-alt() {
|
_yadm-alt() {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ if [[ ! -d "$BOOTSTRAP_D" ]]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
find "$BOOTSTRAP_D" -type f | sort | while IFS= read -r bootstrap; do
|
find -L "$BOOTSTRAP_D" -type f | sort | while IFS= read -r bootstrap; do
|
||||||
if [[ -x "$bootstrap" && ! "$bootstrap" =~ "##" && ! "$bootstrap" =~ "~$" ]]; then
|
if [[ -x "$bootstrap" && ! "$bootstrap" =~ "##" && ! "$bootstrap" =~ "~$" ]]; then
|
||||||
if ! "$bootstrap"; then
|
if ! "$bootstrap"; then
|
||||||
echo "Error: bootstrap '$bootstrap' failed" >&2
|
echo "Error: bootstrap '$bootstrap' failed" >&2
|
||||||
|
9
contrib/commands/README.md
Normal file
9
contrib/commands/README.md
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
## Contributed Commands
|
||||||
|
|
||||||
|
Although these commands are available as part of the official
|
||||||
|
**yadm** source tree, they have a somewhat different status. The intention is to
|
||||||
|
keep interesting and potentially useful commands here, building a library of
|
||||||
|
examples that might help others.
|
||||||
|
|
||||||
|
I recommend *careful review* of any code from here before using it. No
|
||||||
|
guarantees of code quality is assumed.
|
71
contrib/commands/yadm-untracked
Executable file
71
contrib/commands/yadm-untracked
Executable file
@ -0,0 +1,71 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# To run: `yadm-untracked <config-file>`
|
||||||
|
#
|
||||||
|
# If you wish to create a YADM alias to run this as, for example `yadm untracked`
|
||||||
|
# then the following command will add the alias:
|
||||||
|
# `yadm gitconfig alias.untracked '!<PATH>/yadm-untracked'`
|
||||||
|
|
||||||
|
# Possible script improvements:
|
||||||
|
# - Reduce the amount of configuration; I have not figured out a way to
|
||||||
|
# get rid of the non-recursive and ignore. The recursive list could be
|
||||||
|
# built from the directories that are present in `yadm list`
|
||||||
|
|
||||||
|
# Configuration... The script looks at the following 3 arrays:
|
||||||
|
#
|
||||||
|
# yadm_tracked_recursively
|
||||||
|
# The directories and files in this list are searched recursively to build
|
||||||
|
# a list of files that you expect are tracked with `yadm`. Items in this
|
||||||
|
# list are relative to the root of your YADM repo (which is $HOME for most).
|
||||||
|
|
||||||
|
# yadm_tracked_nonrecursively
|
||||||
|
# Same as above but don't search recursively
|
||||||
|
#
|
||||||
|
# ignore_files_and_dirs
|
||||||
|
# A list of directories and files that will not be reported as untracked if
|
||||||
|
# found in the above two searches.
|
||||||
|
#
|
||||||
|
# Example configuration file (uncomment it to use):
|
||||||
|
# yadm_tracked_recursively=(
|
||||||
|
# bin .config .vim
|
||||||
|
# )
|
||||||
|
#
|
||||||
|
# yadm_tracked_nonrecursively=(
|
||||||
|
# ~
|
||||||
|
# )
|
||||||
|
#
|
||||||
|
# ignore_files_and_dirs=(
|
||||||
|
# .CFUserTextEncoding .DS_Store .config/gh
|
||||||
|
# .vim/autoload/plug.vim
|
||||||
|
# )
|
||||||
|
|
||||||
|
if [[ $# -ne 1 ]]; then
|
||||||
|
echo 'Usage: yadm-untracked <config-file>'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
yadm_tracked_recursively=()
|
||||||
|
yadm_tracked_nonrecursively=()
|
||||||
|
ignore_files_and_dirs=()
|
||||||
|
|
||||||
|
source $1
|
||||||
|
|
||||||
|
root=`yadm enter echo '$GIT_WORK_TREE'`
|
||||||
|
|
||||||
|
cd $root
|
||||||
|
|
||||||
|
find_list=$(mktemp -t find_list)
|
||||||
|
find ${yadm_tracked_recursively[*]} -type f >$find_list
|
||||||
|
find ${yadm_tracked_nonrecursively[*]} -maxdepth 1 -type f |
|
||||||
|
awk "{sub(\"^\./\", \"\"); sub(\"^$root/\", \"\"); print }" >>$find_list
|
||||||
|
sort -o $find_list $find_list
|
||||||
|
|
||||||
|
yadm_list=$(mktemp -t yadm_list)
|
||||||
|
yadm list >$yadm_list
|
||||||
|
find ${ignore_files_and_dirs[*]} -type f >>$yadm_list
|
||||||
|
sort -o $yadm_list $yadm_list
|
||||||
|
|
||||||
|
# Show the files not in `yadm list`
|
||||||
|
comm -23 $find_list $yadm_list
|
||||||
|
|
||||||
|
rm -f $find_list $yadm_list
|
2
pylintrc
2
pylintrc
@ -8,7 +8,7 @@ max-attributes=8
|
|||||||
max-statements=65
|
max-statements=65
|
||||||
|
|
||||||
[SIMILARITIES]
|
[SIMILARITIES]
|
||||||
min-similarity-lines=6
|
min-similarity-lines=8
|
||||||
|
|
||||||
[MESSAGES CONTROL]
|
[MESSAGES CONTROL]
|
||||||
disable=redefined-outer-name
|
disable=redefined-outer-name
|
||||||
|
@ -2,8 +2,8 @@ FROM ubuntu:18.04
|
|||||||
MAINTAINER Tim Byrne <sultan@locehilios.com>
|
MAINTAINER Tim Byrne <sultan@locehilios.com>
|
||||||
|
|
||||||
# Shellcheck and esh versions
|
# Shellcheck and esh versions
|
||||||
ARG SC_VER=0.7.1
|
ARG SC_VER=0.8.0
|
||||||
ARG ESH_VER=0.3.0
|
ARG ESH_VER=0.3.1
|
||||||
|
|
||||||
# Install prerequisites and configure UTF-8 locale
|
# Install prerequisites and configure UTF-8 locale
|
||||||
RUN \
|
RUN \
|
||||||
|
@ -25,7 +25,7 @@ def pytest_addoption(parser):
|
|||||||
@pytest.fixture(scope='session')
|
@pytest.fixture(scope='session')
|
||||||
def shellcheck_version():
|
def shellcheck_version():
|
||||||
"""Version of shellcheck supported"""
|
"""Version of shellcheck supported"""
|
||||||
return '0.7.1'
|
return '0.8.0'
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope='session')
|
@pytest.fixture(scope='session')
|
||||||
@ -68,12 +68,29 @@ def tst_distro(runner):
|
|||||||
return distro
|
return distro
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope='session')
|
||||||
|
def tst_distro_family(runner):
|
||||||
|
"""Test session's distro_family"""
|
||||||
|
family = ''
|
||||||
|
with contextlib.suppress(Exception):
|
||||||
|
run = runner(command=[
|
||||||
|
'grep', '-oP', r'ID_LIKE=\K.+', '/etc/os-release'], report=False)
|
||||||
|
family = run.out.strip()
|
||||||
|
return family
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope='session')
|
@pytest.fixture(scope='session')
|
||||||
def tst_sys():
|
def tst_sys():
|
||||||
"""Test session's uname value"""
|
"""Test session's uname value"""
|
||||||
return platform.system()
|
return platform.system()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope='session')
|
||||||
|
def tst_arch():
|
||||||
|
"""Test session's uname value"""
|
||||||
|
return platform.machine()
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope='session')
|
@pytest.fixture(scope='session')
|
||||||
def supported_commands():
|
def supported_commands():
|
||||||
"""List of supported commands
|
"""List of supported commands
|
||||||
@ -109,6 +126,7 @@ def supported_configs():
|
|||||||
This list should be updated every time yadm learns a new config.
|
This list should be updated every time yadm learns a new config.
|
||||||
"""
|
"""
|
||||||
return [
|
return [
|
||||||
|
'local.arch',
|
||||||
'local.class',
|
'local.class',
|
||||||
'local.hostname',
|
'local.hostname',
|
||||||
'local.os',
|
'local.os',
|
||||||
|
@ -82,25 +82,32 @@ def test_relative_link(runner, paths, yadm_alt):
|
|||||||
@pytest.mark.parametrize('suffix', [
|
@pytest.mark.parametrize('suffix', [
|
||||||
'##default',
|
'##default',
|
||||||
'##default,e.txt', '##default,extension.txt',
|
'##default,e.txt', '##default,extension.txt',
|
||||||
|
'##a.$tst_arch', '##arch.$tst_arch',
|
||||||
'##o.$tst_sys', '##os.$tst_sys',
|
'##o.$tst_sys', '##os.$tst_sys',
|
||||||
'##d.$tst_distro', '##distro.$tst_distro',
|
'##d.$tst_distro', '##distro.$tst_distro',
|
||||||
|
'##f.$tst_distro_family', '##distro_family.$tst_distro_family',
|
||||||
'##c.$tst_class', '##class.$tst_class',
|
'##c.$tst_class', '##class.$tst_class',
|
||||||
'##h.$tst_host', '##hostname.$tst_host',
|
'##h.$tst_host', '##hostname.$tst_host',
|
||||||
'##u.$tst_user', '##user.$tst_user',
|
'##u.$tst_user', '##user.$tst_user',
|
||||||
])
|
])
|
||||||
def test_alt_conditions(
|
def test_alt_conditions(
|
||||||
runner, paths,
|
runner, paths,
|
||||||
tst_sys, tst_distro, tst_host, tst_user, suffix):
|
tst_arch, tst_sys, tst_distro, tst_distro_family, tst_host, tst_user,
|
||||||
|
suffix):
|
||||||
"""Test conditions supported by yadm alt"""
|
"""Test conditions supported by yadm alt"""
|
||||||
yadm_dir, yadm_data = setup_standard_yadm_dir(paths)
|
yadm_dir, yadm_data = setup_standard_yadm_dir(paths)
|
||||||
|
|
||||||
# set the class
|
# set the class
|
||||||
tst_class = 'testclass'
|
tst_class = 'testclass'
|
||||||
utils.set_local(paths, 'class', tst_class)
|
utils.set_local(paths, 'class', tst_class + ".before")
|
||||||
|
utils.set_local(paths, 'class', tst_class, add=True)
|
||||||
|
utils.set_local(paths, 'class', tst_class + ".after", add=True)
|
||||||
|
|
||||||
suffix = string.Template(suffix).substitute(
|
suffix = string.Template(suffix).substitute(
|
||||||
|
tst_arch=tst_arch,
|
||||||
tst_sys=tst_sys,
|
tst_sys=tst_sys,
|
||||||
tst_distro=tst_distro,
|
tst_distro=tst_distro,
|
||||||
|
tst_distro_family=tst_distro_family,
|
||||||
tst_class=tst_class,
|
tst_class=tst_class,
|
||||||
tst_host=tst_host,
|
tst_host=tst_host,
|
||||||
tst_user=tst_user,
|
tst_user=tst_user,
|
||||||
|
@ -326,7 +326,7 @@ def test_multi_key(runner, yadm_cmd, gnupg):
|
|||||||
|
|
||||||
# specify two encryption recipient
|
# specify two encryption recipient
|
||||||
os.system(' '.join(yadm_cmd(
|
os.system(' '.join(yadm_cmd(
|
||||||
'config', 'yadm.gpg-recipient', f'"{KEY_NAME} second-key"')))
|
'config', 'yadm.gpg-recipient', f'"second-key {KEY_NAME}"')))
|
||||||
|
|
||||||
env = os.environ.copy()
|
env = os.environ.copy()
|
||||||
env['GNUPGHOME'] = gnupg.home
|
env['GNUPGHOME'] = gnupg.home
|
||||||
|
26
test/test_unit_query_distro_family.py
Normal file
26
test/test_unit_query_distro_family.py
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
"""Unit tests: query_distro_family"""
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
'condition', ['os-release', 'os-release-quotes', 'missing'])
|
||||||
|
def test_query_distro_family(runner, yadm, tmp_path, condition):
|
||||||
|
"""Match ID_LIKE when present"""
|
||||||
|
test_family = 'testfamily'
|
||||||
|
os_release = tmp_path.joinpath('os-release')
|
||||||
|
if 'os-release' in condition:
|
||||||
|
quotes = '"' if 'quotes' in condition else ''
|
||||||
|
os_release.write_text(
|
||||||
|
f"testing\nID_LIKE={quotes}{test_family}{quotes}\nfamily")
|
||||||
|
script = f"""
|
||||||
|
YADM_TEST=1 source {yadm}
|
||||||
|
OS_RELEASE="{os_release}"
|
||||||
|
query_distro_family
|
||||||
|
"""
|
||||||
|
run = runner(command=['bash'], inp=script)
|
||||||
|
assert run.success
|
||||||
|
assert run.err == ''
|
||||||
|
if 'os-release' in condition:
|
||||||
|
assert run.out.rstrip() == test_family
|
||||||
|
else:
|
||||||
|
assert run.out.rstrip() == ''
|
@ -6,25 +6,33 @@ CONDITION = {
|
|||||||
'labels': ['default'],
|
'labels': ['default'],
|
||||||
'modifier': 0,
|
'modifier': 0,
|
||||||
},
|
},
|
||||||
|
'arch': {
|
||||||
|
'labels': ['a', 'arch'],
|
||||||
|
'modifier': 1,
|
||||||
|
},
|
||||||
'system': {
|
'system': {
|
||||||
'labels': ['o', 'os'],
|
'labels': ['o', 'os'],
|
||||||
'modifier': 1,
|
'modifier': 2,
|
||||||
},
|
},
|
||||||
'distro': {
|
'distro': {
|
||||||
'labels': ['d', 'distro'],
|
'labels': ['d', 'distro'],
|
||||||
'modifier': 2,
|
'modifier': 4,
|
||||||
|
},
|
||||||
|
'distro_family': {
|
||||||
|
'labels': ['f', 'distro_family'],
|
||||||
|
'modifier': 8,
|
||||||
},
|
},
|
||||||
'class': {
|
'class': {
|
||||||
'labels': ['c', 'class'],
|
'labels': ['c', 'class'],
|
||||||
'modifier': 4,
|
'modifier': 16,
|
||||||
},
|
},
|
||||||
'hostname': {
|
'hostname': {
|
||||||
'labels': ['h', 'hostname'],
|
'labels': ['h', 'hostname'],
|
||||||
'modifier': 8,
|
'modifier': 32,
|
||||||
},
|
},
|
||||||
'user': {
|
'user': {
|
||||||
'labels': ['u', 'user'],
|
'labels': ['u', 'user'],
|
||||||
'modifier': 16,
|
'modifier': 64,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
TEMPLATE_LABELS = ['t', 'template', 'yadm']
|
TEMPLATE_LABELS = ['t', 'template', 'yadm']
|
||||||
@ -44,6 +52,12 @@ def calculate_score(filename):
|
|||||||
label, value = condition.split('.', 1)
|
label, value = condition.split('.', 1)
|
||||||
if label in CONDITION['default']['labels']:
|
if label in CONDITION['default']['labels']:
|
||||||
score += 1000
|
score += 1000
|
||||||
|
elif label in CONDITION['arch']['labels']:
|
||||||
|
if value == 'testarch':
|
||||||
|
score += 1000 + CONDITION['arch']['modifier']
|
||||||
|
else:
|
||||||
|
score = 0
|
||||||
|
break
|
||||||
elif label in CONDITION['system']['labels']:
|
elif label in CONDITION['system']['labels']:
|
||||||
if value == 'testsystem':
|
if value == 'testsystem':
|
||||||
score += 1000 + CONDITION['system']['modifier']
|
score += 1000 + CONDITION['system']['modifier']
|
||||||
@ -82,6 +96,8 @@ def calculate_score(filename):
|
|||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
'default', ['default', None], ids=['default', 'no-default'])
|
'default', ['default', None], ids=['default', 'no-default'])
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
'arch', ['arch', None], ids=['arch', 'no-arch'])
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
'system', ['system', None], ids=['system', 'no-system'])
|
'system', ['system', None], ids=['system', 'no-system'])
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
@ -93,10 +109,11 @@ def calculate_score(filename):
|
|||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
'user', ['user', None], ids=['user', 'no-user'])
|
'user', ['user', None], ids=['user', 'no-user'])
|
||||||
def test_score_values(
|
def test_score_values(
|
||||||
runner, yadm, default, system, distro, cla, host, user):
|
runner, yadm, default, arch, system, distro, cla, host, user):
|
||||||
"""Test score results"""
|
"""Test score results"""
|
||||||
# pylint: disable=too-many-branches
|
# pylint: disable=too-many-branches
|
||||||
local_class = 'testclass'
|
local_class = 'testclass'
|
||||||
|
local_arch = 'testarch'
|
||||||
local_system = 'testsystem'
|
local_system = 'testsystem'
|
||||||
local_distro = 'testdistro'
|
local_distro = 'testdistro'
|
||||||
local_host = 'testhost'
|
local_host = 'testhost'
|
||||||
@ -111,6 +128,18 @@ def test_score_values(
|
|||||||
newfile += ','
|
newfile += ','
|
||||||
newfile += label
|
newfile += label
|
||||||
filenames[newfile] = calculate_score(newfile)
|
filenames[newfile] = calculate_score(newfile)
|
||||||
|
if arch:
|
||||||
|
for filename in list(filenames):
|
||||||
|
for match in [True, False]:
|
||||||
|
for label in CONDITION[arch]['labels']:
|
||||||
|
newfile = filename
|
||||||
|
if not newfile.endswith('##'):
|
||||||
|
newfile += ','
|
||||||
|
newfile += '.'.join([
|
||||||
|
label,
|
||||||
|
local_arch if match else 'badarch'
|
||||||
|
])
|
||||||
|
filenames[newfile] = calculate_score(newfile)
|
||||||
if system:
|
if system:
|
||||||
for filename in list(filenames):
|
for filename in list(filenames):
|
||||||
for match in [True, False]:
|
for match in [True, False]:
|
||||||
@ -176,6 +205,8 @@ def test_score_values(
|
|||||||
YADM_TEST=1 source {yadm}
|
YADM_TEST=1 source {yadm}
|
||||||
score=0
|
score=0
|
||||||
local_class={local_class}
|
local_class={local_class}
|
||||||
|
local_classes=({local_class})
|
||||||
|
local_arch={local_arch}
|
||||||
local_system={local_system}
|
local_system={local_system}
|
||||||
local_distro={local_distro}
|
local_distro={local_distro}
|
||||||
local_host={local_host}
|
local_host={local_host}
|
||||||
@ -221,6 +252,7 @@ def test_extensions(runner, yadm, ext):
|
|||||||
def test_score_values_templates(runner, yadm):
|
def test_score_values_templates(runner, yadm):
|
||||||
"""Test score results"""
|
"""Test score results"""
|
||||||
local_class = 'testclass'
|
local_class = 'testclass'
|
||||||
|
local_arch = 'arch'
|
||||||
local_system = 'testsystem'
|
local_system = 'testsystem'
|
||||||
local_distro = 'testdistro'
|
local_distro = 'testdistro'
|
||||||
local_host = 'testhost'
|
local_host = 'testhost'
|
||||||
@ -239,6 +271,7 @@ def test_score_values_templates(runner, yadm):
|
|||||||
YADM_TEST=1 source {yadm}
|
YADM_TEST=1 source {yadm}
|
||||||
score=0
|
score=0
|
||||||
local_class={local_class}
|
local_class={local_class}
|
||||||
|
local_arch={local_arch}
|
||||||
local_system={local_system}
|
local_system={local_system}
|
||||||
local_distro={local_distro}
|
local_distro={local_distro}
|
||||||
local_host={local_host}
|
local_host={local_host}
|
||||||
@ -282,3 +315,37 @@ def test_template_recording(runner, yadm, cmd_generated):
|
|||||||
assert run.success
|
assert run.success
|
||||||
assert run.err == ''
|
assert run.err == ''
|
||||||
assert run.out.rstrip() == expected
|
assert run.out.rstrip() == expected
|
||||||
|
|
||||||
|
|
||||||
|
def test_underscores_in_distro_and_family(runner, yadm):
|
||||||
|
"""Test replacing spaces in distro / distro_family with underscores"""
|
||||||
|
local_distro = 'test distro'
|
||||||
|
local_distro_family = 'test family'
|
||||||
|
filenames = {
|
||||||
|
'filename##distro.test distro': 1004,
|
||||||
|
'filename##distro.test-distro': 0,
|
||||||
|
'filename##distro.test_distro': 1004,
|
||||||
|
'filename##distro_family.test family': 1008,
|
||||||
|
'filename##distro_family.test-family': 0,
|
||||||
|
'filename##distro_family.test_family': 1008,
|
||||||
|
}
|
||||||
|
|
||||||
|
script = f"""
|
||||||
|
YADM_TEST=1 source {yadm}
|
||||||
|
score=0
|
||||||
|
local_distro="{local_distro}"
|
||||||
|
local_distro_family="{local_distro_family}"
|
||||||
|
"""
|
||||||
|
expected = ''
|
||||||
|
for filename in filenames:
|
||||||
|
script += f"""
|
||||||
|
score_file "{filename}"
|
||||||
|
echo "{filename}"
|
||||||
|
echo "$score"
|
||||||
|
"""
|
||||||
|
expected += filename + '\n'
|
||||||
|
expected += str(filenames[filename]) + '\n'
|
||||||
|
run = runner(command=['bash'], inp=script)
|
||||||
|
assert run.success
|
||||||
|
assert run.err == ''
|
||||||
|
assert run.out == expected
|
||||||
|
@ -7,6 +7,7 @@ import utils
|
|||||||
'override', [
|
'override', [
|
||||||
False,
|
False,
|
||||||
'class',
|
'class',
|
||||||
|
'arch',
|
||||||
'os',
|
'os',
|
||||||
'hostname',
|
'hostname',
|
||||||
'user',
|
'user',
|
||||||
@ -14,6 +15,7 @@ import utils
|
|||||||
ids=[
|
ids=[
|
||||||
'no-override',
|
'no-override',
|
||||||
'override-class',
|
'override-class',
|
||||||
|
'override-arch',
|
||||||
'override-os',
|
'override-os',
|
||||||
'override-hostname',
|
'override-hostname',
|
||||||
'override-user',
|
'override-user',
|
||||||
@ -21,7 +23,7 @@ import utils
|
|||||||
)
|
)
|
||||||
@pytest.mark.usefixtures('ds1_copy')
|
@pytest.mark.usefixtures('ds1_copy')
|
||||||
def test_set_local_alt_values(
|
def test_set_local_alt_values(
|
||||||
runner, yadm, paths, tst_sys, tst_host, tst_user, override):
|
runner, yadm, paths, tst_arch, tst_sys, tst_host, tst_user, override):
|
||||||
"""Use issue_legacy_path_warning"""
|
"""Use issue_legacy_path_warning"""
|
||||||
script = f"""
|
script = f"""
|
||||||
YADM_TEST=1 source {yadm} &&
|
YADM_TEST=1 source {yadm} &&
|
||||||
@ -29,12 +31,16 @@ def test_set_local_alt_values(
|
|||||||
YADM_DIR={paths.yadm} YADM_DATA={paths.data} configure_paths &&
|
YADM_DIR={paths.yadm} YADM_DATA={paths.data} configure_paths &&
|
||||||
set_local_alt_values
|
set_local_alt_values
|
||||||
echo "class='$local_class'"
|
echo "class='$local_class'"
|
||||||
|
echo "arch='$local_arch'"
|
||||||
echo "os='$local_system'"
|
echo "os='$local_system'"
|
||||||
echo "host='$local_host'"
|
echo "host='$local_host'"
|
||||||
echo "user='$local_user'"
|
echo "user='$local_user'"
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if override:
|
if override == 'class':
|
||||||
|
utils.set_local(paths, override, 'first')
|
||||||
|
utils.set_local(paths, override, 'override', add=True)
|
||||||
|
elif override:
|
||||||
utils.set_local(paths, override, 'override')
|
utils.set_local(paths, override, 'override')
|
||||||
|
|
||||||
run = runner(command=['bash'], inp=script)
|
run = runner(command=['bash'], inp=script)
|
||||||
@ -46,6 +52,11 @@ def test_set_local_alt_values(
|
|||||||
else:
|
else:
|
||||||
assert "class=''" in run.out
|
assert "class=''" in run.out
|
||||||
|
|
||||||
|
if override == 'arch':
|
||||||
|
assert "arch='override'" in run.out
|
||||||
|
else:
|
||||||
|
assert f"arch='{tst_arch}'" in run.out
|
||||||
|
|
||||||
if override == 'os':
|
if override == 'os':
|
||||||
assert "os='override'" in run.out
|
assert "os='override'" in run.out
|
||||||
else:
|
else:
|
||||||
@ -62,17 +73,20 @@ def test_set_local_alt_values(
|
|||||||
assert f"user='{tst_user}'" in run.out
|
assert f"user='{tst_user}'" in run.out
|
||||||
|
|
||||||
|
|
||||||
def test_distro(runner, yadm):
|
def test_distro_and_family(runner, yadm):
|
||||||
"""Assert that local_distro is set"""
|
"""Assert that local_distro/local_distro_family are set"""
|
||||||
|
|
||||||
script = f"""
|
script = f"""
|
||||||
YADM_TEST=1 source {yadm}
|
YADM_TEST=1 source {yadm}
|
||||||
function config() {{ echo "$1"; }}
|
function config() {{ echo "$1"; }}
|
||||||
function query_distro() {{ echo "testdistro"; }}
|
function query_distro() {{ echo "testdistro"; }}
|
||||||
|
function query_distro_family() {{ echo "testfamily"; }}
|
||||||
set_local_alt_values
|
set_local_alt_values
|
||||||
echo "distro='$local_distro'"
|
echo "distro='$local_distro'"
|
||||||
|
echo "distro_family='$local_distro_family'"
|
||||||
"""
|
"""
|
||||||
run = runner(command=['bash'], inp=script)
|
run = runner(command=['bash'], inp=script)
|
||||||
assert run.success
|
assert run.success
|
||||||
assert run.err == ''
|
assert run.err == ''
|
||||||
assert run.out.strip() == "distro='testdistro'"
|
assert "distro='testdistro'" in run.out
|
||||||
|
assert "distro_family='testfamily'" in run.out
|
||||||
|
@ -5,17 +5,23 @@ FILE_MODE = 0o754
|
|||||||
|
|
||||||
# these values are also testing the handling of bizarre characters
|
# these values are also testing the handling of bizarre characters
|
||||||
LOCAL_CLASS = "default_Test+@-!^Class"
|
LOCAL_CLASS = "default_Test+@-!^Class"
|
||||||
|
LOCAL_CLASS2 = "default_Test+@-|^2nd_Class withSpace"
|
||||||
|
LOCAL_ARCH = "default_Test+@-!^Arch"
|
||||||
LOCAL_SYSTEM = "default_Test+@-!^System"
|
LOCAL_SYSTEM = "default_Test+@-!^System"
|
||||||
LOCAL_HOST = "default_Test+@-!^Host"
|
LOCAL_HOST = "default_Test+@-!^Host"
|
||||||
LOCAL_USER = "default_Test+@-!^User"
|
LOCAL_USER = "default_Test+@-!^User"
|
||||||
LOCAL_DISTRO = "default_Test+@-!^Distro"
|
LOCAL_DISTRO = "default_Test+@-!^Distro"
|
||||||
|
LOCAL_DISTRO_FAMILY = "default_Test+@-!^Family"
|
||||||
TEMPLATE = f'''
|
TEMPLATE = f'''
|
||||||
start of template
|
start of template
|
||||||
default class = >{{{{yadm.class}}}}<
|
default class = >{{{{yadm.class}}}}<
|
||||||
default os = >{{{{yadm.os}}}}<
|
default arch = >{{{{yadm.arch}}}}<
|
||||||
default host = >{{{{yadm.hostname}}}}<
|
default os = >{{{{yadm.os}}}}<
|
||||||
default user = >{{{{yadm.user}}}}<
|
default host = >{{{{yadm.hostname}}}}<
|
||||||
default distro = >{{{{yadm.distro}}}}<
|
default user = >{{{{yadm.user}}}}<
|
||||||
|
default distro = >{{{{yadm.distro}}}}<
|
||||||
|
default distro_family = >{{{{yadm.distro_family}}}}<
|
||||||
|
classes = >{{{{yadm.classes}}}}<
|
||||||
{{% if yadm.class == "else1" %}}
|
{{% if yadm.class == "else1" %}}
|
||||||
wrong else 1
|
wrong else 1
|
||||||
{{% else %}}
|
{{% else %}}
|
||||||
@ -30,9 +36,21 @@ Multiple lines
|
|||||||
{{% else %}}
|
{{% else %}}
|
||||||
Should not be included...
|
Should not be included...
|
||||||
{{% endif %}}
|
{{% endif %}}
|
||||||
|
{{% if yadm.class == "{LOCAL_CLASS2}" %}}
|
||||||
|
Included section for second class
|
||||||
|
{{% endif %}}
|
||||||
{{% if yadm.class == "wrongclass2" %}}
|
{{% if yadm.class == "wrongclass2" %}}
|
||||||
wrong class 2
|
wrong class 2
|
||||||
{{% endif %}}
|
{{% endif %}}
|
||||||
|
{{% if yadm.arch == "wrongarch1" %}}
|
||||||
|
wrong arch 1
|
||||||
|
{{% endif %}}
|
||||||
|
{{% if yadm.arch == "{LOCAL_ARCH}" %}}
|
||||||
|
Included section for arch = {{{{yadm.arch}}}} ({{{{yadm.arch}}}} repeated)
|
||||||
|
{{% endif %}}
|
||||||
|
{{% if yadm.arch == "wrongarch2" %}}
|
||||||
|
wrong arch 2
|
||||||
|
{{% endif %}}
|
||||||
{{% if yadm.os == "wrongos1" %}}
|
{{% if yadm.os == "wrongos1" %}}
|
||||||
wrong os 1
|
wrong os 1
|
||||||
{{% endif %}}
|
{{% endif %}}
|
||||||
@ -69,22 +87,40 @@ Included section for distro = {{{{yadm.distro}}}} ({{{{yadm.distro}}}} again)
|
|||||||
{{% if yadm.distro == "wrongdistro2" %}}
|
{{% if yadm.distro == "wrongdistro2" %}}
|
||||||
wrong distro 2
|
wrong distro 2
|
||||||
{{% endif %}}
|
{{% endif %}}
|
||||||
|
{{% if yadm.distro_family == "wrongfamily1" %}}
|
||||||
|
wrong family 1
|
||||||
|
{{% endif %}}
|
||||||
|
{{% if yadm.distro_family == "{LOCAL_DISTRO_FAMILY}" %}}
|
||||||
|
Included section for distro_family = \
|
||||||
|
{{{{yadm.distro_family}}}} ({{{{yadm.distro_family}}}} again)
|
||||||
|
{{% endif %}}
|
||||||
|
{{% if yadm.distro_family == "wrongfamily2" %}}
|
||||||
|
wrong family 2
|
||||||
|
{{% endif %}}
|
||||||
end of template
|
end of template
|
||||||
'''
|
'''
|
||||||
EXPECTED = f'''
|
EXPECTED = f'''
|
||||||
start of template
|
start of template
|
||||||
default class = >{LOCAL_CLASS}<
|
default class = >{LOCAL_CLASS}<
|
||||||
default os = >{LOCAL_SYSTEM}<
|
default arch = >{LOCAL_ARCH}<
|
||||||
default host = >{LOCAL_HOST}<
|
default os = >{LOCAL_SYSTEM}<
|
||||||
default user = >{LOCAL_USER}<
|
default host = >{LOCAL_HOST}<
|
||||||
default distro = >{LOCAL_DISTRO}<
|
default user = >{LOCAL_USER}<
|
||||||
|
default distro = >{LOCAL_DISTRO}<
|
||||||
|
default distro_family = >{LOCAL_DISTRO_FAMILY}<
|
||||||
|
classes = >{LOCAL_CLASS2}
|
||||||
|
{LOCAL_CLASS}<
|
||||||
Included section from else
|
Included section from else
|
||||||
Included section for class = {LOCAL_CLASS} ({LOCAL_CLASS} repeated)
|
Included section for class = {LOCAL_CLASS} ({LOCAL_CLASS} repeated)
|
||||||
Multiple lines
|
Multiple lines
|
||||||
|
Included section for second class
|
||||||
|
Included section for arch = {LOCAL_ARCH} ({LOCAL_ARCH} repeated)
|
||||||
Included section for os = {LOCAL_SYSTEM} ({LOCAL_SYSTEM} repeated)
|
Included section for os = {LOCAL_SYSTEM} ({LOCAL_SYSTEM} repeated)
|
||||||
Included section for host = {LOCAL_HOST} ({LOCAL_HOST} again)
|
Included section for host = {LOCAL_HOST} ({LOCAL_HOST} again)
|
||||||
Included section for user = {LOCAL_USER} ({LOCAL_USER} repeated)
|
Included section for user = {LOCAL_USER} ({LOCAL_USER} repeated)
|
||||||
Included section for distro = {LOCAL_DISTRO} ({LOCAL_DISTRO} again)
|
Included section for distro = {LOCAL_DISTRO} ({LOCAL_DISTRO} again)
|
||||||
|
Included section for distro_family = \
|
||||||
|
{LOCAL_DISTRO_FAMILY} ({LOCAL_DISTRO_FAMILY} again)
|
||||||
end of template
|
end of template
|
||||||
'''
|
'''
|
||||||
|
|
||||||
@ -137,10 +173,13 @@ def test_template_default(runner, yadm, tmpdir):
|
|||||||
YADM_TEST=1 source {yadm}
|
YADM_TEST=1 source {yadm}
|
||||||
set_awk
|
set_awk
|
||||||
local_class="{LOCAL_CLASS}"
|
local_class="{LOCAL_CLASS}"
|
||||||
|
local_classes=("{LOCAL_CLASS2}" "{LOCAL_CLASS}")
|
||||||
|
local_arch="{LOCAL_ARCH}"
|
||||||
local_system="{LOCAL_SYSTEM}"
|
local_system="{LOCAL_SYSTEM}"
|
||||||
local_host="{LOCAL_HOST}"
|
local_host="{LOCAL_HOST}"
|
||||||
local_user="{LOCAL_USER}"
|
local_user="{LOCAL_USER}"
|
||||||
local_distro="{LOCAL_DISTRO}"
|
local_distro="{LOCAL_DISTRO}"
|
||||||
|
local_distro_family="{LOCAL_DISTRO_FAMILY}"
|
||||||
template_default "{input_file}" "{output_file}"
|
template_default "{input_file}" "{output_file}"
|
||||||
"""
|
"""
|
||||||
run = runner(command=['bash'], inp=script)
|
run = runner(command=['bash'], inp=script)
|
||||||
@ -202,3 +241,22 @@ def test_include(runner, yadm, tmpdir):
|
|||||||
assert run.err == ''
|
assert run.err == ''
|
||||||
assert output_file.read() == EXPECTED_INCLUDE
|
assert output_file.read() == EXPECTED_INCLUDE
|
||||||
assert os.stat(output_file).st_mode == os.stat(input_file).st_mode
|
assert os.stat(output_file).st_mode == os.stat(input_file).st_mode
|
||||||
|
|
||||||
|
|
||||||
|
def test_env(runner, yadm, tmpdir):
|
||||||
|
"""Test env"""
|
||||||
|
|
||||||
|
input_file = tmpdir.join('input')
|
||||||
|
input_file.write('{{env.PWD}}', ensure=True)
|
||||||
|
input_file.chmod(FILE_MODE)
|
||||||
|
output_file = tmpdir.join('output')
|
||||||
|
|
||||||
|
script = f"""
|
||||||
|
YADM_TEST=1 source {yadm}
|
||||||
|
set_awk
|
||||||
|
template_default "{input_file}" "{output_file}"
|
||||||
|
"""
|
||||||
|
run = runner(command=['bash'], inp=script)
|
||||||
|
assert run.success
|
||||||
|
assert run.err == ''
|
||||||
|
assert output_file.read().strip() == os.environ['PWD']
|
||||||
|
@ -4,31 +4,50 @@ import os
|
|||||||
FILE_MODE = 0o754
|
FILE_MODE = 0o754
|
||||||
|
|
||||||
LOCAL_CLASS = "esh_Test+@-!^Class"
|
LOCAL_CLASS = "esh_Test+@-!^Class"
|
||||||
|
LOCAL_CLASS2 = "esh_Test+@-|^2nd_Class withSpace"
|
||||||
|
LOCAL_ARCH = "esh_Test+@-!^Arch"
|
||||||
LOCAL_SYSTEM = "esh_Test+@-!^System"
|
LOCAL_SYSTEM = "esh_Test+@-!^System"
|
||||||
LOCAL_HOST = "esh_Test+@-!^Host"
|
LOCAL_HOST = "esh_Test+@-!^Host"
|
||||||
LOCAL_USER = "esh_Test+@-!^User"
|
LOCAL_USER = "esh_Test+@-!^User"
|
||||||
LOCAL_DISTRO = "esh_Test+@-!^Distro"
|
LOCAL_DISTRO = "esh_Test+@-!^Distro"
|
||||||
|
LOCAL_DISTRO_FAMILY = "esh_Test+@-!^Family"
|
||||||
TEMPLATE = f'''
|
TEMPLATE = f'''
|
||||||
start of template
|
start of template
|
||||||
esh class = ><%=$YADM_CLASS%><
|
esh class = ><%=$YADM_CLASS%><
|
||||||
esh os = ><%=$YADM_OS%><
|
esh arch = ><%=$YADM_ARCH%><
|
||||||
esh host = ><%=$YADM_HOSTNAME%><
|
esh os = ><%=$YADM_OS%><
|
||||||
esh user = ><%=$YADM_USER%><
|
esh host = ><%=$YADM_HOSTNAME%><
|
||||||
esh distro = ><%=$YADM_DISTRO%><
|
esh user = ><%=$YADM_USER%><
|
||||||
|
esh distro = ><%=$YADM_DISTRO%><
|
||||||
|
esh distro_family = ><%=$YADM_DISTRO_FAMILY%><
|
||||||
|
esh classes = ><%=$YADM_CLASSES%><
|
||||||
<% if [ "$YADM_CLASS" = "wrongclass1" ]; then -%>
|
<% if [ "$YADM_CLASS" = "wrongclass1" ]; then -%>
|
||||||
wrong class 1
|
wrong class 1
|
||||||
<% fi -%>
|
<% fi -%>
|
||||||
<% if [ "$YADM_CLASS" = "{LOCAL_CLASS}" ]; then -%>
|
<% if [ "$YADM_CLASS" = "{LOCAL_CLASS}" ]; then -%>
|
||||||
Included section for class = <%=$YADM_CLASS%> (<%=$YADM_CLASS%> repeated)
|
Included esh section for class = <%=$YADM_CLASS%> (<%=$YADM_CLASS%> repeated)
|
||||||
<% fi -%>
|
<% fi -%>
|
||||||
<% if [ "$YADM_CLASS" = "wrongclass2" ]; then -%>
|
<% if [ "$YADM_CLASS" = "wrongclass2" ]; then -%>
|
||||||
wrong class 2
|
wrong class 2
|
||||||
<% fi -%>
|
<% fi -%>
|
||||||
|
<% echo "$YADM_CLASSES" | while IFS='' read cls; do
|
||||||
|
if [ "$cls" = "{LOCAL_CLASS2}" ]; then -%>
|
||||||
|
Included esh section for second class
|
||||||
|
<% fi; done -%>
|
||||||
|
<% if [ "$YADM_ARCH" = "wrongarch1" ]; then -%>
|
||||||
|
wrong arch 1
|
||||||
|
<% fi -%>
|
||||||
|
<% if [ "$YADM_ARCH" = "{LOCAL_ARCH}" ]; then -%>
|
||||||
|
Included esh section for arch = <%=$YADM_ARCH%> (<%=$YADM_ARCH%> repeated)
|
||||||
|
<% fi -%>
|
||||||
|
<% if [ "$YADM_ARCH" = "wrongarch2" ]; then -%>
|
||||||
|
wrong arch 2
|
||||||
|
<% fi -%>
|
||||||
<% if [ "$YADM_OS" = "wrongos1" ]; then -%>
|
<% if [ "$YADM_OS" = "wrongos1" ]; then -%>
|
||||||
wrong os 1
|
wrong os 1
|
||||||
<% fi -%>
|
<% fi -%>
|
||||||
<% if [ "$YADM_OS" = "{LOCAL_SYSTEM}" ]; then -%>
|
<% if [ "$YADM_OS" = "{LOCAL_SYSTEM}" ]; then -%>
|
||||||
Included section for os = <%=$YADM_OS%> (<%=$YADM_OS%> repeated)
|
Included esh section for os = <%=$YADM_OS%> (<%=$YADM_OS%> repeated)
|
||||||
<% fi -%>
|
<% fi -%>
|
||||||
<% if [ "$YADM_OS" = "wrongos2" ]; then -%>
|
<% if [ "$YADM_OS" = "wrongos2" ]; then -%>
|
||||||
wrong os 2
|
wrong os 2
|
||||||
@ -37,7 +56,7 @@ wrong os 2
|
|||||||
wrong host 1
|
wrong host 1
|
||||||
<% fi -%>
|
<% fi -%>
|
||||||
<% if [ "$YADM_HOSTNAME" = "{LOCAL_HOST}" ]; then -%>
|
<% if [ "$YADM_HOSTNAME" = "{LOCAL_HOST}" ]; then -%>
|
||||||
Included section for host = <%=$YADM_HOSTNAME%> (<%=$YADM_HOSTNAME%> again)
|
Included esh section for host = <%=$YADM_HOSTNAME%> (<%=$YADM_HOSTNAME%> again)
|
||||||
<% fi -%>
|
<% fi -%>
|
||||||
<% if [ "$YADM_HOSTNAME" = "wronghost2" ]; then -%>
|
<% if [ "$YADM_HOSTNAME" = "wronghost2" ]; then -%>
|
||||||
wrong host 2
|
wrong host 2
|
||||||
@ -46,7 +65,7 @@ wrong host 2
|
|||||||
wrong user 1
|
wrong user 1
|
||||||
<% fi -%>
|
<% fi -%>
|
||||||
<% if [ "$YADM_USER" = "{LOCAL_USER}" ]; then -%>
|
<% if [ "$YADM_USER" = "{LOCAL_USER}" ]; then -%>
|
||||||
Included section for user = <%=$YADM_USER%> (<%=$YADM_USER%> repeated)
|
Included esh section for user = <%=$YADM_USER%> (<%=$YADM_USER%> repeated)
|
||||||
<% fi -%>
|
<% fi -%>
|
||||||
<% if [ "$YADM_USER" = "wronguser2" ]; then -%>
|
<% if [ "$YADM_USER" = "wronguser2" ]; then -%>
|
||||||
wrong user 2
|
wrong user 2
|
||||||
@ -55,25 +74,42 @@ wrong user 2
|
|||||||
wrong distro 1
|
wrong distro 1
|
||||||
<% fi -%>
|
<% fi -%>
|
||||||
<% if [ "$YADM_DISTRO" = "{LOCAL_DISTRO}" ]; then -%>
|
<% if [ "$YADM_DISTRO" = "{LOCAL_DISTRO}" ]; then -%>
|
||||||
Included section for distro = <%=$YADM_DISTRO%> (<%=$YADM_DISTRO%> again)
|
Included esh section for distro = <%=$YADM_DISTRO%> (<%=$YADM_DISTRO%> again)
|
||||||
<% fi -%>
|
<% fi -%>
|
||||||
<% if [ "$YADM_DISTRO" = "wrongdistro2" ]; then -%>
|
<% if [ "$YADM_DISTRO" = "wrongdistro2" ]; then -%>
|
||||||
wrong distro 2
|
wrong distro 2
|
||||||
<% fi -%>
|
<% fi -%>
|
||||||
|
<% if [ "$YADM_DISTRO_FAMILY" = "wrongfamily1" ]; then -%>
|
||||||
|
wrong family 1
|
||||||
|
<% fi -%>
|
||||||
|
<% if [ "$YADM_DISTRO_FAMILY" = "{LOCAL_DISTRO_FAMILY}" ]; then -%>
|
||||||
|
Included esh section for distro_family = \
|
||||||
|
<%=$YADM_DISTRO_FAMILY%> (<%=$YADM_DISTRO_FAMILY%> again)
|
||||||
|
<% fi -%>
|
||||||
|
<% if [ "$YADM_DISTRO" = "wrongfamily2" ]; then -%>
|
||||||
|
wrong family 2
|
||||||
|
<% fi -%>
|
||||||
end of template
|
end of template
|
||||||
'''
|
'''
|
||||||
EXPECTED = f'''
|
EXPECTED = f'''
|
||||||
start of template
|
start of template
|
||||||
esh class = >{LOCAL_CLASS}<
|
esh class = >{LOCAL_CLASS}<
|
||||||
esh os = >{LOCAL_SYSTEM}<
|
esh arch = >{LOCAL_ARCH}<
|
||||||
esh host = >{LOCAL_HOST}<
|
esh os = >{LOCAL_SYSTEM}<
|
||||||
esh user = >{LOCAL_USER}<
|
esh host = >{LOCAL_HOST}<
|
||||||
esh distro = >{LOCAL_DISTRO}<
|
esh user = >{LOCAL_USER}<
|
||||||
Included section for class = {LOCAL_CLASS} ({LOCAL_CLASS} repeated)
|
esh distro = >{LOCAL_DISTRO}<
|
||||||
Included section for os = {LOCAL_SYSTEM} ({LOCAL_SYSTEM} repeated)
|
esh distro_family = >{LOCAL_DISTRO_FAMILY}<
|
||||||
Included section for host = {LOCAL_HOST} ({LOCAL_HOST} again)
|
esh classes = >{LOCAL_CLASS2} {LOCAL_CLASS}<
|
||||||
Included section for user = {LOCAL_USER} ({LOCAL_USER} repeated)
|
Included esh section for class = {LOCAL_CLASS} ({LOCAL_CLASS} repeated)
|
||||||
Included section for distro = {LOCAL_DISTRO} ({LOCAL_DISTRO} again)
|
Included esh section for second class
|
||||||
|
Included esh section for arch = {LOCAL_ARCH} ({LOCAL_ARCH} repeated)
|
||||||
|
Included esh section for os = {LOCAL_SYSTEM} ({LOCAL_SYSTEM} repeated)
|
||||||
|
Included esh section for host = {LOCAL_HOST} ({LOCAL_HOST} again)
|
||||||
|
Included esh section for user = {LOCAL_USER} ({LOCAL_USER} repeated)
|
||||||
|
Included esh section for distro = {LOCAL_DISTRO} ({LOCAL_DISTRO} again)
|
||||||
|
Included esh section for distro_family = \
|
||||||
|
{LOCAL_DISTRO_FAMILY} ({LOCAL_DISTRO_FAMILY} again)
|
||||||
end of template
|
end of template
|
||||||
'''
|
'''
|
||||||
|
|
||||||
@ -95,10 +131,13 @@ def test_template_esh(runner, yadm, tmpdir):
|
|||||||
script = f"""
|
script = f"""
|
||||||
YADM_TEST=1 source {yadm}
|
YADM_TEST=1 source {yadm}
|
||||||
local_class="{LOCAL_CLASS}"
|
local_class="{LOCAL_CLASS}"
|
||||||
|
local_classes=("{LOCAL_CLASS2}" "{LOCAL_CLASS}")
|
||||||
|
local_arch="{LOCAL_ARCH}"
|
||||||
local_system="{LOCAL_SYSTEM}"
|
local_system="{LOCAL_SYSTEM}"
|
||||||
local_host="{LOCAL_HOST}"
|
local_host="{LOCAL_HOST}"
|
||||||
local_user="{LOCAL_USER}"
|
local_user="{LOCAL_USER}"
|
||||||
local_distro="{LOCAL_DISTRO}"
|
local_distro="{LOCAL_DISTRO}"
|
||||||
|
local_distro_family="{LOCAL_DISTRO_FAMILY}"
|
||||||
template_esh "{input_file}" "{output_file}"
|
template_esh "{input_file}" "{output_file}"
|
||||||
"""
|
"""
|
||||||
run = runner(command=['bash'], inp=script)
|
run = runner(command=['bash'], inp=script)
|
||||||
|
@ -5,31 +5,50 @@ import pytest
|
|||||||
FILE_MODE = 0o754
|
FILE_MODE = 0o754
|
||||||
|
|
||||||
LOCAL_CLASS = "j2_Test+@-!^Class"
|
LOCAL_CLASS = "j2_Test+@-!^Class"
|
||||||
|
LOCAL_CLASS2 = "j2_Test+@-|^2nd_Class withSpace"
|
||||||
|
LOCAL_ARCH = "j2_Test+@-!^Arch"
|
||||||
LOCAL_SYSTEM = "j2_Test+@-!^System"
|
LOCAL_SYSTEM = "j2_Test+@-!^System"
|
||||||
LOCAL_HOST = "j2_Test+@-!^Host"
|
LOCAL_HOST = "j2_Test+@-!^Host"
|
||||||
LOCAL_USER = "j2_Test+@-!^User"
|
LOCAL_USER = "j2_Test+@-!^User"
|
||||||
LOCAL_DISTRO = "j2_Test+@-!^Distro"
|
LOCAL_DISTRO = "j2_Test+@-!^Distro"
|
||||||
|
LOCAL_DISTRO_FAMILY = "j2_Test+@-!^Family"
|
||||||
TEMPLATE = f'''
|
TEMPLATE = f'''
|
||||||
start of template
|
start of template
|
||||||
j2 class = >{{{{YADM_CLASS}}}}<
|
j2 class = >{{{{YADM_CLASS}}}}<
|
||||||
j2 os = >{{{{YADM_OS}}}}<
|
j2 arch = >{{{{YADM_ARCH}}}}<
|
||||||
j2 host = >{{{{YADM_HOSTNAME}}}}<
|
j2 os = >{{{{YADM_OS}}}}<
|
||||||
j2 user = >{{{{YADM_USER}}}}<
|
j2 host = >{{{{YADM_HOSTNAME}}}}<
|
||||||
j2 distro = >{{{{YADM_DISTRO}}}}<
|
j2 user = >{{{{YADM_USER}}}}<
|
||||||
|
j2 distro = >{{{{YADM_DISTRO}}}}<
|
||||||
|
j2 distro_family = >{{{{YADM_DISTRO_FAMILY}}}}<
|
||||||
|
j2 classes = >{{{{YADM_CLASSES}}}}<
|
||||||
{{%- if YADM_CLASS == "wrongclass1" %}}
|
{{%- if YADM_CLASS == "wrongclass1" %}}
|
||||||
wrong class 1
|
wrong class 1
|
||||||
{{%- endif %}}
|
{{%- endif %}}
|
||||||
{{%- if YADM_CLASS == "{LOCAL_CLASS}" %}}
|
{{%- if YADM_CLASS == "{LOCAL_CLASS}" %}}
|
||||||
Included section for class = {{{{YADM_CLASS}}}} ({{{{YADM_CLASS}}}} repeated)
|
Included j2 section for class = \
|
||||||
|
{{{{YADM_CLASS}}}} ({{{{YADM_CLASS}}}} repeated)
|
||||||
{{%- endif %}}
|
{{%- endif %}}
|
||||||
{{%- if YADM_CLASS == "wrongclass2" %}}
|
{{%- if YADM_CLASS == "wrongclass2" %}}
|
||||||
wrong class 2
|
wrong class 2
|
||||||
{{%- endif %}}
|
{{%- endif %}}
|
||||||
|
{{%- if "{LOCAL_CLASS2}" in YADM_CLASSES.split("\\n") %}}
|
||||||
|
Included j2 section for second class
|
||||||
|
{{%- endif %}}
|
||||||
|
{{%- if YADM_ARCH == "wrongarch1" %}}
|
||||||
|
wrong arch 1
|
||||||
|
{{%- endif %}}
|
||||||
|
{{%- if YADM_ARCH == "{LOCAL_ARCH}" %}}
|
||||||
|
Included j2 section for arch = {{{{YADM_ARCH}}}} ({{{{YADM_ARCH}}}} repeated)
|
||||||
|
{{%- endif %}}
|
||||||
|
{{%- if YADM_ARCH == "wrongarch2" %}}
|
||||||
|
wrong arch 2
|
||||||
|
{{%- endif %}}
|
||||||
{{%- if YADM_OS == "wrongos1" %}}
|
{{%- if YADM_OS == "wrongos1" %}}
|
||||||
wrong os 1
|
wrong os 1
|
||||||
{{%- endif %}}
|
{{%- endif %}}
|
||||||
{{%- if YADM_OS == "{LOCAL_SYSTEM}" %}}
|
{{%- if YADM_OS == "{LOCAL_SYSTEM}" %}}
|
||||||
Included section for os = {{{{YADM_OS}}}} ({{{{YADM_OS}}}} repeated)
|
Included j2 section for os = {{{{YADM_OS}}}} ({{{{YADM_OS}}}} repeated)
|
||||||
{{%- endif %}}
|
{{%- endif %}}
|
||||||
{{%- if YADM_OS == "wrongos2" %}}
|
{{%- if YADM_OS == "wrongos2" %}}
|
||||||
wrong os 2
|
wrong os 2
|
||||||
@ -38,7 +57,8 @@ wrong os 2
|
|||||||
wrong host 1
|
wrong host 1
|
||||||
{{%- endif %}}
|
{{%- endif %}}
|
||||||
{{%- if YADM_HOSTNAME == "{LOCAL_HOST}" %}}
|
{{%- if YADM_HOSTNAME == "{LOCAL_HOST}" %}}
|
||||||
Included section for host = {{{{YADM_HOSTNAME}}}} ({{{{YADM_HOSTNAME}}}} again)
|
Included j2 section for host = \
|
||||||
|
{{{{YADM_HOSTNAME}}}} ({{{{YADM_HOSTNAME}}}} again)
|
||||||
{{%- endif %}}
|
{{%- endif %}}
|
||||||
{{%- if YADM_HOSTNAME == "wronghost2" %}}
|
{{%- if YADM_HOSTNAME == "wronghost2" %}}
|
||||||
wrong host 2
|
wrong host 2
|
||||||
@ -47,7 +67,7 @@ wrong host 2
|
|||||||
wrong user 1
|
wrong user 1
|
||||||
{{%- endif %}}
|
{{%- endif %}}
|
||||||
{{%- if YADM_USER == "{LOCAL_USER}" %}}
|
{{%- if YADM_USER == "{LOCAL_USER}" %}}
|
||||||
Included section for user = {{{{YADM_USER}}}} ({{{{YADM_USER}}}} repeated)
|
Included j2 section for user = {{{{YADM_USER}}}} ({{{{YADM_USER}}}} repeated)
|
||||||
{{%- endif %}}
|
{{%- endif %}}
|
||||||
{{%- if YADM_USER == "wronguser2" %}}
|
{{%- if YADM_USER == "wronguser2" %}}
|
||||||
wrong user 2
|
wrong user 2
|
||||||
@ -56,25 +76,44 @@ wrong user 2
|
|||||||
wrong distro 1
|
wrong distro 1
|
||||||
{{%- endif %}}
|
{{%- endif %}}
|
||||||
{{%- if YADM_DISTRO == "{LOCAL_DISTRO}" %}}
|
{{%- if YADM_DISTRO == "{LOCAL_DISTRO}" %}}
|
||||||
Included section for distro = {{{{YADM_DISTRO}}}} ({{{{YADM_DISTRO}}}} again)
|
Included j2 section for distro = \
|
||||||
|
{{{{YADM_DISTRO}}}} ({{{{YADM_DISTRO}}}} again)
|
||||||
{{%- endif %}}
|
{{%- endif %}}
|
||||||
{{%- if YADM_DISTRO == "wrongdistro2" %}}
|
{{%- if YADM_DISTRO == "wrongdistro2" %}}
|
||||||
wrong distro 2
|
wrong distro 2
|
||||||
{{%- endif %}}
|
{{%- endif %}}
|
||||||
|
{{%- if YADM_DISTRO_FAMILY == "wrongfamily1" %}}
|
||||||
|
wrong family 1
|
||||||
|
{{%- endif %}}
|
||||||
|
{{%- if YADM_DISTRO_FAMILY == "{LOCAL_DISTRO_FAMILY}" %}}
|
||||||
|
Included j2 section for distro_family = \
|
||||||
|
{{{{YADM_DISTRO_FAMILY}}}} ({{{{YADM_DISTRO_FAMILY}}}} again)
|
||||||
|
{{%- endif %}}
|
||||||
|
{{%- if YADM_DISTRO_FAMILY == "wrongfamily2" %}}
|
||||||
|
wrong family 2
|
||||||
|
{{%- endif %}}
|
||||||
end of template
|
end of template
|
||||||
'''
|
'''
|
||||||
EXPECTED = f'''
|
EXPECTED = f'''
|
||||||
start of template
|
start of template
|
||||||
j2 class = >{LOCAL_CLASS}<
|
j2 class = >{LOCAL_CLASS}<
|
||||||
j2 os = >{LOCAL_SYSTEM}<
|
j2 arch = >{LOCAL_ARCH}<
|
||||||
j2 host = >{LOCAL_HOST}<
|
j2 os = >{LOCAL_SYSTEM}<
|
||||||
j2 user = >{LOCAL_USER}<
|
j2 host = >{LOCAL_HOST}<
|
||||||
j2 distro = >{LOCAL_DISTRO}<
|
j2 user = >{LOCAL_USER}<
|
||||||
Included section for class = {LOCAL_CLASS} ({LOCAL_CLASS} repeated)
|
j2 distro = >{LOCAL_DISTRO}<
|
||||||
Included section for os = {LOCAL_SYSTEM} ({LOCAL_SYSTEM} repeated)
|
j2 distro_family = >{LOCAL_DISTRO_FAMILY}<
|
||||||
Included section for host = {LOCAL_HOST} ({LOCAL_HOST} again)
|
j2 classes = >{LOCAL_CLASS2}
|
||||||
Included section for user = {LOCAL_USER} ({LOCAL_USER} repeated)
|
{LOCAL_CLASS}<
|
||||||
Included section for distro = {LOCAL_DISTRO} ({LOCAL_DISTRO} again)
|
Included j2 section for class = {LOCAL_CLASS} ({LOCAL_CLASS} repeated)
|
||||||
|
Included j2 section for second class
|
||||||
|
Included j2 section for arch = {LOCAL_ARCH} ({LOCAL_ARCH} repeated)
|
||||||
|
Included j2 section for os = {LOCAL_SYSTEM} ({LOCAL_SYSTEM} repeated)
|
||||||
|
Included j2 section for host = {LOCAL_HOST} ({LOCAL_HOST} again)
|
||||||
|
Included j2 section for user = {LOCAL_USER} ({LOCAL_USER} repeated)
|
||||||
|
Included j2 section for distro = {LOCAL_DISTRO} ({LOCAL_DISTRO} again)
|
||||||
|
Included j2 section for distro_family = \
|
||||||
|
{LOCAL_DISTRO_FAMILY} ({LOCAL_DISTRO_FAMILY} again)
|
||||||
end of template
|
end of template
|
||||||
'''
|
'''
|
||||||
|
|
||||||
@ -97,10 +136,13 @@ def test_template_j2(runner, yadm, tmpdir, processor):
|
|||||||
script = f"""
|
script = f"""
|
||||||
YADM_TEST=1 source {yadm}
|
YADM_TEST=1 source {yadm}
|
||||||
local_class="{LOCAL_CLASS}"
|
local_class="{LOCAL_CLASS}"
|
||||||
|
local_classes=("{LOCAL_CLASS2}" "{LOCAL_CLASS}")
|
||||||
|
local_arch="{LOCAL_ARCH}"
|
||||||
local_system="{LOCAL_SYSTEM}"
|
local_system="{LOCAL_SYSTEM}"
|
||||||
local_host="{LOCAL_HOST}"
|
local_host="{LOCAL_HOST}"
|
||||||
local_user="{LOCAL_USER}"
|
local_user="{LOCAL_USER}"
|
||||||
local_distro="{LOCAL_DISTRO}"
|
local_distro="{LOCAL_DISTRO}"
|
||||||
|
local_distro_family="{LOCAL_DISTRO_FAMILY}"
|
||||||
template_{processor} "{input_file}" "{output_file}"
|
template_{processor} "{input_file}" "{output_file}"
|
||||||
"""
|
"""
|
||||||
run = runner(command=['bash'], inp=script)
|
run = runner(command=['bash'], inp=script)
|
||||||
|
@ -29,8 +29,10 @@ def test_semantic_version(expected_version):
|
|||||||
@pytest.mark.parametrize('cmd', ['--version', 'version'])
|
@pytest.mark.parametrize('cmd', ['--version', 'version'])
|
||||||
def test_reported_version(
|
def test_reported_version(
|
||||||
runner, yadm_cmd, cmd, expected_version):
|
runner, yadm_cmd, cmd, expected_version):
|
||||||
"""Report correct version"""
|
"""Report correct version and bash/git versions"""
|
||||||
run = runner(command=yadm_cmd(cmd))
|
run = runner(command=yadm_cmd(cmd))
|
||||||
assert run.success
|
assert run.success
|
||||||
assert run.err == ''
|
assert run.err == ''
|
||||||
assert run.out == f'yadm {expected_version}\n'
|
assert 'bash version' in run.out
|
||||||
|
assert 'git version' in run.out
|
||||||
|
assert run.out.endswith(f'\nyadm version {expected_version}\n')
|
||||||
|
@ -21,11 +21,12 @@ INCLUDE_DIRS = ['', 'test alt']
|
|||||||
INCLUDE_CONTENT = '8780846c02e34c930d0afd127906668f'
|
INCLUDE_CONTENT = '8780846c02e34c930d0afd127906668f'
|
||||||
|
|
||||||
|
|
||||||
def set_local(paths, variable, value):
|
def set_local(paths, variable, value, add=False):
|
||||||
"""Set local override"""
|
"""Set local override"""
|
||||||
|
add = "--add" if add else ""
|
||||||
os.system(
|
os.system(
|
||||||
f'GIT_DIR={str(paths.repo)} '
|
f'GIT_DIR={str(paths.repo)} '
|
||||||
f'git config --local "local.{variable}" "{value}"'
|
f'git config --local {add} "local.{variable}" "{value}"'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
170
yadm
170
yadm
@ -1,6 +1,6 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# yadm - Yet Another Dotfiles Manager
|
# yadm - Yet Another Dotfiles Manager
|
||||||
# Copyright (C) 2015-2021 Tim Byrne
|
# Copyright (C) 2015-2023 Tim Byrne
|
||||||
|
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# This program is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
@ -21,7 +21,7 @@ if [ -z "$BASH_VERSION" ]; then
|
|||||||
[ "$YADM_TEST" != 1 ] && exec bash "$0" "$@"
|
[ "$YADM_TEST" != 1 ] && exec bash "$0" "$@"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
VERSION=3.1.0
|
VERSION=3.2.2
|
||||||
|
|
||||||
YADM_WORK="$HOME"
|
YADM_WORK="$HOME"
|
||||||
YADM_DIR=
|
YADM_DIR=
|
||||||
@ -170,8 +170,8 @@ function score_file() {
|
|||||||
tgt="${src%%##*}"
|
tgt="${src%%##*}"
|
||||||
conditions="${src#*##}"
|
conditions="${src#*##}"
|
||||||
|
|
||||||
if [ "${tgt#$YADM_ALT/}" != "${tgt}" ]; then
|
if [ "${tgt#"$YADM_ALT/"}" != "${tgt}" ]; then
|
||||||
tgt="${YADM_BASE}/${tgt#$YADM_ALT/}"
|
tgt="${YADM_BASE}/${tgt#"$YADM_ALT/"}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
score=0
|
score=0
|
||||||
@ -189,37 +189,51 @@ function score_file() {
|
|||||||
if [[ "$label" =~ ^(default)$ ]]; then
|
if [[ "$label" =~ ^(default)$ ]]; then
|
||||||
score=$((score + 0))
|
score=$((score + 0))
|
||||||
# variable conditions
|
# variable conditions
|
||||||
elif [[ "$label" =~ ^(o|os)$ ]]; then
|
elif [[ "$label" =~ ^(a|arch)$ ]]; then
|
||||||
if [ "$value" = "$local_system" ]; then
|
if [ "$value" = "$local_arch" ]; then
|
||||||
score=$((score + 1))
|
score=$((score + 1))
|
||||||
else
|
else
|
||||||
score=0
|
score=0
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
elif [[ "$label" =~ ^(d|distro)$ ]]; then
|
elif [[ "$label" =~ ^(o|os)$ ]]; then
|
||||||
if [ "$value" = "$local_distro" ]; then
|
if [ "$value" = "$local_system" ]; then
|
||||||
score=$((score + 2))
|
score=$((score + 2))
|
||||||
else
|
else
|
||||||
score=0
|
score=0
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
elif [[ "$label" =~ ^(c|class)$ ]]; then
|
elif [[ "$label" =~ ^(d|distro)$ ]]; then
|
||||||
if [ "$value" = "$local_class" ]; then
|
if [ "${value/\ /_}" = "${local_distro/\ /_}" ]; then
|
||||||
score=$((score + 4))
|
score=$((score + 4))
|
||||||
else
|
else
|
||||||
score=0
|
score=0
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
elif [[ "$label" =~ ^(f|distro_family)$ ]]; then
|
||||||
|
if [ "${value/\ /_}" = "${local_distro_family/\ /_}" ]; then
|
||||||
|
score=$((score + 8))
|
||||||
|
else
|
||||||
|
score=0
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
elif [[ "$label" =~ ^(c|class)$ ]]; then
|
||||||
|
if in_list "$value" "${local_classes[@]}"; then
|
||||||
|
score=$((score + 16))
|
||||||
|
else
|
||||||
|
score=0
|
||||||
|
return
|
||||||
|
fi
|
||||||
elif [[ "$label" =~ ^(h|hostname)$ ]]; then
|
elif [[ "$label" =~ ^(h|hostname)$ ]]; then
|
||||||
if [ "$value" = "$local_host" ]; then
|
if [ "$value" = "$local_host" ]; then
|
||||||
score=$((score + 8))
|
score=$((score + 32))
|
||||||
else
|
else
|
||||||
score=0
|
score=0
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
elif [[ "$label" =~ ^(u|user)$ ]]; then
|
elif [[ "$label" =~ ^(u|user)$ ]]; then
|
||||||
if [ "$value" = "$local_user" ]; then
|
if [ "$value" = "$local_user" ]; then
|
||||||
score=$((score + 16))
|
score=$((score + 64))
|
||||||
else
|
else
|
||||||
score=0
|
score=0
|
||||||
return
|
return
|
||||||
@ -356,23 +370,26 @@ function template_default() {
|
|||||||
read -r -d '' awk_pgm << "EOF"
|
read -r -d '' awk_pgm << "EOF"
|
||||||
# built-in default template processor
|
# built-in default template processor
|
||||||
BEGIN {
|
BEGIN {
|
||||||
blank = "[ ]"
|
blank = "[ ]"
|
||||||
c["class"] = class
|
c["class"] = class
|
||||||
c["os"] = os
|
c["classes"] = classes
|
||||||
c["hostname"] = host
|
c["arch"] = arch
|
||||||
c["user"] = user
|
c["os"] = os
|
||||||
c["distro"] = distro
|
c["hostname"] = host
|
||||||
c["source"] = source
|
c["user"] = user
|
||||||
ifs = "^{%" blank "*if"
|
c["distro"] = distro
|
||||||
els = "^{%" blank "*else" blank "*%}$"
|
c["distro_family"] = distro_family
|
||||||
end = "^{%" blank "*endif" blank "*%}$"
|
c["source"] = source
|
||||||
skp = "^{%" blank "*(if|else|endif)"
|
ifs = "^{%" blank "*if"
|
||||||
vld = conditions()
|
els = "^{%" blank "*else" blank "*%}$"
|
||||||
inc_start = "^{%" blank "*include" blank "+\"?"
|
end = "^{%" blank "*endif" blank "*%}$"
|
||||||
inc_end = "\"?" blank "*%}$"
|
skp = "^{%" blank "*(if|else|endif)"
|
||||||
inc = inc_start ".+" inc_end
|
vld = conditions()
|
||||||
prt = 1
|
inc_start = "^{%" blank "*include" blank "+\"?"
|
||||||
err = 0
|
inc_end = "\"?" blank "*%}$"
|
||||||
|
inc = inc_start ".+" inc_end
|
||||||
|
prt = 1
|
||||||
|
err = 0
|
||||||
}
|
}
|
||||||
END { exit err }
|
END { exit err }
|
||||||
{ replace_vars() } # variable replacements
|
{ replace_vars() } # variable replacements
|
||||||
@ -409,13 +426,26 @@ function replace_vars() {
|
|||||||
for (label in c) {
|
for (label in c) {
|
||||||
gsub(("{{" blank "*yadm\\." label blank "*}}"), c[label])
|
gsub(("{{" blank "*yadm\\." label blank "*}}"), c[label])
|
||||||
}
|
}
|
||||||
|
for (label in ENVIRON) {
|
||||||
|
gsub(("{{" blank "*env\\." label blank "*}}"), ENVIRON[label])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function condition_helper(label, value) {
|
||||||
|
gsub(/[\\.^$(){}\[\]|*+?]/, "\\\\&", value)
|
||||||
|
return sprintf("yadm\\.%s" blank "*==" blank "*\"%s\"", label, value)
|
||||||
}
|
}
|
||||||
function conditions() {
|
function conditions() {
|
||||||
pattern = ifs blank "+("
|
pattern = ifs blank "+("
|
||||||
for (label in c) {
|
for (label in c) {
|
||||||
value = c[label]
|
if (label != "class") {
|
||||||
gsub(/[\\.^$(){}\[\]|*+?]/, "\\\\&", value)
|
value = c[label]
|
||||||
pattern = sprintf("%syadm\\.%s" blank "*==" blank "*\"%s\"|", pattern, label, value)
|
pattern = sprintf("%s%s|", pattern, condition_helper(label, value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
split(classes, cls_array, "\n")
|
||||||
|
for (idx in cls_array) {
|
||||||
|
value = cls_array[idx]
|
||||||
|
pattern = sprintf("%s%s|", pattern, condition_helper("class", value));
|
||||||
}
|
}
|
||||||
sub(/\|$/, ")" blank "*%}$", pattern)
|
sub(/\|$/, ")" blank "*%}$", pattern)
|
||||||
return pattern
|
return pattern
|
||||||
@ -424,12 +454,15 @@ EOF
|
|||||||
|
|
||||||
"${AWK_PROGRAM[0]}" \
|
"${AWK_PROGRAM[0]}" \
|
||||||
-v class="$local_class" \
|
-v class="$local_class" \
|
||||||
|
-v arch="$local_arch" \
|
||||||
-v os="$local_system" \
|
-v os="$local_system" \
|
||||||
-v host="$local_host" \
|
-v host="$local_host" \
|
||||||
-v user="$local_user" \
|
-v user="$local_user" \
|
||||||
-v distro="$local_distro" \
|
-v distro="$local_distro" \
|
||||||
|
-v distro_family="$local_distro_family" \
|
||||||
-v source="$input" \
|
-v source="$input" \
|
||||||
-v source_dir="$(dirname "$input")" \
|
-v source_dir="$(dirname "$input")" \
|
||||||
|
-v classes="$(join_string $'\n' "${local_classes[@]}")" \
|
||||||
"$awk_pgm" \
|
"$awk_pgm" \
|
||||||
"$input" > "$temp_file" || rm -f "$temp_file"
|
"$input" > "$temp_file" || rm -f "$temp_file"
|
||||||
|
|
||||||
@ -442,11 +475,14 @@ function template_j2cli() {
|
|||||||
temp_file="${output}.$$.$RANDOM"
|
temp_file="${output}.$$.$RANDOM"
|
||||||
|
|
||||||
YADM_CLASS="$local_class" \
|
YADM_CLASS="$local_class" \
|
||||||
|
YADM_ARCH="$local_arch" \
|
||||||
YADM_OS="$local_system" \
|
YADM_OS="$local_system" \
|
||||||
YADM_HOSTNAME="$local_host" \
|
YADM_HOSTNAME="$local_host" \
|
||||||
YADM_USER="$local_user" \
|
YADM_USER="$local_user" \
|
||||||
YADM_DISTRO="$local_distro" \
|
YADM_DISTRO="$local_distro" \
|
||||||
|
YADM_DISTRO_FAMILY="$local_distro_family" \
|
||||||
YADM_SOURCE="$input" \
|
YADM_SOURCE="$input" \
|
||||||
|
YADM_CLASSES="$(join_string $'\n' "${local_classes[@]}")" \
|
||||||
"$J2CLI_PROGRAM" "$input" -o "$temp_file"
|
"$J2CLI_PROGRAM" "$input" -o "$temp_file"
|
||||||
|
|
||||||
move_file "$input" "$output" "$temp_file"
|
move_file "$input" "$output" "$temp_file"
|
||||||
@ -458,11 +494,14 @@ function template_envtpl() {
|
|||||||
temp_file="${output}.$$.$RANDOM"
|
temp_file="${output}.$$.$RANDOM"
|
||||||
|
|
||||||
YADM_CLASS="$local_class" \
|
YADM_CLASS="$local_class" \
|
||||||
|
YADM_ARCH="$local_arch" \
|
||||||
YADM_OS="$local_system" \
|
YADM_OS="$local_system" \
|
||||||
YADM_HOSTNAME="$local_host" \
|
YADM_HOSTNAME="$local_host" \
|
||||||
YADM_USER="$local_user" \
|
YADM_USER="$local_user" \
|
||||||
YADM_DISTRO="$local_distro" \
|
YADM_DISTRO="$local_distro" \
|
||||||
|
YADM_DISTRO_FAMILY="$local_distro_family" \
|
||||||
YADM_SOURCE="$input" \
|
YADM_SOURCE="$input" \
|
||||||
|
YADM_CLASSES="$(join_string $'\n' "${local_classes[@]}")" \
|
||||||
"$ENVTPL_PROGRAM" --keep-template "$input" -o "$temp_file"
|
"$ENVTPL_PROGRAM" --keep-template "$input" -o "$temp_file"
|
||||||
|
|
||||||
move_file "$input" "$output" "$temp_file"
|
move_file "$input" "$output" "$temp_file"
|
||||||
@ -473,12 +512,15 @@ function template_esh() {
|
|||||||
output="$2"
|
output="$2"
|
||||||
temp_file="${output}.$$.$RANDOM"
|
temp_file="${output}.$$.$RANDOM"
|
||||||
|
|
||||||
|
YADM_CLASSES="$(join_string $'\n' "${local_classes[@]}")" \
|
||||||
"$ESH_PROGRAM" -o "$temp_file" "$input" \
|
"$ESH_PROGRAM" -o "$temp_file" "$input" \
|
||||||
YADM_CLASS="$local_class" \
|
YADM_CLASS="$local_class" \
|
||||||
|
YADM_ARCH="$local_arch" \
|
||||||
YADM_OS="$local_system" \
|
YADM_OS="$local_system" \
|
||||||
YADM_HOSTNAME="$local_host" \
|
YADM_HOSTNAME="$local_host" \
|
||||||
YADM_USER="$local_user" \
|
YADM_USER="$local_user" \
|
||||||
YADM_DISTRO="$local_distro" \
|
YADM_DISTRO="$local_distro" \
|
||||||
|
YADM_DISTRO_FAMILY="$local_distro_family" \
|
||||||
YADM_SOURCE="$input"
|
YADM_SOURCE="$input"
|
||||||
|
|
||||||
move_file "$input" "$output" "$temp_file"
|
move_file "$input" "$output" "$temp_file"
|
||||||
@ -509,10 +551,13 @@ function alt() {
|
|||||||
|
|
||||||
# gather values for processing alternates
|
# gather values for processing alternates
|
||||||
local local_class
|
local local_class
|
||||||
|
local -a local_classes
|
||||||
|
local local_arch
|
||||||
local local_system
|
local local_system
|
||||||
local local_host
|
local local_host
|
||||||
local local_user
|
local local_user
|
||||||
local local_distro
|
local local_distro
|
||||||
|
local local_distro_family
|
||||||
set_local_alt_values
|
set_local_alt_values
|
||||||
|
|
||||||
# only be noisy if the "alt" command was run directly
|
# only be noisy if the "alt" command was run directly
|
||||||
@ -539,8 +584,8 @@ function alt() {
|
|||||||
if [[ $possible_alt =~ .\#\#. ]]; then
|
if [[ $possible_alt =~ .\#\#. ]]; then
|
||||||
base_alt="${possible_alt%%##*}"
|
base_alt="${possible_alt%%##*}"
|
||||||
yadm_alt="${YADM_BASE}/${base_alt}"
|
yadm_alt="${YADM_BASE}/${base_alt}"
|
||||||
if [ "${yadm_alt#$YADM_ALT/}" != "${yadm_alt}" ]; then
|
if [ "${yadm_alt#"$YADM_ALT/"}" != "${yadm_alt}" ]; then
|
||||||
base_alt="${yadm_alt#$YADM_ALT/}"
|
base_alt="${yadm_alt#"$YADM_ALT/"}"
|
||||||
fi
|
fi
|
||||||
possible_alts+=("$YADM_BASE/${base_alt}")
|
possible_alts+=("$YADM_BASE/${base_alt}")
|
||||||
fi
|
fi
|
||||||
@ -607,7 +652,17 @@ function remove_stale_links() {
|
|||||||
|
|
||||||
function set_local_alt_values() {
|
function set_local_alt_values() {
|
||||||
|
|
||||||
local_class="$(config local.class)"
|
local -a all_classes
|
||||||
|
all_classes=$(config --get-all local.class)
|
||||||
|
while IFS='' read -r class; do
|
||||||
|
local_classes+=("$class")
|
||||||
|
local_class="$class"
|
||||||
|
done <<< "$all_classes"
|
||||||
|
|
||||||
|
local_arch="$(config local.arch)"
|
||||||
|
if [ -z "$local_arch" ] ; then
|
||||||
|
local_arch=$(uname -m)
|
||||||
|
fi
|
||||||
|
|
||||||
local_system="$(config local.os)"
|
local_system="$(config local.os)"
|
||||||
if [ -z "$local_system" ] ; then
|
if [ -z "$local_system" ] ; then
|
||||||
@ -626,6 +681,7 @@ function set_local_alt_values() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
local_distro="$(query_distro)"
|
local_distro="$(query_distro)"
|
||||||
|
local_distro_family="$(query_distro_family)"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -767,8 +823,8 @@ function clone() {
|
|||||||
rm -rf "$YADM_REPO" "$wc"
|
rm -rf "$YADM_REPO" "$wc"
|
||||||
error_out "Unable to clone the repository"
|
error_out "Unable to clone the repository"
|
||||||
}
|
}
|
||||||
rm -rf "$wc"
|
|
||||||
configure_repo
|
configure_repo
|
||||||
|
rm -rf "$wc"
|
||||||
|
|
||||||
# then reset the index as the --no-checkout flag makes the index empty
|
# then reset the index as the --no-checkout flag makes the index empty
|
||||||
"$GIT_PROGRAM" reset --quiet -- .
|
"$GIT_PROGRAM" reset --quiet -- .
|
||||||
@ -819,7 +875,7 @@ EOF
|
|||||||
function config() {
|
function config() {
|
||||||
|
|
||||||
use_repo_config=0
|
use_repo_config=0
|
||||||
local_options="^local\.(class|os|hostname|user)$"
|
local_options="^local\.(class|arch|os|hostname|user)$"
|
||||||
for option in "$@"; do
|
for option in "$@"; do
|
||||||
[[ "$option" =~ $local_options ]] && use_repo_config=1
|
[[ "$option" =~ $local_options ]] && use_repo_config=1
|
||||||
done
|
done
|
||||||
@ -865,7 +921,10 @@ function _set_gpg_options() {
|
|||||||
if [ "$gpg_key" = "ASK" ]; then
|
if [ "$gpg_key" = "ASK" ]; then
|
||||||
GPG_OPTS=("--no-default-recipient" "-e")
|
GPG_OPTS=("--no-default-recipient" "-e")
|
||||||
elif [ "$gpg_key" != "" ]; then
|
elif [ "$gpg_key" != "" ]; then
|
||||||
GPG_OPTS=("-e" "-r $gpg_key")
|
GPG_OPTS=("-e")
|
||||||
|
for key in $gpg_key; do
|
||||||
|
GPG_OPTS+=("-r $key")
|
||||||
|
done
|
||||||
else
|
else
|
||||||
GPG_OPTS=("-c")
|
GPG_OPTS=("-c")
|
||||||
fi
|
fi
|
||||||
@ -1188,6 +1247,7 @@ EOF
|
|||||||
function introspect_configs() {
|
function introspect_configs() {
|
||||||
local msg
|
local msg
|
||||||
read -r -d '' msg <<-EOF
|
read -r -d '' msg <<-EOF
|
||||||
|
local.arch
|
||||||
local.class
|
local.class
|
||||||
local.hostname
|
local.hostname
|
||||||
local.os
|
local.os
|
||||||
@ -1361,7 +1421,7 @@ function upgrade() {
|
|||||||
;
|
;
|
||||||
do
|
do
|
||||||
if [ -e "$legacy_path" ]; then
|
if [ -e "$legacy_path" ]; then
|
||||||
new_filename=${legacy_path#$YADM_LEGACY_DIR/}
|
new_filename="${legacy_path#"$YADM_LEGACY_DIR/"}"
|
||||||
new_filename="$YADM_DIR/$new_filename"
|
new_filename="$YADM_DIR/$new_filename"
|
||||||
actions_performed=1
|
actions_performed=1
|
||||||
echo "Moving $legacy_path to $new_filename"
|
echo "Moving $legacy_path to $new_filename"
|
||||||
@ -1392,7 +1452,9 @@ function upgrade() {
|
|||||||
|
|
||||||
function version() {
|
function version() {
|
||||||
|
|
||||||
echo "yadm $VERSION"
|
echo "bash version $BASH_VERSION"
|
||||||
|
printf " "; "$GIT_PROGRAM" --version
|
||||||
|
echo "yadm version $VERSION"
|
||||||
exit_with_hook 0
|
exit_with_hook 0
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1463,6 +1525,20 @@ function query_distro() {
|
|||||||
echo "$distro"
|
echo "$distro"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function query_distro_family() {
|
||||||
|
family=""
|
||||||
|
if [ -f "$OS_RELEASE" ]; then
|
||||||
|
while IFS='' read -r line || [ -n "$line" ]; do
|
||||||
|
if [[ "$line" = ID_LIKE=* ]]; then
|
||||||
|
family="${line#ID_LIKE=}"
|
||||||
|
family="${family//\"}"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done < "$OS_RELEASE"
|
||||||
|
fi
|
||||||
|
echo "$family"
|
||||||
|
}
|
||||||
|
|
||||||
function process_global_args() {
|
function process_global_args() {
|
||||||
|
|
||||||
# global arguments are removed before the main processing is done
|
# global arguments are removed before the main processing is done
|
||||||
@ -1925,7 +2001,7 @@ function relative_path() {
|
|||||||
result=""
|
result=""
|
||||||
|
|
||||||
count=0
|
count=0
|
||||||
while [ "${full#$common_part}" == "${full}" ]; do
|
while [ "${full#"$common_part"}" == "${full}" ]; do
|
||||||
[ "$count" = "500" ] && return # this is a failsafe
|
[ "$count" = "500" ] && return # this is a failsafe
|
||||||
# no match, means that candidate common part is not correct
|
# no match, means that candidate common part is not correct
|
||||||
# go up one level (reduce common part)
|
# go up one level (reduce common part)
|
||||||
@ -1946,7 +2022,7 @@ function relative_path() {
|
|||||||
|
|
||||||
# since we now have identified the common part,
|
# since we now have identified the common part,
|
||||||
# compute the non-common part
|
# compute the non-common part
|
||||||
forward_part="${full#$common_part}"
|
forward_part="${full#"$common_part"}"
|
||||||
|
|
||||||
# and now stick all parts together
|
# and now stick all parts together
|
||||||
if [[ -n $result ]] && [[ -n $forward_part ]]; then
|
if [[ -n $result ]] && [[ -n $forward_part ]]; then
|
||||||
@ -2011,6 +2087,16 @@ function join_string {
|
|||||||
printf "%s" "${*:2}"
|
printf "%s" "${*:2}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function in_list {
|
||||||
|
local element="$1"
|
||||||
|
shift
|
||||||
|
|
||||||
|
for e in "$@"; do
|
||||||
|
[[ "$e" = "$element" ]] && return 0
|
||||||
|
done
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
function get_mode {
|
function get_mode {
|
||||||
local filename="$1"
|
local filename="$1"
|
||||||
local mode
|
local mode
|
||||||
|
83
yadm.1
83
yadm.1
@ -1,5 +1,5 @@
|
|||||||
.\" vim: set spell so=8:
|
.\" vim: set spell so=8:
|
||||||
.TH yadm 1 "3 April 2021" "3.1.0"
|
.TH yadm 1 "23 January 2023" "3.2.2"
|
||||||
|
|
||||||
.SH NAME
|
.SH NAME
|
||||||
|
|
||||||
@ -427,7 +427,7 @@ Disable the permission changes to
|
|||||||
This feature is enabled by default.
|
This feature is enabled by default.
|
||||||
|
|
||||||
.RE
|
.RE
|
||||||
The following four "local" configurations are not stored in the
|
The following five "local" configurations are not stored in the
|
||||||
.IR $HOME/.config/yadm/config,
|
.IR $HOME/.config/yadm/config,
|
||||||
they are stored in the local repository.
|
they are stored in the local repository.
|
||||||
|
|
||||||
@ -435,6 +435,14 @@ they are stored in the local repository.
|
|||||||
.B local.class
|
.B local.class
|
||||||
Specify a class for the purpose of symlinking alternate files.
|
Specify a class for the purpose of symlinking alternate files.
|
||||||
By default, no class will be matched.
|
By default, no class will be matched.
|
||||||
|
The local host can be assigned multiple classes using command:
|
||||||
|
|
||||||
|
.RS
|
||||||
|
yadm config --add local.class <additional-class>
|
||||||
|
.RE
|
||||||
|
.TP
|
||||||
|
.B local.arch
|
||||||
|
Override the architecture for the purpose of symlinking alternate files.
|
||||||
.TP
|
.TP
|
||||||
.B local.hostname
|
.B local.hostname
|
||||||
Override the hostname for the purpose of symlinking alternate files.
|
Override the hostname for the purpose of symlinking alternate files.
|
||||||
@ -478,17 +486,11 @@ Valid if the value matches the current user.
|
|||||||
Current user is calculated by running
|
Current user is calculated by running
|
||||||
.BR "id -u -n" .
|
.BR "id -u -n" .
|
||||||
.TP
|
.TP
|
||||||
.BR distro , " d
|
.BR hostname , " h
|
||||||
Valid if the value matches the distro.
|
Valid if the value matches the short hostname.
|
||||||
Distro is calculated by running
|
Hostname is calculated by running
|
||||||
.B "lsb_release -si"
|
.BR "uname -n" ,
|
||||||
or by inspecting the ID from
|
and trimming off any domain.
|
||||||
.BR "/etc/os-release" .
|
|
||||||
.TP
|
|
||||||
.BR os , " o
|
|
||||||
Valid if the value matches the OS.
|
|
||||||
OS is calculated by running
|
|
||||||
.BR "uname -s" .
|
|
||||||
.TP
|
.TP
|
||||||
.BR class , " c
|
.BR class , " c
|
||||||
Valid if the value matches the
|
Valid if the value matches the
|
||||||
@ -499,11 +501,27 @@ Class must be manually set using
|
|||||||
See the CONFIGURATION section for more details about setting
|
See the CONFIGURATION section for more details about setting
|
||||||
.BR local.class .
|
.BR local.class .
|
||||||
.TP
|
.TP
|
||||||
.BR hostname , " h
|
.BR distro , " d
|
||||||
Valid if the value matches the short hostname.
|
Valid if the value matches the distro.
|
||||||
Hostname is calculated by running
|
Distro is calculated by running
|
||||||
.BR "uname -n" ,
|
.B "lsb_release -si"
|
||||||
and trimming off any domain.
|
or by inspecting the ID from
|
||||||
|
.BR "/etc/os-release" .
|
||||||
|
.TP
|
||||||
|
.BR distro_family , " f
|
||||||
|
Valid if the value matches the distro family.
|
||||||
|
Distro family is calculated by inspecting the ID_LIKE line from
|
||||||
|
.BR "/etc/os-release" .
|
||||||
|
.TP
|
||||||
|
.BR os , " o
|
||||||
|
Valid if the value matches the OS.
|
||||||
|
OS is calculated by running
|
||||||
|
.BR "uname -s" .
|
||||||
|
.TP
|
||||||
|
.BR arch , " a
|
||||||
|
Valid if the value matches the architecture.
|
||||||
|
Architecture is calculated by running
|
||||||
|
.BR "uname -m" .
|
||||||
.TP
|
.TP
|
||||||
.B default
|
.B default
|
||||||
Valid when no other alternate is valid.
|
Valid when no other alternate is valid.
|
||||||
@ -577,7 +595,7 @@ If no "##default" version exists and no files have valid conditions, then no
|
|||||||
link will be created.
|
link will be created.
|
||||||
|
|
||||||
Links are also created for directories named this way, as long as they have at
|
Links are also created for directories named this way, as long as they have at
|
||||||
least one yadm managed file within them.
|
least one yadm managed file within them (at the top level).
|
||||||
|
|
||||||
yadm will automatically create these links by default. This can be disabled
|
yadm will automatically create these links by default. This can be disabled
|
||||||
using the
|
using the
|
||||||
@ -596,8 +614,9 @@ command. The following sets the class to be "Work".
|
|||||||
|
|
||||||
yadm config local.class Work
|
yadm config local.class Work
|
||||||
|
|
||||||
Similarly, the values of os, hostname, and user can be manually overridden
|
Similarly, the values of architecture, os, hostname, and user can be manually
|
||||||
using the configuration options
|
overridden using the configuration options
|
||||||
|
.BR local.arch ,
|
||||||
.BR local.os ,
|
.BR local.os ,
|
||||||
.BR local.hostname ,
|
.BR local.hostname ,
|
||||||
and
|
and
|
||||||
@ -645,14 +664,18 @@ to create or overwrite files.
|
|||||||
|
|
||||||
During processing, the following variables are available in the template:
|
During processing, the following variables are available in the template:
|
||||||
|
|
||||||
Default Jinja or ESH Description
|
Default Jinja or ESH Description
|
||||||
------------- ------------- --------------------------
|
------------- ------------- ----------------------------
|
||||||
yadm.class YADM_CLASS Locally defined yadm class
|
yadm.arch YADM_ARCH uname -m
|
||||||
yadm.distro YADM_DISTRO lsb_release -si
|
yadm.class YADM_CLASS Last locally defined class
|
||||||
yadm.hostname YADM_HOSTNAME uname -n (without domain)
|
yadm.classes YADM_CLASSES All classes
|
||||||
yadm.os YADM_OS uname -s
|
yadm.distro YADM_DISTRO lsb_release -si
|
||||||
yadm.user YADM_USER id -u -n
|
yadm.distro_family YADM_DISTRO_FAMILY ID_LIKE from /etc/os-release
|
||||||
yadm.source YADM_SOURCE Template filename
|
yadm.hostname YADM_HOSTNAME uname -n (without domain)
|
||||||
|
yadm.os YADM_OS uname -s
|
||||||
|
yadm.source YADM_SOURCE Template filename
|
||||||
|
yadm.user YADM_USER id -u -n
|
||||||
|
env.VAR Environment variable VAR
|
||||||
|
|
||||||
.BR NOTE :
|
.BR NOTE :
|
||||||
The OS for "Windows Subsystem for Linux" is reported as "WSL", even
|
The OS for "Windows Subsystem for Linux" is reported as "WSL", even
|
||||||
@ -723,7 +746,7 @@ and
|
|||||||
.BR openssl (1)
|
.BR openssl (1)
|
||||||
are supported.
|
are supported.
|
||||||
gpg is used by default, but openssl can be configured with the
|
gpg is used by default, but openssl can be configured with the
|
||||||
.I yadm.cypher
|
.I yadm.cipher
|
||||||
configuration.
|
configuration.
|
||||||
|
|
||||||
To use this feature, a list of patterns must be created and saved as
|
To use this feature, a list of patterns must be created and saved as
|
||||||
|
383
yadm.md
383
yadm.md
@ -42,68 +42,68 @@
|
|||||||
|
|
||||||
|
|
||||||
## DESCRIPTION
|
## DESCRIPTION
|
||||||
yadm is a tool for managing a collection of files across multiple com-
|
yadm is a tool for managing a collection of files across multiple com‐
|
||||||
puters, using a shared Git repository. In addition, yadm provides a
|
puters, using a shared Git repository. In addition, yadm provides a
|
||||||
feature to select alternate versions of files for particular systems.
|
feature to select alternate versions of files for particular systems.
|
||||||
Lastly, yadm supplies the ability to manage a subset of secure files,
|
Lastly, yadm supplies the ability to manage a subset of secure files,
|
||||||
which are encrypted before they are included in the repository.
|
which are encrypted before they are included in the repository.
|
||||||
|
|
||||||
|
|
||||||
## COMMANDS
|
## COMMANDS
|
||||||
git-command or git-alias
|
git-command or git-alias
|
||||||
Any command not internally handled by yadm is passed through to
|
Any command not internally handled by yadm is passed through to
|
||||||
git(1). Git commands or aliases are invoked with the yadm man-
|
git(1). Git commands or aliases are invoked with the yadm man‐
|
||||||
aged repository. The working directory for Git commands will be
|
aged repository. The working directory for Git commands will be
|
||||||
the configured work-tree (usually $HOME).
|
the configured work-tree (usually $HOME).
|
||||||
|
|
||||||
Dotfiles are managed by using standard git commands; add, com-
|
Dotfiles are managed by using standard git commands; add, com‐
|
||||||
mit, push, pull, etc.
|
mit, push, pull, etc.
|
||||||
|
|
||||||
The config command is not passed directly through. Instead use
|
The config command is not passed directly through. Instead use
|
||||||
the gitconfig command (see below).
|
the gitconfig command (see below).
|
||||||
|
|
||||||
alt Create symbolic links and process templates for any managed
|
alt Create symbolic links and process templates for any managed
|
||||||
files matching the naming rules described in the ALTERNATES and
|
files matching the naming rules described in the ALTERNATES and
|
||||||
TEMPLATES sections. It is usually unnecessary to run this com-
|
TEMPLATES sections. It is usually unnecessary to run this com‐
|
||||||
mand, as yadm automatically processes alternates by default.
|
mand, as yadm automatically processes alternates by default.
|
||||||
This automatic behavior can be disabled by setting the configu-
|
This automatic behavior can be disabled by setting the configu‐
|
||||||
ration yadm.auto-alt to "false".
|
ration yadm.auto-alt to "false".
|
||||||
|
|
||||||
bootstrap
|
bootstrap
|
||||||
Execute $HOME/.config/yadm/bootstrap if it exists.
|
Execute $HOME/.config/yadm/bootstrap if it exists.
|
||||||
|
|
||||||
clone url
|
clone url
|
||||||
Clone a remote repository for tracking dotfiles. After the con-
|
Clone a remote repository for tracking dotfiles. After the con‐
|
||||||
tents of the remote repository have been fetched, a "check out"
|
tents of the remote repository have been fetched, a "check out"
|
||||||
of the remote HEAD branch is attempted. If there are conflict-
|
of the remote HEAD branch is attempted. If there are conflict‐
|
||||||
ing files already present in the work-tree, the local version
|
ing files already present in the work-tree, the local version
|
||||||
will be left unmodified and you'll have to review and resolve
|
will be left unmodified and you'll have to review and resolve
|
||||||
the difference.
|
the difference.
|
||||||
|
|
||||||
The repository is stored in $HOME/.local/share/yadm/repo.git.
|
The repository is stored in $HOME/.local/share/yadm/repo.git.
|
||||||
By default, $HOME will be used as the work-tree, but this can be
|
By default, $HOME will be used as the work-tree, but this can be
|
||||||
overridden with the -w option. yadm can be forced to overwrite
|
overridden with the -w option. yadm can be forced to overwrite
|
||||||
an existing repository by providing the -f option. If you want
|
an existing repository by providing the -f option. If you want
|
||||||
to use a branch other than the remote HEAD branch you can spec-
|
to use a branch other than the remote HEAD branch you can spec‐
|
||||||
ify it using the -b option. By default yadm will ask the user
|
ify it using the -b option. By default yadm will ask the user
|
||||||
if the bootstrap program should be run (if it exists). The
|
if the bootstrap program should be run (if it exists). The op‐
|
||||||
options --bootstrap or --no-bootstrap will either force the
|
tions --bootstrap or --no-bootstrap will either force the boot‐
|
||||||
bootstrap to be run, or prevent it from being run, without
|
strap to be run, or prevent it from being run, without prompting
|
||||||
prompting the user.
|
the user.
|
||||||
|
|
||||||
config This command manages configurations for yadm. This command
|
config This command manages configurations for yadm. This command
|
||||||
works exactly the way git-config(1) does. See the CONFIGURATION
|
works exactly the way git-config(1) does. See the CONFIGURATION
|
||||||
section for more details.
|
section for more details.
|
||||||
|
|
||||||
decrypt
|
decrypt
|
||||||
Decrypt all files stored in $HOME/.local/share/yadm/archive.
|
Decrypt all files stored in $HOME/.local/share/yadm/archive.
|
||||||
Files decrypted will be relative to the configured work-tree
|
Files decrypted will be relative to the configured work-tree
|
||||||
(usually $HOME). Using the -l option will list the files stored
|
(usually $HOME). Using the -l option will list the files stored
|
||||||
without extracting them.
|
without extracting them.
|
||||||
|
|
||||||
encrypt
|
encrypt
|
||||||
Encrypt all files matching the patterns found in $HOME/.con-
|
Encrypt all files matching the patterns found in $HOME/.con‐
|
||||||
fig/yadm/encrypt. See the ENCRYPTION section for more details.
|
fig/yadm/encrypt. See the ENCRYPTION section for more details.
|
||||||
|
|
||||||
enter Run a sub-shell with all Git variables set. Exit the sub-shell
|
enter Run a sub-shell with all Git variables set. Exit the sub-shell
|
||||||
the same way you leave your normal shell (usually with the
|
the same way you leave your normal shell (usually with the
|
||||||
@ -116,7 +116,7 @@
|
|||||||
of invoking your shell, that command will be run with all of the
|
of invoking your shell, that command will be run with all of the
|
||||||
Git variables exposed to the command's environment.
|
Git variables exposed to the command's environment.
|
||||||
|
|
||||||
Emacs Tramp and Magit can manage files by using this configura-
|
Emacs Tramp and Magit can manage files by using this configura‐
|
||||||
tion:
|
tion:
|
||||||
|
|
||||||
(add-to-list 'tramp-methods
|
(add-to-list 'tramp-methods
|
||||||
@ -130,9 +130,9 @@
|
|||||||
With this config, use (magit-status "/yadm::").
|
With this config, use (magit-status "/yadm::").
|
||||||
|
|
||||||
git-crypt options
|
git-crypt options
|
||||||
If git-crypt is installed, this command allows you to pass
|
If git-crypt is installed, this command allows you to pass op‐
|
||||||
options directly to git-crypt, with the environment configured
|
tions directly to git-crypt, with the environment configured to
|
||||||
to use the yadm repository.
|
use the yadm repository.
|
||||||
|
|
||||||
git-crypt enables transparent encryption and decryption of files
|
git-crypt enables transparent encryption and decryption of files
|
||||||
in a git repository. You can read https://github.com/AGWA/git-
|
in a git repository. You can read https://github.com/AGWA/git-
|
||||||
@ -140,13 +140,13 @@
|
|||||||
|
|
||||||
gitconfig
|
gitconfig
|
||||||
Pass options to the git config command. Since yadm already uses
|
Pass options to the git config command. Since yadm already uses
|
||||||
the config command to manage its own configurations, this com-
|
the config command to manage its own configurations, this com‐
|
||||||
mand is provided as a way to change configurations of the repos-
|
mand is provided as a way to change configurations of the repos‐
|
||||||
itory managed by yadm. One useful case might be to configure
|
itory managed by yadm. One useful case might be to configure
|
||||||
the repository so untracked files are shown in status commands.
|
the repository so untracked files are shown in status commands.
|
||||||
yadm initially configures its repository so that untracked files
|
yadm initially configures its repository so that untracked files
|
||||||
are not shown. If you wish use the default Git behavior (to
|
are not shown. If you wish use the default Git behavior (to
|
||||||
show untracked files and directories), you can remove this con-
|
show untracked files and directories), you can remove this con‐
|
||||||
figuration.
|
figuration.
|
||||||
|
|
||||||
yadm gitconfig --unset status.showUntrackedFiles
|
yadm gitconfig --unset status.showUntrackedFiles
|
||||||
@ -169,15 +169,15 @@
|
|||||||
support command line completion.
|
support command line completion.
|
||||||
|
|
||||||
perms Update permissions as described in the PERMISSIONS section. It
|
perms Update permissions as described in the PERMISSIONS section. It
|
||||||
is usually unnecessary to run this command, as yadm automati-
|
is usually unnecessary to run this command, as yadm automati‐
|
||||||
cally processes permissions by default. This automatic behavior
|
cally processes permissions by default. This automatic behavior
|
||||||
can be disabled by setting the configuration yadm.auto-perms to
|
can be disabled by setting the configuration yadm.auto-perms to
|
||||||
"false".
|
"false".
|
||||||
|
|
||||||
transcrypt options
|
transcrypt options
|
||||||
If transcrypt is installed, this command allows you to pass
|
If transcrypt is installed, this command allows you to pass op‐
|
||||||
options directly to transcrypt, with the environment configured
|
tions directly to transcrypt, with the environment configured to
|
||||||
to use the yadm repository.
|
use the yadm repository.
|
||||||
|
|
||||||
transcrypt enables transparent encryption and decryption of
|
transcrypt enables transparent encryption and decryption of
|
||||||
files in a git repository. You can read
|
files in a git repository. You can read
|
||||||
@ -186,7 +186,7 @@
|
|||||||
upgrade
|
upgrade
|
||||||
Version 3 of yadm uses a different directory for storing data.
|
Version 3 of yadm uses a different directory for storing data.
|
||||||
When you start to use version 3 for the first time, you may see
|
When you start to use version 3 for the first time, you may see
|
||||||
warnings about moving your data to this new directory. The eas-
|
warnings about moving your data to this new directory. The eas‐
|
||||||
iest way to accomplish this is by running "yadm upgrade". This
|
iest way to accomplish this is by running "yadm upgrade". This
|
||||||
command will start by moving your yadm repo to the new path.
|
command will start by moving your yadm repo to the new path.
|
||||||
Next it will move any archive data. If the archive is tracked
|
Next it will move any archive data. If the archive is tracked
|
||||||
@ -194,18 +194,18 @@
|
|||||||
that file in the repo's index.
|
that file in the repo's index.
|
||||||
|
|
||||||
Upgrading will attempt to de-initialize and re-initialize your
|
Upgrading will attempt to de-initialize and re-initialize your
|
||||||
submodules. If your submodules cannot be de-initialized, the
|
submodules. If your submodules cannot be de-initialized, the up‐
|
||||||
upgrade will fail. The most common reason submodules will fail
|
grade will fail. The most common reason submodules will fail to
|
||||||
to de-initialize is because they have local modifications. If
|
de-initialize is because they have local modifications. If you
|
||||||
you are willing to lose the local modifications to those submod-
|
are willing to lose the local modifications to those submodules,
|
||||||
ules, you can use the -f option with the "upgrade" command to
|
you can use the -f option with the "upgrade" command to force
|
||||||
force the de-initialization.
|
the de-initialization.
|
||||||
|
|
||||||
After running "yadm upgrade", you should run "yadm status" to
|
After running "yadm upgrade", you should run "yadm status" to
|
||||||
review changes which have been staged, and commit them to your
|
review changes which have been staged, and commit them to your
|
||||||
repository.
|
repository.
|
||||||
|
|
||||||
You can read https://yadm.io/docs/upgrade_from_2 for more infor-
|
You can read https://yadm.io/docs/upgrade_from_2 for more infor‐
|
||||||
mation.
|
mation.
|
||||||
|
|
||||||
version
|
version
|
||||||
@ -214,7 +214,7 @@
|
|||||||
|
|
||||||
## OPTIONS
|
## OPTIONS
|
||||||
yadm supports a set of universal options that alter the paths it uses.
|
yadm supports a set of universal options that alter the paths it uses.
|
||||||
The default paths are documented in the FILES section. Any path speci-
|
The default paths are documented in the FILES section. Any path speci‐
|
||||||
fied by these options must be fully qualified. If you always want to
|
fied by these options must be fully qualified. If you always want to
|
||||||
override one or more of these paths, it may be useful to create an
|
override one or more of these paths, it may be useful to create an
|
||||||
alias for the yadm command. For example, the following alias could be
|
alias for the yadm command. For example, the following alias could be
|
||||||
@ -261,24 +261,24 @@
|
|||||||
The following is the full list of supported configurations:
|
The following is the full list of supported configurations:
|
||||||
|
|
||||||
yadm.alt-copy
|
yadm.alt-copy
|
||||||
If set to "true", alternate files will be copies instead of sym-
|
If set to "true", alternate files will be copies instead of sym‐
|
||||||
bolic links. This might be desirable, because some systems may
|
bolic links. This might be desirable, because some systems may
|
||||||
not properly support symlinks.
|
not properly support symlinks.
|
||||||
|
|
||||||
yadm.auto-alt
|
yadm.auto-alt
|
||||||
Disable the automatic linking described in the section ALTER-
|
Disable the automatic linking described in the section ALTER‐
|
||||||
NATES. If disabled, you may still run "yadm alt" manually to
|
NATES. If disabled, you may still run "yadm alt" manually to
|
||||||
create the alternate links. This feature is enabled by default.
|
create the alternate links. This feature is enabled by default.
|
||||||
|
|
||||||
yadm.auto-exclude
|
yadm.auto-exclude
|
||||||
Disable the automatic exclusion of patterns defined in
|
Disable the automatic exclusion of patterns defined in
|
||||||
$HOME/.config/yadm/encrypt. This feature is enabled by default.
|
$HOME/.config/yadm/encrypt. This feature is enabled by default.
|
||||||
|
|
||||||
yadm.auto-perms
|
yadm.auto-perms
|
||||||
Disable the automatic permission changes described in the sec-
|
Disable the automatic permission changes described in the sec‐
|
||||||
tion PERMISSIONS. If disabled, you may still run yadm perms
|
tion PERMISSIONS. If disabled, you may still run yadm perms
|
||||||
manually to update permissions. This feature is enabled by
|
manually to update permissions. This feature is enabled by de‐
|
||||||
default.
|
fault.
|
||||||
|
|
||||||
yadm.auto-private-dirs
|
yadm.auto-private-dirs
|
||||||
Disable the automatic creating of private directories described
|
Disable the automatic creating of private directories described
|
||||||
@ -287,20 +287,20 @@
|
|||||||
yadm.cipher
|
yadm.cipher
|
||||||
Configure which encryption system is used by the encrypt/decrypt
|
Configure which encryption system is used by the encrypt/decrypt
|
||||||
commands. Valid options are "gpg" and "openssl". The default is
|
commands. Valid options are "gpg" and "openssl". The default is
|
||||||
"gpg". Detailed information can be found in the section ENCRYP-
|
"gpg". Detailed information can be found in the section ENCRYP‐
|
||||||
TION.
|
TION.
|
||||||
|
|
||||||
yadm.git-program
|
yadm.git-program
|
||||||
Specify an alternate program to use instead of "git". By
|
Specify an alternate program to use instead of "git". By de‐
|
||||||
default, the first "git" found in $PATH is used.
|
fault, the first "git" found in $PATH is used.
|
||||||
|
|
||||||
yadm.gpg-perms
|
yadm.gpg-perms
|
||||||
Disable the permission changes to $HOME/.gnupg/*. This feature
|
Disable the permission changes to $HOME/.gnupg/*. This feature
|
||||||
is enabled by default.
|
is enabled by default.
|
||||||
|
|
||||||
yadm.gpg-program
|
yadm.gpg-program
|
||||||
Specify an alternate program to use instead of "gpg". By
|
Specify an alternate program to use instead of "gpg". By de‐
|
||||||
default, the first "gpg" found in $PATH is used.
|
fault, the first "gpg" found in $PATH is used.
|
||||||
|
|
||||||
yadm.gpg-recipient
|
yadm.gpg-recipient
|
||||||
Asymmetrically encrypt files with a gpg public/private key pair.
|
Asymmetrically encrypt files with a gpg public/private key pair.
|
||||||
@ -308,9 +308,9 @@
|
|||||||
The key must exist in your public keyrings. Multiple recipients
|
The key must exist in your public keyrings. Multiple recipients
|
||||||
can be specified (separated by space). If left blank or not
|
can be specified (separated by space). If left blank or not
|
||||||
provided, symmetric encryption is used instead. If set to
|
provided, symmetric encryption is used instead. If set to
|
||||||
"ASK", gpg will interactively ask for recipients. See the
|
"ASK", gpg will interactively ask for recipients. See the EN‐
|
||||||
ENCRYPTION section for more details. This feature is disabled
|
CRYPTION section for more details. This feature is disabled by
|
||||||
by default.
|
default.
|
||||||
|
|
||||||
yadm.openssl-ciphername
|
yadm.openssl-ciphername
|
||||||
Specify which cipher should be used by openssl. "aes-256-cbc"
|
Specify which cipher should be used by openssl. "aes-256-cbc"
|
||||||
@ -331,13 +331,20 @@
|
|||||||
Disable the permission changes to $HOME/.ssh/*. This feature is
|
Disable the permission changes to $HOME/.ssh/*. This feature is
|
||||||
enabled by default.
|
enabled by default.
|
||||||
|
|
||||||
The following four "local" configurations are not stored in the
|
The following five "local" configurations are not stored in the
|
||||||
$HOME/.config/yadm/config, they are stored in the local repository.
|
$HOME/.config/yadm/config, they are stored in the local repository.
|
||||||
|
|
||||||
|
|
||||||
local.class
|
local.class
|
||||||
Specify a class for the purpose of symlinking alternate files.
|
Specify a class for the purpose of symlinking alternate files.
|
||||||
By default, no class will be matched.
|
By default, no class will be matched. The local host can be as‐
|
||||||
|
signed multiple classes using command:
|
||||||
|
|
||||||
|
yadm config --add local.class <additional-class>
|
||||||
|
|
||||||
|
local.arch
|
||||||
|
Override the architecture for the purpose of symlinking alter‐
|
||||||
|
nate files.
|
||||||
|
|
||||||
local.hostname
|
local.hostname
|
||||||
Override the hostname for the purpose of symlinking alternate
|
Override the hostname for the purpose of symlinking alternate
|
||||||
@ -355,52 +362,60 @@
|
|||||||
to have an automated way of choosing an alternate version of a file for
|
to have an automated way of choosing an alternate version of a file for
|
||||||
a different operating system, host, user, etc.
|
a different operating system, host, user, etc.
|
||||||
|
|
||||||
yadm will automatically create a symbolic link to the appropriate ver-
|
yadm will automatically create a symbolic link to the appropriate ver‐
|
||||||
sion of a file, when a valid suffix is appended to the filename. The
|
sion of a file, when a valid suffix is appended to the filename. The
|
||||||
suffix contains the conditions that must be met for that file to be
|
suffix contains the conditions that must be met for that file to be
|
||||||
used.
|
used.
|
||||||
|
|
||||||
The suffix begins with "##", followed by any number of conditions sepa-
|
The suffix begins with "##", followed by any number of conditions sepa‐
|
||||||
rated by commas.
|
rated by commas.
|
||||||
|
|
||||||
##<condition>[,<condition>,...]
|
##<condition>[,<condition>,...]
|
||||||
|
|
||||||
Each condition is an attribute/value pair, separated by a period. Some
|
Each condition is an attribute/value pair, separated by a period. Some
|
||||||
conditions do not require a "value", and in that case, the period and
|
conditions do not require a "value", and in that case, the period and
|
||||||
value can be omitted. Most attributes can be abbreviated as a single
|
value can be omitted. Most attributes can be abbreviated as a single
|
||||||
letter.
|
letter.
|
||||||
|
|
||||||
<attribute>[.<value>]
|
<attribute>[.<value>]
|
||||||
|
|
||||||
These are the supported attributes, in the order of the weighted prece-
|
These are the supported attributes, in the order of the weighted prece‐
|
||||||
dence:
|
dence:
|
||||||
|
|
||||||
|
|
||||||
template, t
|
template, t
|
||||||
Valid when the value matches a supported template processor.
|
Valid when the value matches a supported template processor.
|
||||||
See the TEMPLATES section for more details.
|
See the TEMPLATES section for more details.
|
||||||
|
|
||||||
user, u
|
user, u
|
||||||
Valid if the value matches the current user. Current user is
|
Valid if the value matches the current user. Current user is
|
||||||
calculated by running id -u -n.
|
calculated by running id -u -n.
|
||||||
|
|
||||||
distro, d
|
hostname, h
|
||||||
Valid if the value matches the distro. Distro is calculated by
|
Valid if the value matches the short hostname. Hostname is cal‐
|
||||||
running lsb_release -si or by inspecting the ID from /etc/os-
|
culated by running uname -n, and trimming off any domain.
|
||||||
release.
|
|
||||||
|
|
||||||
os, o Valid if the value matches the OS. OS is calculated by running
|
|
||||||
uname -s.
|
|
||||||
|
|
||||||
class, c
|
class, c
|
||||||
Valid if the value matches the local.class configuration. Class
|
Valid if the value matches the local.class configuration. Class
|
||||||
must be manually set using yadm config local.class <class>. See
|
must be manually set using yadm config local.class <class>. See
|
||||||
the CONFIGURATION section for more details about setting
|
the CONFIGURATION section for more details about setting lo‐
|
||||||
local.class.
|
cal.class.
|
||||||
|
|
||||||
hostname, h
|
distro, d
|
||||||
Valid if the value matches the short hostname. Hostname is cal-
|
Valid if the value matches the distro. Distro is calculated by
|
||||||
culated by running uname -n, and trimming off any domain.
|
running lsb_release -si or by inspecting the ID from /etc/os-re‐
|
||||||
|
lease.
|
||||||
|
|
||||||
|
distro_family, f
|
||||||
|
Valid if the value matches the distro family. Distro family is
|
||||||
|
calculated by inspecting the ID_LIKE line from /etc/os-release.
|
||||||
|
|
||||||
|
os, o Valid if the value matches the OS. OS is calculated by running
|
||||||
|
uname -s.
|
||||||
|
|
||||||
|
arch, a
|
||||||
|
Valid if the value matches the architecture. Architecture is
|
||||||
|
calculated by running uname -m.
|
||||||
|
|
||||||
default
|
default
|
||||||
Valid when no other alternate is valid.
|
Valid when no other alternate is valid.
|
||||||
@ -408,31 +423,30 @@
|
|||||||
extension, e
|
extension, e
|
||||||
A special "condition" that doesn't affect the selection process.
|
A special "condition" that doesn't affect the selection process.
|
||||||
Its purpose is instead to allow the alternate file to end with a
|
Its purpose is instead to allow the alternate file to end with a
|
||||||
certain extension to e.g. make editors highlight the content
|
certain extension to e.g. make editors highlight the content
|
||||||
properly.
|
properly.
|
||||||
|
|
||||||
|
NOTE: The OS for "Windows Subsystem for Linux" is reported as "WSL",
|
||||||
NOTE: The OS for "Windows Subsystem for Linux" is reported as "WSL",
|
|
||||||
even though uname identifies as "Linux".
|
even though uname identifies as "Linux".
|
||||||
|
|
||||||
You may use any number of conditions, in any order. An alternate will
|
You may use any number of conditions, in any order. An alternate will
|
||||||
only be used if ALL conditions are valid. For all files managed by
|
only be used if ALL conditions are valid. For all files managed by
|
||||||
yadm's repository or listed in $HOME/.config/yadm/encrypt, if they
|
yadm's repository or listed in $HOME/.config/yadm/encrypt, if they
|
||||||
match this naming convention, symbolic links will be created for the
|
match this naming convention, symbolic links will be created for the
|
||||||
most appropriate version.
|
most appropriate version.
|
||||||
|
|
||||||
The "most appropriate" version is determined by calculating a score for
|
The "most appropriate" version is determined by calculating a score for
|
||||||
each version of a file. A template is always scored higher than any
|
each version of a file. A template is always scored higher than any
|
||||||
symlink condition. The number of conditions is the next largest factor
|
symlink condition. The number of conditions is the next largest factor
|
||||||
in scoring. Files with more conditions will always be favored. Any
|
in scoring. Files with more conditions will always be favored. Any in‐
|
||||||
invalid condition will disqualify that file completely.
|
valid condition will disqualify that file completely.
|
||||||
|
|
||||||
If you don't care to have all versions of alternates stored in the same
|
If you don't care to have all versions of alternates stored in the same
|
||||||
directory as the generated symlink, you can place them in the
|
directory as the generated symlink, you can place them in the
|
||||||
$HOME/.config/yadm/alt directory. The generated symlink or processed
|
$HOME/.config/yadm/alt directory. The generated symlink or processed
|
||||||
template will be created using the same relative path.
|
template will be created using the same relative path.
|
||||||
|
|
||||||
Alternate linking may best be demonstrated by example. Assume the fol-
|
Alternate linking may best be demonstrated by example. Assume the fol‐
|
||||||
lowing files are managed by yadm's repository:
|
lowing files are managed by yadm's repository:
|
||||||
|
|
||||||
- $HOME/path/example.txt##default
|
- $HOME/path/example.txt##default
|
||||||
@ -447,7 +461,7 @@
|
|||||||
If running on a Macbook named "host2", yadm will create a symbolic link
|
If running on a Macbook named "host2", yadm will create a symbolic link
|
||||||
which looks like this:
|
which looks like this:
|
||||||
|
|
||||||
$HOME/path/example.txt -> $HOME/path/example.txt##os.Darwin,host-
|
$HOME/path/example.txt -> $HOME/path/example.txt##os.Darwin,host‐
|
||||||
name.host2
|
name.host2
|
||||||
|
|
||||||
However, on another Mackbook named "host3", yadm will create a symbolic
|
However, on another Mackbook named "host3", yadm will create a symbolic
|
||||||
@ -455,7 +469,7 @@
|
|||||||
|
|
||||||
$HOME/path/example.txt -> $HOME/path/example.txt##os.Darwin
|
$HOME/path/example.txt -> $HOME/path/example.txt##os.Darwin
|
||||||
|
|
||||||
Since the hostname doesn't match any of the managed files, the more
|
Since the hostname doesn't match any of the managed files, the more
|
||||||
generic version is chosen.
|
generic version is chosen.
|
||||||
|
|
||||||
If running on a Linux server named "host4", the link will be:
|
If running on a Linux server named "host4", the link will be:
|
||||||
@ -470,81 +484,84 @@
|
|||||||
|
|
||||||
$HOME/path/example.txt -> $HOME/path/example.txt##class.Work
|
$HOME/path/example.txt -> $HOME/path/example.txt##class.Work
|
||||||
|
|
||||||
If no "##default" version exists and no files have valid conditions,
|
If no "##default" version exists and no files have valid conditions,
|
||||||
then no link will be created.
|
then no link will be created.
|
||||||
|
|
||||||
Links are also created for directories named this way, as long as they
|
Links are also created for directories named this way, as long as they
|
||||||
have at least one yadm managed file within them.
|
have at least one yadm managed file within them (at the top level).
|
||||||
|
|
||||||
yadm will automatically create these links by default. This can be dis-
|
yadm will automatically create these links by default. This can be dis‐
|
||||||
abled using the yadm.auto-alt configuration. Even if disabled, links
|
abled using the yadm.auto-alt configuration. Even if disabled, links
|
||||||
can be manually created by running yadm alt.
|
can be manually created by running yadm alt.
|
||||||
|
|
||||||
Class is a special value which is stored locally on each host (inside
|
Class is a special value which is stored locally on each host (inside
|
||||||
the local repository). To use alternate symlinks using class, you must
|
the local repository). To use alternate symlinks using class, you must
|
||||||
set the value of class using the configuration local.class. This is
|
set the value of class using the configuration local.class. This is
|
||||||
set like any other yadm configuration with the yadm config command. The
|
set like any other yadm configuration with the yadm config command. The
|
||||||
following sets the class to be "Work".
|
following sets the class to be "Work".
|
||||||
|
|
||||||
yadm config local.class Work
|
yadm config local.class Work
|
||||||
|
|
||||||
Similarly, the values of os, hostname, and user can be manually over-
|
Similarly, the values of architecture, os, hostname, and user can be
|
||||||
ridden using the configuration options local.os, local.hostname, and
|
manually overridden using the configuration options local.arch, lo‐
|
||||||
local.user.
|
cal.os, local.hostname, and local.user.
|
||||||
|
|
||||||
|
|
||||||
## TEMPLATES
|
## TEMPLATES
|
||||||
If a template condition is defined in an alternate file's "##" suffix,
|
If a template condition is defined in an alternate file's "##" suffix,
|
||||||
and the necessary dependencies for the template are available, then the
|
and the necessary dependencies for the template are available, then the
|
||||||
file will be processed to create or overwrite files.
|
file will be processed to create or overwrite files.
|
||||||
|
|
||||||
Supported template processors:
|
Supported template processors:
|
||||||
|
|
||||||
default
|
default
|
||||||
This is yadm's built-in template processor. This processor is
|
This is yadm's built-in template processor. This processor is
|
||||||
very basic, with a Jinja-like syntax. The advantage of this pro-
|
very basic, with a Jinja-like syntax. The advantage of this pro‐
|
||||||
cessor is that it only depends upon awk, which is available on
|
cessor is that it only depends upon awk, which is available on
|
||||||
most *nix systems. To use this processor, specify the value of
|
most *nix systems. To use this processor, specify the value of
|
||||||
"default" or just leave the value off (e.g. "##template").
|
"default" or just leave the value off (e.g. "##template").
|
||||||
|
|
||||||
ESH ESH is a template processor written in POSIX compliant shell. It
|
ESH ESH is a template processor written in POSIX compliant shell. It
|
||||||
allows executing shell commands within templates. This can be
|
allows executing shell commands within templates. This can be
|
||||||
used to reference your own configurations within templates, for
|
used to reference your own configurations within templates, for
|
||||||
example:
|
example:
|
||||||
|
|
||||||
<% yadm config mysection.myconfig %>
|
<% yadm config mysection.myconfig %>
|
||||||
|
|
||||||
To use the ESH template processor, specify the value of "esh"
|
To use the ESH template processor, specify the value of "esh"
|
||||||
|
|
||||||
j2cli To use the j2cli Jinja template processor, specify the value of
|
j2cli To use the j2cli Jinja template processor, specify the value of
|
||||||
"j2" or "j2cli".
|
"j2" or "j2cli".
|
||||||
|
|
||||||
envtpl To use the envtpl Jinja template processor, specify the value of
|
envtpl To use the envtpl Jinja template processor, specify the value of
|
||||||
"j2" or "envtpl".
|
"j2" or "envtpl".
|
||||||
|
|
||||||
|
NOTE: Specifying "j2" as the processor will attempt to use j2cli or en‐
|
||||||
|
vtpl, whichever is available.
|
||||||
|
|
||||||
NOTE: Specifying "j2" as the processor will attempt to use j2cli or
|
If the template processor specified is available, templates will be
|
||||||
envtpl, whichever is available.
|
|
||||||
|
|
||||||
If the template processor specified is available, templates will be
|
|
||||||
processed to create or overwrite files.
|
processed to create or overwrite files.
|
||||||
|
|
||||||
During processing, the following variables are available in the tem-
|
During processing, the following variables are available in the tem‐
|
||||||
plate:
|
plate:
|
||||||
|
|
||||||
Default Jinja or ESH Description
|
Default Jinja or ESH Description
|
||||||
------------- ------------- --------------------------
|
------------- ------------- ----------------------------
|
||||||
yadm.class YADM_CLASS Locally defined yadm class
|
yadm.arch YADM_ARCH uname -m
|
||||||
yadm.distro YADM_DISTRO lsb_release -si
|
yadm.class YADM_CLASS Last locally defined class
|
||||||
yadm.hostname YADM_HOSTNAME uname -n (without domain)
|
yadm.classes YADM_CLASSES All classes
|
||||||
yadm.os YADM_OS uname -s
|
yadm.distro YADM_DISTRO lsb_release -si
|
||||||
yadm.user YADM_USER id -u -n
|
yadm.distro_family YADM_DISTRO_FAMILY ID_LIKE from /etc/os-release
|
||||||
yadm.source YADM_SOURCE Template filename
|
yadm.hostname YADM_HOSTNAME uname -n (without domain)
|
||||||
|
yadm.os YADM_OS uname -s
|
||||||
|
yadm.source YADM_SOURCE Template filename
|
||||||
|
yadm.user YADM_USER id -u -n
|
||||||
|
env.VAR Environment variable VAR
|
||||||
|
|
||||||
NOTE: The OS for "Windows Subsystem for Linux" is reported as "WSL",
|
NOTE: The OS for "Windows Subsystem for Linux" is reported as "WSL",
|
||||||
even though uname identifies as "Linux".
|
even though uname identifies as "Linux".
|
||||||
|
|
||||||
NOTE: If lsb_release is not available, DISTRO will be the ID specified
|
NOTE: If lsb_release is not available, DISTRO will be the ID specified
|
||||||
in /etc/os-release.
|
in /etc/os-release.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
@ -558,7 +575,7 @@
|
|||||||
{% include "whatever.extra" %}
|
{% include "whatever.extra" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
would output a file named whatever with the following content if the
|
would output a file named whatever with the following content if the
|
||||||
user is "harvey":
|
user is "harvey":
|
||||||
|
|
||||||
config=work-Linux
|
config=work-Linux
|
||||||
@ -568,7 +585,7 @@
|
|||||||
config=dev-whatever
|
config=dev-whatever
|
||||||
admin=false
|
admin=false
|
||||||
|
|
||||||
An equivalent Jinja template named whatever##template.j2 would look
|
An equivalent Jinja template named whatever##template.j2 would look
|
||||||
like:
|
like:
|
||||||
|
|
||||||
{% if YADM_USER == 'harvey' -%}
|
{% if YADM_USER == 'harvey' -%}
|
||||||
@ -578,7 +595,7 @@
|
|||||||
{% include 'whatever.extra' %}
|
{% include 'whatever.extra' %}
|
||||||
{% endif -%}
|
{% endif -%}
|
||||||
|
|
||||||
An equivalent ESH templated named whatever##template.esh would look
|
An equivalent ESH templated named whatever##template.esh would look
|
||||||
like:
|
like:
|
||||||
|
|
||||||
<% if [ "$YADM_USER" = "harvey" ]; then -%>
|
<% if [ "$YADM_USER" = "harvey" ]; then -%>
|
||||||
@ -590,55 +607,55 @@
|
|||||||
|
|
||||||
|
|
||||||
## ENCRYPTION
|
## ENCRYPTION
|
||||||
It can be useful to manage confidential files, like SSH or GPG keys,
|
It can be useful to manage confidential files, like SSH or GPG keys,
|
||||||
across multiple systems. However, doing so would put plain text data
|
across multiple systems. However, doing so would put plain text data
|
||||||
into a Git repository, which often resides on a public system. yadm can
|
into a Git repository, which often resides on a public system. yadm can
|
||||||
make it easy to encrypt and decrypt a set of files so the encrypted
|
make it easy to encrypt and decrypt a set of files so the encrypted
|
||||||
version can be maintained in the Git repository. This feature will
|
version can be maintained in the Git repository. This feature will
|
||||||
only work if a supported tool is available. Both gpg(1) and openssl(1)
|
only work if a supported tool is available. Both gpg(1) and openssl(1)
|
||||||
are supported. gpg is used by default, but openssl can be configured
|
are supported. gpg is used by default, but openssl can be configured
|
||||||
with the yadm.cypher configuration.
|
with the yadm.cipher configuration.
|
||||||
|
|
||||||
To use this feature, a list of patterns must be created and saved as
|
To use this feature, a list of patterns must be created and saved as
|
||||||
$HOME/.config/yadm/encrypt. This list of patterns should be relative
|
$HOME/.config/yadm/encrypt. This list of patterns should be relative
|
||||||
to the configured work-tree (usually $HOME). For example:
|
to the configured work-tree (usually $HOME). For example:
|
||||||
|
|
||||||
.ssh/*.key
|
.ssh/*.key
|
||||||
.gnupg/*.gpg
|
.gnupg/*.gpg
|
||||||
|
|
||||||
Standard filename expansions (*, ?, [) are supported. If you have Bash
|
Standard filename expansions (*, ?, [) are supported. If you have Bash
|
||||||
version 4, you may use "**" to match all subdirectories. Other shell
|
version 4, you may use "**" to match all subdirectories. Other shell
|
||||||
expansions like brace and tilde are not supported. Spaces in paths are
|
expansions like brace and tilde are not supported. Spaces in paths are
|
||||||
supported, and should not be quoted. If a directory is specified, its
|
supported, and should not be quoted. If a directory is specified, its
|
||||||
contents will be included, but not recursively. Paths beginning with a
|
contents will be included, but not recursively. Paths beginning with a
|
||||||
"!" will be excluded.
|
"!" will be excluded.
|
||||||
|
|
||||||
The yadm encrypt command will find all files matching the patterns, and
|
The yadm encrypt command will find all files matching the patterns, and
|
||||||
prompt for a password. Once a password has confirmed, the matching
|
prompt for a password. Once a password has confirmed, the matching
|
||||||
files will be encrypted and saved as $HOME/.local/share/yadm/archive.
|
files will be encrypted and saved as $HOME/.local/share/yadm/archive.
|
||||||
The "encrypt" and "archive" files should be added to the yadm reposi-
|
The "encrypt" and "archive" files should be added to the yadm reposi‐
|
||||||
tory so they are available across multiple systems.
|
tory so they are available across multiple systems.
|
||||||
|
|
||||||
To decrypt these files later, or on another system run yadm decrypt and
|
To decrypt these files later, or on another system run yadm decrypt and
|
||||||
provide the correct password. After files are decrypted, permissions
|
provide the correct password. After files are decrypted, permissions
|
||||||
are automatically updated as described in the PERMISSIONS section.
|
are automatically updated as described in the PERMISSIONS section.
|
||||||
|
|
||||||
Symmetric encryption is used by default, but asymmetric encryption may
|
Symmetric encryption is used by default, but asymmetric encryption may
|
||||||
be enabled using the yadm.gpg-recipient configuration.
|
be enabled using the yadm.gpg-recipient configuration.
|
||||||
|
|
||||||
NOTE: It is recommended that you use a private repository when keeping
|
NOTE: It is recommended that you use a private repository when keeping
|
||||||
confidential files, even though they are encrypted.
|
confidential files, even though they are encrypted.
|
||||||
|
|
||||||
Patterns found in $HOME/.config/yadm/encrypt are automatically added to
|
Patterns found in $HOME/.config/yadm/encrypt are automatically added to
|
||||||
the repository's info/exclude file every time yadm encrypt is run.
|
the repository's info/exclude file every time yadm encrypt is run.
|
||||||
This is to prevent accidentally committing sensitive data to the repos-
|
This is to prevent accidentally committing sensitive data to the repos‐
|
||||||
itory. This can be disabled using the yadm.auto-exclude configuration.
|
itory. This can be disabled using the yadm.auto-exclude configuration.
|
||||||
|
|
||||||
Using transcrypt or git-crypt
|
Using transcrypt or git-crypt
|
||||||
|
|
||||||
A completely separate option for encrypting data is to install and use
|
A completely separate option for encrypting data is to install and use
|
||||||
transcrypt or git-crypt. Once installed, you can use these tools by
|
transcrypt or git-crypt. Once installed, you can use these tools by
|
||||||
running yadm transcrypt or yadm git-crypt. These tools enables trans-
|
running yadm transcrypt or yadm git-crypt. These tools enables trans‐
|
||||||
parent encryption and decryption of files in a git repository. See the
|
parent encryption and decryption of files in a git repository. See the
|
||||||
following web sites for more information:
|
following web sites for more information:
|
||||||
|
|
||||||
@ -646,10 +663,8 @@
|
|||||||
|
|
||||||
- https://github.com/AGWA/git-crypt
|
- https://github.com/AGWA/git-crypt
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## PERMISSIONS
|
## PERMISSIONS
|
||||||
When files are checked out of a Git repository, their initial permis-
|
When files are checked out of a Git repository, their initial permis‐
|
||||||
sions are dependent upon the user's umask. Because of this, yadm will
|
sions are dependent upon the user's umask. Because of this, yadm will
|
||||||
automatically update the permissions of some file paths. The "group"
|
automatically update the permissions of some file paths. The "group"
|
||||||
and "others" permissions will be removed from the following files:
|
and "others" permissions will be removed from the following files:
|
||||||
@ -662,11 +677,11 @@
|
|||||||
|
|
||||||
- The GPG directory and files, .gnupg/*
|
- The GPG directory and files, .gnupg/*
|
||||||
|
|
||||||
yadm will automatically update permissions by default. This can be dis-
|
yadm will automatically update permissions by default. This can be dis‐
|
||||||
abled using the yadm.auto-perms configuration. Even if disabled, per-
|
abled using the yadm.auto-perms configuration. Even if disabled, per‐
|
||||||
missions can be manually updated by running yadm perms. The .ssh
|
missions can be manually updated by running yadm perms. The .ssh di‐
|
||||||
directory processing can be disabled using the yadm.ssh-perms configu-
|
rectory processing can be disabled using the yadm.ssh-perms configura‐
|
||||||
ration. The .gnupg directory processing can be disabled using the
|
tion. The .gnupg directory processing can be disabled using the
|
||||||
yadm.gpg-perms configuration.
|
yadm.gpg-perms configuration.
|
||||||
|
|
||||||
When cloning a repo which includes data in a .ssh or .gnupg directory,
|
When cloning a repo which includes data in a .ssh or .gnupg directory,
|
||||||
@ -676,18 +691,18 @@
|
|||||||
|
|
||||||
When running a Git command and .ssh or .gnupg directories do not exist,
|
When running a Git command and .ssh or .gnupg directories do not exist,
|
||||||
yadm will create those directories with mask 0700 prior to running the
|
yadm will create those directories with mask 0700 prior to running the
|
||||||
Git command. This can be disabled using the yadm.auto-private-dirs con-
|
Git command. This can be disabled using the yadm.auto-private-dirs con‐
|
||||||
figuration.
|
figuration.
|
||||||
|
|
||||||
|
|
||||||
## HOOKS
|
## HOOKS
|
||||||
For every command yadm supports, a program can be provided to run
|
For every command yadm supports, a program can be provided to run be‐
|
||||||
before or after that command. These are referred to as "hooks". yadm
|
fore or after that command. These are referred to as "hooks". yadm
|
||||||
looks for hooks in the directory $HOME/.config/yadm/hooks. Each hook
|
looks for hooks in the directory $HOME/.config/yadm/hooks. Each hook
|
||||||
is named using a prefix of pre_ or post_, followed by the command which
|
is named using a prefix of pre_ or post_, followed by the command which
|
||||||
should trigger the hook. For example, to create a hook which is run
|
should trigger the hook. For example, to create a hook which is run af‐
|
||||||
after every yadm pull command, create a hook named post_pull. Hooks
|
ter every yadm pull command, create a hook named post_pull. Hooks must
|
||||||
must have the executable file permission set.
|
have the executable file permission set.
|
||||||
|
|
||||||
If a pre_ hook is defined, and the hook terminates with a non-zero exit
|
If a pre_ hook is defined, and the hook terminates with a non-zero exit
|
||||||
status, yadm will refuse to run the yadm command. For example, if a
|
status, yadm will refuse to run the yadm command. For example, if a
|
||||||
@ -718,15 +733,15 @@
|
|||||||
|
|
||||||
## FILES
|
## FILES
|
||||||
All of yadm's configurations are relative to the "yadm directory".
|
All of yadm's configurations are relative to the "yadm directory".
|
||||||
yadm uses the "XDG Base Directory Specification" to determine this
|
yadm uses the "XDG Base Directory Specification" to determine this di‐
|
||||||
directory. If the environment variable $XDG_CONFIG_HOME is defined as
|
rectory. If the environment variable $XDG_CONFIG_HOME is defined as a
|
||||||
a fully qualified path, this directory will be $XDG_CONFIG_HOME/yadm.
|
fully qualified path, this directory will be $XDG_CONFIG_HOME/yadm.
|
||||||
Otherwise it will be $HOME/.config/yadm.
|
Otherwise it will be $HOME/.config/yadm.
|
||||||
|
|
||||||
Similarly, yadm's data files are relative to the "yadm data directory".
|
Similarly, yadm's data files are relative to the "yadm data directory".
|
||||||
yadm uses the "XDG Base Directory Specification" to determine this
|
yadm uses the "XDG Base Directory Specification" to determine this di‐
|
||||||
directory. If the environment variable $XDG_DATA_HOME is defined as a
|
rectory. If the environment variable $XDG_DATA_HOME is defined as a
|
||||||
fully qualified path, this directory will be $XDG_DATA_HOME/yadm. Oth-
|
fully qualified path, this directory will be $XDG_DATA_HOME/yadm. Oth‐
|
||||||
erwise it will be $HOME/.local/share/yadm.
|
erwise it will be $HOME/.local/share/yadm.
|
||||||
|
|
||||||
The following are the default paths yadm uses for its own data. Most
|
The following are the default paths yadm uses for its own data. Most
|
||||||
@ -734,7 +749,7 @@
|
|||||||
section for details.
|
section for details.
|
||||||
|
|
||||||
$HOME/.config/yadm
|
$HOME/.config/yadm
|
||||||
The yadm directory. By default, all configs yadm stores is rela-
|
The yadm directory. By default, all configs yadm stores is rela‐
|
||||||
tive to this directory.
|
tive to this directory.
|
||||||
|
|
||||||
$HOME/.local/share/yadm
|
$HOME/.local/share/yadm
|
||||||
@ -746,7 +761,7 @@
|
|||||||
|
|
||||||
$YADM_DIR/alt
|
$YADM_DIR/alt
|
||||||
This is a directory to keep "alternate files" without having
|
This is a directory to keep "alternate files" without having
|
||||||
them side-by-side with the resulting symlink or processed tem-
|
them side-by-side with the resulting symlink or processed tem‐
|
||||||
plate. Alternate files placed in this directory will be created
|
plate. Alternate files placed in this directory will be created
|
||||||
relative to $HOME instead.
|
relative to $HOME instead.
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
%{!?_pkgdocdir: %global _pkgdocdir %{_docdir}/%{name}-%{version}}
|
%{!?_pkgdocdir: %global _pkgdocdir %{_docdir}/%{name}-%{version}}
|
||||||
Name: yadm
|
Name: yadm
|
||||||
Summary: Yet Another Dotfiles Manager
|
Summary: Yet Another Dotfiles Manager
|
||||||
Version: 3.1.0
|
Version: 3.2.2
|
||||||
Group: Development/Tools
|
Group: Development/Tools
|
||||||
Release: 1%{?dist}
|
Release: 1%{?dist}
|
||||||
URL: https://yadm.io
|
URL: https://yadm.io
|
||||||
|
Loading…
Reference in New Issue
Block a user