Compare commits
3
Commits
v1.0.0-beta.1
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c0e0d6269d | ||
|
|
4290892cb2 | ||
|
|
24098e8845 |
No files matched your search
@@ -1,66 +1,132 @@
|
||||
<div align="center">
|
||||
|
||||
<img src="fastlane/metadata/android/en-US/images/icon.png" width="112" alt="Clockula icon">
|
||||
|
||||
<h1>Clockula</h1>
|
||||
|
||||
<p><strong>A modern Material 3 Expressive clock app for Android.</strong><br>
|
||||
Alarms, timers, stopwatch and world clock. Open standards, no account required.</p>
|
||||
<p><strong>A Material 3 Expressive clock app for Android.</strong><br>
|
||||
Alarms, timers, stopwatch and world clock. No account and no network access.</p>
|
||||
|
||||
<p>
|
||||
<a href="https://codeberg.org/jlmakiola/clockula/actions"><img src="https://codeberg.org/jlmakiola/clockula/actions/workflows/ci.yaml/badge.svg?branch=main" alt="CI"></a>
|
||||
<img src="https://img.shields.io/badge/Android-10%2B-3DDC84?logo=android&logoColor=white" alt="Android 10+">
|
||||
<img src="https://img.shields.io/badge/Kotlin-Compose-7F52FF?logo=kotlin&logoColor=white" alt="Kotlin + Compose">
|
||||
<img src="https://img.shields.io/badge/Material%203-Expressive-4285F4" alt="Material 3 Expressive">
|
||||
<a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-green" alt="MIT License"></a>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<a href="https://apps.obtainium.imranr.dev/redirect?r=obtainium://add/https://codeberg.org/jlmakiola/clockula"><img src="https://github.com/ImranR98/Obtainium/blob/main/assets/graphics/badge_obtainium.png?raw=true" alt="Get it on Obtainium" height="56"></a>
|
||||
|
||||
<a href="https://ko-fi.com/jeanlucmakiola"><img src="https://storage.ko-fi.com/cdn/brandasset/v2/support_me_on_kofi_badge_beige.png" alt="Support me on Ko-fi" height="56"></a>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
Clockula is the clock sibling to [Calendula](https://codeberg.org/jlmakiola/calendula)
|
||||
(calendar) and [Agendula](https://codeberg.org/jlmakiola/agendula) (tasks). The
|
||||
name follows theirs: *clock*, given Calendula's `-ula` ending. A Calendula flower
|
||||
name follows theirs: *clock* with Calendula's `-ula` ending. A Calendula flower
|
||||
head is botanically a cluster of many small *florets*, so the three apps are
|
||||
florets of one bloom — and they share one, [floret-kit](https://codeberg.org/jlmakiola/floret-kit).
|
||||
florets of one bloom. They share one library,
|
||||
[floret-kit](https://codeberg.org/jlmakiola/floret-kit).
|
||||
|
||||
> 🚧 **Early development.** The spec is locked; the app is being built. See
|
||||
> [`docs/ROADMAP.md`](docs/ROADMAP.md) for where it actually is.
|
||||
1.0.0 is in its last betas before the stable release.
|
||||
|
||||
## The honest difference from its siblings
|
||||
## Features
|
||||
|
||||
Calendula is a pure front-end over Android's `CalendarContract`. Agendula speaks
|
||||
the dmfs `TaskContract`. Both put a good interface on a standard someone else
|
||||
already maintains.
|
||||
### Alarms
|
||||
|
||||
**There is no open provider behind a clock.** Alarms, timers and laps are
|
||||
Clockula's own data, so Clockula is the first app in the family to own its
|
||||
storage — by design, not as a fallback. What that commitment is replaced with is
|
||||
the first section of [`docs/PLAN.md`](docs/PLAN.md), and it comes down to three
|
||||
things:
|
||||
- Repeat schedules, snooze, your own ringtones and per-alarm settings
|
||||
- Scheduled as real alarm clocks: exempt from Doze, and shown on the lock
|
||||
screen and in the status bar
|
||||
- Re-resolved against your current time zone whenever it changes, so DST and
|
||||
travel don't shift them
|
||||
- A self-check screen that reads your device's actual settings. If one of them
|
||||
would stop an alarm ringing, Clockula names it and opens that settings page,
|
||||
instead of failing quietly at 7am.
|
||||
|
||||
- **Clockula speaks Android's standard alarm contract.** It implements
|
||||
`android.provider.AlarmClock` in full, so your assistant and your automation
|
||||
apps can set alarms and timers in it exactly as they would in any stock clock,
|
||||
and the system status bar and lock screen show its next alarm.
|
||||
- **World clocks are IANA time zones**, not a bespoke city list that goes stale.
|
||||
- **Your data exports** to a documented, versioned JSON file whenever you want
|
||||
it, because data you can't take with you isn't really yours.
|
||||
### Timers, stopwatch and world clock
|
||||
|
||||
## Alarms that actually ring
|
||||
- Several timers at once, controllable from the notification shade
|
||||
- A stopwatch with laps
|
||||
- World clocks from the IANA time-zone database built into Android, so the
|
||||
city list doesn't go stale
|
||||
- A running timer or stopwatch stays reachable from every tab
|
||||
|
||||
An alarm app is only worth having if you can trust it, so Clockula treats that as
|
||||
the feature rather than the plumbing. Alarms are scheduled as real alarm clocks —
|
||||
doze-exempt, visible to the system — and re-resolved against your current time
|
||||
zone whenever anything moves underneath them, so DST and travel don't silently
|
||||
shift them.
|
||||
### Widgets
|
||||
|
||||
When something on your device *would* stop an alarm ringing, Clockula tells you
|
||||
which setting it is and takes you there, instead of failing quietly at 7am.
|
||||
- Three home-screen widgets: next alarm, timer and clock
|
||||
- Each widget picks its own theme, or takes its colours from your wallpaper
|
||||
|
||||
## Documentation
|
||||
### Works with other apps
|
||||
|
||||
Start with [`docs/`](docs/): [`PLAN.md`](docs/PLAN.md) is the spec and the
|
||||
reasoning, [`ROADMAP.md`](docs/ROADMAP.md) is the status,
|
||||
[`ARCHITECTURE.md`](docs/ARCHITECTURE.md) is how the code is put together, and
|
||||
[`RELEASING.md`](docs/RELEASING.md) is the release runbook.
|
||||
- Clockula implements Android's standard `AlarmClock` intents in full. Your
|
||||
voice assistant and automation apps can set alarms and timers in it the same
|
||||
way they would in the stock clock.
|
||||
- Alarms, timers, world clocks and settings export to a JSON file whose format
|
||||
is documented in [`docs/BACKUP.md`](docs/BACKUP.md), and import back from it.
|
||||
|
||||
## Building
|
||||
### Design and privacy
|
||||
|
||||
- Material 3 Expressive throughout, with dynamic colour on Android 12+, light
|
||||
and dark themes, and expressive motion and shapes
|
||||
- A per-app language setting. Clockula ships in English for now;
|
||||
[help translate](#translations).
|
||||
- No telemetry, no analytics and no internet permission
|
||||
|
||||
## Where your data lives
|
||||
|
||||
Calendula works on top of Android's `CalendarContract`, and Agendula can work on
|
||||
top of the dmfs `TaskContract`. Both put an interface on a standard someone else
|
||||
maintains. Clocks have no such provider, so Clockula keeps alarms, timers and
|
||||
laps in its own database, the first app in the family to do so. The first
|
||||
section of [`docs/PLAN.md`](docs/PLAN.md) explains how it makes up for the
|
||||
missing standard: the `AlarmClock` intents, IANA time zones and the documented
|
||||
backup format listed above.
|
||||
|
||||
## Install
|
||||
|
||||
| Channel | Available | Notes |
|
||||
| --- | --- | --- |
|
||||
| [Codeberg release / Obtainium](#codeberg-release--obtainium) | Now, as betas | Plain APK download, or automatic with Obtainium |
|
||||
| [Self-hosted F-Droid repo](#self-hosted-f-droid-repo) | From 1.0.0 | Add the repo once |
|
||||
| [Build from source](#build-from-source) | Now | Full control |
|
||||
|
||||
### Codeberg release / Obtainium
|
||||
|
||||
Every release is on
|
||||
[Codeberg](https://codeberg.org/jlmakiola/clockula/releases) with the signed
|
||||
APK and a `.sha256` checksum. Betas are published as pre-releases. Download the
|
||||
APK and install it directly.
|
||||
|
||||
For automatic updates, use [Obtainium](https://github.com/ImranR98/Obtainium).
|
||||
On your phone,
|
||||
[add Clockula in one tap](https://apps.obtainium.imranr.dev/redirect?r=obtainium://add/https://codeberg.org/jlmakiola/clockula),
|
||||
or add it by hand: *Add App*, paste `https://codeberg.org/jlmakiola/clockula`,
|
||||
then *Add*. While Clockula is in beta, switch on *Include prereleases* for it,
|
||||
or Obtainium won't find anything. A beta updates in place to later betas and to
|
||||
the stable release.
|
||||
|
||||
### Self-hosted F-Droid repo
|
||||
|
||||
From the stable 1.0.0 on, every release is also published to the self-hosted
|
||||
F-Droid repository that serves Calendula and Agendula. If you already have it,
|
||||
Clockula will show up there. Otherwise add it once:
|
||||
|
||||
1. In your F-Droid client, open *Settings → Repositories → Add* (or open the
|
||||
link below on your phone):
|
||||
|
||||
```
|
||||
https://apps.dev.jeanlucmakiola.de/dev/fdroid/repo?fingerprint=C2C0640402BF458FC0ED957AF0B37AA4C14022E72F89CE90B5965B458CF73425
|
||||
```
|
||||
|
||||
<sub>Repo: `https://apps.dev.jeanlucmakiola.de/dev/fdroid/repo` ·
|
||||
fingerprint (SHA-256):
|
||||
`C2C0 6404 02BF 458F C0ED 957A F0B3 7AA4 C140 22E7 2F89 CE90 B596 5B45 8CF7 3425`</sub>
|
||||
|
||||
2. Refresh, search for Clockula and install it.
|
||||
|
||||
### Build from source
|
||||
|
||||
```sh
|
||||
git clone --recurse-submodules https://codeberg.org/jlmakiola/clockula.git
|
||||
@@ -69,10 +135,53 @@ cd clockula
|
||||
```
|
||||
|
||||
floret-kit is a submodule built from source as a Gradle composite build, so
|
||||
`--recurse-submodules` is not optional. The included build needs to find the
|
||||
Android SDK on its own: either export `ANDROID_HOME`, or drop a `sdk.dir=…` line
|
||||
in a (gitignored) `floret-kit/local.properties`.
|
||||
`--recurse-submodules` is required. The included build has to find the Android
|
||||
SDK on its own: either export `ANDROID_HOME`, or put a `sdk.dir=…` line in a
|
||||
(gitignored) `floret-kit/local.properties`. [CONTRIBUTING.md](CONTRIBUTING.md)
|
||||
covers tests and lint.
|
||||
|
||||
<sub>The F-Droid repo and the Codeberg releases share the same signing key, so
|
||||
you can switch between them without reinstalling.</sub>
|
||||
|
||||
## Documentation
|
||||
|
||||
- [Contributing](CONTRIBUTING.md): the workflow, the build and the
|
||||
architectural rule changes are reviewed against
|
||||
- [Plan](docs/PLAN.md): the spec and the reasoning behind it
|
||||
- [Roadmap](docs/ROADMAP.md): what has shipped and what's next
|
||||
- [Architecture](docs/ARCHITECTURE.md): how the code is put together
|
||||
- [Backup format](docs/BACKUP.md): the JSON export schema
|
||||
- [Releasing](docs/RELEASING.md): the release runbook
|
||||
- [Privacy policy](docs/PRIVACY.md): the source of the page at
|
||||
[jeanlucmakiola.de/clockula/privacy](https://jeanlucmakiola.de/clockula/privacy)
|
||||
|
||||
## Contributing
|
||||
|
||||
Bug reports, ideas and patches are welcome on
|
||||
[Codeberg](https://codeberg.org/jlmakiola/clockula/issues). Translations go
|
||||
through [Weblate](#translations), not pull requests. Read
|
||||
[CONTRIBUTING.md](CONTRIBUTING.md) before writing code.
|
||||
|
||||
## Translations
|
||||
|
||||
Clockula is written in English. Translations are managed on a self-hosted
|
||||
Weblate, and partial ones are fine: untranslated strings fall back to English.
|
||||
|
||||
[Help translate Clockula](https://weblate.dev.jeanlucmakiola.de/engage/clockula/)
|
||||
|
||||
You don't need to code. Register on the Weblate server, pick a language (or
|
||||
request one) and translate in your browser.
|
||||
|
||||
## Privacy
|
||||
|
||||
Clockula has no analytics, tracking, ads, crash-reporting SDK or third-party
|
||||
services. It doesn't have the internet permission, so it can't send anything
|
||||
anywhere. Your alarms, timers and world clocks stay in the app's private
|
||||
storage on your device.
|
||||
|
||||
[Privacy policy](https://jeanlucmakiola.de/clockula/privacy), written in
|
||||
[`docs/PRIVACY.md`](docs/PRIVACY.md), which is what that page renders.
|
||||
|
||||
## Licence
|
||||
|
||||
MIT — see [`LICENSE`](LICENSE).
|
||||
[MIT](LICENSE), Jean-Luc Makiola, 2026
|
||||
+1
-1
Submodule floret-kit updated: 6ef77bd5b2...8b33635a85.
@@ -1,8 +1,8 @@
|
||||
[versions]
|
||||
agp = "9.2.1"
|
||||
kotlin = "2.3.21"
|
||||
ksp = "2.3.9"
|
||||
hilt = "2.59.2"
|
||||
agp = "9.4.1"
|
||||
kotlin = "2.4.20"
|
||||
ksp = "2.3.11"
|
||||
hilt = "2.60.1"
|
||||
coreKtx = "1.19.0"
|
||||
appcompat = "1.7.1"
|
||||
lifecycleRuntime = "2.10.0"
|
||||
|
||||
Vendored
BIN
Binary file not shown.
+4
-2
@@ -1,8 +1,10 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.1-bin.zip
|
||||
distributionSha256Sum=bafc141b619ad6350fd975fc903156dd5c151998cc8b058e8c1044ab5f7b031f
|
||||
distributionSha256Sum=bafd5ce9cfaea0fbccfdc8439a1ac42fbd4cd9c89dc9a988228d8a2639a58e6c
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.8.0-bin.zip
|
||||
networkTimeout=10000
|
||||
retries=0
|
||||
retryBackOffMs=500
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
# Copyright © 2015 the original authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Gradle start up script for POSIX generated by Gradle.
|
||||
# gradlew start up script for POSIX generated by Gradle.
|
||||
#
|
||||
# Important for running:
|
||||
#
|
||||
@@ -29,7 +29,7 @@
|
||||
# bash, then to run this script, type that shell name before the whole
|
||||
# command line, like:
|
||||
#
|
||||
# ksh Gradle
|
||||
# ksh gradlew
|
||||
#
|
||||
# Busybox and similar reduced shells will NOT work, because this script
|
||||
# requires all of these POSIX shell features:
|
||||
@@ -57,7 +57,7 @@
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# https://github.com/gradle/gradle/blob/3d91ce3b8caaf77ad09f381f43615b715b53f72c/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
@@ -114,7 +114,6 @@ case "$( uname )" in #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
esac
|
||||
|
||||
CLASSPATH="\\\"\\\""
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
@@ -172,7 +171,6 @@ fi
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if "$cygwin" || "$msys" ; then
|
||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||
|
||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||
|
||||
@@ -212,7 +210,6 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
|
||||
"$@"
|
||||
|
||||
|
||||
Vendored
+52
-34
@@ -19,12 +19,39 @@
|
||||
@if "%DEBUG%"=="" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem gradlew startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
@rem Set local scope for the variables, and ensure extensions are enabled
|
||||
setlocal EnableExtensions
|
||||
|
||||
@rem Catch executions from older scripts and ensure they exit cleanly.
|
||||
@rem This can be removed once we can be reasonably confident that few people
|
||||
@rem will be migrating directly to this new wrapper.
|
||||
goto afterSafetyNet
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
goto exitWithErrorLevel
|
||||
:afterSafetyNet
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%"=="" set DIRNAME=.
|
||||
@@ -45,13 +72,14 @@ set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
1>&2 echo.
|
||||
1>&2 echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
1>&2 echo.
|
||||
1>&2 echo Please set the JAVA_HOME variable in your environment to match the
|
||||
1>&2 echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
"%COMSPEC%" /c exit 1
|
||||
goto exitWithErrorLevel
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
@@ -59,36 +87,26 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
1>&2 echo.
|
||||
1>&2 echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
1>&2 echo.
|
||||
1>&2 echo Please set the JAVA_HOME variable in your environment to match the
|
||||
1>&2 echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
"%COMSPEC%" /c exit 1
|
||||
goto exitWithErrorLevel
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
|
||||
@rem Execute gradlew
|
||||
@rem endlocal doesn't take effect until after the line is parsed and variables are expanded
|
||||
@rem which allows us to clear the local environment before executing the java command
|
||||
endlocal & "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* & call :exitWithErrorLevel & goto exitWithErrorLevel
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
set EXIT_CODE=%ERRORLEVEL%
|
||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||
exit /b %EXIT_CODE%
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
@rem This label must not be changed. We rely on old scripts being able to jump to this point.
|
||||
:exitWithErrorLevel
|
||||
@rem Use "%COMSPEC%" /c exit to allow operators to work properly in scripts
|
||||
"%COMSPEC%" /c exit %ERRORLEVEL%
|
||||
Reference in new issue
Block a user