update instructions
[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 or TAB or whatever, to a format understood by `webi`.
63
64 - Using Github releases? See `ripgrep/releases.js` (which uses `_common/github.js`)
65 - Have a special format? See `golang/releases.js` or `node/releases.js`.
66
67 It looks like this:
68
69 `releases.js`:
70
71 ```js
72 module.exports = function (request) {
73   return github(request, owner, repo).then(function (all) {
74     // if you need to do something special, you can do it here
75     // ...
76     return all;
77   });
78 };
79 ```
80
81 ### 2. Version Check (semi-optional)
82
83 If the thing is already installed, we don't need to download and install it again.
84
85 You create a version check that looks like this:
86
87 ```
88     # if the output is "foobar 1.3.4", we just need the "1.3.4"
89     cur_ver=$(foobar --version | cut -d ' ' -f 2)
90 ```
91
92 And then you wrap it in some **boilerplate** (copy/paste/replace) that looks like this:
93
94 ```
95 new_foobar="${HOME}/.local/bin/foobar"
96
97 # Test for existing version
98 set +e
99 current_foobar="$(command -v foobar)"
100 set -e
101 if [ -n "$current_foobar" ]; then
102   # if the output is "foobar 1.3.4", we just need the "1.3.4"
103   cur_ver=$(foobar --version | cut -d ' ' -f 2)
104   if [ "$cur_ver" == "$WEBI_VERSION" ]; then
105     echo "foobar v$WEBI_VERSION already installed at $current_foobar"
106     exit 0
107   elif [ "$current_foobar" != "$new_foobar" ]; then
108     echo "WARN: possible conflict with foobar v$WEBI_VERSION at $current_foobar"
109   fi
110 fi
111 ```
112
113 ### 3. Move files to $HOME/.local
114
115 The `webi_download` and `webi_extract` functions will handle download and unpacking.
116 All you have to do is move your files into the right place.
117
118 If you have a single binary that'll look like this:
119
120 ```
121     mv ./foobar-*/bin/foobar "$HOME/.local/bin/"
122 ```
123
124 If you have something with more parts it'll look like this:
125
126 ```
127     if [ -n "$(command -v rsync 2>/dev/null | grep rsync)" ]; then
128       rsync -Krl ./foobar*/ "$new_foobar_home/" 2>/dev/null
129     else
130       cp -Hr ./foobar*/* "$new_foobar_home/" 2>/dev/null
131       cp -Hr ./foobar*/.* "$new_foobar_home/" 2>/dev/null
132     fi
133 ```
134
135 ### 4. Update PATH
136
137 Typically speaking, `$HOME/.local/bin` will be added to the PATH for you.
138
139 However, you should call `webi_path_add` to add any special paths.
140
141 Again, just look at the examples.
142
143 ## Script API
144
145 See `webi/template.bash`
146
147 These variables will be set by the server:
148
149 ```
150 WEBI_PKG=example@v1
151 WEBI_NAME=example
152 WEBI_HOST=https://webinstall.dev
153 WEBI_RELEASES=https://webinstall.dev/api/releases/example@v1?os=macos&arch=amd64&pretty=true
154 WEBI_CSV=v1.0.2,
155 WEBI_VERSION=1.0.2
156 WEBI_MAJOR=1
157 WEBI_MINOR=0
158 WEBI_PATCH=2
159 WEBI_LTS=
160 WEBI_CHANNEL=stable
161 WEBI_EXT=tar
162 WEBI_PKG_URL=https://cdn.example.com/example-macos-amd64.tar.gz
163 WEBI_PKG_FILE=example-macos-amd64.tar.gz
164 ```
165
166 ```bash
167 WEBI_TMP=${WEBI_TMP:-"$(mktemp -d -t webinstall-foobar.XXXXXXXX)"}
168 ```
169
170 ```bash
171 webi_download           # Downloads the selected release to $HOME/Downloads/<package-name>.tar.gz
172 webi_extract            # Extracts the download to /tmp/<package-name>-<random>/
173 webi_path_add /new/path # Adds /new/path to PATH for bash, zsh, and fish
174 ```
175
176 # Roadmap
177
178 - Wrap release APIs to unify and expose
179   - [x] Golang <https://golang.org/dl/?mode=json>
180   - [x] Node <https://nodejs.org/dist/index.tab>
181   - [x] Flutter
182         <https://storage.googleapis.com/flutter_infra/releases/releases_linux.json> -
183         Started at
184         <https://github.com/webinstall/packages/blob/master/flutter/versions.js>
185   - [ ] git
186     - Note: do all platforms expose tar/zip releases with the same URLs?
187   - [ ] npm
188   - [x] github (see ripgrep)
189   - [x] gitea (see serviceman)
190 - [ ] Support git urls (i.e. `@github.com/node/node`)
191   - (maybe `ghi node/node` for github specifically)