Skip to content

feat: add tg::SourceMap and integrate with try_get_reference, tangram… #433

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
2 changes: 1 addition & 1 deletion packages/cli/src/artifact/checkout.rs
Original file line number Diff line number Diff line change
@@ -42,7 +42,7 @@ impl Cli {
};

// Get the artifact.
let referent = self.get_reference(&args.reference).await?;
let (referent, _) = self.get_reference(&args.reference).await?;
let Either::Right(object) = referent.item else {
return Err(tg::error!("expected an object"));
};
2 changes: 1 addition & 1 deletion packages/cli/src/cat.rs
Original file line number Diff line number Diff line change
@@ -14,7 +14,7 @@ impl Cli {
pub async fn command_cat(&self, args: Args) -> tg::Result<()> {
let handle = self.handle().await?;
for reference in &args.references {
let referent = self.get_reference(reference).await?;
let (referent, _) = self.get_reference(reference).await?;
let Either::Right(object) = referent.item else {
return Err(tg::error!("expected an object"));
};
2 changes: 1 addition & 1 deletion packages/cli/src/checksum.rs
Original file line number Diff line number Diff line change
@@ -21,7 +21,7 @@ pub struct Args {
impl Cli {
pub async fn command_checksum(&self, args: Args) -> tg::Result<()> {
let handle = self.handle().await?;
let referent = self.get_reference(&args.reference).await?;
let (referent, _) = self.get_reference(&args.reference).await?;
let Either::Right(object) = referent.item else {
return Err(tg::error!("expected an object"));
};
4 changes: 4 additions & 0 deletions packages/cli/src/config.rs
Original file line number Diff line number Diff line change
@@ -202,6 +202,10 @@ pub struct Build {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub max_depth: Option<u64>,

/// Configure if path and tag are set for builds.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub set_path_and_tag: Option<bool>,

/// The remotes to build for.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub remotes: Option<Vec<String>>,
2 changes: 1 addition & 1 deletion packages/cli/src/get.rs
Original file line number Diff line number Diff line change
@@ -23,7 +23,7 @@ pub struct Args {
impl Cli {
pub async fn command_get(&self, args: Args) -> tg::Result<()> {
let handle = self.handle().await?;
let referent = self.get_reference(&args.reference).await?;
let (referent, _) = self.get_reference(&args.reference).await?;
eprintln!("{} item {}", "info".blue().bold(), referent.item);
if let Some(path) = &referent.path {
let path = path.display();
36 changes: 28 additions & 8 deletions packages/cli/src/lib.rs
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@ use crossterm::{style::Stylize as _, tty::IsTty as _};
use futures::FutureExt as _;
use num::ToPrimitive as _;
use std::{fmt::Write as _, path::PathBuf, sync::Mutex, time::Duration};
use tangram_client::{self as tg, Client};
use tangram_client::{self as tg, Client, Handle as _};
use tangram_either::Either;
use tangram_server::Server;
use tokio::io::AsyncWriteExt as _;
@@ -190,7 +190,7 @@ impl Cli {
Ok(config) => config,
Err(error) => {
eprintln!("{} failed to read the config", "error".red().bold());
Cli::print_error(&error, None);
Cli::print_error(&error, None, None);
return 1.into();
},
};
@@ -272,7 +272,7 @@ impl Cli {
Ok(()) => 0.into(),
Err(error) => {
eprintln!("{} failed to run the command", "error".red().bold());
Cli::print_error(&error, cli.config.as_ref());
Cli::print_error(&error, cli.config.as_ref(), None);
1.into()
},
};
@@ -896,7 +896,7 @@ impl Cli {
Ok(())
}

fn print_error(error: &tg::Error, config: Option<&Config>) {
fn print_error(error: &tg::Error, config: Option<&Config>, source_map: Option<&tg::SourceMap>) {
let options = config
.as_ref()
.and_then(|config| config.advanced.as_ref())
@@ -911,6 +911,9 @@ impl Cli {
errors.reverse();
}
for error in errors {
let error = source_map
.map(|map| map.convert_error(error.clone()))
.unwrap_or_else(|| error.clone());
let message = error.message.as_deref().unwrap_or("an error occurred");
eprintln!("{} {message}", "->".red());
if let Some(location) = &error.location {
@@ -938,7 +941,10 @@ impl Cli {
}
}

fn print_diagnostic(diagnostic: &tg::Diagnostic) {
fn print_diagnostic(diagnostic: &tg::Diagnostic, source_map: Option<&tg::SourceMap>) {
let diagnostic = source_map
.map(|map| map.convert_diagnostic(diagnostic.clone()))
.unwrap_or_else(|| diagnostic.clone());
let title = match diagnostic.severity {
tg::diagnostic::Severity::Error => "error".red().bold(),
tg::diagnostic::Severity::Warning => "warning".yellow().bold(),
@@ -1012,7 +1018,7 @@ impl Cli {
async fn get_reference(
&self,
reference: &tg::Reference,
) -> tg::Result<tg::Referent<Either<tg::Build, tg::Object>>> {
) -> tg::Result<(tg::Referent<Either<tg::Build, tg::Object>>, Option<PathBuf>)> {
let handle = self.handle().await?;
let mut item = reference.item().clone();
let mut options = reference.options().cloned();
@@ -1025,8 +1031,22 @@ impl Cli {
.map_err(|source| tg::error!(!source, "failed to get the absolute path"))?;
}
let reference = tg::Reference::with_item_and_options(&item, options.as_ref());
let referent = reference.get(&handle).await?;
Ok(referent)
let output = handle
.try_get_reference(&reference)
.await?
.ok_or_else(|| tg::error!("failed to get reference"))?;
let item = output
.referent
.item
.map_left(tg::Build::with_id)
.map_right(tg::Object::with_id);
let referent = tg::Referent {
item,
path: output.referent.path,
subpath: output.referent.subpath,
tag: output.referent.tag,
};
Ok((referent, output.lockfile))
}

/// Initialize V8.
15 changes: 13 additions & 2 deletions packages/cli/src/package/check.rs
Original file line number Diff line number Diff line change
@@ -29,11 +29,22 @@ impl Cli {
.map(|option| option.unwrap_or_else(|| "default".to_owned()));

// Get the reference.
let referent = self.get_reference(&args.reference).await?;
let (referent, lockfile) = self.get_reference(&args.reference).await?;
let Either::Right(object) = referent.item else {
return Err(tg::error!("expected an object"));
};

// Get the source map.
let source_map = if let Some(lockfile) = lockfile {
let lockfile = tg::Lockfile::try_read(&lockfile)
.await?
.ok_or_else(|| tg::error!(%path = lockfile.display(), "failed to read lockfile"))?;
let source_map = tg::SourceMap::new(&handle, &lockfile, object.clone()).await?;
Some(source_map)
} else {
None
};

// Resolve the referent.
let referent = if let Some(subpath) = &referent.subpath {
let directory = object
@@ -96,7 +107,7 @@ impl Cli {

// Print the diagnostics.
for diagnostic in &output.diagnostics {
Self::print_diagnostic(diagnostic);
Self::print_diagnostic(diagnostic, source_map.as_ref());
}

if !output.diagnostics.is_empty() {
2 changes: 1 addition & 1 deletion packages/cli/src/package/document.rs
Original file line number Diff line number Diff line change
@@ -43,7 +43,7 @@ impl Cli {
}

// Get the reference.
let referent = self.get_reference(&args.reference).await?;
let (referent, _) = self.get_reference(&args.reference).await?;
let Either::Right(object) = referent.item else {
return Err(tg::error!("expected an object"));
};
2 changes: 1 addition & 1 deletion packages/cli/src/progress.rs
Original file line number Diff line number Diff line change
@@ -72,7 +72,7 @@ impl Cli {
},

tg::progress::Event::Diagnostic(diagnostic) => {
Self::print_diagnostic(&diagnostic);
Self::print_diagnostic(&diagnostic, None);
},

tg::progress::Event::Start(indicator) | tg::progress::Event::Update(indicator) => {
2 changes: 1 addition & 1 deletion packages/cli/src/pull.rs
Original file line number Diff line number Diff line change
@@ -27,7 +27,7 @@ impl Cli {
let handle = self.handle().await?;

// Get the reference.
let referent = self.get_reference(&args.reference).await?;
let (referent, _) = self.get_reference(&args.reference).await?;
let item = match referent.item {
Either::Left(build) => Either::Left(build),
Either::Right(object) => {
2 changes: 1 addition & 1 deletion packages/cli/src/push.rs
Original file line number Diff line number Diff line change
@@ -34,7 +34,7 @@ impl Cli {
let remote = args.remote.unwrap_or_else(|| "default".to_owned());

// Get the reference.
let referent = self.get_reference(&args.reference).await?;
let (referent, _) = self.get_reference(&args.reference).await?;
let item = match referent.item {
Either::Left(build) => Either::Left(build),
Either::Right(object) => {
2 changes: 1 addition & 1 deletion packages/cli/src/tag/put.rs
Original file line number Diff line number Diff line change
@@ -30,7 +30,7 @@ impl Cli {
.map(|option| option.unwrap_or_else(|| "default".to_owned()));

// Get the reference.
let referent = self.get_reference(&args.reference).await?;
let (referent, _) = self.get_reference(&args.reference).await?;
let item = match referent.item {
Either::Left(build) => Either::Left(build),
Either::Right(object) => {
17 changes: 15 additions & 2 deletions packages/cli/src/target/build.rs
Original file line number Diff line number Diff line change
@@ -178,7 +178,7 @@ impl Cli {
}

// Get the reference.
let referent = self.get_reference(&reference).await?;
let (referent, lockfile) = self.get_reference(&reference).await?;
let Either::Right(object) = referent.item else {
return Err(tg::error!("expected an object"));
};
@@ -192,6 +192,17 @@ impl Cli {
object
};

// Get the source map.
let (source_map, lock) = if let Some(lockfile) = lockfile {
let lockfile = tg::Lockfile::try_read(&lockfile)
.await?
.ok_or_else(|| tg::error!(%path = lockfile.display(), "failed to read lockfile"))?;
let source_map = tg::SourceMap::new(&handle, &lockfile, object.clone()).await?;
(Some(source_map), Some(lockfile))
} else {
(None, None)
};

// Create the target.
let target = if let tg::Object::Target(target) = object {
// If the object is a target, then use it.
@@ -341,6 +352,7 @@ impl Cli {
let id = target.id(&handle).await?;
let arg = tg::target::build::Arg {
create: args.create,
lock,
parent: None,
remote: remote.clone(),
retry,
@@ -408,7 +420,8 @@ impl Cli {
expand_on_create: true,
};
let item = crate::viewer::Item::Build(build);
let mut viewer = crate::viewer::Viewer::new(&handle, item, options);
let mut viewer =
crate::viewer::Viewer::new(&handle, item, options, source_map);

match args.view {
View::None => (),
40 changes: 34 additions & 6 deletions packages/cli/src/view.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::Cli;
use tangram_client as tg;
use tangram_client::{self as tg, handle::Ext as _};
use tangram_either::Either;
use tangram_futures::task::Task;

@@ -41,7 +41,7 @@ impl Cli {
let handle = self.handle().await?;

// Get the reference.
let referent = self.get_reference(&args.reference).await?;
let (referent, lockfile) = self.get_reference(&args.reference).await?;
let item = match referent.item {
Either::Left(build) => Either::Left(build),
Either::Right(object) => {
@@ -57,9 +57,37 @@ impl Cli {
Either::Right(object)
},
};
let item = match item {
Either::Left(build) => crate::viewer::Item::Build(build),
Either::Right(object) => crate::viewer::Item::Value(object.into()),
let (item, source_map) = match item {
Either::Left(build) => {
let source_map = if let Some(lockfile) = handle.get_build(build.id()).await?.lock {
// Only attempt to load the target if the lock is set.
if let Some(executable) =
&*build.target(&handle).await?.executable(&handle).await?
{
let object = executable.object()[0].clone();
let source_map = tg::SourceMap::new(&handle, &lockfile, object).await?;
Some(source_map)
} else {
None
}
} else {
None
};
(crate::viewer::Item::Build(build), source_map)
},
Either::Right(object) => {
// Get the source map.
let source_map = if let Some(lockfile) = lockfile {
let lockfile = tg::Lockfile::try_read(&lockfile).await?.ok_or_else(
|| tg::error!(%path = lockfile.display(), "failed to read lockfile"),
)?;
let source_map = tg::SourceMap::new(&handle, &lockfile, object.clone()).await?;
Some(source_map)
} else {
None
};
(crate::viewer::Item::Value(object.into()), source_map)
},
};

// Run the view.
@@ -78,7 +106,7 @@ impl Cli {
condensed_builds: false,
expand_on_create: matches!(kind, Kind::Inline),
};
let mut viewer = crate::viewer::Viewer::new(&handle, item, options);
let mut viewer = crate::viewer::Viewer::new(&handle, item, options, source_map);
match kind {
Kind::Inline => {
viewer.run_inline(stop).await?;
8 changes: 7 additions & 1 deletion packages/cli/src/viewer.rs
Original file line number Diff line number Diff line change
@@ -145,7 +145,12 @@ where
}
}

pub fn new(handle: &H, item: Item, options: Options) -> Self {
pub fn new(
handle: &H,
item: Item,
options: Options,
source_map: Option<tg::SourceMap>,
) -> Self {
let (update_sender, update_receiver) = std::sync::mpsc::channel();
let data = Data::new();
let tree = Tree::new(
@@ -154,6 +159,7 @@ where
options,
data.update_sender(),
update_sender.clone(),
source_map,
);
Self {
data,
7 changes: 7 additions & 0 deletions packages/cli/src/viewer/tree.rs
Original file line number Diff line number Diff line change
@@ -38,6 +38,7 @@ struct Node {
log_task: Option<Task<()>>,
options: Rc<Options>,
parent: Option<Weak<RefCell<Self>>>,
source_map: Option<Rc<tg::SourceMap>>,
title: String,
update_receiver: NodeUpdateReceiver,
update_sender: NodeUpdateSender,
@@ -217,6 +218,7 @@ where
let depth = parent.borrow().depth + 1;
let (update_sender, update_receiver) = std::sync::mpsc::channel();
let options = parent.borrow().options.clone();
let source_map = parent.borrow().source_map.clone();
let parent = Rc::downgrade(parent);
let title = item.map_or(String::new(), |item| Self::item_title(item));

@@ -258,6 +260,7 @@ where
log_task: None,
options,
parent: Some(parent),
source_map,
title,
update_receiver,
update_sender,
@@ -1323,8 +1326,11 @@ where
options: Options,
data: data::UpdateSender,
viewer: super::UpdateSender<H>,
source_map: Option<tg::SourceMap>,
) -> Self {
let options = Rc::new(options);
let source_map = source_map.map(Rc::new);

let (update_sender, update_receiver) = std::sync::mpsc::channel();
let title = Self::item_title(&item);
let expand_task = if options.expand_on_create {
@@ -1367,6 +1373,7 @@ where
log_task: None,
options: options.clone(),
parent: None,
source_map,
title,
update_receiver,
update_sender,
Loading