Compare commits

...

14 Commits

Author SHA1 Message Date
adc32e25e1 更新编译工具版本 2026-03-15 16:41:14 +08:00
e2e94e938e 配置编译工具版本 2026-03-15 15:33:12 +08:00
a0c2d12eeb 更新应用密钥配置 2026-03-15 15:06:08 +08:00
11a5cc020e 保留应用签名与WinBoLL主机信息配置,更新编译配置文件 2026-03-15 15:01:42 +08:00
dependabot[bot]
2f40df91e5 Changed: Bump gradle/wrapper-validation-action from 2 to 3
Bumps [gradle/wrapper-validation-action](https://github.com/gradle/wrapper-validation-action) from 2 to 3.
- [Release notes](https://github.com/gradle/wrapper-validation-action/releases)
- [Commits](https://github.com/gradle/wrapper-validation-action/compare/v2...v3)

---
updated-dependencies:
- dependency-name: gradle/wrapper-validation-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-18 21:12:09 +05:00
agnostic-apollo
755b752a95 Reverted: Revert "ci: use termux/upload-release-actions to attach debug builds to new releases"
This reverts commit 2ac7fd1e56.

Do not use `upload-release-action` for uploading artifacts and generating checksum and instead keep using standard `sha256sum` and internal github tools. `upload-release-action` also generates checksum in the wrong format, check https://github.com/termux/termux-app/pull/3241#discussion_r1106019790.
2024-04-16 12:34:31 +05:00
agnostic-apollo
67f4891580 Fixed: Limit max combining characters in TerminalRow to 15 characters to prevent buffer overflows
The exception below causing app crash happens because of malicious input where combining characters keep getting added to same column of the row and this increases the size of `mSpaceUsed` and `mText`, eventually causing a buffer overflow of `mSpaceUsed`, which is limited to max `32767` value as per java `short` limit, but the limit itself isn't the issue, but an endless number of combining characters being added. Check `MAX_COMBINING_CHARACTERS_PER_COLUMN` field javadocs for why the limit `15` was chosen.

```
curl -o matroska.js https://kimapr.net/lappy/matroska.js
cat matroska.js
```

The `charCount` below refers to value of `Character.charCount(codePoint)`, like before `oldCharactersUsedForColumn` is appended to `newCharactersUsedForColumn`.

```
TerminalRow: codePoint=112, mColumns=98, mText=637, columnToSet=18, mSpaceUsed=590, javaCharDifference=0, oldStartOfColumnIndex=510, oldCharactersUsedForColumn=1, newCharactersUsedForColumn=1, oldNextColumnIndex=511, newNextColumnIndex=511, charCount=1, oldCodePointDisplayWidth=1, newCodePointDisplayWidth=1
TerminalRow: codePoint=40, mColumns=98, mText=637, columnToSet=19, mSpaceUsed=590, javaCharDifference=0, oldStartOfColumnIndex=511, oldCharactersUsedForColumn=1, newCharactersUsedForColumn=1, oldNextColumnIndex=512, newNextColumnIndex=512, charCount=1, oldCodePointDisplayWidth=1, newCodePointDisplayWidth=1
TerminalRow: codePoint=40, mColumns=98, mText=637, columnToSet=20, mSpaceUsed=590, javaCharDifference=0, oldStartOfColumnIndex=512, oldCharactersUsedForColumn=1, newCharactersUsedForColumn=1, oldNextColumnIndex=513, newNextColumnIndex=513, charCount=1, oldCodePointDisplayWidth=1, newCodePointDisplayWidth=1
TerminalRow: codePoint=101, mColumns=98, mText=637, columnToSet=21, mSpaceUsed=590, javaCharDifference=0, oldStartOfColumnIndex=513, oldCharactersUsedForColumn=1, newCharactersUsedForColumn=1, oldNextColumnIndex=514, newNextColumnIndex=514, charCount=1, oldCodePointDisplayWidth=1, newCodePointDisplayWidth=1
TerminalRow: codePoint=917772, mColumns=98, mText=147, columnToSet=18, mSpaceUsed=98, javaCharDifference=2, oldStartOfColumnIndex=18, oldCharactersUsedForColumn=1, newCharactersUsedForColumn=3, oldNextColumnIndex=19, newNextColumnIndex=21, charCount=2, oldCodePointDisplayWidth=1, newCodePointDisplayWidth=0
I TerminalRow: codePoint=65024, mColumns=98, mText=147, columnToSet=18, mSpaceUsed=100, javaCharDifference=1, oldStartOfColumnIndex=18, oldCharactersUsedForColumn=3, newCharactersUsedForColumn=4, oldNextColumnIndex=21, newNextColumnIndex=22, charCount=1, oldCodePointDisplayWidth=1, newCodePointDisplayWidth=0
TerminalRow: codePoint=917772, mColumns=98, mText=147, columnToSet=18, mSpaceUsed=101, javaCharDifference=2, oldStartOfColumnIndex=18, oldCharactersUsedForColumn=4, newCharactersUsedForColumn=6, oldNextColumnIndex=22, newNextColumnIndex=24, charCount=2, oldCodePointDisplayWidth=1, newCodePointDisplayWidth=0
...
TerminalRow: codePoint=917959, mColumns=98, mText=32781, columnToSet=18, mSpaceUsed=32763, javaCharDifference=2, oldStartOfColumnIndex=18, oldCharactersUsedForColumn=32666, newCharactersUsedForColumn=32668, oldNextColumnIndex=32684, newNextColumnIndex=32686, charCount=2, oldCodePointDisplayWidth=1, newCodePointDisplayWidth=0
TerminalRow: codePoint=917939, mColumns=98, mText=32781, columnToSet=18, mSpaceUsed=32765, javaCharDifference=2, oldStartOfColumnIndex=18, oldCharactersUsedForColumn=32668, newCharactersUsedForColumn=32670, oldNextColumnIndex=32686, newNextColumnIndex=32688, charCount=2, oldCodePointDisplayWidth=1, newCodePointDisplayWidth=0
TerminalRow: codePoint=917961, mColumns=98, mText=32781, columnToSet=18, mSpaceUsed=32767, javaCharDifference=2, oldStartOfColumnIndex=18, oldCharactersUsedForColumn=32670, newCharactersUsedForColumn=32672, oldNextColumnIndex=32688, newNextColumnIndex=32690, charCount=2, oldCodePointDisplayWidth=1, newCodePointDisplayWidth=0
TerminalRow: codePoint=917804, mColumns=98, mText=32781, columnToSet=18, mSpaceUsed=-32767, javaCharDifference=2, oldStartOfColumnIndex=18, oldCharactersUsedForColumn=1, newCharactersUsedForColumn=3, oldNextColumnIndex=19, newNextColumnIndex=21, charCount=2, oldCodePointDisplayWidth=1, newCodePointDisplayWidth=0
```

```
java.lang.ArrayIndexOutOfBoundsException: src.length=32781 srcPos=19 dst.length=32781 dstPos=21 length=-32786
	at java.lang.System.arraycopy(System.java:469)
	at com.termux.terminal.TerminalRow.setChar(TerminalRow.java:196)
	at com.termux.terminal.TerminalBuffer.setChar(TerminalBuffer.java:455)
	at com.termux.terminal.TerminalEmulator.emitCodePoint(TerminalEmulator.java:2380)
	at com.termux.terminal.TerminalEmulator.processCodePoint(TerminalEmulator.java:624)
	at com.termux.terminal.TerminalEmulator.processByte(TerminalEmulator.java:520)
	at com.termux.terminal.TerminalEmulator.append(TerminalEmulator.java:487)
	at com.termux.terminal.TerminalSession$MainThreadHandler.handleMessage(TerminalSession.java:358)
	at android.os.Handler.dispatchMessage(Handler.java:106)
	at android.os.Looper.loop(Looper.java:223)
	at android.app.ActivityThread.main(ActivityThread.java:7664)
	at java.lang.reflect.Method.invoke(Native Method)
	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
```

See also following links for history of related changes to `TerminalRow` for combining characters. Note that jackpal terminal does not crash for above, which termux-app is based on, but changes were done by fornwall in initial commit of termux-app to change the behaviour, hence the crash, but he added the `FIXME: Put a limit of combining characters` comment as a note to solve the current issue in future, which is now.

- 9a47042620
- https://github.com/jackpal/Android-Terminal-Emulator/pull/338
- a18ee58f7a (diff-f84d215b18106c037e01986a3968fa54b74691174a78fcc99493f745d3805be5)

Closes #3839
2024-04-07 15:52:48 +05:00
dependabot[bot]
7b19cd2f5a Changed: Bump termux/upload-release-action from 4.1.0 to 4.2.0
Bumps [termux/upload-release-action](https://github.com/termux/upload-release-action) from 4.1.0 to 4.2.0.
- [Release notes](https://github.com/termux/upload-release-action/releases)
- [Changelog](https://github.com/termux/upload-release-action/blob/master/CHANGELOG.md)
- [Commits](https://github.com/termux/upload-release-action/compare/v4.1.0...v4.2.0)

---
updated-dependencies:
- dependency-name: termux/upload-release-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-02 01:05:37 +05:00
dependabot[bot]
882da34fcd Changed: Bump gradle/wrapper-validation-action from 1 to 2
Bumps [gradle/wrapper-validation-action](https://github.com/gradle/wrapper-validation-action) from 1 to 2.
- [Release notes](https://github.com/gradle/wrapper-validation-action/releases)
- [Commits](https://github.com/gradle/wrapper-validation-action/compare/v1...v2)

---
updated-dependencies:
- dependency-name: gradle/wrapper-validation-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-02 00:34:43 +05:00
dependabot[bot]
8e3a8980a8 Changed: Bump actions/upload-artifact from 3 to 4 (#3735) 2024-01-01 15:19:33 +00:00
dependabot[bot]
e4385832b7 Changed: Bump actions/download-artifact from 3 to 4 (#3736)
l
2024-01-01 15:19:09 +00:00
agnostic-apollo
3b5018b4c7 Changed: Update Twitter to X (Twitter) in README
Co-authored-by: @BandhiyaHardik <bandhiya.hardik1905@gmail.com>
Co-authored-by: @agnostic-apollo  <agnosticapollo@gmail.com>

Related pull #3681
2023-11-02 09:20:21 +05:00
agnostic-apollo
c84d4804c8 Changed!: Update commit messages guidelines in README to be more clear and remove Docs as a valid type
The `Docs` refer to "something" that is changed, and not the type of change being made. If docs are to be changed in future, it should be added as a scope instead, like `Added(docs): Add some docs` or `Fixed(docs): Fix some docs`.
2023-11-01 17:30:43 +05:00
agnostic-apollo
6727bbecc4 Changed: Put GitHub debug keystore information in README in dropdown 2023-10-19 08:04:45 +05:00
17 changed files with 834 additions and 96 deletions

View File

@@ -6,7 +6,7 @@ on:
- published
jobs:
build:
attach-apks:
runs-on: ubuntu-latest
strategy:
fail-fast: false
@@ -21,15 +21,23 @@ jobs:
with:
ref: ${{ env.GITHUB_REF }}
- name: Build
- name: Build and attach APKs to release
shell: bash {0}
env:
PACKAGE_VARIANT: ${{ matrix.package_variant }}
run: |
exit_on_error() {
echo "$1"
echo "Deleting '$RELEASE_VERSION_NAME' release and '$GITHUB_REF' tag"
hub release delete "$RELEASE_VERSION_NAME"
git push --delete origin "$GITHUB_REF"
exit 1
}
echo "Setting vars"
RELEASE_VERSION_NAME="${GITHUB_REF/refs\/tags\//}"
if ! printf "%s" "${RELEASE_VERSION_NAME/v/}" | grep -qP '^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$'; then
echo "The versionName '${RELEASE_VERSION_NAME/v/}' is not a valid version as per semantic version '2.0.0' spec in the format 'major.minor.patch(-prerelease)(+buildmetadata)'. https://semver.org/spec/v2.0.0.html."
exit 1
exit_on_error "The versionName '${RELEASE_VERSION_NAME/v/}' is not a valid version as per semantic version '2.0.0' spec in the format 'major.minor.patch(-prerelease)(+buildmetadata)'. https://semver.org/spec/v2.0.0.html."
fi
APK_DIR_PATH="./app/build/outputs/apk/debug"
@@ -39,35 +47,38 @@ jobs:
echo "Building APKs for 'APK_VERSION_TAG' release"
export TERMUX_APK_VERSION_TAG="$APK_VERSION_TAG" # Used by app/build.gradle
export TERMUX_PACKAGE_VARIANT="${{ env.PACKAGE_VARIANT }}" # Used by app/build.gradle
./gradlew assembleDebug
if ! ./gradlew assembleDebug; then
exit_on_error "Build failed for '$APK_VERSION_TAG' release."
fi
echo "Validating APKs"
for abi in universal arm64-v8a armeabi-v7a x86_64 x86; do
if ! test -f "$APK_DIR_PATH/${APK_BASENAME_PREFIX}_$abi.apk"; then
files_found="$(ls "$APK_DIR_PATH")"
echo "Failed to find built APK at '$APK_DIR_PATH/${APK_BASENAME_PREFIX}_$abi.apk'. Files found: "$'\n'"$files_found"
exit 1
exit_on_error "Failed to find built APK at '$APK_DIR_PATH/${APK_BASENAME_PREFIX}_$abi.apk'. Files found: "$'\n'"$files_found"
fi
done
- name: Upload APKs to GitHub artifact
uses: actions/upload-artifact@v3
with:
name: ${{ matrix.package_variant }}
path: ./app/build/outputs/apk/debug/*.apk
upload:
runs-on: ubuntu-latest
needs: build
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- name: Download artifact
uses: actions/download-artifact@v3
- name: Upload APKs to release
uses: termux/upload-release-action@v4.1.0
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: "**/*.apk"
file_glob: true
release_name:
tag: ${{ github.event.release.tag_name }}
checksums: sha256,sha512,md5
echo "Generating sha25sums file"
if ! (cd "$APK_DIR_PATH"; sha256sum \
"${APK_BASENAME_PREFIX}_universal.apk" \
"${APK_BASENAME_PREFIX}_arm64-v8a.apk" \
"${APK_BASENAME_PREFIX}_armeabi-v7a.apk" \
"${APK_BASENAME_PREFIX}_x86_64.apk" \
"${APK_BASENAME_PREFIX}_x86.apk" \
> "${APK_BASENAME_PREFIX}_sha256sums"); then
exit_on_error "Generate sha25sums failed for '$APK_VERSION_TAG' release."
fi
echo "Attaching APKs to github release"
if ! hub release edit \
-m "" \
-a "$APK_DIR_PATH/${APK_BASENAME_PREFIX}_universal.apk" \
-a "$APK_DIR_PATH/${APK_BASENAME_PREFIX}_arm64-v8a.apk" \
-a "$APK_DIR_PATH/${APK_BASENAME_PREFIX}_armeabi-v7a.apk" \
-a "$APK_DIR_PATH/${APK_BASENAME_PREFIX}_x86_64.apk" \
-a "$APK_DIR_PATH/${APK_BASENAME_PREFIX}_x86.apk" \
-a "$APK_DIR_PATH/${APK_BASENAME_PREFIX}_sha256sums" \
"$RELEASE_VERSION_NAME"; then
exit_on_error "Attach APKs to release failed for '$APK_VERSION_TAG' release."
fi

View File

@@ -78,7 +78,7 @@ jobs:
fi
- name: Attach universal APK file
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: ${{ env.APK_BASENAME_PREFIX }}_universal
path: |
@@ -86,7 +86,7 @@ jobs:
${{ env.APK_DIR_PATH }}/output-metadata.json
- name: Attach arm64-v8a APK file
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: ${{ env.APK_BASENAME_PREFIX }}_arm64-v8a
path: |
@@ -94,7 +94,7 @@ jobs:
${{ env.APK_DIR_PATH }}/output-metadata.json
- name: Attach armeabi-v7a APK file
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: ${{ env.APK_BASENAME_PREFIX }}_armeabi-v7a
path: |
@@ -102,7 +102,7 @@ jobs:
${{ env.APK_DIR_PATH }}/output-metadata.json
- name: Attach x86_64 APK file
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: ${{ env.APK_BASENAME_PREFIX }}_x86_64
path: |
@@ -110,7 +110,7 @@ jobs:
${{ env.APK_DIR_PATH }}/output-metadata.json
- name: Attach x86 APK file
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: ${{ env.APK_BASENAME_PREFIX }}_x86
path: |
@@ -118,7 +118,7 @@ jobs:
${{ env.APK_DIR_PATH }}/output-metadata.json
- name: Attach sha256sums file
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: ${{ env.APK_BASENAME_PREFIX }}_sha256sums
path: |

View File

@@ -16,4 +16,4 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: gradle/wrapper-validation-action@v1
- uses: gradle/wrapper-validation-action@v3

6
.gitignore vendored
View File

@@ -37,3 +37,9 @@ local.properties
.swp
ehthumbs.db
Thumbs.db
## WinBoLL Studio Configs
winboll.properties
appkey.jks
appkey.keystore

View File

@@ -91,7 +91,8 @@ Both universal and architecture specific APKs are released. The APK and bootstra
The [test key](https://github.com/termux/termux-app/blob/master/app/testkey_untrusted.jks) shall not be used to impersonate @termux and can't be used for this anyway. This key is not trusted by us and it is quite easy to detect its use in user generated content.
Keystore information:
<details>
<summary>Keystore information</summary>
```
Alias name: alias
@@ -111,6 +112,8 @@ Subject Public Key Algorithm: 2048-bit RSA key
Version: 3
```
</details>
### Google Play Store **(Deprecated)**
**Termux and its plugins are no longer updated on [Google Play Store](https://play.google.com/store/apps/details?id=com.termux) due to [android 10 issues](https://github.com/termux/termux-packages/wiki/Termux-and-Android-10) and have been deprecated.** The last version released for Android `>= 7` was `v0.101`. **It is highly recommended to not install Termux apps from Play Store any more.**
@@ -174,7 +177,7 @@ The main ones are the following.
- [Termux Reddit community](https://reddit.com/r/termux)
- [Termux User Matrix Channel](https://matrix.to/#/#termux_termux:gitter.im) ([Gitter](https://gitter.im/termux/termux))
- [Termux Dev Matrix Channel](https://matrix.to/#/#termux_dev:gitter.im) ([Gitter](https://gitter.im/termux/dev))
- [Termux Twitter](https://twitter.com/termuxdevs)
- [Termux X (Twitter)](https://twitter.com/termuxdevs)
- [Termux Support Email](mailto:support@termux.dev)
### Wikis
@@ -261,7 +264,21 @@ The main Termux constants are defined by [`TermuxConstants`](https://github.com/
Check [Termux Libraries](https://github.com/termux/termux-app/wiki/Termux-Libraries) for how to import termux libraries in plugin apps and [Forking and Local Development](https://github.com/termux/termux-app/wiki/Termux-Libraries#forking-and-local-development) for how to update termux libraries for plugins.
Commit messages **must** use [Conventional Commits](https://www.conventionalcommits.org) specs so that chagelogs can automatically be generated by the [`create-conventional-changelog`](https://github.com/termux/create-conventional-changelog) script, check its repo for further details on the spec. Use the following `types` as `Added: Add foo`, `Added|Fixed: Add foo and fix bar`, `Changed!: Change baz as a breaking change`, etc. You can optionally add a scope as well, like `Fixed(terminal): Some bug`. The space after `:` is necessary.
The `versionName` in `build.gradle` files of Termux and its plugin apps must follow the [semantic version `2.0.0` spec](https://semver.org/spec/v2.0.0.html) in the format `major.minor.patch(-prerelease)(+buildmetadata)`. When bumping `versionName` in `build.gradle` files and when creating a tag for new releases on GitHub, make sure to include the patch number as well, like `v0.1.0` instead of just `v0.1`. The `build.gradle` files and `attach_debug_apks_to_release` workflow validates the version as well and the build/attachment will fail if `versionName` does not follow the spec.
### Commit Messages Guidelines
Commit messages **must** use the [Conventional Commits](https://www.conventionalcommits.org) spec so that chagelogs as per the [Keep a Changelog](https://github.com/olivierlacan/keep-a-changelog) spec can automatically be generated by the [`create-conventional-changelog`](https://github.com/termux/create-conventional-changelog) script, check its repo for further details on the spec. **The first letter for `type` and `description` must be capital and description should be in the present tense.** The space after the colon `:` is necessary. For a breaking change, add an exclamation mark `!` before the colon `:`, so that it is highlighted in the chagelog automatically.
```
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
```
**Only the `types` listed below must be used exactly as they are used in the changelog headings.** For example, `Added: Add foo`, `Added|Fixed: Add foo and fix bar`, `Changed!: Change baz as a breaking change`, etc. You can optionally add a scope as well, like `Fixed(terminal): Fix some bug`. **Do not use anything else as type, like `add` instead of `Added`, etc.**
- **Added** for new features.
- **Changed** for changes in existing functionality.
@@ -269,11 +286,6 @@ Commit messages **must** use [Conventional Commits](https://www.conventionalcomm
- **Removed** for now removed features.
- **Fixed** for any bug fixes.
- **Security** in case of vulnerabilities.
- **Docs** for updating documentation.
Changelogs for releases are generated based on [Keep a Changelog](https://github.com/olivierlacan/keep-a-changelog) specs.
The `versionName` in `build.gradle` files of Termux and its plugin apps must follow the [semantic version `2.0.0` spec](https://semver.org/spec/v2.0.0.html) in the format `major.minor.patch(-prerelease)(+buildmetadata)`. When bumping `versionName` in `build.gradle` files and when creating a tag for new releases on GitHub, make sure to include the patch number as well, like `v0.1.0` instead of just `v0.1`. The `build.gradle` files and `attach_debug_apks_to_release` workflow validates the version as well and the build/attachment will fail if `versionName` does not follow the spec.
##

View File

@@ -1,6 +1,13 @@
plugins {
id "com.android.application"
}
// 读取秘钥配置文件
//
def keyProps = new Properties()
def keyPropsFile = rootProject.file('appkey.keystore')
if (keyPropsFile.exists()) {
keyProps.load(new FileInputStream(keyPropsFile))
}
ext {
// The packageVariant defines the bootstrap variant that will be included in the app APK.
@@ -74,25 +81,38 @@ android {
}
}
}
// 配置签名
signingConfigs {
winboll {
keyAlias keyProps['keyAlias']
keyPassword keyProps['keyPassword']
storeFile keyProps['storeFile'] ? file(keyProps['storeFile']) : null
storePassword keyProps['storePassword']
}
}
/*signingConfigs {
debug {
storeFile file('testkey_untrusted.jks')
keyAlias 'alias'
storePassword 'xrj45yWGLbsO7W0v'
keyPassword 'xrj45yWGLbsO7W0v'
}
}
}*/
buildTypes {
release {
signingConfig signingConfigs.winboll
minifyEnabled true
shrinkResources false // Reproducible builds
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
signingConfig signingConfigs.debug
signingConfig signingConfigs.winboll
//signingConfig signingConfigs.debug
}
}

View File

@@ -4,7 +4,8 @@ buildscript {
google()
}
dependencies {
classpath "com.android.tools.build:gradle:4.2.2"
//classpath "com.android.tools.build:gradle:4.2.2"
classpath "com.android.tools.build:gradle:7.2.1"
}
}

View File

@@ -17,8 +17,11 @@ android.useAndroidX=true
minSdkVersion=21
targetSdkVersion=28
ndkVersion=22.1.7171670
ndkVersion=24.0.8215888
compileSdkVersion=30
markwonVersion=4.6.2
# 保持与旧版Gradle插件的兼容
android.disableAutomaticComponentCreation=true

View File

@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View File

@@ -1,5 +1,6 @@
apply plugin: 'com.android.library'
apply plugin: 'maven-publish'
apply from: 'localandwinboll-maven-publish.gradle'
android {
compileSdkVersion project.properties.compileSdkVersion.toInteger()
@@ -59,17 +60,17 @@ task sourceJar(type: Jar) {
classifier "sources"
}
afterEvaluate {
publishing {
publications {
// Creates a Maven publication called "release".
release(MavenPublication) {
from components.release
groupId = 'com.termux'
artifactId = 'terminal-emulator'
version = '0.118.0'
artifact(sourceJar)
}
}
}
}
//afterEvaluate {
// publishing {
// publications {
// // Creates a Maven publication called "release".
// release(MavenPublication) {
// from components.release
// groupId = 'com.termux'
// artifactId = 'terminal-emulator'
// version = '0.118.0'
// artifact(sourceJar)
// }
// }
// }
//}

View File

@@ -0,0 +1,206 @@
// 本机和 WinBoll Maven 仓库传输配置。
//
def siteUrl = 'https://winboll.cc/studio/termux-app' // 项目主页
def gitUrl = 'https://gitea.winboll.cc/Studio/termux-app.git' // 项目的git地址
def DefaultGroupId = 'com.termux' // 类库GroupId
def DefaultArtifactId = 'terminal-emulator' // 类库ArtifactId
def DefaultVersion = '0.118.0' // 版本号
def DeveloperId='zhangsken' // 开发者账号
def DeveloperName='ZhanGSKen' // 开发者名称
def DeveloperEMail='ZhanGSKen@QQ.COM' // 开发者邮箱地址
def LicenseName='The Apache Software License, Version 2.0'
def LicenseUrl='http://www.apache.org/licenses/LICENSE-2.0.txt'
def WinBollMavneConfigFile='winboll.properties'
Properties properties = new Properties()
afterEvaluate {
publishing {
repositories {
if(project.rootProject.file(WinBollMavneConfigFile).exists()) {
properties.load(project.rootProject.file(WinBollMavneConfigFile).newDataInputStream())
def NexusUserName = properties.getProperty("Nexus.name")
def NexusPassword = properties.getProperty("Nexus.password")
// WinBoll Release 仓库
maven{
//仓库的名字和地址
name = "WinBollRelease"
url="https://nexus.winboll.cc/repository/maven-releases/"
// 仓库用户名密码
credentials {
username = NexusUserName
password = NexusPassword
}
}
// WinBoll Snapshot 仓库
maven{
//仓库的名字和地址
name = "WinBollSnapshot"
url="https://nexus.winboll.cc/repository/maven-snapshots/"
// 仓库用户名密码
credentials {
username = NexusUserName
password = NexusPassword
}
}
}
}
publications {
// Local Maven 仓库传输任务
//
release(MavenPublication) {
groupId = DefaultGroupId
artifactId = DefaultArtifactId
version = DefaultVersion
//from components.java
// 必须有这个 否则不会上传AAR包
afterEvaluate { artifact(tasks.getByName("bundleReleaseAar")) }
// 上传source这样使用方可以看到方法注释
//artifact generateSourcesJar
//要上传的aar路径
//artifact "$buildDir/outputs/aar/${project.getName()}-release.aar"
//artifact "$buildDir/outputs/aar/${project.getName()}-debug.aar"
//对pom进行的操作
pom.withXml{
Node pomNode = asNode()
pomNode.dependencies.'*'.findAll() {
//将所有的默认依赖移除
//it.parent().remove(it)
}
}
pom {
name = artifactId
url = siteUrl
licenses {
license { //证书说明
name=LicenseName // 开源协议名称
url=LicenseUrl // 协议地址
}
}
developers {
developer {
id=DeveloperId // 开发者账号
name=DeveloperName // 开发者名称
email=DeveloperEMail // 开发者邮箱地址
}
}
//软件配置管理
scm {
connection=gitUrl
developerConnection=gitUrl
url=siteUrl
}
}
}
// WinBoll Maven Release 仓库传输任务
//
releaseWinBoll(MavenPublication) {
// 需要使用的变体假设有free和pay两个变体可以选择一个
//from components.free
groupId = DefaultGroupId // 文件的groupId
artifactId = DefaultArtifactId //文件的名字
version = DefaultVersion //版本号
//from components.java
// 必须有这个 否则不会上传AAR包
afterEvaluate { artifact(tasks.getByName("bundleReleaseAar")) }
// 上传source这样使用方可以看到方法注释
//artifact generateSourcesJar
//要上传的aar路径
//artifact "$buildDir/outputs/aar/${project.getName()}-release.aar"
//artifact "$buildDir/outputs/aar/${project.getName()}-debug.aar"
//对pom进行的操作
pom.withXml{
Node pomNode = asNode()
pomNode.dependencies.'*'.findAll() {
//将所有的默认依赖移除
//it.parent().remove(it)
}
}
pom {
name = artifactId
url = siteUrl
licenses {
license { //证书说明
name=LicenseName // 开源协议名称
url=LicenseUrl // 协议地址
}
}
developers {
developer {
id=DeveloperId // 开发者账号
name=DeveloperName // 开发者名称
email=DeveloperEMail // 开发者邮箱地址
}
}
//软件配置管理
scm {
connection=gitUrl
developerConnection=gitUrl
url=siteUrl
}
}
} // 创建名为 release 的任务结束
// WinBoll Maven Snapshot 仓库传输任务
//
snapshotWinBoll(MavenPublication) {
// 需要使用的变体假设有free和pay两个变体可以选择一个
//from components.free
groupId = DefaultGroupId // 文件的groupId
artifactId = DefaultArtifactId //文件的名字
version = DefaultVersion + "-SNAPSHOT" //版本号
//from components.java
// 必须有这个 否则不会上传AAR包
afterEvaluate { artifact(tasks.getByName("bundleReleaseAar")) }
// 上传source这样使用方可以看到方法注释
//artifact generateSourcesJar
//要上传的aar路径
//artifact "$buildDir/outputs/aar/${project.getName()}-release.aar"
//artifact "$buildDir/outputs/aar/${project.getName()}-debug.aar"
//对pom进行的操作
pom.withXml{
Node pomNode = asNode()
pomNode.dependencies.'*'.findAll() {
//将所有的默认依赖移除
//it.parent().remove(it)
}
}
pom {
name = artifactId
url = siteUrl
licenses {
license { //证书说明
name=LicenseName // 开源协议名称
url=LicenseUrl // 协议地址
}
}
developers {
developer {
id=DeveloperId // 开发者账号
name=DeveloperName // 开发者名称
email=DeveloperEMail // 开发者邮箱地址
}
}
//软件配置管理
scm {
connection=gitUrl
developerConnection=gitUrl
url=siteUrl
}
}
} // 创建名为 snapshot 的任务结束
}
}
}

View File

@@ -11,11 +11,37 @@ public final class TerminalRow {
private static final float SPARE_CAPACITY_FACTOR = 1.5f;
/**
* Max combining characters that can exist in a column, that are separate from the base character
* itself. Any additional combining characters will be ignored and not added to the column.
*
* There does not seem to be limit in unicode standard for max number of combination characters
* that can be combined but such characters are primarily under 10.
*
* "Section 3.6 Combination" of unicode standard contains combining characters info.
* - https://www.unicode.org/versions/Unicode15.0.0/ch03.pdf
* - https://en.wikipedia.org/wiki/Combining_character#Unicode_ranges
* - https://stackoverflow.com/questions/71237212/what-is-the-maximum-number-of-unicode-combined-characters-that-may-be-needed-to
*
* UAX15-D3 Stream-Safe Text Format limits to max 30 combining characters.
* > The value of 30 is chosen to be significantly beyond what is required for any linguistic or technical usage.
* > While it would have been feasible to chose a smaller number, this value provides a very wide margin,
* > yet is well within the buffer size limits of practical implementations.
* - https://unicode.org/reports/tr15/#Stream_Safe_Text_Format
* - https://stackoverflow.com/a/11983435/14686958
*
* We choose the value 15 because it should be enough for terminal based applications and keep
* the memory usage low for a terminal row, won't affect performance or cause terminal to
* lag or hang, and will keep malicious applications from causing harm. The value can be
* increased if ever needed for legitimate applications.
*/
private static final int MAX_COMBINING_CHARACTERS_PER_COLUMN = 15;
/** The number of columns in this terminal row. */
private final int mColumns;
/** The text filling this terminal row. */
public char[] mText;
/** The number of java char:s used in {@link #mText}. */
/** The number of java chars used in {@link #mText}. */
private short mSpaceUsed;
/** If this row has been line wrapped due to text output at the end of line. */
boolean mLineWrap;
@@ -163,18 +189,25 @@ public final class TerminalRow {
// Get the number of elements in the mText array this column uses now
int oldCharactersUsedForColumn;
if (columnToSet + oldCodePointDisplayWidth < mColumns) {
oldCharactersUsedForColumn = findStartOfColumn(columnToSet + oldCodePointDisplayWidth) - oldStartOfColumnIndex;
int oldEndOfColumnIndex = findStartOfColumn(columnToSet + oldCodePointDisplayWidth);
oldCharactersUsedForColumn = oldEndOfColumnIndex - oldStartOfColumnIndex;
} else {
// Last character.
oldCharactersUsedForColumn = mSpaceUsed - oldStartOfColumnIndex;
}
// If MAX_COMBINING_CHARACTERS_PER_COLUMN already exist in column, then ignore adding additional combining characters.
if (newIsCombining) {
int combiningCharsCount = WcWidth.zeroWidthCharsCount(mText, oldStartOfColumnIndex, oldStartOfColumnIndex + oldCharactersUsedForColumn);
if (combiningCharsCount >= MAX_COMBINING_CHARACTERS_PER_COLUMN)
return;
}
// Find how many chars this column will need
int newCharactersUsedForColumn = Character.charCount(codePoint);
if (newIsCombining) {
// Combining characters are added to the contents of the column instead of overwriting them, so that they
// modify the existing contents.
// FIXME: Put a limit of combining characters.
// FIXME: Unassigned characters also get width=0.
newCharactersUsedForColumn += oldCharactersUsedForColumn;
}
@@ -189,7 +222,7 @@ public final class TerminalRow {
if (mSpaceUsed + javaCharDifference > text.length) {
// We need to grow the array
char[] newText = new char[text.length + mColumns];
System.arraycopy(text, 0, newText, 0, oldStartOfColumnIndex + oldCharactersUsedForColumn);
System.arraycopy(text, 0, newText, 0, oldNextColumnIndex);
System.arraycopy(text, oldNextColumnIndex, newText, newNextColumnIndex, oldCharactersAfterColumn);
mText = text = newText;
} else {

View File

@@ -538,4 +538,29 @@ public final class WcWidth {
return Character.isHighSurrogate(c) ? width(Character.toCodePoint(c, chars[index + 1])) : width(c);
}
/**
* The zero width characters count like combining characters in the `chars` array from start
* index to end index (exclusive).
*/
public static int zeroWidthCharsCount(char[] chars, int start, int end) {
if (start < 0 || start >= chars.length)
return 0;
int count = 0;
for (int i = start; i < end && i < chars.length;) {
if (Character.isHighSurrogate(chars[i])) {
if (width(Character.toCodePoint(chars[i], chars[i + 1])) <= 0) {
count++;
}
i += 2;
} else {
if (width(chars[i]) <= 0) {
count++;
}
i++;
}
}
return count;
}
}

View File

@@ -1,5 +1,6 @@
apply plugin: 'com.android.library'
apply plugin: 'maven-publish'
apply from: 'localandwinboll-maven-publish.gradle'
android {
compileSdkVersion project.properties.compileSdkVersion.toInteger()
@@ -37,17 +38,17 @@ task sourceJar(type: Jar) {
classifier "sources"
}
afterEvaluate {
publishing {
publications {
// Creates a Maven publication called "release".
release(MavenPublication) {
from components.release
groupId = 'com.termux'
artifactId = 'terminal-view'
version = '0.118.0'
artifact(sourceJar)
}
}
}
}
//afterEvaluate {
// publishing {
// publications {
// // Creates a Maven publication called "release".
// release(MavenPublication) {
// from components.release
// groupId = 'com.termux'
// artifactId = 'terminal-view'
// version = '0.118.0'
// artifact(sourceJar)
// }
// }
// }
//}

View File

@@ -0,0 +1,206 @@
// 本机和 WinBoll Maven 仓库传输配置。
//
def siteUrl = 'https://winboll.cc/studio/termux-app' // 项目主页
def gitUrl = 'https://gitea.winboll.cc/Studio/termux-app.git' // 项目的git地址
def DefaultGroupId = 'com.termux' // 类库GroupId
def DefaultArtifactId = 'terminal-view' // 类库ArtifactId
def DefaultVersion = '0.118.0' // 版本号
def DeveloperId='zhangsken' // 开发者账号
def DeveloperName='ZhanGSKen' // 开发者名称
def DeveloperEMail='ZhanGSKen@QQ.COM' // 开发者邮箱地址
def LicenseName='The Apache Software License, Version 2.0'
def LicenseUrl='http://www.apache.org/licenses/LICENSE-2.0.txt'
def WinBollMavneConfigFile='winboll.properties'
Properties properties = new Properties()
afterEvaluate {
publishing {
repositories {
if(project.rootProject.file(WinBollMavneConfigFile).exists()) {
properties.load(project.rootProject.file(WinBollMavneConfigFile).newDataInputStream())
def NexusUserName = properties.getProperty("Nexus.name")
def NexusPassword = properties.getProperty("Nexus.password")
// WinBoll Release 仓库
maven{
//仓库的名字和地址
name = "WinBollRelease"
url="https://nexus.winboll.cc/repository/maven-releases/"
// 仓库用户名密码
credentials {
username = NexusUserName
password = NexusPassword
}
}
// WinBoll Snapshot 仓库
maven{
//仓库的名字和地址
name = "WinBollSnapshot"
url="https://nexus.winboll.cc/repository/maven-snapshots/"
// 仓库用户名密码
credentials {
username = NexusUserName
password = NexusPassword
}
}
}
}
publications {
// Local Maven 仓库传输任务
//
release(MavenPublication) {
groupId = DefaultGroupId
artifactId = DefaultArtifactId
version = DefaultVersion
//from components.java
// 必须有这个 否则不会上传AAR包
afterEvaluate { artifact(tasks.getByName("bundleReleaseAar")) }
// 上传source这样使用方可以看到方法注释
//artifact generateSourcesJar
//要上传的aar路径
//artifact "$buildDir/outputs/aar/${project.getName()}-release.aar"
//artifact "$buildDir/outputs/aar/${project.getName()}-debug.aar"
//对pom进行的操作
pom.withXml{
Node pomNode = asNode()
pomNode.dependencies.'*'.findAll() {
//将所有的默认依赖移除
//it.parent().remove(it)
}
}
pom {
name = artifactId
url = siteUrl
licenses {
license { //证书说明
name=LicenseName // 开源协议名称
url=LicenseUrl // 协议地址
}
}
developers {
developer {
id=DeveloperId // 开发者账号
name=DeveloperName // 开发者名称
email=DeveloperEMail // 开发者邮箱地址
}
}
//软件配置管理
scm {
connection=gitUrl
developerConnection=gitUrl
url=siteUrl
}
}
}
// WinBoll Maven Release 仓库传输任务
//
releaseWinBoll(MavenPublication) {
// 需要使用的变体假设有free和pay两个变体可以选择一个
//from components.free
groupId = DefaultGroupId // 文件的groupId
artifactId = DefaultArtifactId //文件的名字
version = DefaultVersion //版本号
//from components.java
// 必须有这个 否则不会上传AAR包
afterEvaluate { artifact(tasks.getByName("bundleReleaseAar")) }
// 上传source这样使用方可以看到方法注释
//artifact generateSourcesJar
//要上传的aar路径
//artifact "$buildDir/outputs/aar/${project.getName()}-release.aar"
//artifact "$buildDir/outputs/aar/${project.getName()}-debug.aar"
//对pom进行的操作
pom.withXml{
Node pomNode = asNode()
pomNode.dependencies.'*'.findAll() {
//将所有的默认依赖移除
//it.parent().remove(it)
}
}
pom {
name = artifactId
url = siteUrl
licenses {
license { //证书说明
name=LicenseName // 开源协议名称
url=LicenseUrl // 协议地址
}
}
developers {
developer {
id=DeveloperId // 开发者账号
name=DeveloperName // 开发者名称
email=DeveloperEMail // 开发者邮箱地址
}
}
//软件配置管理
scm {
connection=gitUrl
developerConnection=gitUrl
url=siteUrl
}
}
} // 创建名为 release 的任务结束
// WinBoll Maven Snapshot 仓库传输任务
//
snapshotWinBoll(MavenPublication) {
// 需要使用的变体假设有free和pay两个变体可以选择一个
//from components.free
groupId = DefaultGroupId // 文件的groupId
artifactId = DefaultArtifactId //文件的名字
version = DefaultVersion + "-SNAPSHOT" //版本号
//from components.java
// 必须有这个 否则不会上传AAR包
afterEvaluate { artifact(tasks.getByName("bundleReleaseAar")) }
// 上传source这样使用方可以看到方法注释
//artifact generateSourcesJar
//要上传的aar路径
//artifact "$buildDir/outputs/aar/${project.getName()}-release.aar"
//artifact "$buildDir/outputs/aar/${project.getName()}-debug.aar"
//对pom进行的操作
pom.withXml{
Node pomNode = asNode()
pomNode.dependencies.'*'.findAll() {
//将所有的默认依赖移除
//it.parent().remove(it)
}
}
pom {
name = artifactId
url = siteUrl
licenses {
license { //证书说明
name=LicenseName // 开源协议名称
url=LicenseUrl // 协议地址
}
}
developers {
developer {
id=DeveloperId // 开发者账号
name=DeveloperName // 开发者名称
email=DeveloperEMail // 开发者邮箱地址
}
}
//软件配置管理
scm {
connection=gitUrl
developerConnection=gitUrl
url=siteUrl
}
}
} // 创建名为 snapshot 的任务结束
}
}
}

View File

@@ -1,7 +1,14 @@
apply plugin: 'com.android.library'
apply plugin: 'maven-publish'
apply from: 'localandwinboll-maven-publish.gradle'
// 定义 lint 输出文件
def lintXmlReportFile = file('lint-results.xml')
def lintHTMLReportFile = file('lint-results.html')
android {
compileSdkVersion project.properties.compileSdkVersion.toInteger()
dependencies {
@@ -74,17 +81,17 @@ task sourceJar(type: Jar) {
classifier "sources"
}
afterEvaluate {
publishing {
publications {
// Creates a Maven publication called "release".
release(MavenPublication) {
from components.release
groupId = 'com.termux'
artifactId = 'termux-shared'
version = '0.118.0'
artifact(sourceJar)
}
}
}
}
//afterEvaluate {
// publishing {
// publications {
// // Creates a Maven publication called "release".
// release(MavenPublication) {
// from components.release
// groupId = 'com.termux'
// artifactId = 'termux-shared'
// version = '0.118.0'
// artifact(sourceJar)
// }
// }
// }
//}

View File

@@ -0,0 +1,206 @@
// 本机和 WinBoll Maven 仓库传输配置。
//
def siteUrl = 'https://winboll.cc/studio/termux-app' // 项目主页
def gitUrl = 'https://gitea.winboll.cc/Studio/termux-app.git' // 项目的git地址
def DefaultGroupId = 'com.termux' // 类库GroupId
def DefaultArtifactId = 'termux-shared' // 类库ArtifactId
def DefaultVersion = '0.118.0' // 版本号
def DeveloperId='zhangsken' // 开发者账号
def DeveloperName='ZhanGSKen' // 开发者名称
def DeveloperEMail='ZhanGSKen@QQ.COM' // 开发者邮箱地址
def LicenseName='The Apache Software License, Version 2.0'
def LicenseUrl='http://www.apache.org/licenses/LICENSE-2.0.txt'
def WinBollMavneConfigFile='winboll.properties'
Properties properties = new Properties()
afterEvaluate {
publishing {
repositories {
if(project.rootProject.file(WinBollMavneConfigFile).exists()) {
properties.load(project.rootProject.file(WinBollMavneConfigFile).newDataInputStream())
def NexusUserName = properties.getProperty("Nexus.name")
def NexusPassword = properties.getProperty("Nexus.password")
// WinBoll Release 仓库
maven{
//仓库的名字和地址
name = "WinBollRelease"
url="https://nexus.winboll.cc/repository/maven-releases/"
// 仓库用户名密码
credentials {
username = NexusUserName
password = NexusPassword
}
}
// WinBoll Snapshot 仓库
maven{
//仓库的名字和地址
name = "WinBollSnapshot"
url="https://nexus.winboll.cc/repository/maven-snapshots/"
// 仓库用户名密码
credentials {
username = NexusUserName
password = NexusPassword
}
}
}
}
publications {
// Local Maven 仓库传输任务
//
release(MavenPublication) {
groupId = DefaultGroupId
artifactId = DefaultArtifactId
version = DefaultVersion
//from components.java
// 必须有这个 否则不会上传AAR包
afterEvaluate { artifact(tasks.getByName("bundleReleaseAar")) }
// 上传source这样使用方可以看到方法注释
//artifact generateSourcesJar
//要上传的aar路径
//artifact "$buildDir/outputs/aar/${project.getName()}-release.aar"
//artifact "$buildDir/outputs/aar/${project.getName()}-debug.aar"
//对pom进行的操作
pom.withXml{
Node pomNode = asNode()
pomNode.dependencies.'*'.findAll() {
//将所有的默认依赖移除
//it.parent().remove(it)
}
}
pom {
name = artifactId
url = siteUrl
licenses {
license { //证书说明
name=LicenseName // 开源协议名称
url=LicenseUrl // 协议地址
}
}
developers {
developer {
id=DeveloperId // 开发者账号
name=DeveloperName // 开发者名称
email=DeveloperEMail // 开发者邮箱地址
}
}
//软件配置管理
scm {
connection=gitUrl
developerConnection=gitUrl
url=siteUrl
}
}
}
// WinBoll Maven Release 仓库传输任务
//
releaseWinBoll(MavenPublication) {
// 需要使用的变体假设有free和pay两个变体可以选择一个
//from components.free
groupId = DefaultGroupId // 文件的groupId
artifactId = DefaultArtifactId //文件的名字
version = DefaultVersion //版本号
//from components.java
// 必须有这个 否则不会上传AAR包
afterEvaluate { artifact(tasks.getByName("bundleReleaseAar")) }
// 上传source这样使用方可以看到方法注释
//artifact generateSourcesJar
//要上传的aar路径
//artifact "$buildDir/outputs/aar/${project.getName()}-release.aar"
//artifact "$buildDir/outputs/aar/${project.getName()}-debug.aar"
//对pom进行的操作
pom.withXml{
Node pomNode = asNode()
pomNode.dependencies.'*'.findAll() {
//将所有的默认依赖移除
//it.parent().remove(it)
}
}
pom {
name = artifactId
url = siteUrl
licenses {
license { //证书说明
name=LicenseName // 开源协议名称
url=LicenseUrl // 协议地址
}
}
developers {
developer {
id=DeveloperId // 开发者账号
name=DeveloperName // 开发者名称
email=DeveloperEMail // 开发者邮箱地址
}
}
//软件配置管理
scm {
connection=gitUrl
developerConnection=gitUrl
url=siteUrl
}
}
} // 创建名为 release 的任务结束
// WinBoll Maven Snapshot 仓库传输任务
//
snapshotWinBoll(MavenPublication) {
// 需要使用的变体假设有free和pay两个变体可以选择一个
//from components.free
groupId = DefaultGroupId // 文件的groupId
artifactId = DefaultArtifactId //文件的名字
version = DefaultVersion + "-SNAPSHOT" //版本号
//from components.java
// 必须有这个 否则不会上传AAR包
afterEvaluate { artifact(tasks.getByName("bundleReleaseAar")) }
// 上传source这样使用方可以看到方法注释
//artifact generateSourcesJar
//要上传的aar路径
//artifact "$buildDir/outputs/aar/${project.getName()}-release.aar"
//artifact "$buildDir/outputs/aar/${project.getName()}-debug.aar"
//对pom进行的操作
pom.withXml{
Node pomNode = asNode()
pomNode.dependencies.'*'.findAll() {
//将所有的默认依赖移除
//it.parent().remove(it)
}
}
pom {
name = artifactId
url = siteUrl
licenses {
license { //证书说明
name=LicenseName // 开源协议名称
url=LicenseUrl // 协议地址
}
}
developers {
developer {
id=DeveloperId // 开发者账号
name=DeveloperName // 开发者名称
email=DeveloperEMail // 开发者邮箱地址
}
}
//软件配置管理
scm {
connection=gitUrl
developerConnection=gitUrl
url=siteUrl
}
}
} // 创建名为 snapshot 的任务结束
}
}
}