├── .gitattributes
├── .github
├── FUNDING.yml
├── dependabot.yml
└── workflows
│ └── build.yml
├── .gitignore
├── .idea
└── copyright
│ ├── LGPL_3_0.xml
│ └── profiles_settings.xml
├── LICENSE
├── README.md
├── build.gradle
├── buildSrc
├── build.gradle
└── src
│ └── main
│ └── groovy
│ ├── base.base-conventions.gradle
│ ├── base.lenni0451-maven-publishing.gradle
│ └── class-token-replacer.publishing-conventions.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
└── src
└── main
└── java
└── net
└── raphimc
└── classtokenreplacer
├── ClassTokenReplacerPlugin.java
├── extension
├── ClassTokenReplacerExtension.java
└── ClassTokenReplacerExtensionImpl.java
└── task
└── ReplaceTokensTask.java
/.gitattributes:
--------------------------------------------------------------------------------
1 | #
2 | # https://help.github.com/articles/dealing-with-line-endings/
3 | #
4 | # Linux start script should use lf
5 | /gradlew text eol=lf
6 |
7 | # These are Windows script files and should use crlf
8 | *.bat text eol=crlf
9 |
10 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | ko_fi: rk_01
2 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | registries:
3 | maven-central:
4 | type: maven-repository
5 | url: "https://repo.maven.apache.org/maven2/"
6 | updates:
7 | - package-ecosystem: "gradle"
8 | directory: "/"
9 | schedule:
10 | interval: "daily"
11 | registries:
12 | - maven-central
13 | - package-ecosystem: "github-actions"
14 | directory: "/"
15 | schedule:
16 | interval: "weekly"
17 |
--------------------------------------------------------------------------------
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: build
2 | on: [push, pull_request, workflow_dispatch]
3 |
4 | jobs:
5 | build:
6 | runs-on: ubuntu-24.04
7 | if: ${{ github.event_name != 'pull_request' || github.repository != github.event.pull_request.head.repo.full_name }}
8 | steps:
9 | - name: Checkout Repository
10 | uses: actions/checkout@v4
11 | with:
12 | persist-credentials: false
13 | - name: Validate Gradle Wrapper
14 | uses: gradle/actions/wrapper-validation@v4
15 | - name: Set up JDK 21
16 | uses: actions/setup-java@v4
17 | with:
18 | distribution: temurin
19 | java-version: 21
20 | check-latest: true
21 | - name: Build with Gradle
22 | run: ./gradlew build
23 | - name: Upload Artifacts to GitHub
24 | uses: actions/upload-artifact@v4
25 | with:
26 | name: Artifacts
27 | path: build/libs/
28 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled class file
2 | *.class
3 |
4 | # Log file
5 | *.log
6 | *.log.gz
7 |
8 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
9 | hs_err_pid*
10 |
11 | # Project files
12 | /.idea/*
13 | !/.idea/copyright/
14 | /.gradle/
15 | /buildSrc/.gradle/
16 | build/
17 | out/
18 | /run/
19 |
--------------------------------------------------------------------------------
/.idea/copyright/LGPL_3_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 |
9 | This version of the GNU Lesser General Public License incorporates
10 | the terms and conditions of version 3 of the GNU General Public
11 | License, supplemented by the additional permissions listed below.
12 |
13 | 0. Additional Definitions.
14 |
15 | As used herein, "this License" refers to version 3 of the GNU Lesser
16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU
17 | General Public License.
18 |
19 | "The Library" refers to a covered work governed by this License,
20 | other than an Application or a Combined Work as defined below.
21 |
22 | An "Application" is any work that makes use of an interface provided
23 | by the Library, but which is not otherwise based on the Library.
24 | Defining a subclass of a class defined by the Library is deemed a mode
25 | of using an interface provided by the Library.
26 |
27 | A "Combined Work" is a work produced by combining or linking an
28 | Application with the Library. The particular version of the Library
29 | with which the Combined Work was made is also called the "Linked
30 | Version".
31 |
32 | The "Minimal Corresponding Source" for a Combined Work means the
33 | Corresponding Source for the Combined Work, excluding any source code
34 | for portions of the Combined Work that, considered in isolation, are
35 | based on the Application, and not on the Linked Version.
36 |
37 | The "Corresponding Application Code" for a Combined Work means the
38 | object code and/or source code for the Application, including any data
39 | and utility programs needed for reproducing the Combined Work from the
40 | Application, but excluding the System Libraries of the Combined Work.
41 |
42 | 1. Exception to Section 3 of the GNU GPL.
43 |
44 | You may convey a covered work under sections 3 and 4 of this License
45 | without being bound by section 3 of the GNU GPL.
46 |
47 | 2. Conveying Modified Versions.
48 |
49 | If you modify a copy of the Library, and, in your modifications, a
50 | facility refers to a function or data to be supplied by an Application
51 | that uses the facility (other than as an argument passed when the
52 | facility is invoked), then you may convey a copy of the modified
53 | version:
54 |
55 | a) under this License, provided that you make a good faith effort to
56 | ensure that, in the event an Application does not supply the
57 | function or data, the facility still operates, and performs
58 | whatever part of its purpose remains meaningful, or
59 |
60 | b) under the GNU GPL, with none of the additional permissions of
61 | this License applicable to that copy.
62 |
63 | 3. Object Code Incorporating Material from Library Header Files.
64 |
65 | The object code form of an Application may incorporate material from
66 | a header file that is part of the Library. You may convey such object
67 | code under terms of your choice, provided that, if the incorporated
68 | material is not limited to numerical parameters, data structure
69 | layouts and accessors, or small macros, inline functions and templates
70 | (ten or fewer lines in length), you do both of the following:
71 |
72 | a) Give prominent notice with each copy of the object code that the
73 | Library is used in it and that the Library and its use are
74 | covered by this License.
75 |
76 | b) Accompany the object code with a copy of the GNU GPL and this license
77 | document.
78 |
79 | 4. Combined Works.
80 |
81 | You may convey a Combined Work under terms of your choice that,
82 | taken together, effectively do not restrict modification of the
83 | portions of the Library contained in the Combined Work and reverse
84 | engineering for debugging such modifications, if you also do each of
85 | the following:
86 |
87 | a) Give prominent notice with each copy of the Combined Work that
88 | the Library is used in it and that the Library and its use are
89 | covered by this License.
90 |
91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license
92 | document.
93 |
94 | c) For a Combined Work that displays copyright notices during
95 | execution, include the copyright notice for the Library among
96 | these notices, as well as a reference directing the user to the
97 | copies of the GNU GPL and this license document.
98 |
99 | d) Do one of the following:
100 |
101 | 0) Convey the Minimal Corresponding Source under the terms of this
102 | License, and the Corresponding Application Code in a form
103 | suitable for, and under terms that permit, the user to
104 | recombine or relink the Application with a modified version of
105 | the Linked Version to produce a modified Combined Work, in the
106 | manner specified by section 6 of the GNU GPL for conveying
107 | Corresponding Source.
108 |
109 | 1) Use a suitable shared library mechanism for linking with the
110 | Library. A suitable mechanism is one that (a) uses at run time
111 | a copy of the Library already present on the user's computer
112 | system, and (b) will operate properly with a modified version
113 | of the Library that is interface-compatible with the Linked
114 | Version.
115 |
116 | e) Provide Installation Information, but only if you would otherwise
117 | be required to provide such information under section 6 of the
118 | GNU GPL, and only to the extent that such information is
119 | necessary to install and execute a modified version of the
120 | Combined Work produced by recombining or relinking the
121 | Application with a modified version of the Linked Version. (If
122 | you use option 4d0, the Installation Information must accompany
123 | the Minimal Corresponding Source and Corresponding Application
124 | Code. If you use option 4d1, you must provide the Installation
125 | Information in the manner specified by section 6 of the GNU GPL
126 | for conveying Corresponding Source.)
127 |
128 | 5. Combined Libraries.
129 |
130 | You may place library facilities that are a work based on the
131 | Library side by side in a single library together with other library
132 | facilities that are not Applications and are not covered by this
133 | License, and convey such a combined library under terms of your
134 | choice, if you do both of the following:
135 |
136 | a) Accompany the combined library with a copy of the same work based
137 | on the Library, uncombined with any other library facilities,
138 | conveyed under the terms of this License.
139 |
140 | b) Give prominent notice with the combined library that part of it
141 | is a work based on the Library, and explaining where to find the
142 | accompanying uncombined form of the same work.
143 |
144 | 6. Revised Versions of the GNU Lesser General Public License.
145 |
146 | The Free Software Foundation may publish revised and/or new versions
147 | of the GNU Lesser General Public License from time to time. Such new
148 | versions will be similar in spirit to the present version, but may
149 | differ in detail to address new problems or concerns.
150 |
151 | Each version is given a distinguishing version number. If the
152 | Library as you received it specifies that a certain numbered version
153 | of the GNU Lesser General Public License "or any later version"
154 | applies to it, you have the option of following the terms and
155 | conditions either of that published version or of any later version
156 | published by the Free Software Foundation. If the Library as you
157 | received it does not specify a version number of the GNU Lesser
158 | General Public License, you may choose any version of the GNU Lesser
159 | General Public License ever published by the Free Software Foundation.
160 |
161 | If the Library as you received it specifies that a proxy can decide
162 | whether future versions of the GNU Lesser General Public License shall
163 | apply, that proxy's public statement of acceptance of any version is
164 | permanent authorization for you to choose that version for the
165 | Library.
166 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ClassTokenReplacer
2 | Gradle plugin to replace string tokens in class files during compile time.
3 |
4 | ClassTokenReplacer allows you to replace string placeholders in your code with actual values during the building process.
5 | This can be used to replace tokens like ``${version}`` with the actual version of the project.
6 |
7 | ## Releases
8 | ### Gradle
9 | To use ClassTokenReplacer in your Gradle project you can follow the instructions on the [Gradle Plugin Portal](https://plugins.gradle.org/plugin/net.raphimc.class-token-replacer).
10 |
11 | ## Usage
12 | The plugin extends all source sets with a new extension called ``classTokenReplacer``. This allows you to specify replacements for your source sets:
13 | ```groovy
14 | sourceSets {
15 | main {
16 | classTokenReplacer {
17 | property("\${version}", project.version)
18 | }
19 | }
20 | }
21 | ```
22 |
23 | That's it! Now all compiled class files in the main source set will be scanned for the token ``${version}`` and have it replaced with the value specified in the ``property`` method.
24 | Be careful to choose placeholders in a way where don't accidentally match some other strings in your code.
25 |
26 | ### Additional Options
27 | You can also specify the following options in the ``classTokenReplacer`` block:
28 | - ``replaceInPlace`` (boolean, default: false): If set to true, the original class files will be replaced with the modified ones. This is useful if your build setup uses the class files directly. This option requires a project rebuild if the contents of a token changes.
29 |
30 | ## Contact
31 | If you encounter any issues, please report them on the
32 | [issue tracker](https://github.com/RaphiMC/ClassTokenReplacer/issues).
33 | If you just want to talk or need help implementing ClassTokenReplacer feel free to join my
34 | [Discord](https://discord.gg/dCzT9XHEWu).
35 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id "java-gradle-plugin"
3 | id "base.base-conventions"
4 | id "class-token-replacer.publishing-conventions"
5 | id "com.gradle.plugin-publish" version "1.3.1"
6 | }
7 |
8 | dependencies {
9 | compileOnly gradleApi()
10 |
11 | api "org.ow2.asm:asm-commons:9.8"
12 | }
13 |
14 | gradlePlugin {
15 | website = "https://github.com/RaphiMC/ClassTokenReplacer"
16 | vcsUrl = "https://github.com/RaphiMC/ClassTokenReplacer"
17 | plugins {
18 | classtokenreplacer {
19 | id = "net.raphimc.class-token-replacer"
20 | implementationClass = "net.raphimc.classtokenreplacer.ClassTokenReplacerPlugin"
21 | displayName = "ClassTokenReplacer"
22 | description = "Gradle plugin to replace string tokens in class files during compile time"
23 | tags.addAll("replacement", "token replacement")
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/buildSrc/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id "groovy-gradle-plugin"
3 | }
4 |
5 | repositories {
6 | gradlePluginPortal()
7 | }
8 |
--------------------------------------------------------------------------------
/buildSrc/src/main/groovy/base.base-conventions.gradle:
--------------------------------------------------------------------------------
1 | base {
2 | java.toolchain.languageVersion = JavaLanguageVersion.of(project.java_version)
3 |
4 | group = project.maven_group
5 | archivesName = project.name
6 | version = project.maven_version
7 | }
8 |
9 | repositories {
10 | mavenCentral()
11 | }
12 |
13 | jar {
14 | if (layout.projectDirectory.file("LICENSE").asFile.exists()) {
15 | def projectName = project.name
16 | from(layout.projectDirectory.file("LICENSE")) {
17 | rename { "${it}_${projectName}" }
18 | }
19 | } else if (rootProject.layout.projectDirectory.file("LICENSE").asFile.exists()) {
20 | def projectName = rootProject.name
21 | from(rootProject.layout.projectDirectory.file("LICENSE")) {
22 | rename { "${it}_${projectName}" }
23 | }
24 | }
25 | }
26 |
27 | tasks.withType(JavaCompile).configureEach {
28 | it.options.encoding = "UTF-8"
29 | }
30 |
31 | tasks.withType(Javadoc).configureEach {
32 | it.options.encoding = "UTF-8"
33 | it.options.addStringOption("Xdoclint:none", "-quiet")
34 | }
35 |
--------------------------------------------------------------------------------
/buildSrc/src/main/groovy/base.lenni0451-maven-publishing.gradle:
--------------------------------------------------------------------------------
1 | publishing {
2 | repositories {
3 | maven {
4 | name = "reposilite"
5 | url = "https://maven.lenni0451.net/" + (project.maven_version.endsWith("SNAPSHOT") ? "snapshots" : "releases")
6 |
7 | credentials(PasswordCredentials)
8 | authentication {
9 | basic(BasicAuthentication)
10 | }
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/buildSrc/src/main/groovy/class-token-replacer.publishing-conventions.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id "maven-publish"
3 | id "signing"
4 | id "base.lenni0451-maven-publishing"
5 | }
6 |
7 | java {
8 | withSourcesJar()
9 | withJavadocJar()
10 | }
11 |
12 | publishing {
13 | publications {
14 | pluginMaven(MavenPublication) {
15 | pom {
16 | name = "ClassTokenReplacer"
17 | description = "Gradle plugin to replace string tokens in class files during compile time"
18 | url = "https://github.com/RaphiMC/ClassTokenReplacer"
19 | licenses {
20 | license {
21 | name = "LGPL-3.0 License"
22 | url = "https://github.com/RaphiMC/ClassTokenReplacer/blob/main/LICENSE"
23 | }
24 | }
25 | developers {
26 | developer {
27 | id = "RK_01"
28 | }
29 | }
30 | scm {
31 | connection = "scm:git:git://github.com/RaphiMC/ClassTokenReplacer.git"
32 | developerConnection = "scm:git:ssh://github.com/RaphiMC/ClassTokenReplacer.git"
33 | url = "https://github.com/RaphiMC/ClassTokenReplacer.git"
34 | }
35 | }
36 | }
37 | }
38 | }
39 |
40 | signing {
41 | setRequired(false)
42 | sign(publishing.publications.pluginMaven)
43 | }
44 |
45 | tasks.withType(PublishToMavenRepository).configureEach {
46 | it.dependsOn(tasks.withType(Sign))
47 | }
48 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.daemon=true
2 | org.gradle.parallel=true
3 | org.gradle.configuration-cache=false
4 |
5 | java_version=8
6 | maven_group=net.raphimc
7 | maven_name=ClassTokenReplacer
8 | maven_version=1.1.7-SNAPSHOT
9 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaphiMC/ClassTokenReplacer/9988e001ddf77a1dc40dd4d0d723428a5f9ea01a/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionSha256Sum=845952a9d6afa783db70bb3b0effaae45ae5542ca2bb7929619e8af49cb634cf
4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.1-bin.zip
5 | networkTimeout=10000
6 | validateDistributionUrl=true
7 | zipStoreBase=GRADLE_USER_HOME
8 | zipStorePath=wrapper/dists
9 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | #
4 | # Copyright © 2015-2021 the original authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 | # SPDX-License-Identifier: Apache-2.0
19 | #
20 |
21 | ##############################################################################
22 | #
23 | # Gradle start up script for POSIX generated by Gradle.
24 | #
25 | # Important for running:
26 | #
27 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
28 | # noncompliant, but you have some other compliant shell such as ksh or
29 | # bash, then to run this script, type that shell name before the whole
30 | # command line, like:
31 | #
32 | # ksh Gradle
33 | #
34 | # Busybox and similar reduced shells will NOT work, because this script
35 | # requires all of these POSIX shell features:
36 | # * functions;
37 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
38 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»;
39 | # * compound commands having a testable exit status, especially «case»;
40 | # * various built-in commands including «command», «set», and «ulimit».
41 | #
42 | # Important for patching:
43 | #
44 | # (2) This script targets any POSIX shell, so it avoids extensions provided
45 | # by Bash, Ksh, etc; in particular arrays are avoided.
46 | #
47 | # The "traditional" practice of packing multiple parameters into a
48 | # space-separated string is a well documented source of bugs and security
49 | # problems, so this is (mostly) avoided, by progressively accumulating
50 | # options in "$@", and eventually passing that to Java.
51 | #
52 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
53 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
54 | # see the in-line comments for details.
55 | #
56 | # There are tweaks for specific operating systems such as AIX, CygWin,
57 | # Darwin, MinGW, and NonStop.
58 | #
59 | # (3) This script is generated from the Groovy template
60 | # https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
61 | # within the Gradle project.
62 | #
63 | # You can find Gradle at https://github.com/gradle/gradle/.
64 | #
65 | ##############################################################################
66 |
67 | # Attempt to set APP_HOME
68 |
69 | # Resolve links: $0 may be a link
70 | app_path=$0
71 |
72 | # Need this for daisy-chained symlinks.
73 | while
74 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
75 | [ -h "$app_path" ]
76 | do
77 | ls=$( ls -ld "$app_path" )
78 | link=${ls#*' -> '}
79 | case $link in #(
80 | /*) app_path=$link ;; #(
81 | *) app_path=$APP_HOME$link ;;
82 | esac
83 | done
84 |
85 | # This is normally unused
86 | # shellcheck disable=SC2034
87 | APP_BASE_NAME=${0##*/}
88 | # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
89 | APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
90 |
91 | # Use the maximum available, or set MAX_FD != -1 to use that value.
92 | MAX_FD=maximum
93 |
94 | warn () {
95 | echo "$*"
96 | } >&2
97 |
98 | die () {
99 | echo
100 | echo "$*"
101 | echo
102 | exit 1
103 | } >&2
104 |
105 | # OS specific support (must be 'true' or 'false').
106 | cygwin=false
107 | msys=false
108 | darwin=false
109 | nonstop=false
110 | case "$( uname )" in #(
111 | CYGWIN* ) cygwin=true ;; #(
112 | Darwin* ) darwin=true ;; #(
113 | MSYS* | MINGW* ) msys=true ;; #(
114 | NONSTOP* ) nonstop=true ;;
115 | esac
116 |
117 | CLASSPATH="\\\"\\\""
118 |
119 |
120 | # Determine the Java command to use to start the JVM.
121 | if [ -n "$JAVA_HOME" ] ; then
122 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
123 | # IBM's JDK on AIX uses strange locations for the executables
124 | JAVACMD=$JAVA_HOME/jre/sh/java
125 | else
126 | JAVACMD=$JAVA_HOME/bin/java
127 | fi
128 | if [ ! -x "$JAVACMD" ] ; then
129 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
130 |
131 | Please set the JAVA_HOME variable in your environment to match the
132 | location of your Java installation."
133 | fi
134 | else
135 | JAVACMD=java
136 | if ! command -v java >/dev/null 2>&1
137 | then
138 | die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
139 |
140 | Please set the JAVA_HOME variable in your environment to match the
141 | location of your Java installation."
142 | fi
143 | fi
144 |
145 | # Increase the maximum file descriptors if we can.
146 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
147 | case $MAX_FD in #(
148 | max*)
149 | # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
150 | # shellcheck disable=SC2039,SC3045
151 | MAX_FD=$( ulimit -H -n ) ||
152 | warn "Could not query maximum file descriptor limit"
153 | esac
154 | case $MAX_FD in #(
155 | '' | soft) :;; #(
156 | *)
157 | # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
158 | # shellcheck disable=SC2039,SC3045
159 | ulimit -n "$MAX_FD" ||
160 | warn "Could not set maximum file descriptor limit to $MAX_FD"
161 | esac
162 | fi
163 |
164 | # Collect all arguments for the java command, stacking in reverse order:
165 | # * args from the command line
166 | # * the main class name
167 | # * -classpath
168 | # * -D...appname settings
169 | # * --module-path (only if needed)
170 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
171 |
172 | # For Cygwin or MSYS, switch paths to Windows format before running java
173 | if "$cygwin" || "$msys" ; then
174 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
175 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
176 |
177 | JAVACMD=$( cygpath --unix "$JAVACMD" )
178 |
179 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
180 | for arg do
181 | if
182 | case $arg in #(
183 | -*) false ;; # don't mess with options #(
184 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
185 | [ -e "$t" ] ;; #(
186 | *) false ;;
187 | esac
188 | then
189 | arg=$( cygpath --path --ignore --mixed "$arg" )
190 | fi
191 | # Roll the args list around exactly as many times as the number of
192 | # args, so each arg winds up back in the position where it started, but
193 | # possibly modified.
194 | #
195 | # NB: a `for` loop captures its iteration list before it begins, so
196 | # changing the positional parameters here affects neither the number of
197 | # iterations, nor the values presented in `arg`.
198 | shift # remove old arg
199 | set -- "$@" "$arg" # push replacement arg
200 | done
201 | fi
202 |
203 |
204 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
205 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
206 |
207 | # Collect all arguments for the java command:
208 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
209 | # and any embedded shellness will be escaped.
210 | # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
211 | # treated as '${Hostname}' itself on the command line.
212 |
213 | set -- \
214 | "-Dorg.gradle.appname=$APP_BASE_NAME" \
215 | -classpath "$CLASSPATH" \
216 | -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
217 | "$@"
218 |
219 | # Stop when "xargs" is not available.
220 | if ! command -v xargs >/dev/null 2>&1
221 | then
222 | die "xargs is not available"
223 | fi
224 |
225 | # Use "xargs" to parse quoted args.
226 | #
227 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed.
228 | #
229 | # In Bash we could simply go:
230 | #
231 | # readarray ARGS < <( xargs -n1 <<<"$var" ) &&
232 | # set -- "${ARGS[@]}" "$@"
233 | #
234 | # but POSIX shell has neither arrays nor command substitution, so instead we
235 | # post-process each arg (as a line of input to sed) to backslash-escape any
236 | # character that might be a shell metacharacter, then use eval to reverse
237 | # that process (while maintaining the separation between arguments), and wrap
238 | # the whole thing up as a single "set" statement.
239 | #
240 | # This will of course break if any of these variables contains a newline or
241 | # an unmatched quote.
242 | #
243 |
244 | eval "set -- $(
245 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
246 | xargs -n1 |
247 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
248 | tr '\n' ' '
249 | )" '"$@"'
250 |
251 | exec "$JAVACMD" "$@"
252 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 | @rem SPDX-License-Identifier: Apache-2.0
17 | @rem
18 |
19 | @if "%DEBUG%"=="" @echo off
20 | @rem ##########################################################################
21 | @rem
22 | @rem Gradle startup script for Windows
23 | @rem
24 | @rem ##########################################################################
25 |
26 | @rem Set local scope for the variables with windows NT shell
27 | if "%OS%"=="Windows_NT" setlocal
28 |
29 | set DIRNAME=%~dp0
30 | if "%DIRNAME%"=="" set DIRNAME=.
31 | @rem This is normally unused
32 | set APP_BASE_NAME=%~n0
33 | set APP_HOME=%DIRNAME%
34 |
35 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
36 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
37 |
38 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
39 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
40 |
41 | @rem Find java.exe
42 | if defined JAVA_HOME goto findJavaFromJavaHome
43 |
44 | set JAVA_EXE=java.exe
45 | %JAVA_EXE% -version >NUL 2>&1
46 | if %ERRORLEVEL% equ 0 goto execute
47 |
48 | echo. 1>&2
49 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
50 | echo. 1>&2
51 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2
52 | echo location of your Java installation. 1>&2
53 |
54 | goto fail
55 |
56 | :findJavaFromJavaHome
57 | set JAVA_HOME=%JAVA_HOME:"=%
58 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
59 |
60 | if exist "%JAVA_EXE%" goto execute
61 |
62 | echo. 1>&2
63 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
64 | echo. 1>&2
65 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2
66 | echo location of your Java installation. 1>&2
67 |
68 | goto fail
69 |
70 | :execute
71 | @rem Setup the command line
72 |
73 | set CLASSPATH=
74 |
75 |
76 | @rem Execute Gradle
77 | "%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" %*
78 |
79 | :end
80 | @rem End local scope for the variables with windows NT shell
81 | if %ERRORLEVEL% equ 0 goto mainEnd
82 |
83 | :fail
84 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
85 | rem the _cmd.exe /c_ return code!
86 | set EXIT_CODE=%ERRORLEVEL%
87 | if %EXIT_CODE% equ 0 set EXIT_CODE=1
88 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
89 | exit /b %EXIT_CODE%
90 |
91 | :mainEnd
92 | if "%OS%"=="Windows_NT" endlocal
93 |
94 | :omega
95 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | repositories {
3 | mavenCentral()
4 | gradlePluginPortal()
5 | }
6 | }
7 |
8 | plugins {
9 | id "org.gradle.toolchains.foojay-resolver-convention" version "1.0.0"
10 | }
11 |
12 | rootProject.name = "ClassTokenReplacer"
13 |
--------------------------------------------------------------------------------
/src/main/java/net/raphimc/classtokenreplacer/ClassTokenReplacerPlugin.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of ClassTokenReplacer - https://github.com/RaphiMC/ClassTokenReplacer
3 | * Copyright (C) 2023-2025 RK_01/RaphiMC and contributors
4 | *
5 | * This program is free software; you can redistribute it and/or
6 | * modify it under the terms of the GNU Lesser General Public
7 | * License as published by the Free Software Foundation; either
8 | * version 3 of the License, or (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package net.raphimc.classtokenreplacer;
19 |
20 | import net.raphimc.classtokenreplacer.extension.ClassTokenReplacerExtension;
21 | import net.raphimc.classtokenreplacer.extension.ClassTokenReplacerExtensionImpl;
22 | import net.raphimc.classtokenreplacer.task.ReplaceTokensTask;
23 | import org.gradle.api.Plugin;
24 | import org.gradle.api.Project;
25 | import org.gradle.api.Task;
26 | import org.gradle.api.file.RegularFile;
27 | import org.gradle.api.tasks.SourceSetContainer;
28 | import org.gradle.api.tasks.TaskProvider;
29 | import org.gradle.jvm.tasks.Jar;
30 | import org.jetbrains.annotations.NotNull;
31 |
32 | import java.io.File;
33 |
34 | public class ClassTokenReplacerPlugin implements Plugin {
35 |
36 | @Override
37 | public void apply(@NotNull Project project) {
38 | final SourceSetContainer sourceSets = project.getExtensions().getByType(SourceSetContainer.class);
39 | sourceSets.configureEach(set -> {
40 | final ClassTokenReplacerExtension extension = set.getExtensions().create(ClassTokenReplacerExtension.class, "classTokenReplacer", ClassTokenReplacerExtensionImpl.class, project.getObjects());
41 |
42 | final TaskProvider replaceTokensTaskProvider = project.getTasks().register(set.getTaskName("replace", "tokens"), ReplaceTokensTask.class, task -> {
43 | task.getClassesDirs().set(set.getOutput().getClassesDirs());
44 | task.getProperties().set(extension.getProperties());
45 | task.getReplaceInPlace().set(extension.getReplaceInPlace());
46 | task.getOutputDir().set(project.getLayout().getBuildDirectory().dir("classTokenReplacer/" + set.getName()).get().getAsFile());
47 | });
48 | final ReplaceTokensTask replaceTokensTask = replaceTokensTaskProvider.get();
49 | replaceTokensTask.dependsOn(set.getClassesTaskName());
50 |
51 | if (!extension.getReplaceInPlace().get()) {
52 | final Jar jarTask = (Jar) project.getTasks().findByName(set.getJarTaskName());
53 | if (jarTask != null) {
54 | final RegularFile replacedClassesDir = replaceTokensTask.getOutputDir().get();
55 | jarTask.dependsOn(replaceTokensTask);
56 | jarTask.from(replacedClassesDir);
57 | jarTask.exclude(fileTreeElement -> {
58 | final File modifiedFile = fileTreeElement.getRelativePath().getFile(replacedClassesDir.getAsFile());
59 | if (modifiedFile.equals(fileTreeElement.getFile())) {
60 | return false;
61 | }
62 | return modifiedFile.isFile();
63 | });
64 | }
65 | } else {
66 | final Task classesTask = project.getTasks().findByName(set.getClassesTaskName());
67 | if (classesTask != null) {
68 | classesTask.finalizedBy(replaceTokensTask);
69 | }
70 | }
71 | });
72 | }
73 |
74 | }
75 |
--------------------------------------------------------------------------------
/src/main/java/net/raphimc/classtokenreplacer/extension/ClassTokenReplacerExtension.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of ClassTokenReplacer - https://github.com/RaphiMC/ClassTokenReplacer
3 | * Copyright (C) 2023-2025 RK_01/RaphiMC and contributors
4 | *
5 | * This program is free software; you can redistribute it and/or
6 | * modify it under the terms of the GNU Lesser General Public
7 | * License as published by the Free Software Foundation; either
8 | * version 3 of the License, or (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package net.raphimc.classtokenreplacer.extension;
19 |
20 | import org.gradle.api.provider.MapProperty;
21 | import org.gradle.api.provider.Property;
22 | import org.gradle.api.provider.Provider;
23 | import org.gradle.api.tasks.Input;
24 | import org.jetbrains.annotations.NotNull;
25 |
26 | public interface ClassTokenReplacerExtension {
27 |
28 | @Input
29 | @NotNull
30 | MapProperty getProperties();
31 |
32 | default void property(final String property, final Object value) {
33 | this.getProperties().put(property, value);
34 | }
35 |
36 | default void property(final String property, final Provider