{"id":14069682,"url":"https://github.com/strapsh/strap","last_synced_at":"2025-07-30T06:32:18.994Z","repository":{"id":48634209,"uuid":"239002020","full_name":"strapsh/strap","owner":"strapsh","description":"Bootstrap a machine with one command!","archived":false,"fork":false,"pushed_at":"2024-01-29T02:02:20.000Z","size":278,"stargazers_count":13,"open_issues_count":4,"forks_count":9,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-08-13T07:16:04.645Z","etag":null,"topics":["ansible","ansible-playbook","ansible-role","bootstrap","convergence","linux","machine","macos"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/strapsh.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":"2020-02-07T18:58:58.000Z","updated_at":"2024-03-21T17:25:34.000Z","dependencies_parsed_at":"2024-01-29T03:16:51.589Z","dependency_job_id":"3c6f3831-ae8b-4178-892d-84b7c79ac368","html_url":"https://github.com/strapsh/strap","commit_stats":null,"previous_names":[],"tags_count":24,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/strapsh%2Fstrap","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/strapsh%2Fstrap/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/strapsh%2Fstrap/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/strapsh%2Fstrap/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/strapsh","download_url":"https://codeload.github.com/strapsh/strap/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":228102074,"owners_count":17869774,"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":["ansible","ansible-playbook","ansible-role","bootstrap","convergence","linux","machine","macos"],"created_at":"2024-08-13T07:07:08.376Z","updated_at":"2024-12-04T11:30:31.301Z","avatar_url":"https://github.com/strapsh.png","language":"Shell","funding_links":[],"categories":["Shell"],"sub_categories":[],"readme":"# Strap: Bootstrap Your Machine with One Command\n\n`strap` is a simple shell command designed to do one thing: \n\nStrap will take your machine from a starting state (for example, right after you buy it or receive it from your \nemployer) and install and configure everything you want on your machine in a *single command*, in *one shot*.  Run \n`strap` and you can rest assured that your machine will have your favorite command line tools, system defaults, gui \napplications, and development tools installed and ready to go.\n\nStrap was initially created to help newly-hired software engineers get up and running and\nproductive in *minutes* after they receive their machine instead of the hours or days it usually takes.  But Strap\nisn't limited to software engineering needs - anyone can use Strap to install what they want - graphics software, \noffice suites, web browsers, whatever.\n\n\u003c!-- \n\n## Watch It Run!\n\nHere's a little `strap run` recording to whet your appetite for the things Strap can do for you:\n\n[![asciicast](https://asciinema.org/a/188040.png)](https://asciinema.org/a/188040)\n\n--\u003e\n\n## Overview\n\nAt the highest level:\n\n**strap is a shell command that does the _bare minimum necessary_ to ensure \n[Ansible](https://docs.ansible.com/ansible/latest/index.html) is available and then immediately runs \nansible to setup (aka 'converge') the local machine**.\n\nIn this sense, we're not reinventing the wheel - there are plenty of machine convergence tools out there already, and\nit's best to just use one of them, like Ansible.\n\nThe only difference with strap is that strap covers the 'last mile' to obtain Ansible in a generic way that:\n\n1. Ensures anyone can run it without knowing what Ansible is\n1. Doesn't interfere with system or user-specific Ansible installations if there are any.\n1. Ensures that the fastest way to remove it is to just delete the `~/.strap` directory.\n\nAs soon as Ansible is available, strap immediately delegates to it, automatically running one or more Ansible \n[playbooks](https://docs.ansible.com/ansible/latest/user_guide/playbooks.html) or \n[roles](https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html) on the local machine.\n\nAnd we think that's pretty great - installing Ansible or Python is not always a trivial exercise, and we wanted to\nensure things 'just work', even if someone has never even heard of Python or Ansible.  It's so easy to use, anyone\ncan use it - from setting up a machine, or just installing things for a particular project, etc.\n\n## Installation\n\nTo install strap, run the following on the command line:\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/strapsh/strap/master/install | bash\nsource \"$HOME/.strap/releases/current/etc/straprc\"\n```\n\n## Usage\n\nStrap is a command line tool.  Assuming the strap installation's `bin` directory is in your `$PATH` as shown in the\ninstallation instructions above, you can just type `strap --help` and see what happens:\n\n```bash\nme@myhost:~$ strap --help\nstrap version 0.3.6\nusage: strap [options...] \u003ccommand\u003e [command_options...]\n \ncommands:\n   help        Display help for a command\n   run         Runs strap to ensure your machine is configured\n   version     Display the version of strap\n \nSee `strap help \u003ccommand\u003e' for information on a specific command.\nFor full documentation, see: https://github.com/strapsh/strap\n```\n\nThe `strap` command itself is quite simple - it basically loads some common environment settings and that's pretty \nmuch it. From there, it delegates most functionality to sub-commands, very similar to how the `git` command-line tool \nworks.\n\n## Strap Run\n\n`strap run` ensures ansible is available and then immediately runs ansible to converge the local machine to a desired state.\n\nThis means that, even though one or more people can use `run strap` without knowing anything\nabout ansible (a great benefit to teams), at least one person needs to know how\nto _write_ ansible \"packages\" that will be used during a strap run.  These \"packages\" in ansible's \nterminology are called _playbooks_ and _roles_.\n\nOnce a playbook or role is identified or available locally, strap makes running them that much easier.  You can run \nansible playbooks and roles based on the directory where strap is run or by explicitly referencing them by id.\n\n### Working Directory\n\nIf you just type `strap run` (without any arguments) in a working directory, and that directory has an ansible playbook \navailable via the relative path:\n\n```bash\n.strap/ansible/playbooks/default/main.yml\n```\n\nthen strap will run that playbook automatically.\n\nIt does the following steps in order:\n\n1.  If a `.strap/ansible/playbooks/default/meta/requirements.yml` file exists that lists the \n    [playbook's role dependencies](https://galaxy.ansible.com/docs/using/installing.html#installing-multiple-roles-from-a-file),\n    those requirements will be automatically downloaded first using the\n    [ansible-galaxy command](https://docs.ansible.com/ansible/latest/cli/ansible-galaxy.html).\n    \n    **Strap enhancement**: Strap has a really nice feature that enables [transitive role dependency downloads](https://github.com/lhazlewood/ansible-galaxy-install):  if\n    a dependency role is downloaded, and that role in turn has a `meta/requirements.yml` file, Strap will _automatically_\n    transitively download _those_ dependencies that don't yet exist.  It will continue to walk the dependency tree, \n    downloading dependencies as necessary until all dependencies are resolved.\n    \n    Core ansible does not provide transitive resolution, but Strap does.\n\n1. Strap will call the `ansible-playbook` command with the discovered playbook file targeting localhost/127.0.0.1.\n\n### Specific Roles or Playbooks\n\nIf the working directory does not have a `.strap/ansible/playbooks/default/main.yml` playbook file, then you must\nspecify one or more roles or playbooks using the `--playbook` or `--role` arguments, i.e.\n\n```bash\nstrap run [--playbook|--role] \u003cid\u003e\n```\n\nwhere `\u003cid\u003e` is an Ansible Galaxy identifier (i.e. `username.rolename`) or a GitHub url fragment that identifies the\nrole or playbook's git repository, (i.e. `username/repo`).\n\nFor example:\n\n```bash\nstrap run --role geerlinguy.java\n```\n\nor\n\n```bash\nstrap run --playbook example/foo\n```\n\n\n\u003c!-- \n\n## Strap Packages\n\nStrap is designed to have a lean core with most functionality coming from packages.  This section explains \nwhat packages are, how to use them, and how to write your own package(s) if you want to add or extend Strap \nfunctionality.\n\n### What Is A Strap Package?\n\nA Strap package is just a folder with bash scripts described by a `package.yml` file. \nThis means Strap can access functionality from anywhere it can access a folder.  And because git repositories are \nfolders, Strap can pull in functionality from anywhere it can access a git repository via a simple `git clone` command \nbased on the package's unique identifier.\n\n### Strap Package Identifier\n\nA Strap Package Identifier is a string that uniquely identifies a Strap package.\n\nThe package identifier string format MUST adhere to the following definition:\n\n    strap-package-id = group-id \":\" package-name [\":\" package-version]\n    \n    group-id = \"com.github.\" github-account-name\n    \nwhere\n * `github-account-name` equals a valid github username or organization name, for example `jsmith` or `strapsh`\n * `package-name` equals a git repository name within the specified github account, for example `cool-package`\n * `package-version`, if present, equals a git [refname](https://git-scm.com/docs/gitrevisions#gitrevisions-emltrefnamegtemegemmasterememheadsmasterememrefsheadsmasterem) that MUST be a tag, branch\n    or commit sha that can be provided as an argument to `git checkout`.\n    \nA package release SHOULD always have a `package-version` string that conforms to the semantic version name scheme \ndefined in the [Semantic Versioning 2.0.0 specification](https://semver.org/spec/v2.0.0.html).\n\nSome examples:\n\n * `com.github.acme:hello:0.2.1`\n * `com.github.strapsh:cool-package:1.0.3`\n\n\u003e NOTE: we realize it is a rather constrictive requirement to have all packages hosted on github and conform to the\n  specified location and naming scheme.  These restrictions will be relaxed when Strap's functionality\n  is enhanced to support arbitrary repository locations (e.g. bitbucket, gitlab, Artifactory, etc).\n\n#### Strap Package Resolution\n\nHow does Strap download a package based on the package identifier?\n\nConsider the following Strap Package Identifier example:\n\n    com.github.acme:hello:1.0.2\n    \nThis tells strap to download the package source code obtained by (effectively) running:\n\n```bash\ngit clone https://github.com/acme/hello\ncd hello\ngit checkout tags/1.0.2\n```\n\n#### Strap Package Resolution Without `:package-version`\n      \nIf there is not a `:package-version` suffix in a `strap-package-id`, a `:package-version` value of `:HEAD` will be \nassumed and the git repository's `origin/HEAD` will be used as the package source.\n\nFor example, consider the following Strap package id:\n\n    com.github.acme:hello\n    \nThis indicates the package source code will be obtained by (effectively) running:\n\n```bash\ngit clone https://github.com/acme/hello\n\n```\n \nand no specific branch will be checked out (implying the default branch will be used, which is `master` in most cases).\n\n\u003e **WARNING**:\n\u003e \n\u003e It is *strongly recommended to always specify a `:package-version` suffix* in every strap package idenfier to ensure\n\u003e deterministic (repeatable) behavior.  Omitting `:package-version` suffixes - and relying on the `:HEAD` default - \n\u003e can cause errors or problems during a `strap` run. Omission can be useful while developing a package, but it is \n\u003e recommended to provide a `:package-version` suffix at all other times.\n\n### Strap Packages Directory\n\nAny package referenced by you (or by other packages) that are not included in the Strap installation \nare automatically downloaded and stored in your `$HOME/.strap/packages` directory.\n\nThis directory is organized according to the following rules based on the Strap Package ID.  An example Strap\nPackage ID of `com.github.acme:hello:1.0.2` will be used for illustration purposes.\n\n* The strap package id's `group-id` component is parsed, and period characters ( `.` ) are replaced with \n  forward-slash characters ( `/` ).  For example, the `group-id` of `com.github.acme` becomes `com/github/acme`\n\n* The resulting string is appended with a forward-slash ( `/` ).  For example, `com/github/acme` becomes \n  `com/github/acme/`\n  \n* The resulting string is appended with the package id's `package-name` component.  For \n  example, `com/github/acme/` becomes `com/github/acme/hello`\n  \n* The resulting string is appended with a forward-slash ( `/` ).  For example, `com/github/acme/hello` becomes \n  `com/github/acme/hello/`\n\n* The resulting string is appended with the `strap-package-id`'s `package-version` component if one exists, or `HEAD`\n  if one doesn't exist.  For example:\n  \n  * A strap package id of `com.github.acme:hello:1.0.2` becomes `com/github/acme/hello/1.0.2` and\n  * A strap package id of `com.github.acme:hello` becomes `com/github/acme/hello/HEAD`\n  \n* The resulting string is appended to the string `$HOME/.strap/packages/`.  For example,\n  `com/github/acme/hello/1.0.2` becomes `$HOME/.strap/packages/com/github/acme/hello/1.0.2`\n\n* The resulting string is used as the argument to the `mkdir -p` command, which is used to create the directory where \n  that package's code will be downloaded, for example:\n  \n  `mkdir -p \"$HOME/.strap/packages/com/github/acme/hello/1.0.2\"`\n\n\n### Strap Package Structure\n\nA strap package is a folder containing:\n\n* A `META/package.yml` file\n* Any number of bash scripts\n\nAssuming `https://github.com/acme/hello` was a strap package repository, here is an example of what its directory \nstructure might look like:\n\n```\ncmd/\n    hello\nhooks/\n    run\nlib/\n    hello.sh\nMETA/\n    package.yml\n```\n\nThe above tree shows the following:\n\n* `META/package.yml` is a Strap package yaml file.  This file contains metadata about your package that Strap uses\n  to ensure your package can be referenced by other packages, as well as enable any Strap sub-commands your package\n  might provide, and more.\n\n* `cmd/hello` is an executable script that can be executed as a strap sub-command.  That is, a strap user could\n  type `strap hello` and strap would delegate execution to your `cmd/hello` script.  When committing this file to \n  source control, ensure that the file's executable flag is set, for example `chmod u+x cmd/hello`.\n\n* `hooks/run` is an executable script that will execute when `strap run` is called. For example, if a strap user types\n  `strap run` to kick off a run, strap will in turn invoke `hooks/run` as part of that execution phase.  Scripts in \n  the `hooks` directory must match exactly the name of the strap command being run.  Additionally, when committing \n  this file to source control, also ensure that the file's executable flag is set, for example `chmod u+x hooks/run`.\n\n* `lib/hello.sh` is a bash script that may export shell variables and functions that can be sourced (used) by other \n  packages\n  \n  For example, if `lib/hello.sh` had a function definition like this:\n  \n      com::github::acme::hello() { \n        echo \"hello\"\n      }\n      \n  other packages could *import* `hello.sh` and then they would be able to invoke `com::github::acme::hello` when they \n  wanted.\n  \n  We will cover how to import package library scripts soon.\n  \n --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstrapsh%2Fstrap","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstrapsh%2Fstrap","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstrapsh%2Fstrap/lists"}