Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 22 additions & 10 deletions .github/workflows/matrix_ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-20.04]
os: [ubuntu-24.04]
java-version: [11,15,20]
android-api: [31, 33]
fail-fast: false
Expand Down Expand Up @@ -55,7 +55,20 @@ jobs:
- name: Run vab --help
run: vab --help

- name: Run vab doctor
- name: Run 'vab doctor' before install
run: vab doctor

# It is a Sisyphus task to get all combinations of the pre-installed SDK / tools and Java working
# so we simply remove the system install and use our own minimal base-setup via 'vab install auto'...
- name: Setup predictable Android environment
run: |
sudo rm -fr /usr/local/lib/android # location of pre-installed SDK on Ubuntu
unset ANDROID_SDK_ROOT # These are set in the CI by default
unset ANDROID_HOME
unset ANDROID_NDK_ROOT
vab install auto

- name: Run 'vab doctor' after install
run: vab doctor

- name: Run tests
Expand All @@ -70,12 +83,11 @@ jobs:
- name: Run vab install build-tools
run: vab install "build-tools;29.0.0"

- name: Run vab doctor2
- name: Run 'vab doctor' after build-tools install
run: vab doctor

- name: Build examples as APK + AAB (Java ${{ matrix.java-version }}) ${{ matrix.android-api }}
run: |

declare -a v_examples=('flappylearning' '2048' 'fireworks' 'tetris' 'sokol/particles' 'sokol/drawing.v' 'sokol/freetype_raven.v' 'gg/polygons.v' 'gg/raven_text_rendering.v' 'gg/rectangles.v' 'gg/stars.v' 'gg/worker_thread.v')

for example in "${v_examples[@]}"; do
Expand All @@ -101,13 +113,13 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-20.04]
os: [ubuntu-24.04]
java-version: [11, 15, 20]
android-api: [31, 33]
fail-fast: false
timeout-minutes: 20
env:
VAB_FLAGS: -v 3 -gc none --build-tools 29.0.0
VAB_FLAGS: -v 3 -gc none
steps:
- uses: actions/setup-java@v4
with:
Expand Down Expand Up @@ -166,13 +178,13 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-20.04]
os: [ubuntu-24.04]
java-version: [8] # 9, 10 is in a bad state currently
android-api: [31, 33]
fail-fast: false
timeout-minutes: 20
env:
VAB_FLAGS: -v 3 --build-tools 29.0.0
VAB_FLAGS: -v 3
steps:
- uses: actions/setup-java@v4
with:
Expand Down Expand Up @@ -208,7 +220,7 @@ jobs:
run: |
sudo rm -fr /usr/local/lib/android

- name: Run 'vab doctor'
- name: Run 'vab doctor' before install
run: vab doctor

- name: Run 'vab install auto'
Expand All @@ -218,7 +230,7 @@ jobs:
unset ANDROID_NDK_ROOT
vab install auto

- name: Run vab doctor
- name: Run 'vab doctor' after install
run: vab doctor

- name: Run tests
Expand Down
63 changes: 54 additions & 9 deletions android/env/env.v
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ pub const accepted_components = ['auto', 'cmdline-tools', 'platform-tools', 'ndk
// build-tools - Version where apksigner is included from

@[deprecated: 'use get_default_components() instead']
@[deprecated_after: '2027-01-01']
pub const default_components = {
'cmdline-tools': {
'name': 'cmdline-tools'
Expand Down Expand Up @@ -154,6 +155,9 @@ pub fn (io &InstallOptions) verbose(verbosity_level int, msg string) {
}
}

// managable returns `true` if the host system's SDK can be managed by `vab`.
@[deprecated: 'use "is_manageable() or { false }" instead']
@[deprecated_after: '2027-07-20']
pub fn managable() bool {
sdk_is_writable := os.is_writable(sdk.root())
// sdkmanager checks
Expand Down Expand Up @@ -199,7 +203,55 @@ pub fn managable() bool {
return sdk_is_writable && has_sdkmanager && sdkmanger_works
}

// is_manageable returns `true` if the host system's SDK can be managed by `vab`, an error with
// details is returned otherwise.
pub fn is_manageable() !bool {
if !os.is_writable(sdk.root()) {
return error('No permission to write in Android SDK root. Please install manually or ensure write access to "${sdk.root()}".')
}

// sdkmanager checks
sdkm := sdkmanager()
if sdkm == '' {
return error('An executable `sdkmanager` seems to be missing.')
}
// We have detected `sdkmanager` - but does it work with the Java version? *sigh*
// Android development will let us find out I guess:
cmd := [
sdkm,
'--list',
]
mut cmd_res := util.run(cmd)
if cmd_res.exit_code > 0 {
// Failed let's try a workaround from stackoverflow:
// https://stackoverflow.com/a/51644855/1904615
if 'windows' == os.user_os() {
util.run([
'set JAVA_OPTS=-XX:+IgnoreUnrecognizedVMOptions --add-modules java.se.ee',
])
util.run([
'set JAVA_OPTS=-XX:+IgnoreUnrecognizedVMOptions --add-modules java.xml.bind',
])
} else {
util.run([
"export JAVA_OPTS='-XX:+IgnoreUnrecognizedVMOptions --add-modules java.se.ee'",
])
util.run([
"export JAVA_OPTS='-XX:+IgnoreUnrecognizedVMOptions --add-modules java.xml.bind'",
])
}
// Let try again
cmd_res = util.run(cmd)
if cmd_res.exit_code != 0 {
return error('The detected `sdkmanager` seems outdated or incompatible with the Java version used. Manual intervention is needed.\nPath: "${sdkmanager()}"\nVersion: ${sdkmanager_version()}\nOutput: ${cmd_res.output}')
}
// Give up trying to fix this horrible eco-system
}
return true
}

@[deprecated: 'use install_components instead']
@[deprecated_after: '2027-01-01']
pub fn install(components string, verbosity int) int {
mut iopts := []InstallOptions{}
mut ensure_sdk := true
Expand Down Expand Up @@ -500,16 +552,9 @@ pub fn install_components(arguments []string, verbosity int) ! {
fn install_opt(opt InstallOptions) !bool {
loose := opt.dep == .bundletool || opt.dep == .aapt2

if !loose && !managable() {
if !os.is_writable(sdk.root()) {
return error(@MOD + '.' + @FN + ' ' +
'No permission to write in Android SDK root. Please install manually or ensure write access to "${sdk.root()}".')
} else {
return error(@MOD + '.' + @FN + ' ' +
'The `sdkmanager` seems outdated or incompatible with the Java version used". Please fix your setup manually.\nPath: "${sdkmanager()}"\nVersion: ${sdkmanager_version()}')
}
if !loose {
is_manageable()!
}

// Accept all SDK licenses
$if windows {
os.mkdir_all(work_path) or {}
Expand Down
1 change: 1 addition & 0 deletions cli/cli.v
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ pub fn input_from_args(arguments []string) (string, []string) {
// args_to_options returns an `Option` merged from (CLI/Shell) `arguments` using `defaults` as
// values where no value can be obtained from `arguments`.
@[deprecated: 'use options_from_arguments and run_vab_sub_command instead']
@[deprecated_after: '2027-01-01']
pub fn args_to_options(arguments []string, defaults Options) !(Options, &flag.FlagParser) {
mut args := arguments.clone()

Expand Down
28 changes: 10 additions & 18 deletions cli/doctor.v
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,16 @@ import vab.android.env
// diagnosticing the work environment.
pub fn doctor(opt Options) {
sdkm := env.sdkmanager()
env_managable := env.managable()
env_managable := env.is_manageable() or {
util.vab_notice('${err.msg()}',
details: 'For `${exe_short_name}` to control it\'s own dependencies, please update `sdkmanager` found in:
"${sdkm}"
or use a Java version that is compatible with your `sdkmanager`.
You can set the `SDKMANAGER` env variable or try your luck with `${exe_short_name} install auto`.
See https://stackoverflow.com/a/61176718/1904615 for more help.\n'
)
false
}
env_vars := os.environ()

// Validate Android `sdkmanager` tool
Expand All @@ -31,23 +40,6 @@ pub fn doctor(opt Options) {
See https://stackoverflow.com/a/61176718/1904615 for more help.\n'
}
util.vab_notice('No "sdkmanager" could be detected.', details)
} else {
if !env_managable {
sdk_is_writable := os.is_writable(sdk.root())
if !sdk_is_writable {
util.vab_notice('The SDK at "${sdk.root()}" is not writable.',
details: "`${exe_short_name}` is not able to control the SDK and it's dependencies."
)
} else {
util.vab_notice('The detected `sdkmanager` seems outdated or incompatible with the Java version used.',
details: 'For `${exe_short_name}` to control it\'s own dependencies, please update `sdkmanager` found in:
"${sdkm}"
or use a Java version that is compatible with your `sdkmanager`.
You can set the `SDKMANAGER` env variable or try your luck with `${exe_short_name} install auto`.
See https://stackoverflow.com/a/61176718/1904615 for more help.\n'
)
}
}
}

avdmanager := env.avdmanager()
Expand Down
1 change: 1 addition & 0 deletions cli/options.v
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,7 @@ fn (mut o Options) merge_additional_args(default_additional_args []string) {
// extend_from_dot_vab will merge the `Options` with any content
// found in any `.vab` config files.
@[deprecated: 'use options_from_dot_vab instead']
@[deprecated_after: '2027-01-01']
pub fn (mut opt Options) extend_from_dot_vab() {
// Look up values in input .vab file next to input if no flags or defaults was set
dot_vab_file := dot_vab_path(opt.input)
Expand Down
4 changes: 2 additions & 2 deletions tests/at-runtime/emulator/emulator_test.vv
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const test_v_examples = [
'gg/worker_thread.v',
]

const env_is_managable = env.managable()
const env_is_manageable = env.is_manageable() or { false }

const is_ci = os.getenv('CI') != ''

Expand Down Expand Up @@ -77,7 +77,7 @@ fn ensure_env() {
os.unsetenv('ANDROID_SERIAL')

if !env.has_emulator() {
assert env_is_managable == true, 'These tests requires a *writable* SDK'
assert env_is_manageable == true, 'These tests requires a *writable* SDK'
eprintln('No emulator detected. Installing...')
install_emulator_res := run([vab_exe, 'install', 'emulator'])
if install_emulator_res.exit_code != 0 {
Expand Down
Loading