Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/cli.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::config::CreatorType;
use clap::{Args, Parser, Subcommand};
use clap_verbosity_flag::{InfoLevel, Verbosity};
use std::path::PathBuf;

#[derive(Parser)]
#[command(version, about = "Upload and reference Roblox assets in code.")]
Expand Down Expand Up @@ -65,6 +66,10 @@ pub struct SyncArgs {
/// Provides Roblox with the amount of Robux that you are willing to spend on each non-free asset upload.
#[arg(long)]
pub expected_price: Option<u32>,

/// Path to the project directory. Defaults to the current directory.
#[arg(short, long, default_value = ".")]
pub project: PathBuf,
}

impl SyncArgs {
Expand Down Expand Up @@ -108,4 +113,8 @@ pub struct UploadArgs {
pub struct MigrateLockfileArgs {
/// The default input name to use. Only applies when upgrading from V0 to V1.
pub input_name: Option<String>,

/// Path to the project directory. Defaults to the current directory.
#[arg(short, long, default_value = ".")]
pub project: PathBuf,
}
12 changes: 9 additions & 3 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,24 @@ pub struct Config {

/// A map of input names to input configurations
pub inputs: HashMap<String, Input>,

#[serde(skip)]
pub project_dir: PathBuf,
}

pub type InputMap = HashMap<String, Input>;

pub const FILE_NAME: &str = "asphalt.toml";

impl Config {
pub async fn read() -> anyhow::Result<Config> {
let config = fs::read_to_string(FILE_NAME)
pub async fn read_from(project_dir: PathBuf) -> anyhow::Result<Config> {
let config_path = project_dir.join(FILE_NAME);
let config_str = fs::read_to_string(&config_path)
.await
.context("Failed to read config file")?;
let config: Config = toml::from_str(&config)?;

let mut config: Config = toml::from_str(&config_str)?;
config.project_dir = project_dir;

Ok(config)
}
Expand Down
10 changes: 6 additions & 4 deletions src/lockfile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,12 @@ impl Lockfile {
.insert(hash.to_owned(), entry);
}

pub async fn write(&self, filename: Option<&Path>) -> anyhow::Result<()> {
pub async fn write_to(&self, project_dir: &Path) -> anyhow::Result<()> {
let mut content = toml::to_string(self)?;
content.insert_str(0, "# This file is automatically @generated by Asphalt.\n# It is not intended for manual editing.\n");

fs::write(filename.unwrap_or(Path::new(FILE_NAME)), content).await?;
let lockfile_path = project_dir.join(FILE_NAME);
fs::write(lockfile_path, content).await?;
Ok(())
}
}
Expand Down Expand Up @@ -82,8 +83,9 @@ impl Default for RawLockfile {
}

impl RawLockfile {
pub async fn read() -> anyhow::Result<RawLockfile> {
let content = fs::read_to_string(FILE_NAME).await;
pub async fn read_from(project_dir: &Path) -> anyhow::Result<RawLockfile> {
let lockfile_path = project_dir.join(FILE_NAME);
let content = fs::read_to_string(&lockfile_path).await;

let content = match content {
Err(_) => return Ok(Self::default()),
Expand Down
7 changes: 4 additions & 3 deletions src/migrate_lockfile.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use crate::{cli::MigrateLockfileArgs, lockfile::RawLockfile};
use crate::{cli::MigrateLockfileArgs, config::Config, lockfile::RawLockfile};

pub async fn migrate_lockfile(args: MigrateLockfileArgs) -> anyhow::Result<()> {
let file = RawLockfile::read().await?;
let config = Config::read_from(args.project).await?;
let file = RawLockfile::read_from(&config.project_dir).await?;
let migrated = file.migrate(args.input_name.as_deref()).await?;
migrated.write(None).await?;
migrated.write_to(&config.project_dir).await?;

Ok(())
}
6 changes: 3 additions & 3 deletions src/sync/backend/debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,18 @@ use crate::{asset::Asset, lockfile::LockfileEntry, sync::backend::Params};
use anyhow::Context;
use fs_err::tokio as fs;
use log::info;
use std::{env, path::PathBuf};
use std::path::PathBuf;

pub struct Debug {
sync_path: PathBuf,
}

impl Backend for Debug {
async fn new(_: Params) -> anyhow::Result<Self>
async fn new(params: Params) -> anyhow::Result<Self>
where
Self: Sized,
{
let debug_path = env::current_dir()?.join(".asphalt-debug");
let debug_path = params.project_dir.join(".asphalt-debug");
info!("Assets will be synced to: {}", debug_path.display());

if debug_path.exists() {
Expand Down
2 changes: 2 additions & 0 deletions src/sync/backend/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use crate::{
config,
lockfile::LockfileEntry,
};
use std::path::PathBuf;

mod cloud;
pub use cloud::Cloud;
Expand All @@ -29,4 +30,5 @@ pub struct Params {
pub api_key: Option<String>,
pub creator: config::Creator,
pub expected_price: Option<u32>,
pub project_dir: PathBuf,
}
3 changes: 2 additions & 1 deletion src/sync/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ pub async fn collect_events(
target: SyncTarget,
inputs: InputMap,
mp: MultiProgress,
base_dir: &std::path::Path,
) -> anyhow::Result<CollectResults> {
let mut new_lockfile = Lockfile::default();

Expand Down Expand Up @@ -81,7 +82,7 @@ pub async fn collect_events(
if new {
progress.new += 1;
if target.write_on_sync() {
new_lockfile.write(None).await?;
new_lockfile.write_to(base_dir).await?;
}
}
}
Expand Down
17 changes: 11 additions & 6 deletions src/sync/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,12 @@ enum EventState {
}

pub async fn sync(args: SyncArgs, mp: MultiProgress) -> anyhow::Result<()> {
let config = Config::read().await?;
let config = Config::read_from(args.project.clone()).await?;
let target = args.target();

let existing_lockfile = RawLockfile::read().await?.into_lockfile()?;
let existing_lockfile = RawLockfile::read_from(&config.project_dir)
.await?
.into_lockfile()?;

let font_db = Arc::new({
let mut db = fontdb::Database::new();
Expand All @@ -76,7 +78,8 @@ pub async fn sync(args: SyncArgs, mp: MultiProgress) -> anyhow::Result<()> {

let collector_handle = tokio::spawn({
let inputs = config.inputs.clone();
async move { collect_events(event_rx, target, inputs, mp).await }
let project_dir = config.project_dir.clone();
async move { collect_events(event_rx, target, inputs, mp, &project_dir).await }
});

let params = walk::Params {
Expand All @@ -88,6 +91,7 @@ pub async fn sync(args: SyncArgs, mp: MultiProgress) -> anyhow::Result<()> {
api_key: args.api_key,
creator: config.creator.clone(),
expected_price: args.expected_price,
project_dir: config.project_dir.clone(),
};
match &target {
SyncTarget::Cloud { dry_run: false } => {
Expand Down Expand Up @@ -117,7 +121,7 @@ pub async fn sync(args: SyncArgs, mp: MultiProgress) -> anyhow::Result<()> {
}

if target.write_on_sync() {
results.new_lockfile.write(None).await?;
results.new_lockfile.write_to(&config.project_dir).await?;
}

for (input_name, source) in results.input_sources {
Expand All @@ -140,8 +144,9 @@ pub async fn sync(args: SyncArgs, mp: MultiProgress) -> anyhow::Result<()> {
};
let code = codegen::generate_code(lang, &input_name, &node)?;

fs::create_dir_all(&input.output_path).await?;
fs::write(input.output_path.join(format!("{input_name}.{ext}")), code).await?;
let output_path = config.project_dir.join(&input.output_path);
fs::create_dir_all(&output_path).await?;
fs::write(output_path.join(format!("{input_name}.{ext}")), code).await?;
}
}

Expand Down
15 changes: 12 additions & 3 deletions src/sync/walk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,22 +43,31 @@ pub async fn walk(params: Params, config: &Config, tx: &UnboundedSender<super::E
let params = Arc::new(params);

for (input_name, input) in &config.inputs {
let input_prefix = config.project_dir.join(input.include.get_prefix());

let state = Arc::new(InputState {
params: params.clone(),
input_name: input_name.clone(),
input_prefix: input.include.get_prefix(),
input_prefix: input_prefix.clone(),
seen_hashes: Arc::new(Mutex::new(HashMap::new())),
bleed: input.bleed,
});

let mut join_set = JoinSet::new();
let semaphore = Arc::new(Semaphore::new(50));

for entry in WalkDir::new(input.include.get_prefix())
for entry in WalkDir::new(&input_prefix)
.into_iter()
.filter_entry(|entry| {
let path = entry.path();
path == input.include.get_prefix() || input.include.is_match(path)
if path == input_prefix {
return true;
}
if let Ok(rel_path) = path.strip_prefix(&config.project_dir) {
input.include.is_match(rel_path)
} else {
false
}
})
{
let Ok(entry) = entry else { continue };
Expand Down
Loading