{"id":23415987,"url":"https://github.com/aminehmida/medots","last_synced_at":"2025-04-12T08:53:13.408Z","repository":{"id":40279341,"uuid":"503880983","full_name":"aminehmida/medots","owner":"aminehmida","description":"Cross-platform dot config files manager using a yaml file.","archived":false,"fork":false,"pushed_at":"2023-05-23T18:04:29.000Z","size":43,"stargazers_count":55,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-12T08:53:08.019Z","etag":null,"topics":["cli","command-line","command-line-tool","config","cross-platform","dotfiles","manager"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aminehmida.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-06-15T18:32:12.000Z","updated_at":"2025-01-02T21:13:53.000Z","dependencies_parsed_at":"2024-06-19T06:14:14.153Z","dependency_job_id":null,"html_url":"https://github.com/aminehmida/medots","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aminehmida%2Fmedots","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aminehmida%2Fmedots/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aminehmida%2Fmedots/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aminehmida%2Fmedots/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aminehmida","download_url":"https://codeload.github.com/aminehmida/medots/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248543882,"owners_count":21121838,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","command-line","command-line-tool","config","cross-platform","dotfiles","manager"],"created_at":"2024-12-22T22:11:37.528Z","updated_at":"2025-04-12T08:53:13.383Z","avatar_url":"https://github.com/aminehmida.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# medots: Cross-platform config files manager\n[![Build](https://github.com/aminehmida/medots/actions/workflows/build.yaml/badge.svg)](https://github.com/aminehmida/medots/actions/workflows/build.yaml) [![Go Report Card](https://goreportcard.com/badge/github.com/aminehmida/medots)](https://goreportcard.com/report/github.com/aminehmida/medots)\n\n## Motivation\n\nI use Linux, MacOS and WSL and I switch between them often. I was looking for a tool that can deploy my dot files in different environments quickly and easily. Not only symlinking those configs, I wanted to symlink OS specific files automatically and run commands before and/or after symlinking those file. I couldn't find such tool, so I created *medots*.\n\n## How does it works\n\nmedots uses `dots.yaml` file saved in the same git repo as your dot files to understand how to \"deploy\" them correctly.\n\nYou will usually have to run `medots deploy` in the repo where the `dots.yaml` file is saved.\n\nThe best way to discover medots features is by building a real world `dots.yaml` config file.\n\nAfter installing the tool, check the [Features by example](#features-by-example) section to see how to use the `dots.yaml` file.\n\n## Install\n\n### Using Homebrew\n\n```shell\nbrew tap aminehmida/medots\nbrew install medots\n```\n\n### DEB package\n\nDownload the latest `.deb` file for your architecture from the [release page](https://github.com/aminehmida/medots/releases/latest)\n\n### RPM package\n\nDownload the latest `.rpm` file for your architecture from the [release page](https://github.com/aminehmida/medots/releases/latest)\n\n### From AUR for Arch Linux\n\n```shell\nyay -S medots\n```\n\n### APK package for Alpine Linux\n\nDownload the latest `.apk` file for your architecture from the [release page](https://github.com/aminehmida/medots/releases/latest).\nThe package is not signed. You can still verify the package by comparing its sha256 against values in `checksums_sha256.txt` file. After that you can use `--allow-insecure` flag:\n\n```shell\nsha256sum --check --ignore-missing checksums_sha256.txt\napk add --allow-insecure ./$apk_filename\n```\n\n### Binary archive\n\nDownload the latest `.tar.gz` file for your architecture from the [release page](https://github.com/aminehmida/medots/releases/latest) and extract it in your `$PATH`.\n\n### From source\n\nMake sure you have Go installed first.\n\n```shell\ngo install github.com/aminehmida/medots\n```\n\n## Features by example\n\n### Symlinking files\n\n```yaml\nnvim:\n  - source: ./nvim/init.vim\n    destination: ~/.config/nvim/\n```\n\nWe start by defining the name of the app that we want to manage its config files. This is can be used to target that specific app if you don't want to deploy all your configs.\n\nWe can now run `medots deploy` to deploy all apps or `medots deploy nvim` to target nvim only.\n\nThe following sequence of actions will happen:\n\n1. `~/.config/nvim/` directory will be recursively created if it doesn't exist\n2. `~/.config/nvim/init.vim` will be renamed to `~/.config/nvim/init.vim.bak` if it already exists\n3. `~/.config/nvim/init.vim` will be created as a symlink to `./nvim/init.vim`. The current directory dot `.` in the `source` and the tild `~` in the `destination` will be expanded when creating the symlink.\n\nYou can also set a different name for the destination file as bellow:\n\n```yaml\nnvim:\n  - source: ./nvim/main_config.vim\n    destination: ~/.config/nvim/init.vim\n```\n\nBecause of this behavior make sure to always add a trailing `/` when the destination is a folder.\n\nIt's also possible to symlink multiple files using a glob expression:\n\n```yaml\nnvim:\n  - source: ./nvim/*.vim\n    destination: ~/.config/nvim/\n```\n\nOr by adding multiple entries for your app:\n\n```yaml\nnvim:\n  - source: ./nvim/main_config.vim\n    destination: ~/.config/nvim/init.vim\n  - source: ./nvim/plugins.vim\n    destination: ~/.config/nvim/\n```\n\n### Targeting a specific OS\n\nYou can target a specific OS by adding `if_os`. The supported values are: `linux`, `darwin`, `windows`. Using medots in Windows is not tested. However, I have tested it in WSL. Feel free to report any issues related to Windows.\n\n```yaml\nnvim:\n  - source: ./nvim/init_darwin.vim\n    destination: ~/.config/nvim/\n    if_os: darwin\n  - source: ./nvim/init_linux.vim\n    destination: ~/.config/nvim/\n    if_os: linux\n```\n\n### Running a command\n\nSometimes, a command need to be executed before or after the config file is symlinked. This can be done using `run` or `run_interactive`. `run` will capture the stdout/stderr of the command and show them at the end. `run_interactive` is useful if user input is required. Those commands will be executed by order of appearance.\n\n```yaml\nnvim:\n  # Install vim-plug\n  - run: curl -fLo \"${XDG_DATA_HOME:-$HOME/.local/share}\"/nvim/site/autoload/plug.vim --create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim\n  # This will symlink the config files then install the plugins\n  - source: ./nvim/*\n    destination: ~/.config/nvim/\n    run_interactive: nvim +PlugInstall\n  # This command will be executed last\n  - run_interactive: nvim +UpdateRemotePlugins\n\n# You don't need to have a source and destination in your app block.\n# This allows running any arbitrary command:\npackages:\n  - run_interactive: yay -S neovim tmux wget curl ripgrep jq fzf bat exa fd git-delta github-cli sops age awscli kubectl asdf-vm python-poetry\n    if_os: linux\n  - run_interactive: brew install neovim tmux wget curl ripgrep jq fzf bat exa fd git-delta gh sops age awscli kubectl asdf poetry\n    if_os: darwin\n```\n\n### Full `dots.yaml` example\n\n```yaml\n# Install os specific packages\npackages:\n  - run_interactive: yay -S neovim tmux wget curl ripgrep jq fzf bat exa fd git-delta github-cli sops age awscli kubectl asdf-vm python-poetry\n    if_os: linux\n  - run_interactive: brew install neovim tmux wget curl ripgrep jq fzf bat exa fd git-delta gh sops age awscli kubectl asdf poetry\n    if_os: darwin\n\nnvim:\n  # Install vim-plug\n  - run: curl -fLo \"${XDG_DATA_HOME:-$HOME/.local/share}\"/nvim/site/autoload/plug.vim --create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim\n  # This will copy the config files then install the plugins\n  - source: ./nvim/*\n    destination: ~/.config/nvim/\n    run_interactive: nvim +PlugInstall\n  # This command will be executed last\n  - run_interactive: nvim +UpdateRemotePlugins\n\ntmux:\n  - source: tmux/.tmux.conf\n    destination: ~/.tmux.conf\n  - source: tmux/tmux.darwin.conf\n    destination: ~/.config/tmux/tmux.custom.conf\n    if_os: darwin\n  - source: tmux/tmux.linux.conf\n    destination: ~/.config/tmux.custom.conf\n    if_os: linux\n\nzsh:\n  # Install ohmyzsh\n  - run_interactive: 'sh -c \"$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)\"'\n    if_os: darwin\n  - run_nteractive: yay -S oh-my-zsh-git\n    if_os: linux\n  # Install zsh-histdb\n  - run: mkdir -p $HOME/.oh-my-zsh/custom/plugins/; git clone https://github.com/larkery/zsh-histdb $HOME/.oh-my-zsh/custom/plugins/zsh-histdb\n  - source: zsh/.zshrc\n    destination: ~/.zshrc\n  - source: zsh/*.zsh\n    destination: ~/.config/zsh/\n```\n\n## Contact, bugs and feature requests\n\nI am using `medots` for my personal needs and it's serving me very well. I published this project because I couldn't find any other cross-platform config manager. If you find the it useful, please give it a Star ⭐️ that will make me happy and motivated to work more on it 🤗 also feel free to share it with anyone who could find it useful 😉\n\nIf you find a bug or you have a feature request, please open a github issue.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faminehmida%2Fmedots","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faminehmida%2Fmedots","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faminehmida%2Fmedots/lists"}