mirror of
https://github.com/pesde-pkg/pesde.git
synced 2024-12-12 11:00:36 +00:00
feat: add PESDE_ROOT for bin packages
This commit is contained in:
parent
71eacb8673
commit
d321b8b0aa
10 changed files with 188 additions and 151 deletions
|
@ -1,11 +1,8 @@
|
|||
use std::{ffi::OsString, process::Command};
|
||||
|
||||
use crate::cli::{config::read_config, VersionedPackageName};
|
||||
use anyhow::Context;
|
||||
use clap::Args;
|
||||
use semver::VersionReq;
|
||||
|
||||
use crate::cli::{config::read_config, VersionedPackageName};
|
||||
use pesde::{
|
||||
linking::generator::generate_bin_linking_module,
|
||||
manifest::target::TargetKind,
|
||||
names::PackageName,
|
||||
source::{
|
||||
|
@ -14,6 +11,8 @@ use pesde::{
|
|||
},
|
||||
Project,
|
||||
};
|
||||
use semver::VersionReq;
|
||||
use std::{env::current_dir, ffi::OsString, io::Write, process::Command};
|
||||
|
||||
#[derive(Debug, Args)]
|
||||
pub struct ExecuteCommand {
|
||||
|
@ -72,15 +71,28 @@ impl ExecuteCommand {
|
|||
fs.write_to(tempdir.path(), project.cas_dir(), true)
|
||||
.context("failed to write package contents")?;
|
||||
|
||||
let mut caller =
|
||||
tempfile::NamedTempFile::new_in(tempdir.path()).context("failed to create tempfile")?;
|
||||
caller
|
||||
.write_all(
|
||||
generate_bin_linking_module(
|
||||
tempdir.path(),
|
||||
&format!("{:?}", bin_path.to_path(tempdir.path())),
|
||||
)
|
||||
.as_bytes(),
|
||||
)
|
||||
.context("failed to write to tempfile")?;
|
||||
|
||||
let status = Command::new("lune")
|
||||
.arg("run")
|
||||
.arg(bin_path.to_path(tempdir.path()))
|
||||
.arg(caller.path())
|
||||
.arg("--")
|
||||
.args(&self.args)
|
||||
.current_dir(project.package_dir())
|
||||
.current_dir(current_dir().context("failed to get current directory")?)
|
||||
.status()
|
||||
.context("failed to run script")?;
|
||||
|
||||
drop(caller);
|
||||
drop(tempdir);
|
||||
|
||||
std::process::exit(status.code().unwrap_or(1))
|
||||
|
|
|
@ -9,22 +9,17 @@ use pesde::{
|
|||
errors::ManifestReadError, names::PackageName, scripts::ScriptName, Project, DEFAULT_INDEX_NAME,
|
||||
};
|
||||
|
||||
use crate::cli::config::read_config;
|
||||
use crate::cli::{config::read_config, HOME_DIR};
|
||||
|
||||
#[derive(Debug, Args)]
|
||||
pub struct InitCommand {}
|
||||
|
||||
fn script_contents(path: &Path) -> String {
|
||||
format!(
|
||||
concat!(
|
||||
r#"local process = require("@lune/process")
|
||||
r#"local process = require("@lune/process")
|
||||
local home_dir = if process.os == "windows" then process.env.userprofile else process.env.HOME
|
||||
|
||||
require(home_dir .. ""#,
|
||||
"/.",
|
||||
env!("CARGO_PKG_NAME"),
|
||||
r#"/scripts/{}")"#,
|
||||
),
|
||||
require(home_dir .. "/{HOME_DIR}/scripts/{}"#,
|
||||
path.display()
|
||||
)
|
||||
}
|
||||
|
|
|
@ -43,7 +43,6 @@ fn bin_link_file(alias: &str) -> String {
|
|||
let prefix = String::new();
|
||||
#[cfg(unix)]
|
||||
let prefix = "#!/usr/bin/env -S lune run\n";
|
||||
// TODO: reimplement workspace support in this
|
||||
format!(
|
||||
r#"{prefix}local process = require("@lune/process")
|
||||
local fs = require("@lune/fs")
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
use std::{ffi::OsString, path::PathBuf, process::Command};
|
||||
|
||||
use crate::cli::up_to_date_lockfile;
|
||||
use anyhow::Context;
|
||||
use clap::Args;
|
||||
use relative_path::RelativePathBuf;
|
||||
|
||||
use crate::cli::up_to_date_lockfile;
|
||||
use pesde::{
|
||||
linking::generator::generate_bin_linking_module,
|
||||
names::{PackageName, PackageNames},
|
||||
source::traits::PackageRef,
|
||||
Project, PACKAGES_CONTAINER_NAME,
|
||||
};
|
||||
use relative_path::RelativePathBuf;
|
||||
use std::{env::current_dir, ffi::OsString, io::Write, path::PathBuf, process::Command};
|
||||
|
||||
#[derive(Debug, Args)]
|
||||
pub struct RunCommand {
|
||||
|
@ -25,15 +24,28 @@ pub struct RunCommand {
|
|||
impl RunCommand {
|
||||
pub fn run(self, project: Project) -> anyhow::Result<()> {
|
||||
let run = |path: PathBuf| {
|
||||
let mut caller = tempfile::NamedTempFile::new().expect("failed to create tempfile");
|
||||
caller
|
||||
.write_all(
|
||||
generate_bin_linking_module(
|
||||
project.package_dir(),
|
||||
&format!("{:?}", path.to_string_lossy()),
|
||||
)
|
||||
.as_bytes(),
|
||||
)
|
||||
.expect("failed to write to tempfile");
|
||||
|
||||
let status = Command::new("lune")
|
||||
.arg("run")
|
||||
.arg(path)
|
||||
.arg(caller.path())
|
||||
.arg("--")
|
||||
.args(&self.args)
|
||||
.current_dir(project.package_dir())
|
||||
.current_dir(current_dir().expect("failed to get current directory"))
|
||||
.status()
|
||||
.expect("failed to run script");
|
||||
|
||||
drop(caller);
|
||||
|
||||
std::process::exit(status.code().unwrap_or(1))
|
||||
};
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ pub mod auth;
|
|||
pub mod commands;
|
||||
pub mod config;
|
||||
pub mod files;
|
||||
pub mod scripts;
|
||||
pub mod repos;
|
||||
pub mod version;
|
||||
|
||||
pub const HOME_DIR: &str = concat!(".", env!("CARGO_PKG_NAME"));
|
||||
|
|
114
src/cli/repos.rs
Normal file
114
src/cli/repos.rs
Normal file
|
@ -0,0 +1,114 @@
|
|||
use crate::{
|
||||
cli::{config::read_config, home_dir},
|
||||
util::authenticate_conn,
|
||||
};
|
||||
use anyhow::Context;
|
||||
use gix::remote::Direction;
|
||||
use pesde::Project;
|
||||
use std::path::Path;
|
||||
|
||||
fn update_repo<P: AsRef<Path>>(
|
||||
name: &str,
|
||||
path: P,
|
||||
url: gix::Url,
|
||||
project: &Project,
|
||||
) -> anyhow::Result<()> {
|
||||
let path = path.as_ref();
|
||||
if path.exists() {
|
||||
let repo = gix::open(path).context(format!("failed to open {name} repository"))?;
|
||||
|
||||
let remote = repo
|
||||
.find_default_remote(Direction::Fetch)
|
||||
.context(format!("missing default remote of {name} repository"))?
|
||||
.context(format!(
|
||||
"failed to find default remote of {name} repository"
|
||||
))?;
|
||||
|
||||
let mut connection = remote.connect(Direction::Fetch).context(format!(
|
||||
"failed to connect to default remote of {name} repository"
|
||||
))?;
|
||||
|
||||
authenticate_conn(&mut connection, project.auth_config());
|
||||
|
||||
let results = connection
|
||||
.prepare_fetch(gix::progress::Discard, Default::default())
|
||||
.context(format!("failed to prepare {name} repository fetch"))?
|
||||
.receive(gix::progress::Discard, &false.into())
|
||||
.context(format!("failed to receive new {name} repository contents"))?;
|
||||
|
||||
let remote_ref = results
|
||||
.ref_map
|
||||
.remote_refs
|
||||
.first()
|
||||
.context(format!("failed to get remote refs of {name} repository"))?;
|
||||
|
||||
let unpacked = remote_ref.unpack();
|
||||
let oid = unpacked
|
||||
.1
|
||||
.or(unpacked.2)
|
||||
.context("couldn't find oid in remote ref")?;
|
||||
|
||||
let tree = repo
|
||||
.find_object(oid)
|
||||
.context(format!("failed to find {name} repository tree"))?
|
||||
.peel_to_tree()
|
||||
.context(format!("failed to peel {name} repository object to tree"))?;
|
||||
|
||||
let mut index = gix::index::File::from_state(
|
||||
gix::index::State::from_tree(&tree.id, &repo.objects, Default::default()).context(
|
||||
format!("failed to create index state from {name} repository tree"),
|
||||
)?,
|
||||
repo.index_path(),
|
||||
);
|
||||
|
||||
let opts = gix::worktree::state::checkout::Options {
|
||||
overwrite_existing: true,
|
||||
destination_is_initially_empty: false,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
gix::worktree::state::checkout(
|
||||
&mut index,
|
||||
repo.work_dir().context(format!("{name} repo is bare"))?,
|
||||
repo.objects
|
||||
.clone()
|
||||
.into_arc()
|
||||
.context("failed to clone objects")?,
|
||||
&gix::progress::Discard,
|
||||
&gix::progress::Discard,
|
||||
&false.into(),
|
||||
opts,
|
||||
)
|
||||
.context(format!("failed to checkout {name} repository"))?;
|
||||
|
||||
index
|
||||
.write(gix::index::write::Options::default())
|
||||
.context("failed to write index")?;
|
||||
} else {
|
||||
std::fs::create_dir_all(path).context(format!("failed to create {name} directory"))?;
|
||||
|
||||
gix::prepare_clone(url, path)
|
||||
.context(format!("failed to prepare {name} repository clone"))?
|
||||
.fetch_then_checkout(gix::progress::Discard, &false.into())
|
||||
.context(format!("failed to fetch and checkout {name} repository"))?
|
||||
.0
|
||||
.main_worktree(gix::progress::Discard, &false.into())
|
||||
.context(format!("failed to set {name} repository as main worktree"))?;
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn update_repo_dependencies(project: &Project) -> anyhow::Result<()> {
|
||||
let home_dir = home_dir()?;
|
||||
let config = read_config()?;
|
||||
|
||||
update_repo(
|
||||
"scripts",
|
||||
home_dir.join("scripts"),
|
||||
config.scripts_repo,
|
||||
project,
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -1,94 +0,0 @@
|
|||
use crate::{
|
||||
cli::{config::read_config, home_dir},
|
||||
util::authenticate_conn,
|
||||
};
|
||||
use anyhow::Context;
|
||||
use gix::remote::Direction;
|
||||
use pesde::Project;
|
||||
|
||||
pub fn update_scripts_folder(project: &Project) -> anyhow::Result<()> {
|
||||
let scripts_dir = home_dir()?.join("scripts");
|
||||
|
||||
if scripts_dir.exists() {
|
||||
let repo = gix::open(&scripts_dir).context("failed to open scripts repository")?;
|
||||
|
||||
let remote = repo
|
||||
.find_default_remote(Direction::Fetch)
|
||||
.context("missing default remote of scripts repository")?
|
||||
.context("failed to find default remote of scripts repository")?;
|
||||
|
||||
let mut connection = remote
|
||||
.connect(Direction::Fetch)
|
||||
.context("failed to connect to default remote of scripts repository")?;
|
||||
|
||||
authenticate_conn(&mut connection, project.auth_config());
|
||||
|
||||
let results = connection
|
||||
.prepare_fetch(gix::progress::Discard, Default::default())
|
||||
.context("failed to prepare scripts repository fetch")?
|
||||
.receive(gix::progress::Discard, &false.into())
|
||||
.context("failed to receive new scripts repository contents")?;
|
||||
|
||||
let remote_ref = results
|
||||
.ref_map
|
||||
.remote_refs
|
||||
.first()
|
||||
.context("failed to get remote refs of scripts repository")?;
|
||||
|
||||
let unpacked = remote_ref.unpack();
|
||||
let oid = unpacked
|
||||
.1
|
||||
.or(unpacked.2)
|
||||
.context("couldn't find oid in remote ref")?;
|
||||
|
||||
let tree = repo
|
||||
.find_object(oid)
|
||||
.context("failed to find scripts repository tree")?
|
||||
.peel_to_tree()
|
||||
.context("failed to peel scripts repository object to tree")?;
|
||||
|
||||
let mut index = gix::index::File::from_state(
|
||||
gix::index::State::from_tree(&tree.id, &repo.objects, Default::default())
|
||||
.context("failed to create index state from scripts repository tree")?,
|
||||
repo.index_path(),
|
||||
);
|
||||
|
||||
let opts = gix::worktree::state::checkout::Options {
|
||||
overwrite_existing: true,
|
||||
destination_is_initially_empty: false,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
gix::worktree::state::checkout(
|
||||
&mut index,
|
||||
repo.work_dir().context("scripts repo is bare")?,
|
||||
repo.objects
|
||||
.clone()
|
||||
.into_arc()
|
||||
.context("failed to clone objects")?,
|
||||
&gix::progress::Discard,
|
||||
&gix::progress::Discard,
|
||||
&false.into(),
|
||||
opts,
|
||||
)
|
||||
.context("failed to checkout scripts repository")?;
|
||||
|
||||
index
|
||||
.write(gix::index::write::Options::default())
|
||||
.context("failed to write index")?;
|
||||
} else {
|
||||
std::fs::create_dir_all(&scripts_dir).context("failed to create scripts directory")?;
|
||||
|
||||
let cli_config = read_config()?;
|
||||
|
||||
gix::prepare_clone(cli_config.scripts_repo, &scripts_dir)
|
||||
.context("failed to prepare scripts repository clone")?
|
||||
.fetch_then_checkout(gix::progress::Discard, &false.into())
|
||||
.context("failed to fetch and checkout scripts repository")?
|
||||
.0
|
||||
.main_worktree(gix::progress::Discard, &false.into())
|
||||
.context("failed to set scripts repository as main worktree")?;
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -125,8 +125,12 @@ pub fn get_lib_require_path(
|
|||
}
|
||||
|
||||
/// Generate a linking module for a binary
|
||||
pub fn generate_bin_linking_module(path: &str) -> String {
|
||||
format!("return require({path})")
|
||||
pub fn generate_bin_linking_module<P: AsRef<Path>>(package_root: P, require_path: &str) -> String {
|
||||
format!(
|
||||
r#"_G.PESDE_ROOT = {:?}
|
||||
return require({require_path})"#,
|
||||
package_root.as_ref().to_string_lossy()
|
||||
)
|
||||
}
|
||||
|
||||
/// Get the require path for a binary
|
||||
|
|
|
@ -139,14 +139,15 @@ impl Project {
|
|||
version_id.version(),
|
||||
);
|
||||
|
||||
if let Some((alias, types)) = package_types
|
||||
.get(name)
|
||||
.and_then(|v| v.get(version_id))
|
||||
.and_then(|types| {
|
||||
node.node.direct.as_ref().map(|(alias, _)| (alias, types))
|
||||
})
|
||||
{
|
||||
if let Some(lib_file) = node.target.lib_path() {
|
||||
if let Some((alias, _)) = &node.node.direct.as_ref() {
|
||||
if let Some((lib_file, types)) =
|
||||
node.target.lib_path().and_then(|lib_file| {
|
||||
package_types
|
||||
.get(name)
|
||||
.and_then(|v| v.get(version_id))
|
||||
.map(|types| (lib_file, types))
|
||||
})
|
||||
{
|
||||
write_cas(
|
||||
base_folder.join(format!("{alias}.luau")),
|
||||
self.cas_dir(),
|
||||
|
@ -168,6 +169,7 @@ impl Project {
|
|||
base_folder.join(format!("{alias}.bin.luau")),
|
||||
self.cas_dir(),
|
||||
&generator::generate_bin_linking_module(
|
||||
&container_folder,
|
||||
&generator::get_bin_require_path(
|
||||
&base_folder,
|
||||
bin_file,
|
||||
|
|
39
src/main.rs
39
src/main.rs
|
@ -14,7 +14,7 @@ use crate::cli::{
|
|||
auth::get_token,
|
||||
config::read_config,
|
||||
home_dir,
|
||||
scripts::update_scripts_folder,
|
||||
repos::update_repo_dependencies,
|
||||
version::{check_for_updates, current_version, get_or_download_version, max_installed_version},
|
||||
HOME_DIR,
|
||||
};
|
||||
|
@ -258,32 +258,18 @@ fn run() -> anyhow::Result<()> {
|
|||
std::process::exit(status.code().unwrap());
|
||||
}
|
||||
|
||||
match check_for_updates(&reqwest) {
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
println!(
|
||||
"{}",
|
||||
format!("failed to check for updates: {e}\n\n").red().bold()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
match update_scripts_folder(&project) {
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
println!(
|
||||
"{}",
|
||||
format!("failed to update scripts: {e}\n\n").red().bold()
|
||||
);
|
||||
}
|
||||
}
|
||||
display_err(check_for_updates(&reqwest), " while checking for updates");
|
||||
display_err(
|
||||
update_repo_dependencies(&project),
|
||||
" while updating repository dependencies",
|
||||
);
|
||||
|
||||
Cli::parse().subcommand.run(project, multi, reqwest)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
if let Err(err) = run() {
|
||||
eprintln!("{}: {err}\n", "error".red().bold());
|
||||
fn display_err(result: anyhow::Result<()>, prefix: &str) {
|
||||
if let Err(err) = result {
|
||||
eprintln!("{}: {err}\n", format!("error{prefix}").red().bold());
|
||||
|
||||
let cause = err.chain().skip(1).collect::<Vec<_>>();
|
||||
|
||||
|
@ -309,7 +295,14 @@ fn main() {
|
|||
eprintln!("\n{}: not captured", "backtrace".yellow().bold());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let result = run();
|
||||
let is_err = result.is_err();
|
||||
display_err(result, "");
|
||||
if is_err {
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue