punktf 0.1.0

A cross-platform multi-target dotfiles manager
Documentation
# PunktF - A cross-platform multi-target dotfiles manager

## DISCLAIMER

**CURRENTLY THIS CRATE ONLY PARSES COMMAND LINE ARGUMENTS, NOTHING MORE.**

This crate is sill under development and not all features are currently implemented.
Layouts and formats can and will change will in development.

## Yet another dotfile manager?!

Well yes, but hear me out. This project was driven by the personal need of having to manage several dotfiles for different machines/targets. You want the same experience everywhere: On your work Windows machine along with an Ubuntu WSL instance, your Debian server and your private Arch installation. This tool fixes that problem while beeing cross-platform and blazingly fast.

Features:
- [ ] Merge mutliple layers of dotfiles
- [ ] Create profiles for different targets
- [ ] Use instructions to compile your dotfiles/templates conditionally
- [ ] Use hadlebar-like instructions to insert variables and more
- [ ] Define pre- and post-hooks to customize the behaviour with custom commands
- [ ] Handles file permissions and line endings (CRLF vs LF)

## Commands

```shell
# deploy (dry-run)
punktf deploy windows --dry-run

# deploy (custom home folder)
punktf --home /home/demo deploy windows

# deploy (custom home folder)
PUNKTF_HOME=/home/demo punktf deploy windows
```

## PunktF Home

PunktF searches for the home path in the following order:

1) CLI argument given with `-h/--home`
2) Environment variable `PUNKTF_HOME`
3) Current working directory of the shell

```
+ profiles\
	+ windows.pfp
+ items\
	+ init.vim.win
```

## PFP Format (PunktF profile)

```json5
{
	// OPT: Either read from ENVIRONMENT (std::env::var) or from here
	"env": [
		{
			"key": "RUSTC_PATH",
			"value": "/usr/bin/rustc",
		}
		//, ...
	],

	// Target path of config dir; used when no specific deploy_location was given
	"target": "/home/demo/.config",

	// OPT: Hook which is executed once before the deployment.
	"pre_hook": "echo \"Foo\"",

	// OPT: Hook which is executed once after the deployment.
	"pre_hook": "echo \"Bar\"",

	// Items to be deployed
	"items": [
		{
			// Relative path in `items/`
			"path": "init.vim.win",

			// OPT: Alternative deploy target (PATH: used instead of `root` + `file`, ALIAS: `root` + (alias instead of `file`))
			"target": {
				"kind": "alias",
				"value": "init.vim",
			},

			// OPT: Custom env for the specific file (same as above)
			"env": [
				...
			],

			// OPT: Merge operation/kind (like: overwrite_all, ask, keep, overwrite_deployed)
			"merge": "overwrite",

			// OPT: Wether this file is a template or not (skips template actions (replace, ..) if not)
			"template": false,

			// OPT: Higher priority item is allowed to overwrite lower priority ones
			"priority": 2,
		}
		//, ...
	]
}
```

## Template Format

### Replacement

Prefix (can be combined: e.g. {{#$RUSTC_PATH}}):

- None: First profile.env then profile.file.env
- `$`: Only ENVIRONMENT
- `#`: Only env
- `&`: Only file.env

```python
rustc = {{RUSTC_PATH}}
```

### Conditionals (TODO: think about structure)

```python
{{@if {{OS}} == "windows"}}
	print("running on windows")
{{@else}}
	print("NOT running on windows")
{{@if}}
```

## Future

- File permissions/mode
- Content transformer: take file as input change it and return it (e.g. replace CRLF => LF)
- Remember last deployed files and only overwrite them if they are the same as they were
	- sqlite or json with previous deployments
- Generate profile from directory structure
- Have templates as base for others
- Save version of the profile for compatability checking