Raven
First off, the name is not a play on Rust + maven, but maven and my uni's
mascot.
Second, this is meant to be a simple tool to manage simple Java projects from the command line with sanity.
It takes inspiration from Cargo, and essentially serves as a sanity-preserving
wrapper for javac and java.
Because of the Rust-originating concepts, Raven is opinionated. If you have a major problem with Rust, look away. If you genuinely intend on using Raven, probably still look away. This likely won't enter any form of mainstream or active long-term support.
Installing
Installing with cargo:
cargo install --git https://gitea.cutieguwu.ca/Cutieguwu/raven.git --branch master
raven will likely fall back to panicking in various scenarios. This will be
worked out over time.
raven is only tested under linux. NT and Darwin support is not guaranteed.
WSL may affect the behaviour of Raven. Quirks to be worked out.
Getting Started
raven new demo
cd demo
raven run main
Raven commands
Usage: raven <COMMAND>
Commands:
new Create a new raven project
init Create a new raven project in an existing directory
build Compile the current project
run Run the current project
test !!! BORKED !!! Run the tests
clean Remove the target directory and caching
help Print this message or the help of the given subcommand(s)
Options:
-h, --help Print help
-V, --version Print version
Future plans
- Make
raven runfall back to an entry point specified in Nest.toml, when none provided. - Fix project structure, eliminate inter-dependencies.
- Separate out
java.rsinto a dedicated wrapper library.
- Separate out
- Possibly add support for pulling remote packages via
raven add. This will be implemented should there arise a need. - Wrap errors properly, instead of hap-hazardly using
anyhow - Maybe proper logging?
Project Structure
It helps if you're starting from an understanding of a Cargo Workspace.
- Workspace: The top level of a project. A workspace contains a series of packages.
- Package: An individual library or binary which possesses its own
Nest.tomlorpom.xml. This should be equivalent to Maven's concept of a module. - Module: Any organization of classes and modules which don't possess a
Nest.tomlorpom.xml.
If you're unfamiliar with a cargo workspace manifest,
An example workspace Nest:
[workspace]
default_package = "app"
members = [
"app",
"cli",
"core",
"installer",
"io",
]
[meta]
name = "myProject"
version = "0.1.0"
[dependencies]
cli = { path = "cli" }
core = { path = "core" }
io = { path = "io" }
Inheritance
Again, this takes from cargo's functionality.
To inherit from the workspace Nest (given the workspace example above):
[package]
entry_point = "Main.java"
[meta]
name = "app"
version = "0.1.0"
[dependnencies]
cli.workspace = true
io.workspace = true
Reverse Domain Name Notation
Raven prefers this be trashed, burned, and ground into the earth with your boot.
It is possible to work around this with workspace members and default entry points.
Raven feels little need to respect Java's standards.
Sub-modules
Given the structure:
WORKSPACE/packageA/packageB
If you want to have subpackages like maven permits (via submodules), it is technically possible by listing the submodule like so in the workspace members:
[workspace]
members = [
"packageA",
"packageA/packageB",
]
[dependencies]
packageA = { path = "packageA" }
[dependencies.packageA]
path = "packageA"
dependencies = { packageB = "packageA/packageB" }
Obviously, this is a total disaster, and is considered bad practise under Raven.
The project should be restructured to either:
- Have all packages immediately within the workspace (remove all nesting), or
- Move the complex package with subpackages out of tree into its own workspace and add it as a dependency with a relative path in the workspace Nest. The reason being, that packageA is so complex that it should be maintained as its own thing, and is realistically a fairly universal library.
For Option 1
Example workspace Nest:
[workspace]
members = [
"packageA",
"packageB",
]
[dependencies]
packageA = { path = "packageA" }
packageB = { path = "packageB" }
For Option 2
Example workspace Nest:
[dependencies]
packageA = { path = "external/packageA" }
Where packageA's workspace Nest:
[workspace]
members = [
"core",
"packageB"
]