colored diff

This commit is contained in:
mbecker20
2024-05-10 01:03:23 -07:00
parent ba19e45607
commit c7124bd63c
7 changed files with 62 additions and 61 deletions

13
Cargo.lock generated
View File

@@ -115,17 +115,6 @@ version = "1.0.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3"
[[package]]
name = "async-recursion"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.53",
]
[[package]]
name = "async-stream"
version = "0.3.5"
@@ -2275,7 +2264,6 @@ name = "monitor_core"
version = "1.1.0"
dependencies = [
"anyhow",
"async-recursion",
"async-trait",
"async_timing_util",
"aws-config",
@@ -2283,6 +2271,7 @@ dependencies = [
"axum 0.7.5",
"axum-extra",
"bcrypt",
"colored",
"dotenv",
"envy",
"futures",

View File

@@ -38,7 +38,6 @@ tokio-util = "0.7.11"
futures = "0.3.30"
futures-util = "0.3.30"
async-trait = "0.1.80"
async-recursion = "1.1.1"
# SERVER
axum = { version = "0.7.5", features = ["ws", "json"] }

View File

@@ -28,31 +28,31 @@ mungos.workspace = true
serror.workspace = true
slack.workspace = true
# external
tokio.workspace = true
urlencoding.workspace = true
async-trait.workspace = true
aws-sdk-ec2.workspace = true
aws-config.workspace = true
tokio-util.workspace = true
axum.workspace = true
axum-extra.workspace = true
tower.workspace = true
tower-http.workspace = true
serde.workspace = true
serde_json.workspace = true
typeshare.workspace = true
tracing.workspace = true
reqwest.workspace = true
futures.workspace = true
colored.workspace = true
anyhow.workspace = true
dotenv.workspace = true
bcrypt.workspace = true
tokio.workspace = true
tower.workspace = true
serde.workspace = true
axum.workspace = true
toml.workspace = true
uuid.workspace = true
anyhow.workspace = true
tracing.workspace = true
dotenv.workspace = true
envy.workspace = true
reqwest.workspace = true
urlencoding.workspace = true
rand.workspace = true
jwt.workspace = true
hmac.workspace = true
sha2.workspace = true
bcrypt.workspace = true
jwt.workspace = true
hex.workspace = true
async-trait.workspace = true
async-recursion.workspace = true
futures.workspace = true
aws-config.workspace = true
aws-sdk-ec2.workspace = true
typeshare.workspace = true

View File

@@ -1,6 +1,7 @@
use std::str::FromStr;
use anyhow::{anyhow, Context};
use colored::Colorize;
use futures::future::join_all;
use monitor_client::{
api::write::CreateTag,
@@ -377,7 +378,12 @@ pub async fn update<T: MonitorResource>(
for FieldDiff { field, from, to } in diff.iter_field_diffs() {
diff_log.push_str(&format!(
"\n\nfield: '{field}'\nfrom: {from}\nto: {to}"
"\n\n{}: '{field}'\n{}: {}\n{}: {}",
"field".dimmed(),
"from".dimmed(),
from.red(),
"to".dimmed(),
to.green()
));
}

View File

@@ -20,10 +20,9 @@ import {
SelectTrigger,
SelectValue,
} from "@ui/select";
import sanitizeHtml from "sanitize-html";
import Convert from "ansi-to-html";
import { Input } from "@ui/input";
import { useToast } from "@ui/use-toast";
import { logToHtml } from "@lib/utils";
export const DeploymentLogs = ({ id }: { id: string }) => {
const state = useDeployment(id)?.info.state;
@@ -221,20 +220,3 @@ const TailLengthSelector = ({
</SelectContent>
</Select>
);
const convert = new Convert();
/**
* Converts the ansi colors in log to html.
* sanitizes incoming log first for any eg. script tags.
* @param log incoming log string
*/
const logToHtml = (log: string) => {
if (!log) return "No log.";
const sanitized = sanitizeHtml(log, {
allowedTags: sanitizeHtml.defaults.allowedTags.filter(
(tag) => tag !== "script"
),
allowedAttributes: sanitizeHtml.defaults.allowedAttributes,
});
return convert.toHtml(sanitized);
};

View File

@@ -19,7 +19,7 @@ import { useRead } from "@lib/hooks";
import { ResourceComponents } from "@components/resources";
import { Link } from "react-router-dom";
import { fmt_duration, fmt_version } from "@lib/formatting";
import { usableResourcePath, version_is_none } from "@lib/utils";
import { logToHtml, usableResourcePath, version_is_none } from "@lib/utils";
import { UsableResource } from "@types";
export const UpdateUser = ({ user_id }: { user_id: string }) => {
@@ -85,9 +85,9 @@ export const UpdateDetailsInner = ({
</div>
<div className="flex gap-4">
<Link
to={`/${usableResourcePath(update.target.type as UsableResource)}/${
update.target.id
}`}
to={`/${usableResourcePath(
update.target.type as UsableResource
)}/${update.target.id}`}
>
<div
className="flex items-center gap-2"
@@ -146,17 +146,23 @@ export const UpdateDetailsInner = ({
{log.stdout && (
<div>
<CardDescription>stdout</CardDescription>
<pre className="max-h-[500px] overflow-y-auto">
{log.stdout}
</pre>
<pre
dangerouslySetInnerHTML={{
__html: logToHtml(log.stdout),
}}
className="max-h-[500px] overflow-y-auto"
/>
</div>
)}
{log.stderr && (
<div>
<CardDescription>stdout</CardDescription>
<pre className="max-h-[500px] overflow-y-auto">
{log.stderr}
</pre>
<CardDescription>stderr</CardDescription>
<pre
dangerouslySetInnerHTML={{
__html: logToHtml(log.stderr),
}}
className="max-h-[500px] overflow-y-auto"
/>
</div>
)}
</CardContent>

View File

@@ -1,7 +1,9 @@
import { ResourceComponents } from "@components/resources";
import { Types } from "@monitor/client";
import { UsableResource } from "@types";
import Convert from "ansi-to-html";
import { type ClassValue, clsx } from "clsx";
import sanitizeHtml from "sanitize-html";
import { twMerge } from "tailwind-merge";
export function cn(...inputs: ClassValue[]) {
@@ -96,3 +98,20 @@ export const usableResourcePath = (resource: UsableResource) => {
if (resource === "ServerTemplate") return "server-templates"
return `${resource.toLowerCase()}s`
}
const convert = new Convert();
/**
* Converts the ansi colors in log to html.
* sanitizes incoming log first for any eg. script tags.
* @param log incoming log string
*/
export const logToHtml = (log: string) => {
if (!log) return "No log.";
const sanitized = sanitizeHtml(log, {
allowedTags: sanitizeHtml.defaults.allowedTags.filter(
(tag) => tag !== "script"
),
allowedAttributes: sanitizeHtml.defaults.allowedAttributes,
});
return convert.toHtml(sanitized);
};