update variables _new_ => _src_, _common_ => _dst_,
[webi-installers/.git] / README.md
1 # packages
2
3 Primary and community-submitted packages for
4 [webinstall.dev](https://webinstall.dev)
5
6 # Guidelines
7
8 - Should install to `./local/opt/<package>-<version>`
9 - Should not need `sudo` (except perhaps for a one-time `setcap`, etc)
10 - Follow the example of
11   <https://github.com/webinstall/packages/tree/master/ripgrep>,
12   <https://github.com/webinstall/packages/tree/master/node>, or
13   <https://github.com/webinstall/packages/tree/master/golang>
14
15 ## Creating an Installer
16
17 An install consists of 5 parts in two files:
18
19 ```
20 my-new-package/
21   - releases.js
22   - my-new-package.bash
23 ```
24
25 1. Create Description
26 2. Fetch Releases
27 3. Version Check (semi-optional)
28 4. Update PATH
29
30 See these **examples**:
31
32 - https://github.com/webinstall/packages/blob/master/rg/
33 - https://github.com/webinstall/packages/blob/master/golang/
34
35 The `webinstall.dev` server uses the list of releases returned by
36 `<your-package>/releases.js` to generate a bash script with most necessary
37 variables and functions pre-defined.
38
39 You just fill in the blanks.
40
41 ### 1. Create Description
42
43 Just copy the format from any of the existing packages. It's like this:
44
45 `my-new-package.bash`:
46
47 ````
48 # title: Node.js
49 # homepage: https://nodejs.org
50 # tagline: JavaScript V8 runtime
51 # description: |
52 #   Node.jsĀ® is a JavaScript runtime built on Chrome's V8 JavaScript engine
53 # examples: |
54 #   ```bash
55 #   node -e 'console.log("Hello, World!")'
56 #   > Hello, World!
57 #   ```
58 ````
59
60 ### 1. Fetch Releases
61
62 All you're doing in this step is just translating from one form of JSON or CSV
63 or TAB or whatever, to a format understood by `webi`.
64
65 - Using Github releases? See `ripgrep/releases.js` (which uses
66   `_common/github.js`)
67 - Have a special format? See `golang/releases.js` or `node/releases.js`.
68
69 It looks like this:
70
71 `releases.js`:
72
73 ```js
74 module.exports = function (request) {
75   return github(request, owner, repo).then(function (all) {
76     // if you need to do something special, you can do it here
77     // ...
78     return all;
79   });
80 };
81 ```
82
83 ### 2. Bash Installer
84
85 1. Variables _you_ can set
86 2. Functions _you_ must define
87 3. Convenience / Helper Functions
88
89 (optional, if needed) Bash variables that you _may_ define:
90
91 ```bash
92 # Define this if the package name is different from the command name (i.e. golang => go)
93 pkg_cmd_name="foobar"
94
95 # These are used for symlinks, PATH, and test commands
96 pkg_dst="$HOME/.local/opt/foobar"
97 pkg_dst_bin="$HOME/.local/opt/foobar/bin"
98 pkg_dst_cmd="$HOME/.local/opt/foobar/bin/foobar"
99
100 # These are the _real_ locations for the above
101 pkg_src="$HOME/.local/opt/foobar-v$WEBI_VERSION"
102 pkg_src_bin="$HOME/.local/opt/foobar-v$WEBI_VERSION/bin"
103 pkg_src_cmd="$HOME/.local/opt/foobar-v$WEBI_VERSION/bin/foobar"
104 ```
105
106 (required) A version check function that strips all non-version junk
107
108 ```bash
109 pkg_get_current_version() {
110     # foobar-v1.1.7 => 1.1.7
111     echo "$(foobar --version | head -n 1 | sed 's:foobar-v::')"
112 }
113 ```
114
115 For the rest of the functions you can like copy/paste from the examples:
116
117 ```bash
118 pkg_format_cmd_version() {}       # Optional, pretty prints version
119
120 pkg_link_src_dst() {}             # Required, may be empty for $HOME/.local/bin commands
121
122 pkg_pre_install() {               # Required, runs any webi_* commands
123     webi_check                        # for $HOME/.local/opt tools
124     webi_download                     # for things that have a releases.js
125     webi_extract                      # for .xz, .tar.*, and .zip files
126 }
127
128 pkg_install() {}                  # Required, usually just needs to rename extracted folder to
129                                   # "$HOME/.local/opt/$pkg_cmd_name-v$WEBI_VERSION"
130
131 pkg_post_install() {              # Required
132     pkg_link_src_dst                  # should probably call pkg_link_src_dst()
133     webi_path_add "$pkg_dst_bin"      # should probably update PATH
134 }
135
136 pkg_post_install_message() {}     # Optional, pretty print a success message
137 ```
138
139 ## Script API
140
141 See `webi/template.bash`
142
143 These variables will be set by the server:
144
145 ```
146 WEBI_PKG=example@v1
147 WEBI_NAME=example
148 WEBI_TAG=v1
149 WEBI_HOST=https://webinstall.dev
150 WEBI_RELEASES=https://webinstall.dev/api/releases/example@v1?os=macos&arch=amd64&pretty=true
151 WEBI_CSV=v1.0.2,
152 WEBI_VERSION=1.0.2
153 WEBI_MAJOR=1
154 WEBI_MINOR=0
155 WEBI_PATCH=2
156 WEBI_LTS=
157 WEBI_CHANNEL=stable
158 WEBI_EXT=tar
159 WEBI_PKG_URL=https://cdn.example.com/example-macos-amd64.tar.gz
160 WEBI_PKG_FILE=example-macos-amd64.tar.gz
161 ```
162
163 ```bash
164 WEBI_TMP=${WEBI_TMP:-"$(mktemp -d -t webinstall-foobar.XXXXXXXX)"}
165 ```
166
167 ```bash
168 webi_check              # Checks to see if the selected version is already installed (and re-links if so)
169 webi_download           # Downloads the selected release to $HOME/Downloads/<package-name>.tar.gz
170 webi_extract            # Extracts the download to /tmp/<package-name>-<random>/
171 webi_path_add /new/path # Adds /new/path to PATH for bash, zsh, and fish
172 ```
173
174 # Roadmap
175
176 - Wrap release APIs to unify and expose
177   - [x] Golang <https://golang.org/dl/?mode=json>
178   - [x] Node <https://nodejs.org/dist/index.tab>
179   - [x] Flutter
180         <https://storage.googleapis.com/flutter_infra/releases/releases_linux.json> -
181         Started at
182         <https://github.com/webinstall/packages/blob/master/flutter/versions.js>
183   - [ ] git
184     - Note: do all platforms expose tar/zip releases with the same URLs?
185   - [ ] npm
186   - [x] github (see ripgrep)
187   - [x] gitea (see serviceman)
188 - [ ] Support git urls (i.e. `@github.com/node/node`)
189   - (maybe `ghi node/node` for github specifically)