Compare commits
19 Commits
80e5a27c20
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
54e6350d42 | ||
|
|
f3f79a12df | ||
|
|
649507bbcb | ||
| 676b0b606b | |||
| 82b45d9c66 | |||
| 05390a8f0b | |||
| 6da7586c3e | |||
| 3deedb2f7f | |||
|
|
3db0f53943 | ||
|
|
b5c4f61c8a | ||
|
|
aa851f7616 | ||
|
|
dafc6ea885 | ||
|
|
f6a6d54992 | ||
|
|
a0b75edab3 | ||
|
|
91bf7769b4 | ||
|
|
56a86b371a | ||
|
|
ac364caede | ||
|
|
7291263903 | ||
|
|
11737e67f8 |
8
AUTHORS.md
Normal file
8
AUTHORS.md
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# Authors
|
||||||
|
|
||||||
|
raven was written by Olivia Brooks (Cutieguwu).
|
||||||
|
|
||||||
|
Thanks to Adrian Long (Viffx) who contributed a number of PRs including:
|
||||||
|
|
||||||
|
- An initial implementation of the project root search
|
||||||
|
- Debugging my shitty code many times over
|
||||||
16
Cargo.toml
16
Cargo.toml
@@ -2,23 +2,27 @@
|
|||||||
name = "raven"
|
name = "raven"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
authors = ["Olivia Brooks", "Adrian Long"]
|
||||||
|
repository = "https://gitea.cutieguwu.ca/Cutieguwu/raven"
|
||||||
|
license = "MIT"
|
||||||
|
publish = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0"
|
anyhow = "1.0"
|
||||||
bytesize = "2.3"
|
bytesize = "2.3"
|
||||||
ron = "0.12"
|
ron = "0.12"
|
||||||
sha256 = "1.6.0"
|
sha256 = "1.6"
|
||||||
subprocess = "0.2"
|
subprocess = "0.2"
|
||||||
toml = "0.9"
|
toml = "0.9"
|
||||||
|
|
||||||
[dependencies.serde]
|
|
||||||
version = "1.0"
|
|
||||||
features =["derive"]
|
|
||||||
|
|
||||||
[dependencies.clap]
|
[dependencies.clap]
|
||||||
version = "4.5"
|
version = "4.5"
|
||||||
features = ["derive"]
|
features = ["cargo", "derive"]
|
||||||
|
|
||||||
[dependencies.semver]
|
[dependencies.semver]
|
||||||
version = "1.0"
|
version = "1.0"
|
||||||
features = ["serde"]
|
features = ["serde"]
|
||||||
|
|
||||||
|
[dependencies.serde]
|
||||||
|
version = "1.0"
|
||||||
|
features =["derive"]
|
||||||
|
|||||||
34
README.md
34
README.md
@@ -22,9 +22,39 @@ worked out over time.
|
|||||||
|
|
||||||
`raven` is only tested under linux. NT and Darwin support is **not** guaranteed.
|
`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
|
||||||
|
|
||||||
|
```bash
|
||||||
|
raven new demo
|
||||||
|
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
|
## Future plans
|
||||||
|
|
||||||
- [ ] Make `nest run` fall back to an entry point specified in Nest.toml, when
|
- [ ] Make `raven run` fall back to an entry point specified in Nest.toml, when
|
||||||
none provided.
|
none provided.
|
||||||
- [ ] Possibly add support for pulling remote packages via `nest add`. This
|
- [ ] 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
|
||||||
will be implemented should there arise a need.
|
will be implemented should there arise a need.
|
||||||
|
- [ ] Wrap errors properly, instead of hap-hazardly using `anyhow`
|
||||||
|
- [ ] Maybe proper logging?
|
||||||
|
|||||||
@@ -3,4 +3,8 @@ public class Main {
|
|||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
System.out.println("Hello, world!");
|
System.out.println("Hello, world!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int add(int a, int b) {
|
||||||
|
return a + b;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
10
assets/src/test/MainTest.java
Normal file
10
assets/src/test/MainTest.java
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
public class MainTest {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
testAdd();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void testAdd() {
|
||||||
|
assert Main.add(2, 2) == 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,6 +5,8 @@ use clap::{ArgAction, Parser, Subcommand};
|
|||||||
pub static CONFIG: LazyLock<Args> = LazyLock::new(|| Args::parse());
|
pub static CONFIG: LazyLock<Args> = LazyLock::new(|| Args::parse());
|
||||||
|
|
||||||
#[derive(Debug, Parser)]
|
#[derive(Debug, Parser)]
|
||||||
|
#[clap(author, version)]
|
||||||
|
#[command(help_template = "{author-section}\n{usage-heading} {usage}\n\n{all-args}")]
|
||||||
pub struct Args {
|
pub struct Args {
|
||||||
#[command(subcommand)]
|
#[command(subcommand)]
|
||||||
pub command: Command,
|
pub command: Command,
|
||||||
@@ -27,12 +29,12 @@ pub enum Command {
|
|||||||
#[clap(flatten)]
|
#[clap(flatten)]
|
||||||
assertions: Assertions,
|
assertions: Assertions,
|
||||||
},
|
},
|
||||||
/// Run the tests
|
/// !!! BORKED !!! Run the tests
|
||||||
Test {
|
Test {
|
||||||
#[clap(flatten)]
|
#[clap(flatten)]
|
||||||
assertions: Assertions,
|
assertions: Assertions,
|
||||||
},
|
},
|
||||||
/// Remove the target directory
|
/// Remove the target directory and caching
|
||||||
Clean,
|
Clean,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,10 +35,7 @@ pub fn get_javac_ver() -> anyhow::Result<semver::Version> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_cwd<P: AsRef<Path>>(path: P) -> io::Result<()> {
|
pub fn set_cwd<P: AsRef<Path>>(path: P) -> io::Result<()> {
|
||||||
let mut cwd = crate::PROJECT_ROOT
|
let mut cwd = crate::PROJECT_ROOT.clone();
|
||||||
.lock()
|
|
||||||
.expect("Failed to lock Mutex")
|
|
||||||
.to_owned();
|
|
||||||
cwd.push(path.as_ref());
|
cwd.push(path.as_ref());
|
||||||
std::env::set_current_dir(cwd)
|
std::env::set_current_dir(cwd.as_path())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,12 @@ pub fn expand_files<P: AsRef<Path>>(path: P) -> anyhow::Result<Vec<PathBuf>> {
|
|||||||
Ok(std::fs::read_dir(path)?
|
Ok(std::fs::read_dir(path)?
|
||||||
.filter_map(|entry| {
|
.filter_map(|entry| {
|
||||||
let path = entry.ok()?.path();
|
let path = entry.ok()?.path();
|
||||||
if path.is_file() { Some(path) } else { None }
|
if path.is_dir() {
|
||||||
|
Some(expand_files(path).ok()?)
|
||||||
|
} else {
|
||||||
|
Some(vec![path])
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
.flatten()
|
||||||
.collect())
|
.collect())
|
||||||
}
|
}
|
||||||
|
|||||||
35
src/java.rs
35
src/java.rs
@@ -17,11 +17,15 @@ pub struct JVMBuilder {
|
|||||||
monitor: bool,
|
monitor: bool,
|
||||||
ram_min: Option<ByteSize>,
|
ram_min: Option<ByteSize>,
|
||||||
ram_max: Option<ByteSize>,
|
ram_max: Option<ByteSize>,
|
||||||
|
class_path: PathBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl JVMBuilder {
|
impl JVMBuilder {
|
||||||
pub fn new() -> Self {
|
pub fn new<P: AsRef<Path>>(class_path: P) -> Self {
|
||||||
Self::default()
|
Self {
|
||||||
|
class_path: class_path.as_ref().to_path_buf(),
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn assertions(&mut self, assertions: bool) -> &mut Self {
|
pub fn assertions(&mut self, assertions: bool) -> &mut Self {
|
||||||
@@ -46,7 +50,9 @@ impl JVMBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn build(&self) -> JVM {
|
pub fn build(&self) -> JVM {
|
||||||
let mut flags = vec![];
|
let mut flags = vec![VMFlag::Classpath {
|
||||||
|
path: self.class_path.to_owned(),
|
||||||
|
}];
|
||||||
|
|
||||||
if self.assertions {
|
if self.assertions {
|
||||||
flags.push(VMFlag::EnableAssert);
|
flags.push(VMFlag::EnableAssert);
|
||||||
@@ -85,7 +91,8 @@ impl JVM {
|
|||||||
.into_iter()
|
.into_iter()
|
||||||
.flat_map(|f| Into::<Vec<String>>::into(f)),
|
.flat_map(|f| Into::<Vec<String>>::into(f)),
|
||||||
);
|
);
|
||||||
cmd.push(entry_point.as_ref().display().to_string());
|
|
||||||
|
cmd.push(entry_point.as_ref().to_path_buf().display().to_string());
|
||||||
|
|
||||||
let result = crate::io::run_process(cmd.as_slice());
|
let result = crate::io::run_process(cmd.as_slice());
|
||||||
|
|
||||||
@@ -110,6 +117,7 @@ impl JVM {
|
|||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum VMFlag {
|
pub enum VMFlag {
|
||||||
|
Classpath { path: PathBuf },
|
||||||
EnableAssert,
|
EnableAssert,
|
||||||
HeapMax { size: ByteSize },
|
HeapMax { size: ByteSize },
|
||||||
HeapMin { size: ByteSize },
|
HeapMin { size: ByteSize },
|
||||||
@@ -118,12 +126,10 @@ pub enum VMFlag {
|
|||||||
|
|
||||||
impl Into<Vec<String>> for VMFlag {
|
impl Into<Vec<String>> for VMFlag {
|
||||||
fn into(self) -> Vec<String> {
|
fn into(self) -> Vec<String> {
|
||||||
match self {
|
self.to_string()
|
||||||
Self::EnableAssert => vec![String::from("-ea")],
|
.split_ascii_whitespace()
|
||||||
Self::HeapMax { size } => vec![format!("Xmx{}", size)],
|
.map(|s| s.to_string())
|
||||||
Self::HeapMin { size } => vec![format!("Xms{}", size)],
|
.collect()
|
||||||
Self::Version => vec![String::from("--version")],
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,9 +141,10 @@ impl fmt::Display for VMFlag {
|
|||||||
f,
|
f,
|
||||||
"-{}",
|
"-{}",
|
||||||
match self {
|
match self {
|
||||||
|
Self::Classpath { path } => format!("classpath {}", path.display()),
|
||||||
Self::EnableAssert => String::from("ea"),
|
Self::EnableAssert => String::from("ea"),
|
||||||
Self::HeapMax { size } => format!("Xmx{}", size),
|
Self::HeapMax { size } => format!("Xmx{}", size.as_u64()),
|
||||||
Self::HeapMin { size } => format!("Xms{}", size),
|
Self::HeapMin { size } => format!("Xms{}", size.as_u64()),
|
||||||
Self::Version => String::from("-version"), // --version
|
Self::Version => String::from("-version"), // --version
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -213,14 +220,14 @@ impl Compiler {
|
|||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum CompilerFlag {
|
pub enum CompilerFlag {
|
||||||
Destination { path: PathBuf },
|
|
||||||
Classpath { path: PathBuf },
|
Classpath { path: PathBuf },
|
||||||
|
Destination { path: PathBuf },
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<Vec<String>> for CompilerFlag {
|
impl Into<Vec<String>> for CompilerFlag {
|
||||||
fn into(self) -> Vec<String> {
|
fn into(self) -> Vec<String> {
|
||||||
match self {
|
match self {
|
||||||
Self::Classpath { path } => vec!["-cp".to_string(), path.display().to_string()],
|
Self::Classpath { path } => vec!["-classpath".to_string(), path.display().to_string()],
|
||||||
Self::Destination { path } => vec!["-d".to_string(), path.display().to_string()],
|
Self::Destination { path } => vec!["-d".to_string(), path.display().to_string()],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
131
src/main.rs
131
src/main.rs
@@ -8,7 +8,7 @@ mod nest;
|
|||||||
use std::fs::OpenOptions;
|
use std::fs::OpenOptions;
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::sync::{LazyLock, Mutex};
|
use std::sync::LazyLock;
|
||||||
|
|
||||||
use cli::{CONFIG, Command};
|
use cli::{CONFIG, Command};
|
||||||
use java::{JAVA_EXT_CLASS, JAVA_EXT_SOURCE};
|
use java::{JAVA_EXT_CLASS, JAVA_EXT_SOURCE};
|
||||||
@@ -17,17 +17,33 @@ use nest::{Class, NEST, NestLock};
|
|||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use bytesize::ByteSize;
|
use bytesize::ByteSize;
|
||||||
|
|
||||||
const DIR_TARGET: LazyLock<PathBuf> = LazyLock::new(|| PathBuf::from("target/"));
|
pub static PROJECT_ROOT: LazyLock<PathBuf> = LazyLock::new(|| {
|
||||||
const DIR_TEST: LazyLock<PathBuf> = LazyLock::new(|| PathBuf::from("test/"));
|
// Start from CWD
|
||||||
const DIR_SRC: LazyLock<PathBuf> = LazyLock::new(|| PathBuf::from("src/"));
|
let cwd = std::env::current_dir().expect("Failed to get current working directory");
|
||||||
|
let mut probe = cwd.clone();
|
||||||
|
|
||||||
|
while !probe.join(F_NEST_TOML.as_path()).exists() {
|
||||||
|
if !probe.pop() {
|
||||||
|
// This is easier than having a Result everywhere. For now.
|
||||||
|
panic!(
|
||||||
|
"No {} found in current directory or any ancestor. (cwd: {})",
|
||||||
|
F_NEST_TOML.display(),
|
||||||
|
cwd.display()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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_TOML: LazyLock<PathBuf> = LazyLock::new(|| PathBuf::from("Nest.toml"));
|
||||||
const F_NEST_LOCK: LazyLock<PathBuf> = LazyLock::new(|| PathBuf::from("Nest.lock"));
|
const F_NEST_LOCK: LazyLock<PathBuf> = LazyLock::new(|| PathBuf::from("Nest.lock"));
|
||||||
|
|
||||||
/// This may not actually be the project root.
|
|
||||||
pub static PROJECT_ROOT: LazyLock<Mutex<PathBuf>> = LazyLock::new(|| {
|
|
||||||
Mutex::new(std::env::current_dir().expect("Failed to get current working directory"))
|
|
||||||
});
|
|
||||||
|
|
||||||
fn main() -> anyhow::Result<()> {
|
fn main() -> anyhow::Result<()> {
|
||||||
// Ensure that Nest.toml exists, if the requested command depends upon it.
|
// Ensure that Nest.toml exists, if the requested command depends upon it.
|
||||||
if CONFIG.command.depends_on_nest() && NEST.is_err() {
|
if CONFIG.command.depends_on_nest() && NEST.is_err() {
|
||||||
@@ -64,23 +80,18 @@ fn main() -> anyhow::Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn init() -> anyhow::Result<()> {
|
fn init() -> anyhow::Result<()> {
|
||||||
let is_empty = std::fs::read_dir(PROJECT_ROOT.lock().expect("Failed to lock mutex").as_path())
|
let cwd = std::env::current_dir()?;
|
||||||
.is_ok_and(|tree| tree.count() == 0);
|
|
||||||
|
|
||||||
let project_name = PROJECT_ROOT
|
let is_empty = std::fs::read_dir(cwd.as_path()).is_ok_and(|tree| tree.count() == 0);
|
||||||
.lock()
|
|
||||||
.expect("Failed to lock mutex")
|
let project_name = cwd
|
||||||
.file_name()
|
.file_name()
|
||||||
.context("Invalid directory name")?
|
.context("Invalid directory name")?
|
||||||
.to_str()
|
.to_str()
|
||||||
.context("Unable to convert OsStr to str")?
|
.context("Unable to convert OsStr to str")?
|
||||||
.to_owned();
|
.to_owned();
|
||||||
|
|
||||||
// Make src, target, tests
|
// ORDER MATTERS. THIS MUST COME FIRST.
|
||||||
for dir in [DIR_SRC, DIR_TARGET, DIR_TEST] {
|
|
||||||
std::fs::create_dir(dir.clone())?;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make config file.
|
// Make config file.
|
||||||
if let Result::Ok(mut f) = OpenOptions::new()
|
if let Result::Ok(mut f) = OpenOptions::new()
|
||||||
.write(true)
|
.write(true)
|
||||||
@@ -114,13 +125,29 @@ fn init() -> anyhow::Result<()> {
|
|||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make Main.java
|
// Make src, target, tests
|
||||||
if let Result::Ok(mut f) = OpenOptions::new()
|
for dir in [DIR_SRC, DIR_MAIN, DIR_TARGET, DIR_TEST] {
|
||||||
.write(true)
|
std::fs::create_dir_all(dir.clone())?;
|
||||||
.create_new(is_empty)
|
}
|
||||||
.open(DIR_SRC.clone().join("Main").with_extension(JAVA_EXT_SOURCE))
|
|
||||||
{
|
// Make src/main/Main.java
|
||||||
f.write_all(include_bytes!("../assets/Main.java"))?;
|
if let Result::Ok(mut f) = OpenOptions::new().write(true).create_new(is_empty).open(
|
||||||
|
DIR_MAIN
|
||||||
|
.clone()
|
||||||
|
.join("Main")
|
||||||
|
.with_extension(JAVA_EXT_SOURCE),
|
||||||
|
) {
|
||||||
|
f.write_all(include_bytes!("../assets/src/main/Main.java"))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make src/test/MainTest.java
|
||||||
|
if let Result::Ok(mut f) = OpenOptions::new().write(true).create_new(is_empty).open(
|
||||||
|
DIR_TEST
|
||||||
|
.clone()
|
||||||
|
.join("MainTest")
|
||||||
|
.with_extension(JAVA_EXT_SOURCE),
|
||||||
|
) {
|
||||||
|
f.write_all(include_bytes!("../assets/src/test/MainTest.java"))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// git init .
|
// git init .
|
||||||
@@ -133,15 +160,14 @@ fn init() -> anyhow::Result<()> {
|
|||||||
.read(true)
|
.read(true)
|
||||||
.open(".gitignore")
|
.open(".gitignore")
|
||||||
{
|
{
|
||||||
dbg!();
|
|
||||||
let mut buf = String::new();
|
let mut buf = String::new();
|
||||||
f.read_to_string(&mut buf)?;
|
f.read_to_string(&mut buf)?;
|
||||||
|
|
||||||
for ignored in [
|
for ignored in [
|
||||||
DIR_TARGET.as_path().display().to_string(),
|
format!("{}/", DIR_TARGET.file_name().unwrap().display()),
|
||||||
format!("*.{}", JAVA_EXT_CLASS),
|
format!("*.{}", JAVA_EXT_CLASS),
|
||||||
] {
|
] {
|
||||||
if dbg!(!buf.contains(&ignored)) {
|
if !buf.contains(&ignored) {
|
||||||
f.write(format!("{}\n", ignored).as_bytes())?;
|
f.write(format!("{}\n", ignored).as_bytes())?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -151,23 +177,22 @@ fn init() -> anyhow::Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn new(project_name: String) -> anyhow::Result<()> {
|
fn new(project_name: String) -> anyhow::Result<()> {
|
||||||
let cwd = PROJECT_ROOT
|
let cwd = std::env::current_dir()?.join(project_name);
|
||||||
.lock()
|
|
||||||
.expect("Failed to lock mutex")
|
|
||||||
.join(project_name);
|
|
||||||
|
|
||||||
std::fs::create_dir(&cwd)?;
|
std::fs::create_dir(&cwd)?;
|
||||||
std::env::set_current_dir(&cwd)?;
|
std::env::set_current_dir(&cwd)?;
|
||||||
|
|
||||||
// Replace PathBuf within mutex
|
|
||||||
let mut state = PROJECT_ROOT.lock().expect("Failed to lock mutex");
|
|
||||||
*state = std::env::current_dir().expect("Failed to change current working directory");
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build() -> anyhow::Result<()> {
|
fn build() -> anyhow::Result<()> {
|
||||||
let mut targets = crate::fs::expand_files(DIR_SRC.as_path())?;
|
let mut targets: Vec<PathBuf> = crate::fs::expand_files(DIR_SRC.as_path())?
|
||||||
|
.into_iter()
|
||||||
|
.filter(|f| {
|
||||||
|
f.extension()
|
||||||
|
.is_some_and(|ext| ext.to_str().is_some_and(|ext| ext == JAVA_EXT_SOURCE))
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
let mut nest_lock = NestLock::load().unwrap_or_default();
|
let mut nest_lock = NestLock::load().unwrap_or_default();
|
||||||
|
|
||||||
nest_lock.update();
|
nest_lock.update();
|
||||||
@@ -192,7 +217,7 @@ fn build() -> anyhow::Result<()> {
|
|||||||
|
|
||||||
for target in targets {
|
for target in targets {
|
||||||
println!("Compiling {}", target.display());
|
println!("Compiling {}", target.display());
|
||||||
if javac.clone().compile(target.as_path()).is_ok()
|
if javac.clone().compile(dbg!(target.as_path())).is_ok()
|
||||||
&& let Result::Ok(class) = Class::try_from(target.clone())
|
&& let Result::Ok(class) = Class::try_from(target.clone())
|
||||||
{
|
{
|
||||||
nest_lock.0.insert(target, class);
|
nest_lock.0.insert(target, class);
|
||||||
@@ -212,9 +237,10 @@ fn run<P: AsRef<Path>>(
|
|||||||
entry_point: P,
|
entry_point: P,
|
||||||
assertions: bool,
|
assertions: bool,
|
||||||
) -> anyhow::Result<(Option<String>, Option<String>)> {
|
) -> anyhow::Result<(Option<String>, Option<String>)> {
|
||||||
|
// JRE pathing will be messed up without this.
|
||||||
crate::env::set_cwd(DIR_TARGET.as_path())?;
|
crate::env::set_cwd(DIR_TARGET.as_path())?;
|
||||||
|
|
||||||
java::JVMBuilder::new()
|
java::JVMBuilder::new(DIR_TARGET.as_path())
|
||||||
.assertions(assertions)
|
.assertions(assertions)
|
||||||
.monitor(true)
|
.monitor(true)
|
||||||
.build()
|
.build()
|
||||||
@@ -229,33 +255,18 @@ fn test(assertions: bool) -> anyhow::Result<(Option<String>, Option<String>)> {
|
|||||||
.compile(DIR_TEST.as_path())?;
|
.compile(DIR_TEST.as_path())?;
|
||||||
|
|
||||||
// Change cwd to avoid Java pathing issues.
|
// Change cwd to avoid Java pathing issues.
|
||||||
crate::env::set_cwd(
|
crate::env::set_cwd(DIR_TARGET.as_path())?;
|
||||||
PROJECT_ROOT
|
|
||||||
.lock()
|
|
||||||
.expect("Failed to lock mutex")
|
|
||||||
.join(DIR_TARGET.as_path()),
|
|
||||||
)?;
|
|
||||||
|
|
||||||
java::JVMBuilder::new()
|
java::JVMBuilder::new(DIR_TARGET.as_path())
|
||||||
.assertions(assertions)
|
.assertions(assertions)
|
||||||
.ram_min(ByteSize::mib(128))
|
.ram_min(ByteSize::mib(128))
|
||||||
.ram_max(ByteSize::mib(512))
|
.ram_max(ByteSize::mib(512))
|
||||||
.monitor(true)
|
.monitor(true)
|
||||||
.build()
|
.build()
|
||||||
.run(DIR_TEST.as_path())
|
.run(DIR_TARGET.as_path())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clean() {
|
fn clean() {
|
||||||
let _ = std::fs::remove_file(
|
let _ = std::fs::remove_file(PROJECT_ROOT.join(F_NEST_LOCK.as_path()));
|
||||||
PROJECT_ROOT
|
let _ = std::fs::remove_dir_all(DIR_TARGET.join("/*").as_path());
|
||||||
.lock()
|
|
||||||
.expect("Failed to lock mutex")
|
|
||||||
.join(F_NEST_LOCK.as_path()),
|
|
||||||
);
|
|
||||||
let _ = std::fs::remove_dir_all(
|
|
||||||
PROJECT_ROOT
|
|
||||||
.lock()
|
|
||||||
.expect("Failed to lock mutex")
|
|
||||||
.join(DIR_TARGET.as_path()),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|||||||
14
src/nest.rs
14
src/nest.rs
@@ -11,14 +11,8 @@ use anyhow::Context;
|
|||||||
use semver::Version;
|
use semver::Version;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
pub static NEST: LazyLock<anyhow::Result<Nest>> = LazyLock::new(|| {
|
pub static NEST: LazyLock<anyhow::Result<Nest>> =
|
||||||
Nest::try_from(
|
LazyLock::new(|| Nest::try_from(PROJECT_ROOT.join(F_NEST_TOML.as_path())));
|
||||||
PROJECT_ROOT
|
|
||||||
.lock()
|
|
||||||
.expect("Failed to lock mutex")
|
|
||||||
.join(F_NEST_TOML.as_path()),
|
|
||||||
)
|
|
||||||
});
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||||
pub struct Nest {
|
pub struct Nest {
|
||||||
@@ -133,16 +127,12 @@ impl Class {
|
|||||||
// If the source file exists, hasn't been moved to a package (path is a file) and
|
// If the source file exists, hasn't been moved to a package (path is a file) and
|
||||||
// the associated compiled class file exists in DIR_TARGET
|
// the associated compiled class file exists in DIR_TARGET
|
||||||
PROJECT_ROOT
|
PROJECT_ROOT
|
||||||
.lock()
|
|
||||||
.expect("Failed to lock mutex")
|
|
||||||
.join(DIR_TARGET.as_path())
|
.join(DIR_TARGET.as_path())
|
||||||
.join(self.name.as_path())
|
.join(self.name.as_path())
|
||||||
.with_extension(JAVA_EXT_CLASS)
|
.with_extension(JAVA_EXT_CLASS)
|
||||||
.exists()
|
.exists()
|
||||||
&& sha256::try_digest(
|
&& sha256::try_digest(
|
||||||
PROJECT_ROOT
|
PROJECT_ROOT
|
||||||
.lock()
|
|
||||||
.expect("Failed to lock mutex")
|
|
||||||
.join(if self.test {
|
.join(if self.test {
|
||||||
DIR_TEST.clone()
|
DIR_TEST.clone()
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user