Skip to content

Commit

Permalink
refactor!: make rockspec source optional
Browse files Browse the repository at this point in the history
  • Loading branch information
vhyrro committed Feb 3, 2025
1 parent f3a9749 commit 4ab8aca
Show file tree
Hide file tree
Showing 10 changed files with 148 additions and 40 deletions.
5 changes: 3 additions & 2 deletions rocks-lib/src/build/luarocks.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::lua_rockspec::Remote;
use crate::rockspec::LuaVersionCompatibility;
use crate::rockspec::Rockspec;
use std::{io, path::Path};
Expand Down Expand Up @@ -26,7 +27,7 @@ pub enum LuarocksBuildError {
ExecLuaRocksError(#[from] ExecLuaRocksError),
}

pub(crate) async fn build<R: Rockspec>(
pub(crate) async fn build<R: Rockspec<RType = Remote>>(
rockspec: &R,
output_paths: &RockLayout,
lua: &LuaInstallation,
Expand Down Expand Up @@ -54,7 +55,7 @@ pub(crate) async fn build<R: Rockspec>(
install(rockspec, &luarocks_tree.into_path(), output_paths, config)
}

fn install<R: Rockspec>(
fn install<R: Rockspec<RType = Remote>>(
rockspec: &R,
luarocks_tree: &Path,
output_paths: &RockLayout,
Expand Down
11 changes: 6 additions & 5 deletions rocks-lib/src/build/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::lua_rockspec::Remote;
use crate::rockspec::LuaVersionCompatibility;
use crate::{lua_rockspec::LuaVersionError, rockspec::Rockspec};
use std::{io, path::Path, process::ExitStatus};
Expand Down Expand Up @@ -44,7 +45,7 @@ pub mod variables;
/// over how a package should be built.
#[derive(Builder)]
#[builder(start_fn = new, finish_fn(name = _build, vis = ""))]
pub struct Build<'a, R: Rockspec + HasIntegrity> {
pub struct Build<'a, R: Rockspec<RType = Remote> + HasIntegrity> {
#[builder(start_fn)]
rockspec: &'a R,
#[builder(start_fn)]
Expand All @@ -65,7 +66,7 @@ pub struct Build<'a, R: Rockspec + HasIntegrity> {
}

// Overwrite the `build()` function to use our own instead.
impl<R: Rockspec + HasIntegrity, State> BuildBuilder<'_, R, State>
impl<R: Rockspec<RType = Remote> + HasIntegrity, State> BuildBuilder<'_, R, State>
where
State: build_builder::State + build_builder::IsComplete,
{
Expand Down Expand Up @@ -135,7 +136,7 @@ impl From<bool> for BuildBehaviour {
}
}

async fn run_build<R: Rockspec>(
async fn run_build<R: Rockspec<RType = Remote>>(
rockspec: &R,
output_paths: &RockLayout,
lua: &LuaInstallation,
Expand Down Expand Up @@ -180,7 +181,7 @@ async fn run_build<R: Rockspec>(
)
}

async fn install<R: Rockspec>(
async fn install<R: Rockspec<RType = Remote>>(
rockspec: &R,
tree: &Tree,
output_paths: &RockLayout,
Expand Down Expand Up @@ -233,7 +234,7 @@ async fn install<R: Rockspec>(
Ok(())
}

async fn do_build<R: Rockspec + HasIntegrity>(
async fn do_build<R: Rockspec<RType = Remote> + HasIntegrity>(
build: Build<'_, R>,
) -> Result<LocalPackage, BuildError> {
build.progress.map(|p| {
Expand Down
2 changes: 1 addition & 1 deletion rocks-lib/src/lockfile/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,7 @@ pub struct Lockfile<P: LockfilePermissions> {

#[derive(Error, Debug)]
pub enum LockfileIntegrityError {
#[error("rockspec integirty mismatch.\nExpected: {expected}\nBut got: {got}")]
#[error("rockspec integrity mismatch.\nExpected: {expected}\nBut got: {got}")]
RockspecIntegrityMismatch { expected: Integrity, got: Integrity },
#[error("source integrity mismatch.\nExpected: {expected}\nBut got: {got}")]
SourceIntegrityMismatch { expected: Integrity, got: Integrity },
Expand Down
31 changes: 25 additions & 6 deletions rocks-lib/src/lua_rockspec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,26 @@ pub enum RockspecError {
LuaTable(#[from] LuaTableError),
}

pub trait RockspecType {
type SourceType: PartialEq + Clone + ::std::fmt::Debug + DeserializeOwned;
}

#[derive(Clone, Debug, PartialEq)]
pub struct Local;
#[derive(Clone, Debug, PartialEq)]
pub struct Remote;

impl RockspecType for Local {
type SourceType = Option<RockSourceSpec>;
}

impl RockspecType for Remote {
type SourceType = RockSourceSpec;
}

#[derive(Clone, Debug)]
#[cfg_attr(test, derive(PartialEq))]
pub struct LuaRockspec {
pub struct LuaRockspec<T: RockspecType = Remote> {
/// The file format version. Example: "1.0"
rockspec_format: Option<RockspecFormat>,
/// The name of the package. Example: "luasocket"
Expand All @@ -54,7 +71,7 @@ pub struct LuaRockspec {
build_dependencies: PerPlatform<Vec<PackageReq>>,
external_dependencies: PerPlatform<HashMap<String, ExternalDependencySpec>>,
test_dependencies: PerPlatform<Vec<PackageReq>>,
source: PerPlatform<RockSource>,
source: PerPlatform<RockSource<T>>,
build: PerPlatform<BuildSpec>,
test: PerPlatform<TestSpec>,
/// The original content of this rockspec, needed by luarocks
Expand All @@ -63,7 +80,7 @@ pub struct LuaRockspec {
hash: Integrity,
}

impl LuaRockspec {
impl LuaRockspec<Remote> {
pub fn new(rockspec_content: &str) -> Result<Self, RockspecError> {
let lua = Lua::new();
lua.load(rockspec_content).exec()?;
Expand Down Expand Up @@ -110,7 +127,9 @@ impl LuaRockspec {
}
}

impl Rockspec for LuaRockspec {
impl<T: RockspecType> Rockspec for LuaRockspec<T> {
type RType = T;

fn package(&self) -> &PackageName {
&self.package
}
Expand Down Expand Up @@ -139,7 +158,7 @@ impl Rockspec for LuaRockspec {
&self.test_dependencies
}

fn source(&self) -> &PerPlatform<RockSource> {
fn source(&self) -> &PerPlatform<RockSource<T>> {
&self.source
}

Expand All @@ -155,7 +174,7 @@ impl Rockspec for LuaRockspec {
&self.supported_platforms
}

fn source_mut(&mut self) -> &mut PerPlatform<RockSource> {
fn source_mut(&mut self) -> &mut PerPlatform<RockSource<T>> {
&mut self.source
}

Expand Down
84 changes: 79 additions & 5 deletions rocks-lib/src/lua_rockspec/rock_source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ use thiserror::Error;

use super::{
DisplayAsLuaKV, DisplayLuaKV, DisplayLuaValue, FromPlatformOverridable, PartialOverride,
PerPlatform, PerPlatformWrapper, PlatformOverridable,
PerPlatform, PerPlatformWrapper, PlatformOverridable, RockspecType,
};

#[derive(Deserialize, Clone, Debug, PartialEq)]
pub struct RockSource {
pub source_spec: RockSourceSpec,
pub struct RockSource<T: RockspecType> {
pub source_spec: T::SourceType,
pub integrity: Option<Integrity>,
pub archive_name: Option<String>,
pub unpack_dir: Option<PathBuf>,
Expand All @@ -29,7 +29,7 @@ pub enum RockSourceError {
SourceUrl(#[from] SourceUrlError),
}

impl FromPlatformOverridable<RockSourceInternal, Self> for RockSource {
impl FromPlatformOverridable<RockSourceInternal, Self> for RockSource<super::Remote> {
type Err = RockSourceError;

fn from_platform_overridable(internal: RockSourceInternal) -> Result<Self, Self::Err> {
Expand Down Expand Up @@ -80,7 +80,81 @@ impl FromPlatformOverridable<RockSourceInternal, Self> for RockSource {
}
}

impl FromLua for PerPlatform<RockSource> {
impl FromPlatformOverridable<RockSourceInternal, Self> for RockSource<super::Local> {
type Err = RockSourceError;

fn from_platform_overridable(internal: RockSourceInternal) -> Result<Self, Self::Err> {
match internal.url {
Some(url) => {
let url = SourceUrl::from_str(&url)?;

// The rockspec.source table allows invalid combinations
// This ensures that invalid combinations are caught while parsing.
let source_spec = match (url, internal.tag, internal.branch, internal.module) {
(source, None, None, None) => {
Ok(RockSourceSpec::default_from_source_url(source))
}
(SourceUrl::Cvs(url), None, None, Some(module)) => {
Ok(RockSourceSpec::Cvs(CvsSource { url, module }))
}
(SourceUrl::Git(url), Some(tag), None, None) => {
Ok(RockSourceSpec::Git(GitSource {
url,
checkout_ref: Some(tag),
}))
}
(SourceUrl::Git(url), None, Some(branch), None) => {
Ok(RockSourceSpec::Git(GitSource {
url,
checkout_ref: Some(branch),
}))
}
(SourceUrl::Mercurial(url), Some(tag), None, None) => {
Ok(RockSourceSpec::Mercurial(MercurialSource {
url,
checkout_ref: Some(tag),
}))
}
(SourceUrl::Mercurial(url), None, Some(branch), None) => {
Ok(RockSourceSpec::Mercurial(MercurialSource {
url,
checkout_ref: Some(branch),
}))
}
(SourceUrl::Sscm(url), None, None, Some(module)) => {
Ok(RockSourceSpec::Sscm(SscmSource { url, module }))
}
(SourceUrl::Svn(url), tag, None, module) => {
Ok(RockSourceSpec::Svn(SvnSource { url, tag, module }))
}
_ => Err(RockSourceError::InvalidCombination),
}?;

Ok(RockSource {
source_spec: Some(source_spec),
integrity: internal.hash,
archive_name: internal.file,
unpack_dir: internal.dir,
})
}
None => Ok(RockSource {
source_spec: None,
integrity: internal.hash,
archive_name: internal.file,
unpack_dir: internal.dir,
}),
}
}
}

impl FromLua for PerPlatform<RockSource<super::Local>> {
fn from_lua(value: Value, lua: &Lua) -> mlua::Result<Self> {
let wrapper = PerPlatformWrapper::from_lua(value, lua)?;
Ok(wrapper.un_per_platform)
}
}

impl FromLua for PerPlatform<RockSource<super::Remote>> {
fn from_lua(value: Value, lua: &Lua) -> mlua::Result<Self> {
let wrapper = PerPlatformWrapper::from_lua(value, lua)?;
Ok(wrapper.un_per_platform)
Expand Down
4 changes: 2 additions & 2 deletions rocks-lib/src/luarocks/luarocks_installation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::{
config::{Config, LuaVersion, LuaVersionUnset},
lockfile::{LocalPackage, LocalPackageId, PinnedState},
lua_installation::LuaInstallation,
lua_rockspec::{LuaRockspec, RockspecFormat},
lua_rockspec::{LuaRockspec, Remote, RockspecFormat},
operations::{get_all_dependencies, SearchAndDownloadError},
package::PackageReq,
path::Paths,
Expand Down Expand Up @@ -117,7 +117,7 @@ impl LuaRocksInstallation {
Ok(())
}

pub async fn install_build_dependencies<R: Rockspec>(
pub async fn install_build_dependencies<R: Rockspec<RType = Remote>>(
&self,
build_backend: &str,
rocks: &R,
Expand Down
9 changes: 6 additions & 3 deletions rocks-lib/src/operations/fetch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use thiserror::Error;

use crate::config::Config;
use crate::hash::HasIntegrity;
use crate::lua_rockspec::Remote;
use crate::lua_rockspec::RockSourceSpec;
use crate::operations;
use crate::package::PackageSpec;
Expand All @@ -29,7 +30,7 @@ use super::DownloadSrcRockError;
/// over how a package should be fetched.
#[derive(Builder)]
#[builder(start_fn = new, finish_fn(name = _build, vis = ""))]
pub struct FetchSrc<'a, R: Rockspec> {
pub struct FetchSrc<'a, R: Rockspec<RType = Remote>> {
#[builder(start_fn)]
dest_dir: &'a Path,
#[builder(start_fn)]
Expand All @@ -40,7 +41,7 @@ pub struct FetchSrc<'a, R: Rockspec> {
progress: &'a Progress<ProgressBar>,
}

impl<R: Rockspec, State> FetchSrcBuilder<'_, R, State>
impl<R: Rockspec<RType = Remote>, State> FetchSrcBuilder<'_, R, State>
where
State: fetch_src_builder::State + fetch_src_builder::IsComplete,
{
Expand Down Expand Up @@ -120,7 +121,9 @@ pub enum FetchSrcRockError {
Io(#[from] io::Error),
}

async fn do_fetch_src<R: Rockspec>(fetch: &FetchSrc<'_, R>) -> Result<Integrity, FetchSrcError> {
async fn do_fetch_src<R: Rockspec<RType = Remote>>(
fetch: &FetchSrc<'_, R>,
) -> Result<Integrity, FetchSrcError> {
let rockspec = fetch.rockspec;
let rock_source = rockspec.source().current_platform();
let progress = fetch.progress;
Expand Down
5 changes: 3 additions & 2 deletions rocks-lib/src/operations/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::{io, process::Command, sync::Arc};
use crate::{
build::BuildBehaviour,
config::Config,
lua_rockspec::RockspecType,
package::{PackageName, PackageReq, PackageVersionReqError},
path::Paths,
progress::{MultiProgress, Progress},
Expand Down Expand Up @@ -162,8 +163,8 @@ pub async fn ensure_busted(

/// Ensure dependencies and test dependencies are installed
/// This defaults to the local project tree if cwd is a project root.
async fn ensure_dependencies(
rockspec: &impl Rockspec,
async fn ensure_dependencies<T: RockspecType>(
rockspec: &impl Rockspec<RType = T>,
tree: &Tree,
config: &Config,
progress: Arc<Progress<MultiProgress>>,
Expand Down
Loading

0 comments on commit 4ab8aca

Please sign in to comment.