diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d860a86..4faf6d7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -42,5 +42,5 @@ jobs: run: mvn test - name: Running the example - run: java -cp "./rust-maven-example/target/rust-maven-example-1.0.0-SNAPSHOT.jar${{ matrix.path-sep }}./jar-jni/target/jar-jni-1.0.0-SNAPSHOT.jar" io.questdb.example.rust.Main + run: java -cp "./rust-maven-example/target/*${{ matrix.path-sep }}./jar-jni/target/*" io.questdb.example.rust.Main diff --git a/DEV_NOTES.md b/DEV_NOTES.md new file mode 100644 index 0000000..db2b312 --- /dev/null +++ b/DEV_NOTES.md @@ -0,0 +1,54 @@ +# Developer's Notes + +## Building + +To build the project and run the example: + +```shell +git clone https://github.com/questdb/rust-maven-plugin.git +cd rust-maven-plugin +mvn clean package +java -cp "./rust-maven-example/target/*:./jar-jni/target/*" io.questdb.example.rust.Main +``` + +_(Substituting `:` for `;` if developing on Windows)_ + +## Testing Against Another Project + +To test your changes against another project you need to install +the `jar-jni` and `rust-maven-plugin` artifacts locally in your Maven cache: + +```shell +cd jar-jni +mnv clean install +cd ../rust-maven-plugin +mvn clean install +``` + +## Cutting a new release + +### Maven Upload + +To cut a new release and upload to Maven Central, run: + +``` +mvn -B release:prepare release:perform +``` + +Here the `-B` flag will bump up the release version automatically. +The bump is a patch release, e.g. `1.0.1` to `1.0.2`. + +For full docs, see https://maven.apache.org/maven-release/maven-release-plugin/examples/prepare-release.html. + +### Updating `README.md`. + +The documentation in `README.md` mentions the version explicitly. + +To update it and discourage the use of old versions, run the +`update_doc_version.py` script. + +``` +python3 update_doc_version.py +``` + +This will make changes without checking them in. diff --git a/README.md b/README.md index 27f11c0..dacd234 100644 --- a/README.md +++ b/README.md @@ -35,8 +35,8 @@ $ mvn clean package For your convenience, we've also made `jar-jni` available: An optional Java library to load JNI dynamic libraries from JARs. -Both the plugin and the library support a directory naming convention structure to support compiling -for a multitude of platforms. +Both the plugin and the library support a common directory naming convention +to organize and find compiled artifacts for a multitude of platforms. # Complete Example See the [`rust-maven-example`](rust-maven-example/) directory for a working @@ -58,7 +58,7 @@ Edit your `pom.xml` to add the plugin: - io.questdb + org.questdb rust-maven-plugin 1.0.0-SNAPSHOT @@ -142,6 +142,9 @@ Accepted values are: The plugin can be configured to build in release mode by setting `true` in the `` block. +Building `--release` will cut down binary size considerably and should be taken +into consideration when shipping binaries in `.jar` files. + ## Specifying Crate Features The equivalent of `cargo build --features feat1,feat2,feat3` is @@ -157,6 +160,30 @@ The equivalent of `cargo build --features feat1,feat2,feat3` is You can also specify `--all-features` via `true` and `--no-default-features` via `true`. +Note that you can drive features with maven profiles by introducing variables. + +```xml + + + $rustFeature1 + $rustFeature2 + +``` + +```xml + + + feat-ssl + + ssl + use-rustls + + +``` + +Then building with `mvn package -P feat-ssl` will call +`cargo build --features ssl,use-rustls`. + ## Additional cargo arguments Additional arguments to can go in the `` configuration section. @@ -190,8 +217,8 @@ directory, via `cargo build --target-dir ...`. # De-duplicating build directories when invoking `cargo build` without Maven If you (or your IDE) end up invoking `cargo build` on your Rust crate without -the plugin, you'll notice this creates a duplicate `target` dir that will not -be cleaned at the next `mvn clean`. +the plugin, you'll notice this creates a duplicate `target` dir, inside the +crate's directory, that will not be cleaned at the next `mvn clean`. To avoid this duplicate `target` directory problem, consider adding `.cargo/config.toml` files configured to match the `--target-dir` argument @@ -202,9 +229,10 @@ from the `str-reverse` crate in the example. # Bundling binaries in the `.jar` file -The `` configuration allows copying the binaries anywhere. The example -however choses to copy them to `${project.build.directory}/classes/...`. -Anything placed there gets bundled in the JAR file. +The `` configuration (as shown in the example) allows copying the +binaries any path. The example however choses to copy them to +`${project.build.directory}/classes/...`. Anything placed there gets bundled +into the JAR file. The `classes` directory sits within the `target` directory and outside of the source tree. @@ -238,13 +266,13 @@ code when you need to. - io.questdb + org.questdb rust-maven-plugin 1.0.0-SNAPSHOT ... ``` -You can then enable the profile in Maven via `mvn clean package -Prust ...`. +You can then enable the profile in Maven via `mvn clean package -P rust ...`. ## Supporting Multiple Platforms @@ -273,7 +301,7 @@ The `jar-jni` library is configured as so: ... - io.questdb + org.questdb jar-jni 1.0.0-SNAPSHOT @@ -319,29 +347,5 @@ JarJniLoader.loadLib( If you want to talk to us, we're on [Slack](https://slack.questdb.io/). -## Building - -To build the project and run the example: - -```shell -git clone https://github.com/questdb/rust-maven-plugin.git -cd rust-maven-plugin -mvn clean package -java -cp "./rust-maven-example/target/rust-maven-example-1.0.0-SNAPSHOT.jar:./jar-jni/target/jar-jni-1.0.0-SNAPSHOT.jar" io.questdb.example.rust.Main -``` - -## Testing Against Another Project - -For test your changes against another project you need to install the `jar-jni` and `rust-maven-plugin` artifacts locally in your Maven cache: - -```shell -cd jar-jni -mnv clean install -cd ../rust-maven-plugin -mvn clean install -``` - -## Thanks to - -* OktaDev for covering custom Maven plugins on YouTube https://www.youtube.com/watch?v=wHX4j0z-sUU - It's a great introduction to Maven plugins. -* The CMake maven plugin project https://github.com/cmake-maven-project/cmake-maven-project for inspiration. +Also read the [Developer's Notes](DEV_NOTES.md) with instructions on building +and running from source. diff --git a/jar-jni/pom.xml b/jar-jni/pom.xml index 642c501..2d309ec 100644 --- a/jar-jni/pom.xml +++ b/jar-jni/pom.xml @@ -22,11 +22,10 @@ ~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~--> - 4.0.0 - io.questdb + org.questdb jar-jni 1.0.0-SNAPSHOT jar @@ -52,19 +51,9 @@ https://github.com/questdb/rust-maven-plugin scm:git:https://github.com/questdb/rust-maven-plugin.git - scm:git:git@github.com:questdb/rust-maven-plugin.git + scm:git:https://github.com/questdb/rust-maven-plugin.git HEAD - - - central - https://oss.sonatype.org/content/repositories/snapshots - - - central - https://oss.sonatype.org/service/local/staging/deploy/maven2 - - 1.8 @@ -76,6 +65,74 @@ + + maven-central-release + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.5.0 + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-source-plugin + 3.0.1 + + + attach-sources + + jar + + + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.6 + + + sign-artifacts + verify + + sign + + + + + gpg + + + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.3 + + + default-deploy + deploy + + deploy + + + + + central + https://oss.sonatype.org + + + + + java-module @@ -106,10 +163,11 @@ + destdir="${java9.build.outputDirectory}" + classpath="${project.build.outputDirectory}" + includeantruntime="false" + source="9" + target="9"/> @@ -127,7 +185,8 @@ copy-resources - ${project.build.outputDirectory}/META-INF/versions/9 + ${project.build.outputDirectory}/META-INF/versions/9 + ${java9.build.outputDirectory} @@ -153,4 +212,15 @@ + + + + central + https://oss.sonatype.org/content/repositories/snapshots + + + central + https://oss.sonatype.org/service/local/staging/deploy/maven2 + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 04cbeb6..f40aaea 100644 --- a/pom.xml +++ b/pom.xml @@ -22,12 +22,11 @@ ~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~--> - + 4.0.0 1.0.0-SNAPSHOT - io.questdb + org.questdb rust-maven pom Rust Maven @@ -37,4 +36,40 @@ rust-maven-example jar-jni + + + true + true + + + + + QuestDB Team + hello@questdb.io + + + + + https://github.com/questdb/rust-maven-plugin + scm:git:https://github.com/questdb/rust-maven-plugin.git + scm:git:https://github.com/questdb/rust-maven-plugin.git + HEAD + + + + + + + org.apache.maven.plugins + maven-release-plugin + 2.5.3 + + @{project.version} + -Dmaven.test.skipTests=true -Dmaven.test.skip=true + maven-central-release + + + + + diff --git a/rust-maven-example/pom.xml b/rust-maven-example/pom.xml index a2a26e9..9a78f34 100644 --- a/rust-maven-example/pom.xml +++ b/rust-maven-example/pom.xml @@ -22,11 +22,10 @@ ~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~--> - + 4.0.0 - io.questdb + org.questdb rust-maven-example 1.0.0-SNAPSHOT jar @@ -39,13 +38,22 @@ 1.8 UTF-8 UTF-8 + true + true + + https://github.com/questdb/rust-maven-plugin + scm:git:https://github.com/questdb/rust-maven-plugin.git + scm:git:https://github.com/questdb/rust-maven-plugin.git + HEAD + + - io.questdb + org.questdb jar-jni - 1.0.0-SNAPSHOT + ${project.version} junit @@ -64,9 +72,9 @@ Placing it there will have Maven automatically bundle the compiled code in the Jar. --> - io.questdb + org.questdb rust-maven-plugin - 1.0.0-SNAPSHOT + ${project.version} str-reverse diff --git a/rust-maven-plugin/pom.xml b/rust-maven-plugin/pom.xml index 6e2ab63..74a29c9 100644 --- a/rust-maven-plugin/pom.xml +++ b/rust-maven-plugin/pom.xml @@ -22,13 +22,10 @@ ~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~--> - + 4.0.0 - io.questdb + org.questdb rust-maven-plugin 1.0.0-SNAPSHOT maven-plugin @@ -54,19 +51,9 @@ https://github.com/questdb/rust-maven-plugin scm:git:https://github.com/questdb/rust-maven-plugin.git - scm:git:git@github.com:questdb/rust-maven-plugin.git + scm:git:https://github.com/questdb/rust-maven-plugin.git HEAD - - - central - https://oss.sonatype.org/content/repositories/snapshots - - - central - https://oss.sonatype.org/service/local/staging/deploy/maven2 - - 1.8 @@ -75,11 +62,82 @@ UTF-8 + + + maven-central-release + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.5.0 + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-source-plugin + 3.0.1 + + + attach-sources + + jar + + + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.6 + + + sign-artifacts + verify + + sign + + + + + gpg + + + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.3 + + + default-deploy + deploy + + deploy + + + + + central + https://oss.sonatype.org + + + + + + + - io.questdb + org.questdb jar-jni - 1.0.0-SNAPSHOT + ${project.version} org.apache.maven @@ -128,4 +186,15 @@ + + + + central + https://oss.sonatype.org/content/repositories/snapshots + + + central + https://oss.sonatype.org/service/local/staging/deploy/maven2 + + diff --git a/rust-maven-plugin/src/main/java/io/questdb/maven/rust/Crate.java b/rust-maven-plugin/src/main/java/io/questdb/maven/rust/Crate.java index 125d4f9..bd72a06 100644 --- a/rust-maven-plugin/src/main/java/io/questdb/maven/rust/Crate.java +++ b/rust-maven-plugin/src/main/java/io/questdb/maven/rust/Crate.java @@ -398,7 +398,7 @@ private void addCargoArgs(List args) { if (params.features != null && params.features.length > 0) { args.add("--features"); - args.add(String.join(",", params.features)); + args.add(String.join(",", params.cleanedFeatures())); } if (params.tests) { @@ -497,5 +497,21 @@ public static class Params { public String[] extraArgs; public Path copyToDir; public boolean copyWithPlatformDir; + + /** + * Returns the features array with empty and null elements removed. + */ + public String[] cleanedFeatures() { + List cleanedFeatures = new ArrayList<>(); + for (String feature : features) { + if (feature != null) { + feature = feature.trim(); + if (!feature.isEmpty()) { + cleanedFeatures.add(feature); + } + } + } + return cleanedFeatures.toArray(new String[0]); + } } } diff --git a/change_version.py b/update_doc_version.py similarity index 78% rename from change_version.py rename to update_doc_version.py index 9eb92ad..49bd645 100755 --- a/change_version.py +++ b/update_doc_version.py @@ -3,11 +3,8 @@ import argparse import pathlib import difflib - - -# Running this script will also update the version number in this file. -# Do not edit manually. -CURRENT_VERSION = '1.0.0-SNAPSHOT' +import xml.etree.ElementTree as ET +import re # Table of file names to strings to match and replace. @@ -15,26 +12,14 @@ # during both matching and replacing. # All paths are relative to the root of the repository. MATCHERS = { - 'change_version.py': - ["CURRENT_VERSION = '$$VERSION$$'"], - 'pom.xml': - ["$$VERSION$$"], 'README.md': ["rust-maven-plugin:$$VERSION$$:build", - "$$VERSION$$", - "-$$VERSION$$.jar"], - 'jar-jni/pom.xml': - ["$$VERSION$$"], - 'rust-maven-plugin/pom.xml': - ["$$VERSION$$"], - 'rust-maven-example/pom.xml': - ["$$VERSION$$"], + "$$VERSION$$"], } def parse_args(): parser = argparse.ArgumentParser() - parser.add_argument('version', help='Version number to change to') parser.add_argument('-p', '--preview', action='store_true', help='Preview changes without making them') parser.add_argument('-n', '--num-lines', type=int, default=3, @@ -44,8 +29,26 @@ def parse_args(): return parser.parse_args() +def get_old_vers(): + with open('README.md', 'r', encoding='utf-8') as f: + contents = f.read() + pat = re.compile(r'.*rust-maven-plugin:(.*?):build.*') + for line in contents.splitlines(): + match = pat.search(line) + if match: + return match.group(1) + raise RuntimeError('Could not find old version in README.md') + + +def get_new_vers(): + tree = ET.parse('rust-maven-plugin/pom.xml') + return tree.getroot().find('./{*}version').text + + def main(): args = parse_args() + old_vers = get_old_vers() + new_vers = get_new_vers() old_contents = {} new_contents = {} for filename, matchers in MATCHERS.items(): @@ -55,8 +58,8 @@ def main(): old_contents[file_path] = contents for matcher in matchers: - old_version_text = matcher.replace('$$VERSION$$', CURRENT_VERSION) - new_version_text = matcher.replace('$$VERSION$$', args.version) + old_version_text = matcher.replace('$$VERSION$$', old_vers) + new_version_text = matcher.replace('$$VERSION$$', new_vers) if old_version_text not in contents: raise RuntimeError( 'Could not find "{}" in file "{}"'.format(