Compare commits

1 Commits

7 changed files with 56 additions and 80 deletions

View File

@@ -2,27 +2,23 @@
name = "raven"
version = "0.1.0"
edition = "2024"
authors = ["Olivia Brooks", "Adrian Long"]
repository = "https://gitea.cutieguwu.ca/Cutieguwu/raven"
license = "MIT"
publish = false
[dependencies]
anyhow = "1.0"
bytesize = "2.3"
ron = "0.12"
sha256 = "1.6"
sha256 = "1.6.0"
subprocess = "0.2"
toml = "0.9"
[dependencies.clap]
version = "4.5"
features = ["cargo", "derive"]
[dependencies.semver]
version = "1.0"
features = ["serde"]
[dependencies.serde]
version = "1.0"
features =["derive"]
[dependencies.clap]
version = "4.5"
features = ["derive"]
[dependencies.semver]
version = "1.0"
features = ["serde"]

View File

@@ -32,29 +32,15 @@ cd demo
raven run main.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 run` fall back to an entry point specified in Nest.toml, when
- [ ] Fix `raven test`. Totally borked.
- [ ] Make `nest run` fall back to an entry point specified in Nest.toml, when
none provided.
- [ ] Fix project structure, eliminate inter-dependencies.
- [ ] Separate out `java.rs` into a dedicated wrapper library.
- [ ] Possibly add support for pulling remote packages via `raven add`. This
- [ ] Possibly add support for pulling remote packages via `nest add`. This
will be implemented should there arise a need.
- [ ] Wrap errors properly, instead of hap-hazardly using `anyhow`
- [ ] Maybe proper logging?
- [ ] Fix using hashes to avoid unnesscesary recompilation.

View File

@@ -1,3 +1,5 @@
package main;
public class Main {
public static void main(String[] args) {

View File

@@ -1,10 +1,12 @@
public class MainTest {
package test;
public class Main {
public static void main(String[] args) {
testAdd();
}
public static void testAdd() {
assert Main.add(2, 2) == 4;
assert main.Main.add(2, 2) == 4;
}
}

View File

@@ -5,8 +5,6 @@ use clap::{ArgAction, Parser, Subcommand};
pub static CONFIG: LazyLock<Args> = LazyLock::new(|| Args::parse());
#[derive(Debug, Parser)]
#[clap(author, version)]
#[command(help_template = "{author-section}\n{usage-heading} {usage}\n\n{all-args}")]
pub struct Args {
#[command(subcommand)]
pub command: Command,

View File

@@ -17,15 +17,11 @@ pub struct JVMBuilder {
monitor: bool,
ram_min: Option<ByteSize>,
ram_max: Option<ByteSize>,
class_path: PathBuf,
}
impl JVMBuilder {
pub fn new<P: AsRef<Path>>(class_path: P) -> Self {
Self {
class_path: class_path.as_ref().to_path_buf(),
..Default::default()
}
pub fn new() -> Self {
Self::default()
}
pub fn assertions(&mut self, assertions: bool) -> &mut Self {
@@ -50,9 +46,7 @@ impl JVMBuilder {
}
pub fn build(&self) -> JVM {
let mut flags = vec![VMFlag::Classpath {
path: self.class_path.to_owned(),
}];
let mut flags = vec![];
if self.assertions {
flags.push(VMFlag::EnableAssert);
@@ -91,8 +85,7 @@ impl JVM {
.into_iter()
.flat_map(|f| Into::<Vec<String>>::into(f)),
);
cmd.push(entry_point.as_ref().to_path_buf().display().to_string());
cmd.push(entry_point.as_ref().display().to_string());
let result = crate::io::run_process(cmd.as_slice());
@@ -117,7 +110,6 @@ impl JVM {
#[derive(Debug, Clone)]
pub enum VMFlag {
Classpath { path: PathBuf },
EnableAssert,
HeapMax { size: ByteSize },
HeapMin { size: ByteSize },
@@ -126,10 +118,12 @@ pub enum VMFlag {
impl Into<Vec<String>> for VMFlag {
fn into(self) -> Vec<String> {
self.to_string()
.split_ascii_whitespace()
.map(|s| s.to_string())
.collect()
match self {
Self::EnableAssert => vec![String::from("-ea")],
Self::HeapMax { size } => vec![format!("Xmx{}", size)],
Self::HeapMin { size } => vec![format!("Xms{}", size)],
Self::Version => vec![String::from("--version")],
}
}
}
@@ -141,10 +135,9 @@ impl fmt::Display for VMFlag {
f,
"-{}",
match self {
Self::Classpath { path } => format!("classpath {}", path.display()),
Self::EnableAssert => String::from("ea"),
Self::HeapMax { size } => format!("Xmx{}", size.as_u64()),
Self::HeapMin { size } => format!("Xms{}", size.as_u64()),
Self::HeapMax { size } => format!("Xmx{}", size),
Self::HeapMin { size } => format!("Xms{}", size),
Self::Version => String::from("-version"), // --version
}
)
@@ -220,14 +213,14 @@ impl Compiler {
#[derive(Debug, Clone)]
pub enum CompilerFlag {
Classpath { path: PathBuf },
Destination { path: PathBuf },
Classpath { path: PathBuf },
}
impl Into<Vec<String>> for CompilerFlag {
fn into(self) -> Vec<String> {
match self {
Self::Classpath { path } => vec!["-classpath".to_string(), path.display().to_string()],
Self::Classpath { path } => vec!["-cp".to_string(), path.display().to_string()],
Self::Destination { path } => vec!["-d".to_string(), path.display().to_string()],
}
}

View File

@@ -17,6 +17,14 @@ use nest::{Class, NEST, NestLock};
use anyhow::Context;
use bytesize::ByteSize;
const DIR_TARGET: LazyLock<PathBuf> = LazyLock::new(|| PathBuf::from("target/"));
const DIR_SRC: LazyLock<PathBuf> = LazyLock::new(|| PathBuf::from("src/"));
const DIR_MAIN: LazyLock<PathBuf> = LazyLock::new(|| DIR_SRC.join("main/"));
const DIR_TEST: LazyLock<PathBuf> = LazyLock::new(|| DIR_SRC.join("test/"));
const F_NEST_TOML: LazyLock<PathBuf> = LazyLock::new(|| PathBuf::from("Nest.toml"));
const F_NEST_LOCK: LazyLock<PathBuf> = LazyLock::new(|| PathBuf::from("Nest.lock"));
pub static PROJECT_ROOT: LazyLock<PathBuf> = LazyLock::new(|| {
// Start from CWD
let cwd = std::env::current_dir().expect("Failed to get current working directory");
@@ -36,14 +44,6 @@ pub static PROJECT_ROOT: LazyLock<PathBuf> = LazyLock::new(|| {
probe
});
const DIR_TARGET: LazyLock<PathBuf> = LazyLock::new(|| PROJECT_ROOT.join("target/"));
const DIR_SRC: LazyLock<PathBuf> = LazyLock::new(|| PROJECT_ROOT.join("src/"));
const DIR_MAIN: LazyLock<PathBuf> = LazyLock::new(|| DIR_SRC.join("main/"));
const DIR_TEST: LazyLock<PathBuf> = LazyLock::new(|| DIR_SRC.join("test/"));
const F_NEST_TOML: LazyLock<PathBuf> = LazyLock::new(|| PathBuf::from("Nest.toml"));
const F_NEST_LOCK: LazyLock<PathBuf> = LazyLock::new(|| PathBuf::from("Nest.lock"));
fn main() -> anyhow::Result<()> {
// Ensure that Nest.toml exists, if the requested command depends upon it.
if CONFIG.command.depends_on_nest() && NEST.is_err() {
@@ -91,7 +91,11 @@ fn init() -> anyhow::Result<()> {
.context("Unable to convert OsStr to str")?
.to_owned();
// ORDER MATTERS. THIS MUST COME FIRST.
// Make src, target, tests
for dir in [DIR_SRC, DIR_MAIN, DIR_TARGET, DIR_TEST] {
std::fs::create_dir_all(dir.clone())?;
}
// Make config file.
if let Result::Ok(mut f) = OpenOptions::new()
.write(true)
@@ -125,11 +129,6 @@ fn init() -> anyhow::Result<()> {
)?;
}
// Make src, target, tests
for dir in [DIR_SRC, DIR_MAIN, DIR_TARGET, DIR_TEST] {
std::fs::create_dir_all(dir.clone())?;
}
// Make src/main/Main.java
if let Result::Ok(mut f) = OpenOptions::new().write(true).create_new(is_empty).open(
DIR_MAIN
@@ -140,14 +139,14 @@ fn init() -> anyhow::Result<()> {
f.write_all(include_bytes!("../assets/src/main/Main.java"))?;
}
// Make src/test/MainTest.java
// Make src/test/Main.java
if let Result::Ok(mut f) = OpenOptions::new().write(true).create_new(is_empty).open(
DIR_TEST
.clone()
.join("MainTest")
.join("Main")
.with_extension(JAVA_EXT_SOURCE),
) {
f.write_all(include_bytes!("../assets/src/test/MainTest.java"))?;
f.write_all(include_bytes!("../assets/src/test/Main.java"))?;
}
// git init .
@@ -164,7 +163,7 @@ fn init() -> anyhow::Result<()> {
f.read_to_string(&mut buf)?;
for ignored in [
format!("{}/", DIR_TARGET.file_name().unwrap().display()),
DIR_TARGET.as_path().display().to_string(),
format!("*.{}", JAVA_EXT_CLASS),
] {
if !buf.contains(&ignored) {
@@ -186,7 +185,7 @@ fn new(project_name: String) -> anyhow::Result<()> {
}
fn build() -> anyhow::Result<()> {
let mut targets: Vec<PathBuf> = crate::fs::expand_files(DIR_SRC.as_path())?
let mut targets: Vec<PathBuf> = crate::fs::expand_files(PROJECT_ROOT.clone().join(DIR_SRC.as_path()))?
.into_iter()
.filter(|f| {
f.extension()
@@ -240,7 +239,7 @@ fn run<P: AsRef<Path>>(
// JRE pathing will be messed up without this.
crate::env::set_cwd(DIR_TARGET.as_path())?;
java::JVMBuilder::new(DIR_TARGET.as_path())
java::JVMBuilder::new()
.assertions(assertions)
.monitor(true)
.build()
@@ -255,18 +254,18 @@ fn test(assertions: bool) -> anyhow::Result<(Option<String>, Option<String>)> {
.compile(DIR_TEST.as_path())?;
// Change cwd to avoid Java pathing issues.
crate::env::set_cwd(DIR_TARGET.as_path())?;
crate::env::set_cwd(PROJECT_ROOT.join(DIR_TARGET.as_path()))?;
java::JVMBuilder::new(DIR_TARGET.as_path())
java::JVMBuilder::new()
.assertions(assertions)
.ram_min(ByteSize::mib(128))
.ram_max(ByteSize::mib(512))
.monitor(true)
.build()
.run(DIR_TARGET.as_path())
.run(DIR_TEST.as_path())
}
fn clean() {
let _ = std::fs::remove_file(PROJECT_ROOT.join(F_NEST_LOCK.as_path()));
let _ = std::fs::remove_dir_all(DIR_TARGET.join("/*").as_path());
let _ = std::fs::remove_dir_all(PROJECT_ROOT.join(DIR_TARGET.as_path()));
}