Skip to content

Commit 348030b

Browse files
committed
fix: Actually working system packages!
This is fixed by prefixing the auto-import with `inherited-` if: The auto-import is for the dependency that has a `provided-via` attribute which has the value of the path to a local ftd file that overrides the contents of this dependency. After the prefix is added. We check for this prefix while resolving imports, if the imported module starts with `inherited-` we instead read it's `provided-via` file path and load its contents instead. This way even the third party dependencies end up importing this `imported-` module by sourcing the `provided-via` path. The users don't have to know about this `inherited-` prefixing as it is done by the framework to the auto imports only. Explicitly importing the `provided-via` package by its name works as usual and will import the un-overriden original variant of the dependency. This is useful in case where you want to override a few components in your `provided-via` file but re-export original symbols by importing the original dependency. fixes: #2139
1 parent 8aa6699 commit 348030b

5 files changed

Lines changed: 113 additions & 34 deletions

File tree

fastn-core/src/doc.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,15 +68,26 @@ pub async fn interpret_helper(
6868
caller_module,
6969
} => {
7070
tracing::info!("stuck on import: {module}");
71+
// TODO: also check if module in in dependencies of this package
72+
let caller_module = if module.starts_with("inherited-") {
73+
// We want to use the main package name as the caller_module for this as the
74+
// inherited- package's provided-via path can only be read from the main
75+
// package.
76+
name
77+
} else {
78+
&caller_module
79+
};
80+
7181
let (source, path, foreign_variable, foreign_function, ignore_line_numbers) =
7282
resolve_import_2022(
7383
lib,
7484
&mut st,
7585
module.as_str(),
76-
caller_module.as_str(),
86+
caller_module,
7787
preview_session_id,
7888
)
7989
.await?;
90+
tracing::info!("import resolved: {module} -> {path}");
8091
lib.dependencies_during_render.push(path);
8192
let doc = cached_parse(module.as_str(), source.as_str(), ignore_line_numbers)?;
8293
s = st.continue_after_import(
@@ -137,7 +148,7 @@ pub async fn interpret_helper(
137148
Ok(document)
138149
}
139150

140-
// source, foreign_variable, foreign_function
151+
/// returns: (source, path, foreign_variable, foreign_function, ignore_line_numbers)
141152
#[allow(clippy::type_complexity)]
142153
#[tracing::instrument(skip(lib, _state))]
143154
pub async fn resolve_import_2022(

fastn-core/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ async fn original_package_status(
9090
} else {
9191
let body_prefix = config
9292
.package
93-
.generate_prefix_string(false)
93+
.generate_prefix_string(&config.package, false)
9494
.unwrap_or_default();
9595
format!(
9696
"{}\n\n-- import: {}/original-status as pi\n\n-- pi.original-status-page:",
@@ -116,7 +116,7 @@ async fn translation_package_status(
116116
} else {
117117
let body_prefix = config
118118
.package
119-
.generate_prefix_string(false)
119+
.generate_prefix_string(&config.package, false)
120120
.unwrap_or_default();
121121
format!(
122122
"{}\n\n-- import: {}/translation-status as pi\n\n-- pi.translation-status-page:",

fastn-core/src/library2022/mod.rs

Lines changed: 44 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ impl Library2022 {
6363
session_id: &Option<String>,
6464
) -> fastn_core::Result<(String, String, usize)> {
6565
if name == "fastn" {
66+
tracing::info!("fastn.ftd requested");
6667
if self.config.test_command_running {
6768
return Ok((
6869
fastn_core::commands::test::test_fastn_ftd().to_string(),
@@ -114,30 +115,36 @@ impl Library2022 {
114115
return Ok(val);
115116
}
116117

117-
/*let translation_of = match package.translation_of.as_ref() {
118-
Some(translation_of) => translation_of.to_owned(),
119-
None => return None,
120-
};
121-
122-
let name = name.replacen(package.name.as_str(), translation_of.name.as_str(), 1);
123-
if name.starts_with(translation_of.name.as_str()) {
124-
if let Some((content, size)) =
125-
get_data_from_package(name.as_str(), &translation_of, lib).await
126-
{
127-
return Some((content, name.to_string(), size));
128-
}
129-
}
130-
131-
for (alias, package) in translation_of.aliases() {
132-
if name.starts_with(alias) {
133-
let name = name.replacen(alias, &package.name, 1);
118+
if name.starts_with("inherited-") {
119+
// The inherited- prefix is added to every dependency that is `auto-import`ed
120+
// and has a provided-via in the main package's FASTN.ftd
121+
let new_name = name.trim_start_matches("inherited-");
122+
if let Some(provided_via) = package.dependencies.iter().find_map(|d| {
123+
tracing::info!(
124+
"checking dependency {} for {name} in package {}",
125+
d.package.name,
126+
package.name
127+
);
128+
if d.package.name == new_name.trim_end_matches('/') && d.provided_via.is_some()
129+
{
130+
d.provided_via.clone()
131+
} else {
132+
None
133+
}
134+
}) {
135+
tracing::error!("using provided-via: {provided_via} for {name}");
134136
if let Some((content, size)) =
135-
get_data_from_package(name.as_str(), package, lib).await
137+
get_data_from_package(&provided_via, &package, lib, session_id).await?
136138
{
137-
return Some((content, name.to_string(), size));
139+
// NOTE: we still return `name`. This way, we use source of provided-via's
140+
// module but act as if the source is from `name`.
141+
// Also note that this only applies to modules starting with "inherited-"
142+
let name = format!("{}/", name.trim_end_matches('/'));
143+
tracing::info!(?content, ?name);
144+
return Ok((content, name, size));
138145
}
139146
}
140-
}*/
147+
}
141148

142149
fastn_core::usage_error(format!("library not found 1: {}: {package:?}", name))
143150
}
@@ -149,7 +156,9 @@ impl Library2022 {
149156
package: &fastn_core::Package,
150157
session_id: &Option<String>,
151158
) -> fastn_core::Result<Option<(String, String, usize)>> {
159+
tracing::info!("getting data for {name} in package {}", package.name);
152160
if name.starts_with(package.name.as_str()) {
161+
tracing::info!("found {name} in package {}", package.name);
153162
if let Some((content, size)) =
154163
get_data_from_package(name, package, lib, session_id).await?
155164
{
@@ -158,6 +167,10 @@ impl Library2022 {
158167
}
159168
// Self package referencing
160169
if package.name.ends_with(name.trim_end_matches('/')) {
170+
tracing::info!(
171+
"self package referencing {name} in package {}",
172+
package.name
173+
);
161174
let package_index = format!("{}/", package.name.as_str());
162175
if let Some((content, size)) =
163176
get_data_from_package(package_index.as_str(), package, lib, session_id).await?
@@ -167,6 +180,10 @@ impl Library2022 {
167180
}
168181

169182
for (alias, package) in package.aliases() {
183+
tracing::info!(
184+
"checking alias {alias} for {name} in package {}",
185+
package.name
186+
);
170187
lib.push_package_under_process(name, package, session_id)
171188
.await?;
172189
if name.starts_with(alias) {
@@ -182,7 +199,6 @@ impl Library2022 {
182199
Ok(None)
183200
}
184201

185-
// TODO: This function is too long. Break it down.
186202
#[allow(clippy::await_holding_refcell_ref)]
187203
#[tracing::instrument(skip(lib, package))]
188204
async fn get_data_from_package(
@@ -196,6 +212,7 @@ impl Library2022 {
196212
let package = lib
197213
.config
198214
.find_package_else_default(package.name.as_str(), Some(package.to_owned()));
215+
tracing::info!("checking package: {}", package.name);
199216
// Explicit check for the current package.
200217
let name = format!("{}/", name.trim_end_matches('/'));
201218
if !name.starts_with(format!("{}/", package.name.as_str()).as_str()) {
@@ -231,8 +248,12 @@ impl Library2022 {
231248
return Ok(None);
232249
}
233250
Ok(String::from_utf8(data).ok().map(|body| {
234-
let body_with_prefix =
235-
package.get_prefixed_body(body.as_str(), name.as_str(), true);
251+
let body_with_prefix = package.get_prefixed_body(
252+
&lib.config.package,
253+
body.as_str(),
254+
name.as_str(),
255+
true,
256+
);
236257
let line_number = body_with_prefix.split('\n').count() - body.split('\n').count();
237258
(body_with_prefix, line_number)
238259
}))

fastn-core/src/package/mod.rs

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,12 @@ impl Package {
268268
})
269269
}
270270

271-
pub fn generate_prefix_string(&self, with_alias: bool) -> Option<String> {
271+
#[tracing::instrument(skip(self, current_package))]
272+
pub fn generate_prefix_string(
273+
&self,
274+
current_package: &Package,
275+
with_alias: bool,
276+
) -> Option<String> {
272277
self.auto_import.iter().fold(None, |pre, ai| {
273278
let mut import_doc_path = ai.path.clone();
274279
if !with_alias {
@@ -287,6 +292,34 @@ impl Package {
287292
}
288293
}
289294
}
295+
296+
tracing::info!(?import_doc_path, ?ai.alias, ?ai.exposing);
297+
298+
let import_doc_path = if let Some(provided_via) =
299+
current_package.dependencies.iter().find_map(|d| {
300+
tracing::info!(
301+
"checking dependency {} in package {}",
302+
d.package.name,
303+
current_package.name
304+
);
305+
if d.package.name == import_doc_path && d.provided_via.is_some() {
306+
d.provided_via.clone()
307+
} else {
308+
None
309+
}
310+
}) {
311+
tracing::error!(
312+
?import_doc_path,
313+
?provided_via,
314+
"Prefixing auto-import inherited- because it's a provided-via the main package"
315+
);
316+
format!("inherited-{import_doc_path}")
317+
} else {
318+
import_doc_path
319+
};
320+
321+
tracing::info!(?import_doc_path, "import_doc_path has changed");
322+
290323
Some(format!(
291324
"{}\n-- import: {}{}{}",
292325
pre.unwrap_or_default(),
@@ -467,11 +500,17 @@ impl Package {
467500
Ok(new_body)
468501
}
469502

470-
pub fn get_prefixed_body(&self, body: &str, id: &str, with_alias: bool) -> String {
503+
pub fn get_prefixed_body(
504+
&self,
505+
current_package: &Package,
506+
body: &str,
507+
id: &str,
508+
with_alias: bool,
509+
) -> String {
471510
if id.contains("FPM/") {
472511
return body.to_string();
473512
};
474-
match self.generate_prefix_string(with_alias) {
513+
match self.generate_prefix_string(current_package, with_alias) {
475514
Some(s) => {
476515
let t = format!("{}\n\n{}", s, body);
477516
self.fix_imports_in_body(t.as_str(), id).ok().unwrap_or(t)

fastn-core/src/package/package_doc.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -427,8 +427,12 @@ pub(crate) async fn read_ftd_2022(
427427
config.base_url = base_url.to_string();
428428

429429
// Get Prefix Body => [AutoImports + Actual Doc content]
430-
let mut doc_content =
431-
current_package.get_prefixed_body(main.content.as_str(), main.id.as_str(), true);
430+
let mut doc_content = current_package.get_prefixed_body(
431+
&config.config.package,
432+
main.content.as_str(),
433+
main.id.as_str(),
434+
true,
435+
);
432436
// Fix aliased imports to full path (if any)
433437
doc_content = current_package.fix_imports_in_body(doc_content.as_str(), main.id.as_str())?;
434438

@@ -510,8 +514,12 @@ pub(crate) async fn read_ftd_2023(
510514
config.base_url = base_url.to_string();
511515

512516
// Get Prefix Body => [AutoImports + Actual Doc content]
513-
let mut doc_content =
514-
current_package.get_prefixed_body(main.content.as_str(), main.id.as_str(), true);
517+
let mut doc_content = current_package.get_prefixed_body(
518+
&config.config.package,
519+
main.content.as_str(),
520+
main.id.as_str(),
521+
true,
522+
);
515523
// Fix aliased imports to full path (if any)
516524
doc_content = current_package.fix_imports_in_body(doc_content.as_str(), main.id.as_str())?;
517525

0 commit comments

Comments
 (0)