Skip to content

Commit 3fdfe9d

Browse files
authored
Cairo plugin reexports (#2000)
fixes #2004 - **Fix duplicated component dependency on itself** - **Cairo plugin reexports**
1 parent 92d48d4 commit 3fdfe9d

File tree

10 files changed

+519
-23
lines changed

10 files changed

+519
-23
lines changed

scarb/src/core/manifest/summary.rs

+2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ pub struct SummaryInner {
2424
pub package_id: PackageId,
2525
#[builder(default)]
2626
pub dependencies: Vec<ManifestDependency>,
27+
#[builder(default)]
28+
pub re_export_cairo_plugins: Vec<PackageName>,
2729
#[builder(default = false)]
2830
pub no_core: bool,
2931
#[builder(default)]

scarb/src/core/manifest/toml_manifest.rs

+4
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ pub struct TomlPackage {
203203
pub no_core: Option<bool>,
204204
pub cairo_version: Option<MaybeWorkspaceField<VersionReq>>,
205205
pub experimental_features: Option<Vec<SmolStr>>,
206+
pub re_export_cairo_plugins: Option<Vec<PackageName>>,
206207
}
207208

208209
#[derive(Clone, Debug, Serialize, Eq, PartialEq)]
@@ -490,9 +491,12 @@ impl TomlManifest {
490491

491492
let publish = package.publish.unwrap_or(true);
492493

494+
let re_export_cairo_plugins = package.re_export_cairo_plugins.clone().unwrap_or_default();
495+
493496
let summary = Summary::builder()
494497
.package_id(package_id)
495498
.dependencies(dependencies)
499+
.re_export_cairo_plugins(re_export_cairo_plugins)
496500
.no_core(no_core)
497501
.build();
498502

scarb/src/core/publishing/manifest_normalization.rs

+1
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ fn generate_package(pkg: &Package) -> Box<TomlPackage> {
8181
no_core: summary.no_core.then_some(true),
8282
cairo_version: metadata.cairo_version.clone().map(MaybeWorkspace::Defined),
8383
experimental_features: pkg.manifest.experimental_features.clone(),
84+
re_export_cairo_plugins: Some(pkg.manifest.summary.re_export_cairo_plugins.clone()),
8485
})
8586
}
8687

scarb/src/ops/resolve.rs

+55-18
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,50 @@ impl WorkspaceResolve {
5959
&self,
6060
package_id: PackageId,
6161
target_kind: &TargetKind,
62-
) -> Vec<Package> {
62+
) -> Result<Vec<Package>> {
6363
assert!(self.packages.contains_key(&package_id));
64-
self.resolve
64+
let dependencies = self
65+
.resolve
6566
.package_dependencies_for_target_kind(package_id, target_kind)
6667
.iter()
6768
.map(|id| self.packages[id].clone())
68-
.collect_vec()
69+
.collect_vec();
70+
71+
let re_exported = dependencies
72+
.iter()
73+
.flat_map(|dependency| {
74+
let package_dependencies = self
75+
.resolve
76+
.package_dependencies_for_target_kind(dependency.id, target_kind);
77+
dependency
78+
.manifest
79+
.summary
80+
.re_export_cairo_plugins
81+
.iter()
82+
.map(move |plugin_name| {
83+
package_dependencies
84+
.iter()
85+
.find(|id| id.name == *plugin_name)
86+
.map(|id| {
87+
self.packages.get(id).expect("workspace resolve packages must include all dependency graph nodes").clone()
88+
})
89+
.filter(|package| package.is_cairo_plugin())
90+
.map(Ok)
91+
.unwrap_or_else(|| {
92+
bail!(
93+
"package `{}` cannot re-export cairo plugin `{plugin_name}` which is not a dependency of `{}`",
94+
dependency.id.name, dependency.id.name)
95+
})
96+
})
97+
98+
})
99+
.collect_vec();
100+
101+
dependencies
102+
.into_iter()
103+
.map(Ok)
104+
.chain(re_exported)
105+
.collect::<Result<Vec<Package>>>()
69106
}
70107

71108
/// Get all dependencies with allowed prebuilt macros for a given package.
@@ -517,21 +554,23 @@ fn cairo_compilation_unit_for_target(
517554
.iter()
518555
.find(|component| component.package.id == member.id)
519556
.unwrap();
520-
let mut test_package_deps = solution.component_dependencies(member_component, &components);
521-
test_package_deps.push(CompilationUnitDependency::Library(
522-
member_component.id.clone(),
523-
));
557+
let mut test_package_deps = solution.component_dependencies(member_component, &components)?;
558+
if is_integration_test {
559+
test_package_deps.push(CompilationUnitDependency::Library(
560+
member_component.id.clone(),
561+
));
562+
}
524563

525564
let dependencies_for_components: Vec<_> = components
526565
.iter()
527566
.map(|component| {
528-
if component.package.id == test_package_id {
567+
Ok(if component.package.id == test_package_id {
529568
test_package_deps.clone()
530569
} else {
531-
solution.component_dependencies(component, &components)
532-
}
570+
solution.component_dependencies(component, &components)?
571+
})
533572
})
534-
.collect();
573+
.collect::<Result<Vec<_>>>()?;
535574

536575
for (component, dependencies) in zip(&mut components, dependencies_for_components) {
537576
component.dependencies = dependencies;
@@ -727,14 +766,14 @@ impl<'a> PackageSolutionCollector<'a> {
727766
&self,
728767
component: &CompilationUnitComponent,
729768
components: &[CompilationUnitComponent],
730-
) -> Vec<CompilationUnitDependency> {
769+
) -> Result<Vec<CompilationUnitDependency>> {
731770
let package_id = component.id.package_id;
732771
let component_target_kind = self.target_kind.as_ref().unwrap();
733772

734773
// Those are direct dependencies of the component.
735774
let dependencies_packages = self
736775
.resolve
737-
.package_dependencies(package_id, component_target_kind);
776+
.package_dependencies(package_id, component_target_kind)?;
738777

739778
// We iterate over all the compilation unit components to get dependency's version.
740779
let mut dependencies: Vec<_> = components
@@ -760,10 +799,8 @@ impl<'a> PackageSolutionCollector<'a> {
760799
dependencies.push(CompilationUnitDependency::Library(component.id.clone()));
761800
}
762801

763-
let plugin_dependencies = self
764-
.resolve
765-
.package_dependencies(package_id, component_target_kind)
766-
.into_iter()
802+
let plugin_dependencies = dependencies_packages
803+
.iter()
767804
.filter(|package| package.is_cairo_plugin())
768805
.map(|package| {
769806
CompilationUnitDependency::Plugin(CompilationUnitComponentId {
@@ -773,7 +810,7 @@ impl<'a> PackageSolutionCollector<'a> {
773810
.collect::<Vec<_>>();
774811

775812
dependencies.extend(plugin_dependencies);
776-
dependencies
813+
Ok(dependencies)
777814
}
778815

779816
pub fn show_warnings(self) {

scarb/tests/build_cairo_plugin.rs

+66
Original file line numberDiff line numberDiff line change
@@ -1559,3 +1559,69 @@ fn can_expand_impl_inner_func_attrr() {
15591559
15601560
"#});
15611561
}
1562+
1563+
#[test]
1564+
fn can_be_used_through_re_export() {
1565+
let temp = TempDir::new().unwrap();
1566+
let t = temp.child("some");
1567+
CairoPluginProjectBuilder::default()
1568+
.lib_rs(indoc! {r##"
1569+
use cairo_lang_macro::{ProcMacroResult, TokenStream, attribute_macro};
1570+
1571+
#[attribute_macro]
1572+
pub fn some(_attr: TokenStream, token_stream: TokenStream) -> ProcMacroResult {
1573+
let token_stream = TokenStream::new(
1574+
token_stream
1575+
.to_string()
1576+
.replace("12", "34")
1577+
);
1578+
ProcMacroResult::new(token_stream)
1579+
}
1580+
"##})
1581+
.build(&t);
1582+
let dep = temp.child("dep");
1583+
ProjectBuilder::start()
1584+
.name("dep")
1585+
.version("1.0.0")
1586+
.dep("some", &t)
1587+
.manifest_package_extra(indoc! {r#"
1588+
re-export-cairo-plugins = ["some"]
1589+
"#})
1590+
.build(&dep);
1591+
let project = temp.child("hello");
1592+
ProjectBuilder::start()
1593+
.name("hello")
1594+
.version("1.0.0")
1595+
.dep("dep", &dep)
1596+
.lib_cairo(indoc! {r#"
1597+
#[some]
1598+
fn main() -> felt252 { 12 }
1599+
"#})
1600+
.build(&project);
1601+
1602+
Scarb::quick_snapbox()
1603+
.arg("expand")
1604+
// Disable output from Cargo.
1605+
.env("CARGO_TERM_QUIET", "true")
1606+
.current_dir(&project)
1607+
.assert()
1608+
.success();
1609+
1610+
assert_eq!(
1611+
project.child("target/dev").files(),
1612+
vec!["hello.expanded.cairo"]
1613+
);
1614+
let expanded = project
1615+
.child("target/dev/hello.expanded.cairo")
1616+
.read_to_string();
1617+
snapbox::assert_eq(
1618+
indoc! {r#"
1619+
mod hello {
1620+
fn main() -> felt252 {
1621+
34
1622+
}
1623+
}
1624+
"#},
1625+
expanded,
1626+
);
1627+
}

0 commit comments

Comments
 (0)