Skip to content

Commit 08562dc

Browse files
authored
all: support extra commands, vab <cmd> where <cmd> comes from vab install extra user/vab-<cmd> (vlang#319)
* vab: use notices for deploy hints * docs: add "Extending vab" section * tests: add `v check-md` to `vab test-all` * paths: add `data()` path based on `os.data_dir()` * vab: make suggestions if no input could be matched * doctor: show extra commands with source and hash
1 parent 5800886 commit 08562dc

File tree

18 files changed

+943
-81
lines changed

18 files changed

+943
-81
lines changed

.github/workflows/ci.yml

+59
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,65 @@ jobs:
183183
vab examples/sokol/particles -o apks/particles.apk
184184
[ -f apks/particles.apk ]
185185
186+
ubuntu-latest-extra-command:
187+
runs-on: ubuntu-latest
188+
timeout-minutes: 10
189+
env:
190+
VFLAGS: -d vab_allow_extra_commands
191+
VAB_FLAGS: -v 3
192+
steps:
193+
- name: Checkout V
194+
uses: actions/checkout@v4
195+
with:
196+
repository: vlang/v
197+
198+
- name: Build local v
199+
run: make -j4 && sudo ./v symlink
200+
201+
- name: Install dependencies
202+
run: |
203+
v retry -- sudo apt-get update
204+
v retry -- sudo apt-get install --quiet -y libsdl2-dev libsdl2-ttf-dev
205+
v retry -- sudo apt-get install --quiet -y libsdl2-mixer-dev libsdl2-image-dev
206+
207+
- name: Checkout SDL
208+
uses: actions/checkout@v4
209+
with:
210+
repository: vlang/sdl
211+
fetch-depth: 0
212+
path: sdl
213+
214+
- name: Simulate "v install sdl"
215+
run: mv sdl ~/.vmodules
216+
217+
- name: Setup vlang/sdl
218+
run: v ~/.vmodules/sdl/setup.vsh
219+
220+
- name: Checkout vab
221+
uses: actions/checkout@v4
222+
with:
223+
path: vab
224+
225+
- name: Install vab
226+
run: |
227+
mv vab ~/.vmodules
228+
v -g ~/.vmodules/vab
229+
sudo ln -s ~/.vmodules/vab/vab /usr/local/bin/vab
230+
231+
- name: Run 'vab --help'
232+
run: vab --help
233+
234+
- name: Install extra command
235+
run: |
236+
vab install extra larpon/vab-sdl
237+
238+
- name: Run vab doctor
239+
run: vab doctor
240+
241+
- name: Test extra command
242+
run: |
243+
vab sdl doctor
244+
186245
ubuntu-latest-vab-can-live-anywhere:
187246
runs-on: ubuntu-latest
188247
timeout-minutes: 10

.github/workflows/ci_emulator_run.yml

+4-1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ jobs:
5151
- name: Run vab --help
5252
run: vab --help
5353

54+
- name: Run vab doctor *before*
55+
run: vab doctor
56+
5457
- name: Install dependencies
5558
run: |
5659
v retry -- sudo apt update
@@ -66,7 +69,7 @@ jobs:
6669
vab install bundletool
6770
vab install aapt2
6871
69-
- name: Run vab doctor
72+
- name: Run vab doctor *after*
7073
run: vab doctor
7174

7275
- name: Cache emulator

README.md

+8
Original file line numberDiff line numberDiff line change
@@ -207,8 +207,16 @@ in the [FAQ](docs/FAQ.md).
207207
# Tests
208208

209209
`vab`, like many other V modules, can be tested with `v test .`.
210+
210211
Note that `vab` has *runtime* tests that requires all [runtime dependencies](#runtime-dependencies)
211212
to be installed in order for the tests to run correctly.
213+
Runtime tests can be run with `vab test-runtime` (also part of `vab test-all`).
214+
215+
# Extending `vab`
216+
217+
The `vab` command-line tool can be extended with custom user commands.
218+
See the "[Extending `vab`](docs/docs.md#extending-vab)" section
219+
in the [documentation](docs/docs.md).
212220

213221
# Notes
214222

android/emulator/emulator.v

+50-5
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,7 @@ pub fn (o &Options) validate() ! {
8181
if o.avd == '' {
8282
return error('${@MOD}.${@STRUCT}.${@FN}: No Android Virtual Device (avd) sat')
8383
}
84-
avdmanager := env.avdmanager()
85-
avdmanager_list_cmd := [avdmanager, 'list', 'avd', '-c']
86-
util.verbosity_print_cmd(avdmanager_list_cmd, o.verbosity)
87-
avdmanager_list := util.run_or_error(avdmanager_list_cmd)!
88-
avds := avdmanager_list.split('\n')
84+
avds := Emulator.list_avds()!
8985
if o.avd !in avds {
9086
return error('${@MOD}.${@STRUCT}.${@FN}: Android Virtual Device (avd) "${o.avd}" not found.')
9187
}
@@ -128,6 +124,55 @@ pub fn (mut e Emulator) start(options Options) ! {
128124
}
129125
}
130126

127+
// has_avd returns `true` if `avd_name` can be found. Use `list_avds` to see all locations of AVD's
128+
pub fn Emulator.has_avd(avd_name string) bool {
129+
avds := Emulator.list_avds() or { return false }
130+
return avd_name in avds.keys()
131+
}
132+
133+
// list_avds returns a list of devices detected by running `emulator -list-avds`
134+
// NOTE: for Google reasons, this list can be different from `avdmanager list avd -c`...
135+
pub fn Emulator.list_avds() !map[string]string {
136+
emulator_exe := env.emulator()
137+
list_cmd := [emulator_exe, '-list-avds']
138+
list_res := util.run_or_error(list_cmd)!
139+
list := list_res.split('\n').filter(it != '').filter(!it.contains(' '))
140+
mut m := map[string]string{}
141+
for entry in list {
142+
m[entry] = entry // TODO: should be a path to the AVD...
143+
}
144+
return m
145+
// TODO: find out how to fix this dumb mess for users
146+
// if vab_test_avd !in avds {
147+
// Locating a deterministic location of AVD's has, like so many other Android related things, become a mess.
148+
// (`avdmanager` can put them in places that the `emulator` does not pickup on the *same* host etc... Typical Google-mess)
149+
// ... even passing `--path` to `avdmanager` does not work.
150+
// Here we try a few places and set `ANDROID_AVD_HOME` to make runs a bit more predictable.
151+
// mut avd_home := os.join_path(os.home_dir(), '.android', 'avd')
152+
// eprintln('warning: "${vab_test_avd}" still not in list: ${avds}... trying new location "${avd_home}"')
153+
// os.setenv('ANDROID_AVD_HOME', avd_home, true)
154+
//
155+
// avds = emulator.Emulator.list_avds() or {
156+
// eprintln('${exe_name} error: ${err}')
157+
// exit(1)
158+
// }
159+
// if vab_test_avd !in avds {
160+
// config_dir := os.config_dir() or {
161+
// eprintln('${exe_name} error: ${err}')
162+
// exit(1)
163+
// }
164+
// avd_home = os.join_path(config_dir, '.android', 'avd')
165+
// eprintln('warning: "${vab_test_avd}" still not in list: ${avds}... trying new location "${avd_home}"')
166+
// os.setenv('ANDROID_AVD_HOME', avd_home, true)
167+
//
168+
// avds = emulator.Emulator.list_avds() or {
169+
// eprintln('${exe_name} error: ${err}')
170+
// exit(1)
171+
// }
172+
// }
173+
// }
174+
}
175+
131176
// wait_for_boot blocks execution and waits for the emulator to boot.
132177
// NOTE: this feature is unique to emulator devices.
133178
pub fn (mut e Emulator) wait_for_boot() ! {

0 commit comments

Comments
 (0)