14 - Anatomy of a Small Linux-Adjacent Project¶
What this session is¶
About 45 minutes. Walk through the file structure of typical Linux-adjacent OSS projects - dotfiles repos, shell-script tools, infrastructure-as-code repos, doc projects.
These look different from programming-language projects. There's no pom.xml, no Cargo.toml, no package.json. Files are mostly configs and scripts.
Typical dotfiles repo¶
my-dotfiles/
├── README.md
├── LICENSE
├── install.sh
├── .bashrc
├── .vimrc
├── .gitconfig
├── .config/
│ ├── nvim/
│ │ └── init.vim
│ └── tmux/
│ └── tmux.conf
├── scripts/
│ ├── setup-mac.sh
│ ├── setup-linux.sh
│ └── helpers/
└── .gitignore
Roles:
- README.md - what this is, how to use it, what platforms it supports.
- install.sh - the entry point. Usually creates symlinks from ~/.bashrc etc. to the files in the repo.
- Top-level dotfiles (.bashrc, .vimrc) - the configs themselves.
- .config/ - for tools that follow XDG (Linux convention for per-user config under ~/.config/).
- scripts/ - helpers for setup / system administration.
How they're "installed":
When you edit ~/.bashrc, you're actually editing the file in the repo. Commit. Push. Sync to other machines by cloning + running install.sh.
Tools like stow automate the symlinking. Many dotfile repos use chezmoi or yadm for fancier sync.
Typical shell-script tool¶
For something like tj/git-extras:
git-extras/
├── README.md
├── LICENSE
├── CONTRIBUTING.md
├── Makefile (install / uninstall / lint)
├── bin/
│ ├── git-back
│ ├── git-changelog
│ ├── git-effort
│ └── ... (each a shell script)
├── etc/
│ └── git-extras-completion.zsh
├── man/ (man-page sources)
│ ├── git-back.1.ronn
│ └── ...
├── test/
│ └── tests.bats
└── .github/workflows/
Roles:
- bin/ - the actual scripts. Each is an executable file named git-<subcommand>. When installed (usually to /usr/local/bin/), git finds them and runs them as git back, git changelog, etc.
- man/ - man-page source (in markdown-like ronn format here; compiled to nroff for man to display).
- etc/ - extra files (shell completions, sample configs).
- test/tests.bats - bats is a bash testing framework. Yes, you can unit-test bash.
- Makefile - install/uninstall targets.
A first PR might be: fix a typo in bin/git-back, add a new option to git-changelog, improve the man page for one of them.
Typical Ansible role¶
ansible-role-nginx/
├── README.md
├── LICENSE
├── meta/
│ └── main.yml (role metadata, dependencies)
├── defaults/
│ └── main.yml (default variable values)
├── vars/
│ └── main.yml (role-internal variables)
├── tasks/
│ ├── main.yml (entry point - runs the tasks)
│ └── install.yml
├── handlers/
│ └── main.yml (notifications, e.g., "restart nginx")
├── templates/
│ ├── nginx.conf.j2 (Jinja2 templates)
│ └── site.conf.j2
├── files/
│ └── ... (static files)
├── molecule/ (testing infrastructure)
│ └── default/
│ └── molecule.yml
└── .github/workflows/
Ansible roles automate configuration of remote systems. Mostly YAML and templates; no compiled code. Very approachable for terminal-fluent beginners.
A first contribution: improve a default value, add a missing variable, fix a template that doesn't work on a specific OS, improve the README.
Typical docs project (e.g., kubernetes/website)¶
kubernetes-website/
├── README.md
├── LICENSE
├── content/ (the actual docs)
│ ├── en/
│ │ ├── docs/
│ │ │ ├── concepts/
│ │ │ ├── tasks/
│ │ │ └── tutorials/
│ │ └── ...
│ ├── de/ (German)
│ ├── es/ (Spanish)
│ └── ja/ (Japanese)
├── layouts/ (templates)
├── static/ (CSS, JS, images)
├── hugo.toml (Hugo static-site config)
└── .github/workflows/
Docs sites typically use a static-site generator (Hugo, MkDocs, Sphinx, Docusaurus). The content is Markdown; the generator turns it into HTML.
Contributing: edit a Markdown file under content/en/docs/.... PR. The CI builds the site to preview your changes.
Typical tldr-pages contribution¶
The tldr-pages repo is laid out as:
tldr/
├── README.md
├── CONTRIBUTING.md
├── pages/ (English)
│ ├── common/
│ │ ├── git.md
│ │ ├── ls.md
│ │ └── ...
│ ├── linux/
│ ├── osx/
│ └── windows/
├── pages.fr/ (French translations)
├── pages.es/ (Spanish)
├── pages.de/ (German)
└── ...
Each .md file is one command's tldr page, with example-driven entries. The format is strict but simple. Adding a missing command or example is a 5-minute PR.
CI: what your PR will be measured against¶
Open .github/workflows/. For these projects, CI typically runs:
- For dotfiles:
shellcheck(lints shell scripts). - For shell-script tools: shellcheck + bats tests.
- For Ansible:
ansible-lint+ molecule tests. - For docs: the static-site builder (Hugo / MkDocs) builds without errors; link checker.
Install shellcheck (sudo apt install shellcheck / brew install shellcheck) and use it locally:
Catches common bash bugs. Use before submitting.
Exercise¶
Pick your candidate project from page 13:
- Clone it locally.
- Walk the file structure. Map each file/folder to a category.
- Read
CONTRIBUTING.mdend to end. - Find the CI workflow YAML. Identify the commands it runs.
- Run those commands locally:
- For shell projects:
shellcheck path/to/scripts/*.sh. - For Ansible:
ansible-lint .. - For docs: read the build instructions; build locally with their tool.
- Look at the issue you tentatively picked. Identify which file(s) it touches.
You're ready for the actual contribution.
What you might wonder¶
"How do I know if a project is using Hugo, MkDocs, or something else?"
Look at the root. hugo.toml / config.toml = Hugo. mkdocs.yml = MkDocs. docusaurus.config.js = Docusaurus. conf.py in a docs/ dir = Sphinx.
"What's .bats? Is that really a thing?"
Yes. bats-core is a TAP-compliant testing framework for bash. Common in shell-tool projects (git-extras, bashly, etc.). Read a .bats file once; the format is intuitive.
"What if I want to contribute code, not docs/scripts?" Pick up a programming language. The "Go from scratch", "Python from scratch", "Java from scratch", "Rust from scratch" paths on this site are sized for that.
Done¶
- Recognize the layouts of dotfiles, shell-tool, Ansible, and docs projects.
- Find and read CI workflows.
- Run the same checks locally before pushing.
Next: Your first contribution →