Skip to content
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

Refactor buildpack output #157

Draft
wants to merge 12 commits into
base: main
Choose a base branch
from
69 changes: 50 additions & 19 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions buildpacks/dotnet/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,18 @@ autotests = false
workspace = true

[dependencies]
bullet_stream = "0.3.0"
fun_run = "0.2.0"
hex = "0.4"
indoc = "2"
libcnb = "0.26"
libherokubuildpack = { version = "0.26", default-features = false, features = ["tar", "download", "inventory", "inventory-semver", "inventory-sha2"] }
regex = "1"
buildpacks-jvm-shared = { git = "https://github.com/heroku/buildpacks-jvm", branch = "malax/output" }
roxmltree = "0.20"
semver = "1.0"
serde = "1"
serde_json = "1"
sha2 = "0.10"
shell-words = "1.1.0"

[dev-dependencies]
libcnb-test = "0.26"
Expand Down
106 changes: 41 additions & 65 deletions buildpacks/dotnet/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ use crate::dotnet::{project, solution};
use crate::dotnet_buildpack_configuration::DotnetBuildpackConfigurationError;
use crate::layers::sdk::SdkLayerError;
use crate::DotnetBuildpackError;
use bullet_stream::{style, Print};
use buildpacks_jvm_shared::output;
use indoc::formatdoc;
use std::io::{self, stderr};
use std::io::{self};

