tests: every test dir is removed when its test ends, pass or panic
Many test helpers removed their temp dir only before the test, or only on pass, so runs left them behind: 117,000 filled /tmp (RAM here) and stopped a mutation run. Each now holds a guard that removes the dir on drop, unwind included; servers started on a test dir hold its guard until they stop. A full cargo test --workspace leaves 0 dirs (859 before). just sweep-test-tmp stays for runs killed mid-test. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01T3gXMVt7XJPi6ens1or9Dj
This commit is contained in:
1 parent
c587593d78
commit
6c04342427
44 files changed
+952
-163
No files matched your search
@@ -18,11 +18,33 @@ use ledger_store::{DB_FILE, JOURNAL_FILE, JournalWriter, Store, StoreError};
|
||||
use serde_json::{Value, json};
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
fn test_dir(name: &str) -> PathBuf {
|
||||
/// A test's dir, removed when the test ends, pass or panic.
|
||||
struct TestDir(PathBuf);
|
||||
|
||||
impl std::ops::Deref for TestDir {
|
||||
type Target = std::path::Path;
|
||||
fn deref(&self) -> &std::path::Path {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<std::path::Path> for TestDir {
|
||||
fn as_ref(&self) -> &std::path::Path {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for TestDir {
|
||||
fn drop(&mut self) {
|
||||
let _ = std::fs::remove_dir_all(&self.0);
|
||||
}
|
||||
}
|
||||
|
||||
fn test_dir(name: &str) -> TestDir {
|
||||
let dir = std::env::temp_dir().join(format!("wb-asset-tags-{name}-{}", std::process::id()));
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
std::fs::create_dir_all(&dir).unwrap();
|
||||
dir
|
||||
TestDir(dir)
|
||||
}
|
||||
|
||||
fn usd(amount: &str) -> Money {
|
||||
@@ -78,7 +100,7 @@ fn laptop(store: &mut Store, a: &Accts, name: &str) -> AssetId {
|
||||
}
|
||||
|
||||
/// A store with two untagged laptops.
|
||||
fn fixture(name: &str) -> (PathBuf, Store, Accts, AssetId, AssetId) {
|
||||
fn fixture(name: &str) -> (TestDir, Store, Accts, AssetId, AssetId) {
|
||||
let dir = test_dir(name);
|
||||
let mut s = Store::create(&dir, Currency::USD).unwrap();
|
||||
let a = accounts(&mut s);
|
||||
|
||||
@@ -25,11 +25,33 @@ use std::str::FromStr;
|
||||
|
||||
// ---------------------------------------------------------------- helpers
|
||||
|
||||
fn test_dir(name: &str) -> PathBuf {
|
||||
/// A test's dir, removed when the test ends, pass or panic.
|
||||
struct TestDir(PathBuf);
|
||||
|
||||
impl std::ops::Deref for TestDir {
|
||||
type Target = std::path::Path;
|
||||
fn deref(&self) -> &std::path::Path {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<std::path::Path> for TestDir {
|
||||
fn as_ref(&self) -> &std::path::Path {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for TestDir {
|
||||
fn drop(&mut self) {
|
||||
let _ = std::fs::remove_dir_all(&self.0);
|
||||
}
|
||||
}
|
||||
|
||||
fn test_dir(name: &str) -> TestDir {
|
||||
let dir = std::env::temp_dir().join(format!("wb-attach-{name}-{}", std::process::id()));
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
std::fs::create_dir_all(&dir).unwrap();
|
||||
dir
|
||||
TestDir(dir)
|
||||
}
|
||||
|
||||
fn dec(s: &str) -> Decimal {
|
||||
|
||||
@@ -21,14 +21,36 @@ use rust_decimal::Decimal;
|
||||
use serde_json::json;
|
||||
use std::path::PathBuf;
|
||||
|
||||
fn test_dir(name: &str) -> PathBuf {
|
||||
/// A test's dir, removed when the test ends, pass or panic.
|
||||
struct TestDir(PathBuf);
|
||||
|
||||
impl std::ops::Deref for TestDir {
|
||||
type Target = std::path::Path;
|
||||
fn deref(&self) -> &std::path::Path {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<std::path::Path> for TestDir {
|
||||
fn as_ref(&self) -> &std::path::Path {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for TestDir {
|
||||
fn drop(&mut self) {
|
||||
let _ = std::fs::remove_dir_all(&self.0);
|
||||
}
|
||||
}
|
||||
|
||||
fn test_dir(name: &str) -> TestDir {
|
||||
let dir = std::env::temp_dir().join(format!(
|
||||
"wanderbooks-store-bounds-{name}-{}",
|
||||
std::process::id()
|
||||
));
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
std::fs::create_dir_all(&dir).unwrap();
|
||||
dir
|
||||
TestDir(dir)
|
||||
}
|
||||
|
||||
fn d(y: i32, m: u32, day: u32) -> NaiveDate {
|
||||
@@ -36,8 +58,8 @@ fn d(y: i32, m: u32, day: u32) -> NaiveDate {
|
||||
}
|
||||
|
||||
/// The old-books fixture `name` (tests/fixtures/old-books: written by main
|
||||
/// 188c90ea), opened from a copy.
|
||||
fn open_old_books(name: &str) -> Store {
|
||||
/// 188c90ea), opened from a copy (kept while the guard lives).
|
||||
fn open_old_books(name: &str) -> (TestDir, Store) {
|
||||
let from = std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
|
||||
.join("tests/fixtures/old-books")
|
||||
.join(name);
|
||||
@@ -55,7 +77,8 @@ fn open_old_books(name: &str) -> Store {
|
||||
std::fs::copy(&e, to).unwrap();
|
||||
}
|
||||
}
|
||||
Store::open(&dir).unwrap_or_else(|e| panic!("{name}: {e}"))
|
||||
let store = Store::open(&dir).unwrap_or_else(|e| panic!("{name}: {e}"));
|
||||
(dir, store)
|
||||
}
|
||||
|
||||
/// Every file under `dir`.
|
||||
@@ -114,7 +137,7 @@ fn a_statement_the_books_cant_hold_is_refused() {
|
||||
.unwrap();
|
||||
// A statement an earlier version recorded past both bounds opens, its
|
||||
// balances as recorded.
|
||||
let old = open_old_books("x_statement_max");
|
||||
let (_dir, old) = open_old_books("x_statement_max");
|
||||
let recorded = old.statements(None).unwrap();
|
||||
assert_eq!(
|
||||
recorded[0].closing_balance,
|
||||
@@ -158,7 +181,7 @@ fn a_recurring_run_has_an_end() {
|
||||
assert!(s.run_recurring(last).unwrap().is_empty());
|
||||
// One run an earlier version made of more than that opens, every
|
||||
// draft as generated.
|
||||
let old = open_old_books("x_recurring_run_1044");
|
||||
let (_dir, old) = open_old_books("x_recurring_run_1044");
|
||||
assert_eq!(old.ledger().next_entry_id(), 1045);
|
||||
old.verify().unwrap();
|
||||
}
|
||||
@@ -206,7 +229,7 @@ fn disposal_proceeds_larger_than_a_line_are_refused() {
|
||||
assert!(s.run_depreciation(id, period).is_err(), "{period}");
|
||||
}
|
||||
// Depreciation an earlier version posted for 10000-01 opens.
|
||||
let old = open_old_books("x_depreciation_year10000");
|
||||
let (_dir, old) = open_old_books("x_depreciation_year10000");
|
||||
assert_eq!(old.ledger().get_entry(2).unwrap().date(), d(10000, 1, 31));
|
||||
}
|
||||
|
||||
|
||||
@@ -19,11 +19,33 @@ use rust_decimal::Decimal;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::{Arc, Barrier};
|
||||
|
||||
fn test_dir(name: &str) -> std::path::PathBuf {
|
||||
/// A test's dir, removed when the test ends, pass or panic.
|
||||
struct TestDir(std::path::PathBuf);
|
||||
|
||||
impl std::ops::Deref for TestDir {
|
||||
type Target = std::path::Path;
|
||||
fn deref(&self) -> &std::path::Path {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<std::path::Path> for TestDir {
|
||||
fn as_ref(&self) -> &std::path::Path {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for TestDir {
|
||||
fn drop(&mut self) {
|
||||
let _ = std::fs::remove_dir_all(&self.0);
|
||||
}
|
||||
}
|
||||
|
||||
fn test_dir(name: &str) -> TestDir {
|
||||
let dir = std::env::temp_dir().join(format!("wanderbooks-conc-{name}-{}", std::process::id()));
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
std::fs::create_dir_all(&dir).unwrap();
|
||||
dir
|
||||
TestDir(dir)
|
||||
}
|
||||
|
||||
const ENTRIES: u32 = 400;
|
||||
|
||||
@@ -15,11 +15,33 @@ use rust_decimal::Decimal;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::Command;
|
||||
|
||||
fn test_dir(name: &str) -> PathBuf {
|
||||
/// A test's dir, removed when the test ends, pass or panic.
|
||||
struct TestDir(PathBuf);
|
||||
|
||||
impl std::ops::Deref for TestDir {
|
||||
type Target = std::path::Path;
|
||||
fn deref(&self) -> &std::path::Path {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<std::path::Path> for TestDir {
|
||||
fn as_ref(&self) -> &std::path::Path {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for TestDir {
|
||||
fn drop(&mut self) {
|
||||
let _ = std::fs::remove_dir_all(&self.0);
|
||||
}
|
||||
}
|
||||
|
||||
fn test_dir(name: &str) -> TestDir {
|
||||
let dir = std::env::temp_dir().join(format!("wanderbooks-fault-{name}-{}", std::process::id()));
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
std::fs::create_dir_all(&dir).unwrap();
|
||||
dir
|
||||
TestDir(dir)
|
||||
}
|
||||
|
||||
fn post_one(store: &mut Store, n: u32) -> Result<(), ledger_store::StoreError> {
|
||||
@@ -104,7 +126,7 @@ fn full_disk_case(name: &str, drafts: u32) -> String {
|
||||
"trap '' XFSZ; ulimit -f {blocks}; exec \"$0\" --exact child_append_until_the_disk_is_full --nocapture --test-threads=1"
|
||||
))
|
||||
.arg(&exe)
|
||||
.env("WB_FAULT_DIR", &dir)
|
||||
.env("WB_FAULT_DIR", dir.as_os_str())
|
||||
.output()
|
||||
.unwrap();
|
||||
let stdout = String::from_utf8_lossy(&out.stdout);
|
||||
|
||||
@@ -27,12 +27,34 @@ use rust_decimal::Decimal;
|
||||
use serde_json::json;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
fn test_dir(name: &str) -> PathBuf {
|
||||
/// A test's dir, removed when the test ends, pass or panic.
|
||||
struct TestDir(PathBuf);
|
||||
|
||||
impl std::ops::Deref for TestDir {
|
||||
type Target = std::path::Path;
|
||||
fn deref(&self) -> &std::path::Path {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<std::path::Path> for TestDir {
|
||||
fn as_ref(&self) -> &std::path::Path {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for TestDir {
|
||||
fn drop(&mut self) {
|
||||
let _ = std::fs::remove_dir_all(&self.0);
|
||||
}
|
||||
}
|
||||
|
||||
fn test_dir(name: &str) -> TestDir {
|
||||
let dir =
|
||||
std::env::temp_dir().join(format!("wanderbooks-format-{name}-{}", std::process::id()));
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
std::fs::create_dir_all(&dir).unwrap();
|
||||
dir
|
||||
TestDir(dir)
|
||||
}
|
||||
|
||||
/// Books with one posted entry, closed again.
|
||||
|
||||
@@ -24,11 +24,33 @@ use std::str::FromStr;
|
||||
|
||||
// ---------------------------------------------------------------- helpers
|
||||
|
||||
fn test_dir(name: &str) -> PathBuf {
|
||||
/// A test's dir, removed when the test ends, pass or panic.
|
||||
struct TestDir(PathBuf);
|
||||
|
||||
impl std::ops::Deref for TestDir {
|
||||
type Target = std::path::Path;
|
||||
fn deref(&self) -> &std::path::Path {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<std::path::Path> for TestDir {
|
||||
fn as_ref(&self) -> &std::path::Path {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for TestDir {
|
||||
fn drop(&mut self) {
|
||||
let _ = std::fs::remove_dir_all(&self.0);
|
||||
}
|
||||
}
|
||||
|
||||
fn test_dir(name: &str) -> TestDir {
|
||||
let dir = std::env::temp_dir().join(format!("wb-parties-{name}-{}", std::process::id()));
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
std::fs::create_dir_all(&dir).unwrap();
|
||||
dir
|
||||
TestDir(dir)
|
||||
}
|
||||
|
||||
fn dec(s: &str) -> Decimal {
|
||||
|
||||
@@ -12,11 +12,33 @@ use ledger_store::{DB_FILE, JOURNAL_FILE, JournalWriter, Store};
|
||||
use serde_json::{Value, json};
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
fn test_dir(name: &str) -> PathBuf {
|
||||
/// A test's dir, removed when the test ends, pass or panic.
|
||||
struct TestDir(PathBuf);
|
||||
|
||||
impl std::ops::Deref for TestDir {
|
||||
type Target = std::path::Path;
|
||||
fn deref(&self) -> &std::path::Path {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<std::path::Path> for TestDir {
|
||||
fn as_ref(&self) -> &std::path::Path {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for TestDir {
|
||||
fn drop(&mut self) {
|
||||
let _ = std::fs::remove_dir_all(&self.0);
|
||||
}
|
||||
}
|
||||
|
||||
fn test_dir(name: &str) -> TestDir {
|
||||
let dir = std::env::temp_dir().join(format!("wb-party-tin-{name}-{}", std::process::id()));
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
std::fs::create_dir_all(&dir).unwrap();
|
||||
dir
|
||||
TestDir(dir)
|
||||
}
|
||||
|
||||
fn journal(dir: &Path) -> Vec<(String, Value)> {
|
||||
|
||||
@@ -18,11 +18,33 @@ use serde_json::{Value, json};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::str::FromStr;
|
||||
|
||||
fn test_dir(name: &str) -> PathBuf {
|
||||
/// A test's dir, removed when the test ends, pass or panic.
|
||||
struct TestDir(PathBuf);
|
||||
|
||||
impl std::ops::Deref for TestDir {
|
||||
type Target = std::path::Path;
|
||||
fn deref(&self) -> &std::path::Path {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<std::path::Path> for TestDir {
|
||||
fn as_ref(&self) -> &std::path::Path {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for TestDir {
|
||||
fn drop(&mut self) {
|
||||
let _ = std::fs::remove_dir_all(&self.0);
|
||||
}
|
||||
}
|
||||
|
||||
fn test_dir(name: &str) -> TestDir {
|
||||
let dir = std::env::temp_dir().join(format!("wb-roles-{name}-{}", std::process::id()));
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
std::fs::create_dir_all(&dir).unwrap();
|
||||
dir
|
||||
TestDir(dir)
|
||||
}
|
||||
|
||||
fn dec(s: &str) -> Decimal {
|
||||
|
||||
@@ -17,14 +17,36 @@ use rust_decimal::Decimal;
|
||||
use serde_json::{Value, json};
|
||||
use std::path::PathBuf;
|
||||
|
||||
fn test_dir(name: &str) -> PathBuf {
|
||||
/// A test's dir, removed when the test ends, pass or panic.
|
||||
struct TestDir(PathBuf);
|
||||
|
||||
impl std::ops::Deref for TestDir {
|
||||
type Target = std::path::Path;
|
||||
fn deref(&self) -> &std::path::Path {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<std::path::Path> for TestDir {
|
||||
fn as_ref(&self) -> &std::path::Path {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for TestDir {
|
||||
fn drop(&mut self) {
|
||||
let _ = std::fs::remove_dir_all(&self.0);
|
||||
}
|
||||
}
|
||||
|
||||
fn test_dir(name: &str) -> TestDir {
|
||||
let dir = std::env::temp_dir().join(format!(
|
||||
"wanderbooks-store-settings-{name}-{}",
|
||||
std::process::id()
|
||||
));
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
std::fs::create_dir_all(&dir).unwrap();
|
||||
dir
|
||||
TestDir(dir)
|
||||
}
|
||||
|
||||
fn d(y: i32, m: u32, day: u32) -> NaiveDate {
|
||||
@@ -48,7 +70,7 @@ fn set(k: &str, v: Value) -> Change {
|
||||
}
|
||||
|
||||
/// Books with a small chart.
|
||||
fn books(name: &str) -> (PathBuf, Store) {
|
||||
fn books(name: &str) -> (TestDir, Store) {
|
||||
let dir = test_dir(name);
|
||||
let mut s = Store::create(&dir, Currency::USD).unwrap();
|
||||
for (code, name, t) in [
|
||||
|
||||
@@ -8,11 +8,33 @@ use rust_decimal::Decimal;
|
||||
use std::io::Write;
|
||||
use std::path::PathBuf;
|
||||
|
||||
fn test_dir(name: &str) -> PathBuf {
|
||||
/// A test's dir, removed when the test ends, pass or panic.
|
||||
struct TestDir(PathBuf);
|
||||
|
||||
impl std::ops::Deref for TestDir {
|
||||
type Target = std::path::Path;
|
||||
fn deref(&self) -> &std::path::Path {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<std::path::Path> for TestDir {
|
||||
fn as_ref(&self) -> &std::path::Path {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for TestDir {
|
||||
fn drop(&mut self) {
|
||||
let _ = std::fs::remove_dir_all(&self.0);
|
||||
}
|
||||
}
|
||||
|
||||
fn test_dir(name: &str) -> TestDir {
|
||||
let dir = std::env::temp_dir().join(format!("wanderbooks-snap-{name}-{}", std::process::id()));
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
std::fs::create_dir_all(&dir).unwrap();
|
||||
dir
|
||||
TestDir(dir)
|
||||
}
|
||||
|
||||
fn usd(n: i64) -> Money {
|
||||
|
||||
@@ -21,11 +21,33 @@ use std::path::{Path, PathBuf};
|
||||
|
||||
const GENESIS: &str = "0000000000000000000000000000000000000000000000000000000000000000";
|
||||
|
||||
fn test_dir(name: &str) -> PathBuf {
|
||||
/// A test's dir, removed when the test ends, pass or panic.
|
||||
struct TestDir(PathBuf);
|
||||
|
||||
impl std::ops::Deref for TestDir {
|
||||
type Target = std::path::Path;
|
||||
fn deref(&self) -> &std::path::Path {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<std::path::Path> for TestDir {
|
||||
fn as_ref(&self) -> &std::path::Path {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for TestDir {
|
||||
fn drop(&mut self) {
|
||||
let _ = std::fs::remove_dir_all(&self.0);
|
||||
}
|
||||
}
|
||||
|
||||
fn test_dir(name: &str) -> TestDir {
|
||||
let dir = std::env::temp_dir().join(format!("wb-spec-store-{name}-{}", std::process::id()));
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
std::fs::create_dir_all(&dir).unwrap();
|
||||
dir
|
||||
TestDir(dir)
|
||||
}
|
||||
|
||||
fn usd(amount: u64) -> Money {
|
||||
|
||||
@@ -13,11 +13,33 @@ fn usd(amount: u64) -> Money {
|
||||
Money::new(Decimal::from(amount), Currency::USD)
|
||||
}
|
||||
|
||||
fn test_dir(name: &str) -> PathBuf {
|
||||
/// A test's dir, removed when the test ends, pass or panic.
|
||||
struct TestDir(PathBuf);
|
||||
|
||||
impl std::ops::Deref for TestDir {
|
||||
type Target = std::path::Path;
|
||||
fn deref(&self) -> &std::path::Path {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<std::path::Path> for TestDir {
|
||||
fn as_ref(&self) -> &std::path::Path {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for TestDir {
|
||||
fn drop(&mut self) {
|
||||
let _ = std::fs::remove_dir_all(&self.0);
|
||||
}
|
||||
}
|
||||
|
||||
fn test_dir(name: &str) -> TestDir {
|
||||
let dir = std::env::temp_dir().join(format!("wanderbooks-{name}-{}", std::process::id()));
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
std::fs::create_dir_all(&dir).unwrap();
|
||||
dir
|
||||
TestDir(dir)
|
||||
}
|
||||
|
||||
fn build_books(dir: &std::path::Path) -> Store {
|
||||
@@ -1619,7 +1641,7 @@ fn old_books() -> Vec<PathBuf> {
|
||||
/// A fixture's books (journal and blobs, never expected.json) in a fresh
|
||||
/// directory of its own for `test`: opening writes a database and a lock
|
||||
/// beside them.
|
||||
fn old_books_copy(fixture: &std::path::Path, test: &str) -> PathBuf {
|
||||
fn old_books_copy(fixture: &std::path::Path, test: &str) -> TestDir {
|
||||
fn copy(from: &std::path::Path, to: &std::path::Path) {
|
||||
std::fs::create_dir_all(to).unwrap();
|
||||
for e in std::fs::read_dir(from).unwrap() {
|
||||
|
||||
Reference in new issue
Block a user