pub(crate) fn on_error(error: libcnb::Error<DotnetBuildpackError>) {
match error {
Expand All @@ -20,8 +20,7 @@ pub(crate) fn on_error(error: libcnb::Error<DotnetBuildpackError>) {

Use the debug information above to troubleshoot and retry your build. If you think you found a
bug in the buildpack, reproduce the issue locally with a minimal example and file an issue here:
https://github.com/heroku/buildpacks-dotnet/issues/new
"},
https://github.com/heroku/buildpacks-dotnet/issues/new"},
Some(libcnb_error.to_string()),
),
}
Expand All @@ -46,9 +45,7 @@ fn on_buildpack_error(error: &DotnetBuildpackError) {

To resolve this issue,
* Delete the solution file to build a root project file instead.
* Or reference the projects to build from the solution file.

", solution_path.to_string_lossy()},
* Or reference the projects to build from the solution file.", solution_path.to_string_lossy()},
None,
);
}
Expand All @@ -63,8 +60,7 @@ fn on_buildpack_error(error: &DotnetBuildpackError) {

If you’re porting an application from .NET Framework to .NET, or compiling both
side-by-side, see Microsoft’s documentation for project organization guidance:
https://learn.microsoft.com/en-us/dotnet/core/porting/project-structure
", project_file_paths.iter()
https://learn.microsoft.com/en-us/dotnet/core/porting/project-structure", project_file_paths.iter()
.map(|f| f.to_string_lossy().to_string())
.collect::<Vec<String>>()
.join("`, `"),
Expand Down Expand Up @@ -94,8 +90,7 @@ fn on_buildpack_error(error: &DotnetBuildpackError) {
buildpack currently supports the following TFMs: `net5.0`, `net6.0`, `net7.0`, `net8.0`.

For more information, see:
https://github.com/heroku/buildpacks-dotnet#net-version
"},
https://github.com/heroku/buildpacks-dotnet#net-version"},
None,
);
}
Expand All @@ -110,8 +105,7 @@ fn on_buildpack_error(error: &DotnetBuildpackError) {
formatdoc! {"
We can’t parse the root directory `global.json` file because it contains invalid JSON.

Use the debug information above to troubleshoot and retry your build.
"},
Use the debug information above to troubleshoot and retry your build."},
Some(error.to_string()),
),
// TODO: Consider adding more specific errors for the parsed values (e.g. an invalid rollForward value)
Expand All @@ -122,8 +116,7 @@ fn on_buildpack_error(error: &DotnetBuildpackError) {

Use the debug information above to troubleshoot and retry your build. For more
information, see:
https://github.com/heroku/buildpacks-dotnet#net-version
"},
https://github.com/heroku/buildpacks-dotnet#net-version"},
Some(error.to_string()),
),
DotnetBuildpackError::ParseInventory(error) => log_error(
Expand All @@ -133,9 +126,7 @@ fn on_buildpack_error(error: &DotnetBuildpackError) {
is almost always a buildpack bug.

If you see this error, please file an issue here:
https://github.com/heroku/buildpacks-dotnet/issues/new

"},
https://github.com/heroku/buildpacks-dotnet/issues/new"},
Some(error.to_string()),
),
DotnetBuildpackError::ParseSolutionVersionRequirement(error) => log_error(
Expand All @@ -146,9 +137,7 @@ fn on_buildpack_error(error: &DotnetBuildpackError) {
Use the debug information above to troubleshoot and retry your build. If you think
you found a bug in the buildpack, reproduce the issue locally with a minimal
example and file an issue here:
https://github.com/heroku/buildpacks-dotnet/issues/new

"},
https://github.com/heroku/buildpacks-dotnet/issues/new"},
Some(error.to_string()),
),
DotnetBuildpackError::ResolveSdkVersion(version_req) => log_error(
Expand All @@ -158,8 +147,7 @@ fn on_buildpack_error(error: &DotnetBuildpackError) {
requirement ({version_req}).

For a complete inventory of supported .NET SDK versions and platforms, see:
https://github.com/heroku/buildpacks-dotnet/blob/main/buildpacks/dotnet/inventory.toml
"},
https://github.com/heroku/buildpacks-dotnet/blob/main/buildpacks/dotnet/inventory.toml"},
None,
),
DotnetBuildpackError::SdkLayer(error) => match error {
Expand All @@ -169,8 +157,7 @@ fn on_buildpack_error(error: &DotnetBuildpackError) {
An unexpected error occurred while downloading the .NET SDK. This error can occur
due to an unstable network connection.

Use the debug information above to troubleshoot and retry your build.
"},
Use the debug information above to troubleshoot and retry your build."},
Some(error.to_string()),
),
SdkLayerError::ReadArchive(io_error) => {
Expand All @@ -191,8 +178,7 @@ fn on_buildpack_error(error: &DotnetBuildpackError) {
https://github.com/heroku/buildpacks-dotnet/issues/new

Expected: {expected}
Actual: {actual}
", expected = hex::encode(expected), actual = hex::encode(actual) },
Actual: {actual}", expected = hex::encode(expected), actual = hex::encode(actual) },
None,
),
SdkLayerError::OpenArchive(io_error) => {
Expand Down Expand Up @@ -225,36 +211,31 @@ fn on_buildpack_error(error: &DotnetBuildpackError) {
n
normal
q
quiet
"},
quiet"},
None,
);
}
},
DotnetBuildpackError::PublishCommand(error) => match error {
fun_run::CmdError::SystemError(_message, io_error) => log_io_error(
"Unable to publish",
"running the command to publish the .NET solution/project",
io_error,
),
fun_run::CmdError::NonZeroExitNotStreamed(output)
| fun_run::CmdError::NonZeroExitAlreadyStreamed(output) => log_error(
"Unable to publish",
formatdoc! {"
The `dotnet publish` command exited unsuccessfully ({exit_status}).
DotnetBuildpackError::PublishCommandIoError(io_error) => log_io_error(
"Unable to publish",
"running the command to publish the .NET solution/project",
io_error,
),
DotnetBuildpackError::PublishCommandNonZeroExitCode(output) => log_error(
"Unable to publish",
formatdoc! {"
The `dotnet publish` command exited unsuccessfully ({exit_status}).

This error usually happens due to compilation errors. Use the command output
above to troubleshoot and retry your build.
This error usually happens due to compilation errors. Use the command output
above to troubleshoot and retry your build.

The publish process can also fail for a number of other reasons, such as
intermittent network issues, unavailability of the NuGet package feed and/or
other external dependencies, etc.
The publish process can also fail for a number of other reasons, such as
intermittent network issues, unavailability of the NuGet package feed and/or
other external dependencies, etc.

Try again to see if the error resolves itself.
", exit_status = output.status()},
None,
),
},
Try again to see if the error resolves itself.", exit_status = output.status},
None,
),
DotnetBuildpackError::CopyRuntimeFiles(io_error) => log_io_error(
"Error copying .NET runtime files",
"copying .NET runtime files from the SDK layer to the runtime layer",
Expand Down Expand Up @@ -285,8 +266,7 @@ fn on_load_dotnet_project_error(error: &project::LoadError, occurred_while: &str
You must set this required property.

For more information, see:
https://github.com/heroku/buildpacks-dotnet#net-version
", project_path = project_path.to_string_lossy()},
https://github.com/heroku/buildpacks-dotnet#net-version", project_path = project_path.to_string_lossy()},
None,
);
}
Expand All @@ -301,22 +281,18 @@ fn log_io_error(header: &str, occurred_while: &str, io_error: &io::Error) {

Use the debug information above to troubleshoot and retry your build. If the
issue persists, file an issue here:
https://github.com/heroku/buildpacks-dotnet/issues/new
"},
https://github.com/heroku/buildpacks-dotnet/issues/new"},
Some(io_error.to_string()),
);
}

fn log_error(header: impl AsRef<str>, body: impl AsRef<str>, error: Option<String>) {
let mut log = Print::new(stderr()).without_header();
if let Some(error) = error {
let bullet = log.bullet(style::important("Debug info"));
log = bullet.sub_bullet(error).done();
}
log.error(formatdoc! {"
{header}

{body}
", header = header.as_ref(), body = body.as_ref(),
});
let body = body.as_ref();
output::print_error(
header,
error.map_or_else(
|| body.to_string(),
|x| format!("Debug info: {x}\n\n{body}"),
),
);
}
Loading