mirror of
https://github.com/arcan1s/ahriman.git
synced 2026-04-07 02:53:38 +00:00
Compare commits
2 Commits
cd6fbaae31
...
dcb8724ed2
| Author | SHA1 | Date | |
|---|---|---|---|
| dcb8724ed2 | |||
| db46147f0d |
28
frontend/src/components/common/StringList.tsx
Normal file
28
frontend/src/components/common/StringList.tsx
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2021-2026 ahriman team.
|
||||||
|
*
|
||||||
|
* This file is part of ahriman
|
||||||
|
* (see https://github.com/arcan1s/ahriman).
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
interface StringListProps {
|
||||||
|
items: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function StringList({ items }: StringListProps): React.JSX.Element {
|
||||||
|
return <>{items.join("\n")}</>;
|
||||||
|
}
|
||||||
@@ -46,7 +46,7 @@ export default function DashboardDialog({ open, onClose }: DashboardDialogProps)
|
|||||||
|
|
||||||
const headerStyle = status ? StatusHeaderStyles[status.status.status] : {};
|
const headerStyle = status ? StatusHeaderStyles[status.status.status] : {};
|
||||||
|
|
||||||
return <Dialog open={open} onClose={onClose} keepMounted maxWidth="lg" fullWidth>
|
return <Dialog open={open} onClose={onClose} maxWidth="lg" fullWidth>
|
||||||
<DialogHeader onClose={onClose} sx={headerStyle}>
|
<DialogHeader onClose={onClose} sx={headerStyle}>
|
||||||
System health
|
System health
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ export default function KeyImportDialog({ open, onClose }: KeyImportDialogProps)
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return <Dialog open={open} onClose={handleClose} keepMounted maxWidth="lg" fullWidth>
|
return <Dialog open={open} onClose={handleClose} maxWidth="lg" fullWidth>
|
||||||
<DialogHeader onClose={handleClose}>
|
<DialogHeader onClose={handleClose}>
|
||||||
Import key from PGP server
|
Import key from PGP server
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ export default function LoginDialog({ open, onClose }: LoginDialogProps): React.
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return <Dialog open={open} onClose={handleClose} keepMounted maxWidth="xs" fullWidth>
|
return <Dialog open={open} onClose={handleClose} maxWidth="xs" fullWidth>
|
||||||
<DialogHeader onClose={handleClose}>
|
<DialogHeader onClose={handleClose}>
|
||||||
Login
|
Login
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ export default function PackageAddDialog({ open, onClose }: PackageAddDialogProp
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return <Dialog open={open} onClose={handleClose} keepMounted maxWidth="md" fullWidth>
|
return <Dialog open={open} onClose={handleClose} maxWidth="md" fullWidth>
|
||||||
<DialogHeader onClose={handleClose}>
|
<DialogHeader onClose={handleClose}>
|
||||||
Add new packages
|
Add new packages
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ export default function PackageInfoDialog({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return <Dialog open={open} onClose={handleClose} keepMounted maxWidth="lg" fullWidth>
|
return <Dialog open={open} onClose={handleClose} maxWidth="lg" fullWidth>
|
||||||
<DialogHeader onClose={handleClose} sx={headerStyle}>
|
<DialogHeader onClose={handleClose} sx={headerStyle}>
|
||||||
{pkg && status
|
{pkg && status
|
||||||
? `${pkg.base} ${status.status} at ${new Date(status.timestamp * 1000).toISOStringShort()}`
|
? `${pkg.base} ${status.status} at ${new Date(status.timestamp * 1000).toISOStringShort()}`
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ export default function PackageRebuildDialog({ open, onClose }: PackageRebuildDi
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return <Dialog open={open} onClose={handleClose} keepMounted maxWidth="md" fullWidth>
|
return <Dialog open={open} onClose={handleClose} maxWidth="md" fullWidth>
|
||||||
<DialogHeader onClose={handleClose}>
|
<DialogHeader onClose={handleClose}>
|
||||||
Rebuild depending packages
|
Rebuild depending packages
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
|
|||||||
@@ -71,8 +71,7 @@ export default function EventsTab({ packageBase, repository }: EventsTabProps):
|
|||||||
sorting: { sortModel: [{ field: "timestamp", sort: "desc" }] },
|
sorting: { sortModel: [{ field: "timestamp", sort: "desc" }] },
|
||||||
}}
|
}}
|
||||||
pageSizeOptions={[10, 25]}
|
pageSizeOptions={[10, 25]}
|
||||||
autoHeight
|
sx={{ height: 400, mt: 1 }}
|
||||||
sx={{ mt: 1 }}
|
|
||||||
disableRowSelectionOnClick
|
disableRowSelectionOnClick
|
||||||
/>
|
/>
|
||||||
</Box>;
|
</Box>;
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
import { Grid, Link, Typography } from "@mui/material";
|
import { Grid, Link, Typography } from "@mui/material";
|
||||||
|
import StringList from "components/common/StringList";
|
||||||
import type { Dependencies } from "models/Dependencies";
|
import type { Dependencies } from "models/Dependencies";
|
||||||
import type { Package } from "models/Package";
|
import type { Package } from "models/Package";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
@@ -27,16 +28,6 @@ interface PackageDetailsGridProps {
|
|||||||
dependencies?: Dependencies;
|
dependencies?: Dependencies;
|
||||||
}
|
}
|
||||||
|
|
||||||
function listToString(items: string[]): React.ReactNode {
|
|
||||||
const unique = [...new Set(items)].sort();
|
|
||||||
return unique.map((item, index) =>
|
|
||||||
<React.Fragment key={item}>
|
|
||||||
{item}
|
|
||||||
{index < unique.length - 1 && <br />}
|
|
||||||
</React.Fragment>,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function PackageDetailsGrid({ pkg, dependencies }: PackageDetailsGridProps): React.JSX.Element {
|
export default function PackageDetailsGrid({ pkg, dependencies }: PackageDetailsGridProps): React.JSX.Element {
|
||||||
const packagesList = Object.entries(pkg.packages)
|
const packagesList = Object.entries(pkg.packages)
|
||||||
.map(([name, properties]) => `${name}${properties.description ? ` (${properties.description})` : ""}`);
|
.map(([name, properties]) => `${name}${properties.description ? ` (${properties.description})` : ""}`);
|
||||||
@@ -47,21 +38,27 @@ export default function PackageDetailsGrid({ pkg, dependencies }: PackageDetails
|
|||||||
const licenses = Object.values(pkg.packages)
|
const licenses = Object.values(pkg.packages)
|
||||||
.flatMap(properties => properties.licenses ?? []);
|
.flatMap(properties => properties.licenses ?? []);
|
||||||
|
|
||||||
const upstreamUrls = [...new Set(
|
const upstreamUrls = Object.values(pkg.packages)
|
||||||
Object.values(pkg.packages)
|
.map(properties => properties.url)
|
||||||
.map(properties => properties.url)
|
.filter((url): url is string => !!url)
|
||||||
.filter((url): url is string => !!url),
|
.unique();
|
||||||
)].sort();
|
|
||||||
|
|
||||||
const aurUrl = pkg.remote.web_url;
|
const aurUrl = pkg.remote.web_url;
|
||||||
|
|
||||||
const pkgNames = Object.keys(pkg.packages);
|
const pkgNames = Object.keys(pkg.packages);
|
||||||
const allDepends = Object.values(pkg.packages).flatMap(properties => {
|
const pkgValues = Object.values(pkg.packages);
|
||||||
const deps = (properties.depends ?? []).filter(dep => !pkgNames.includes(dep));
|
const deps = pkgValues
|
||||||
const makeDeps = (properties.make_depends ?? []).filter(dep => !pkgNames.includes(dep)).map(dep => `${dep} (make)`);
|
.flatMap(properties => (properties.depends ?? []).filter(dep => !pkgNames.includes(dep)))
|
||||||
const optDeps = (properties.opt_depends ?? []).filter(dep => !pkgNames.includes(dep)).map(dep => `${dep} (optional)`);
|
.unique();
|
||||||
return [...deps, ...makeDeps, ...optDeps];
|
const makeDeps = pkgValues
|
||||||
});
|
.flatMap(properties => (properties.make_depends ?? []).filter(dep => !pkgNames.includes(dep)))
|
||||||
|
.map(dep => `${dep} (make)`)
|
||||||
|
.unique();
|
||||||
|
const optDeps = pkgValues
|
||||||
|
.flatMap(properties => (properties.opt_depends ?? []).filter(dep => !pkgNames.includes(dep)))
|
||||||
|
.map(dep => `${dep} (optional)`)
|
||||||
|
.unique();
|
||||||
|
const allDepends = [...deps, ...makeDeps, ...optDeps];
|
||||||
|
|
||||||
const implicitDepends = dependencies
|
const implicitDepends = dependencies
|
||||||
? Object.values(dependencies.paths).flat()
|
? Object.values(dependencies.paths).flat()
|
||||||
@@ -70,7 +67,7 @@ export default function PackageDetailsGrid({ pkg, dependencies }: PackageDetails
|
|||||||
return <>
|
return <>
|
||||||
<Grid container spacing={1} sx={{ mt: 1 }}>
|
<Grid container spacing={1} sx={{ mt: 1 }}>
|
||||||
<Grid size={{ xs: 4, md: 1 }}><Typography variant="body2" color="text.secondary" align="right">packages</Typography></Grid>
|
<Grid size={{ xs: 4, md: 1 }}><Typography variant="body2" color="text.secondary" align="right">packages</Typography></Grid>
|
||||||
<Grid size={{ xs: 8, md: 5 }}><Typography variant="body2">{listToString(packagesList)}</Typography></Grid>
|
<Grid size={{ xs: 8, md: 5 }}><Typography variant="body2" sx={{ whiteSpace: "pre-line" }}><StringList items={packagesList.unique()} /></Typography></Grid>
|
||||||
<Grid size={{ xs: 4, md: 1 }}><Typography variant="body2" color="text.secondary" align="right">version</Typography></Grid>
|
<Grid size={{ xs: 4, md: 1 }}><Typography variant="body2" color="text.secondary" align="right">version</Typography></Grid>
|
||||||
<Grid size={{ xs: 8, md: 5 }}><Typography variant="body2">{pkg.version}</Typography></Grid>
|
<Grid size={{ xs: 8, md: 5 }}><Typography variant="body2">{pkg.version}</Typography></Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
@@ -84,9 +81,9 @@ export default function PackageDetailsGrid({ pkg, dependencies }: PackageDetails
|
|||||||
|
|
||||||
<Grid container spacing={1} sx={{ mt: 0.5 }}>
|
<Grid container spacing={1} sx={{ mt: 0.5 }}>
|
||||||
<Grid size={{ xs: 4, md: 1 }}><Typography variant="body2" color="text.secondary" align="right">groups</Typography></Grid>
|
<Grid size={{ xs: 4, md: 1 }}><Typography variant="body2" color="text.secondary" align="right">groups</Typography></Grid>
|
||||||
<Grid size={{ xs: 8, md: 5 }}><Typography variant="body2">{listToString(groups)}</Typography></Grid>
|
<Grid size={{ xs: 8, md: 5 }}><Typography variant="body2" sx={{ whiteSpace: "pre-line" }}><StringList items={groups.unique()} /></Typography></Grid>
|
||||||
<Grid size={{ xs: 4, md: 1 }}><Typography variant="body2" color="text.secondary" align="right">licenses</Typography></Grid>
|
<Grid size={{ xs: 4, md: 1 }}><Typography variant="body2" color="text.secondary" align="right">licenses</Typography></Grid>
|
||||||
<Grid size={{ xs: 8, md: 5 }}><Typography variant="body2">{listToString(licenses)}</Typography></Grid>
|
<Grid size={{ xs: 8, md: 5 }}><Typography variant="body2" sx={{ whiteSpace: "pre-line" }}><StringList items={licenses.unique()} /></Typography></Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<Grid container spacing={1} sx={{ mt: 0.5 }}>
|
<Grid container spacing={1} sx={{ mt: 0.5 }}>
|
||||||
@@ -110,9 +107,9 @@ export default function PackageDetailsGrid({ pkg, dependencies }: PackageDetails
|
|||||||
|
|
||||||
<Grid container spacing={1} sx={{ mt: 0.5 }}>
|
<Grid container spacing={1} sx={{ mt: 0.5 }}>
|
||||||
<Grid size={{ xs: 4, md: 1 }}><Typography variant="body2" color="text.secondary" align="right">depends</Typography></Grid>
|
<Grid size={{ xs: 4, md: 1 }}><Typography variant="body2" color="text.secondary" align="right">depends</Typography></Grid>
|
||||||
<Grid size={{ xs: 8, md: 5 }}><Typography variant="body2">{listToString(allDepends)}</Typography></Grid>
|
<Grid size={{ xs: 8, md: 5 }}><Typography variant="body2" sx={{ whiteSpace: "pre-line" }}><StringList items={allDepends} /></Typography></Grid>
|
||||||
<Grid size={{ xs: 4, md: 1 }}><Typography variant="body2" color="text.secondary" align="right">implicitly depends</Typography></Grid>
|
<Grid size={{ xs: 4, md: 1 }}><Typography variant="body2" color="text.secondary" align="right">implicitly depends</Typography></Grid>
|
||||||
<Grid size={{ xs: 8, md: 5 }}><Typography variant="body2">{listToString(implicitDepends)}</Typography></Grid>
|
<Grid size={{ xs: 8, md: 5 }}><Typography variant="body2" sx={{ whiteSpace: "pre-line" }}><StringList items={implicitDepends.unique()} /></Typography></Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</>;
|
</>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import {
|
|||||||
type GridRowId,
|
type GridRowId,
|
||||||
useGridApiRef,
|
useGridApiRef,
|
||||||
} from "@mui/x-data-grid";
|
} from "@mui/x-data-grid";
|
||||||
|
import StringList from "components/common/StringList";
|
||||||
import DashboardDialog from "components/dialogs/DashboardDialog";
|
import DashboardDialog from "components/dialogs/DashboardDialog";
|
||||||
import KeyImportDialog from "components/dialogs/KeyImportDialog";
|
import KeyImportDialog from "components/dialogs/KeyImportDialog";
|
||||||
import PackageAddDialog from "components/dialogs/PackageAddDialog";
|
import PackageAddDialog from "components/dialogs/PackageAddDialog";
|
||||||
@@ -57,9 +58,7 @@ function createListColumn(
|
|||||||
...options,
|
...options,
|
||||||
valueGetter: (value: string[]) => (value ?? []).join(" "),
|
valueGetter: (value: string[]) => (value ?? []).join(" "),
|
||||||
renderCell: (params: GridRenderCellParams<PackageRow>) =>
|
renderCell: (params: GridRenderCellParams<PackageRow>) =>
|
||||||
((params.row[field] as string[]) ?? []).map((item, index, items) =>
|
<Box sx={{ whiteSpace: "pre-line" }}><StringList items={(params.row[field] as string[]) ?? []} /></Box>,
|
||||||
<React.Fragment key={`${item}-${index}`}>{item}{index < items.length - 1 && <br />}</React.Fragment>,
|
|
||||||
),
|
|
||||||
sortComparator: (left: string, right: string) => left.localeCompare(right),
|
sortComparator: (left: string, right: string) => left.localeCompare(right),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -177,8 +176,8 @@ export default function PackageTable({ autoRefreshIntervals }: PackageTableProps
|
|||||||
}
|
}
|
||||||
table.setSelectedPackage(String(params.id));
|
table.setSelectedPackage(String(params.id));
|
||||||
}}
|
}}
|
||||||
autoHeight
|
|
||||||
sx={{
|
sx={{
|
||||||
|
height: 500,
|
||||||
"& .MuiDataGrid-row": { cursor: "pointer" },
|
"& .MuiDataGrid-row": { cursor: "pointer" },
|
||||||
}}
|
}}
|
||||||
density="compact"
|
density="compact"
|
||||||
|
|||||||
@@ -18,22 +18,31 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
import { useLocalStorage } from "hooks/useLocalStorage";
|
import { useLocalStorage } from "hooks/useLocalStorage";
|
||||||
import { type Dispatch, type SetStateAction, useState } from "react";
|
import { type Dispatch, type SetStateAction, useEffect, useState } from "react";
|
||||||
|
|
||||||
interface AutoRefreshResult {
|
interface AutoRefreshResult {
|
||||||
interval: number;
|
interval: number;
|
||||||
paused: boolean;
|
|
||||||
setInterval: Dispatch<SetStateAction<number>>;
|
setInterval: Dispatch<SetStateAction<number>>;
|
||||||
setPaused: Dispatch<SetStateAction<boolean>>;
|
setPaused: Dispatch<SetStateAction<boolean>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useAutoRefresh(key: string, defaultInterval: number = 0): AutoRefreshResult {
|
export function useAutoRefresh(key: string, defaultInterval: number): AutoRefreshResult {
|
||||||
const [interval, setInterval] = useLocalStorage<number>(`ahriman-${key}`, defaultInterval);
|
const storageKey = `ahriman-${key}`;
|
||||||
|
const [interval, setInterval] = useLocalStorage<number>(storageKey, defaultInterval);
|
||||||
const [paused, setPaused] = useState(false);
|
const [paused, setPaused] = useState(false);
|
||||||
|
|
||||||
|
// Apply defaultInterval when it becomes available (e.g. after info endpoint loads)
|
||||||
|
// but only if the user hasn't explicitly set a preference
|
||||||
|
useEffect(() => {
|
||||||
|
if (defaultInterval > 0 && window.localStorage.getItem(storageKey) === null) {
|
||||||
|
setInterval(defaultInterval);
|
||||||
|
}
|
||||||
|
}, [storageKey, defaultInterval, setInterval]);
|
||||||
|
|
||||||
|
const effectiveInterval = paused ? 0 : interval;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
interval,
|
interval: effectiveInterval,
|
||||||
paused,
|
|
||||||
setInterval,
|
setInterval,
|
||||||
setPaused,
|
setPaused,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ export function useLocalStorage<T>(key: string, initialValue: T): [T, Dispatch<S
|
|||||||
const [storedValue, setStoredValue] = useState<T>(() => {
|
const [storedValue, setStoredValue] = useState<T>(() => {
|
||||||
try {
|
try {
|
||||||
const item = window.localStorage.getItem(key);
|
const item = window.localStorage.getItem(key);
|
||||||
return item ? (JSON.parse(item) as T) : initialValue;
|
return item !== null ? (JSON.parse(item) as T) : initialValue;
|
||||||
} catch {
|
} catch {
|
||||||
return initialValue;
|
return initialValue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,13 +47,13 @@ export function usePackageData(autoRefreshIntervals: AutoRefreshInterval[]): Use
|
|||||||
const { data: packages = [], isLoading } = useQuery({
|
const { data: packages = [], isLoading } = useQuery({
|
||||||
queryKey: current ? QueryKeys.packages(current) : ["packages"],
|
queryKey: current ? QueryKeys.packages(current) : ["packages"],
|
||||||
queryFn: current ? () => client.fetchPackages(current) : skipToken,
|
queryFn: current ? () => client.fetchPackages(current) : skipToken,
|
||||||
refetchInterval: autoRefresh.interval,
|
refetchInterval: autoRefresh.interval > 0 ? autoRefresh.interval : false,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { data: status } = useQuery({
|
const { data: status } = useQuery({
|
||||||
queryKey: current ? QueryKeys.status(current) : ["status"],
|
queryKey: current ? QueryKeys.status(current) : ["status"],
|
||||||
queryFn: current ? () => client.fetchServerStatus(current) : skipToken,
|
queryFn: current ? () => client.fetchServerStatus(current) : skipToken,
|
||||||
refetchInterval: autoRefresh.interval,
|
refetchInterval: autoRefresh.interval > 0 ? autoRefresh.interval : false,
|
||||||
});
|
});
|
||||||
|
|
||||||
const rows = useMemo(() => packages.map(descriptor => new PackageRow(descriptor)), [packages]);
|
const rows = useMemo(() => packages.map(descriptor => new PackageRow(descriptor)), [packages]);
|
||||||
|
|||||||
@@ -39,11 +39,19 @@ export function defaultInterval(intervals: AutoRefreshInterval[]): number {
|
|||||||
}
|
}
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
|
interface Array<T> {
|
||||||
|
unique(): T[];
|
||||||
|
}
|
||||||
|
|
||||||
interface Date {
|
interface Date {
|
||||||
toISOStringShort(): string;
|
toISOStringShort(): string;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Array.prototype.unique = function <T>(): T[] {
|
||||||
|
return [...new Set<T>(this)].sort();
|
||||||
|
};
|
||||||
|
|
||||||
// custom formatter to print pretty date, because there is no builtin for this
|
// custom formatter to print pretty date, because there is no builtin for this
|
||||||
Date.prototype.toISOStringShort = function (): string {
|
Date.prototype.toISOStringShort = function (): string {
|
||||||
const pad: (num: number) => string = num => String(num).padStart(2, "0");
|
const pad: (num: number) => string = num => String(num).padStart(2, "0");
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ class Task(LazyLogging):
|
|||||||
"""
|
"""
|
||||||
command = [self.build_command, "-r", str(self.paths.chroot)]
|
command = [self.build_command, "-r", str(self.paths.chroot)]
|
||||||
command.extend(self.archbuild_flags)
|
command.extend(self.archbuild_flags)
|
||||||
command.extend(["--"] + self.makechrootpkg_flags)
|
command.extend(["--", "-D", str(self.paths.archive)] + self.makechrootpkg_flags)
|
||||||
command.extend(["--"] + self.makepkg_flags)
|
command.extend(["--"] + self.makepkg_flags)
|
||||||
if dry_run:
|
if dry_run:
|
||||||
command.extend(["--nobuild"])
|
command.extend(["--nobuild"])
|
||||||
|
|||||||
@@ -53,7 +53,10 @@ def test_build(task_ahriman: Task, mocker: MockerFixture) -> None:
|
|||||||
|
|
||||||
assert task_ahriman.build(local) == [task_ahriman.package.base]
|
assert task_ahriman.build(local) == [task_ahriman.package.base]
|
||||||
check_output_mock.assert_called_once_with(
|
check_output_mock.assert_called_once_with(
|
||||||
"extra-x86_64-build", "-r", str(task_ahriman.paths.chroot), "--", "--", "--skippgpcheck",
|
"extra-x86_64-build",
|
||||||
|
"-r", str(task_ahriman.paths.chroot),
|
||||||
|
"--", "-D", str(task_ahriman.paths.archive),
|
||||||
|
"--", "--skippgpcheck",
|
||||||
exception=pytest.helpers.anyvar(int),
|
exception=pytest.helpers.anyvar(int),
|
||||||
cwd=local,
|
cwd=local,
|
||||||
logger=task_ahriman.logger,
|
logger=task_ahriman.logger,
|
||||||
@@ -76,7 +79,10 @@ def test_build_environment(task_ahriman: Task, mocker: MockerFixture) -> None:
|
|||||||
|
|
||||||
task_ahriman.build(local, **environment, empty=None)
|
task_ahriman.build(local, **environment, empty=None)
|
||||||
check_output_mock.assert_called_once_with(
|
check_output_mock.assert_called_once_with(
|
||||||
"extra-x86_64-build", "-r", str(task_ahriman.paths.chroot), "--", "--", "--skippgpcheck",
|
"extra-x86_64-build",
|
||||||
|
"-r", str(task_ahriman.paths.chroot),
|
||||||
|
"--", "-D", str(task_ahriman.paths.archive),
|
||||||
|
"--", "--skippgpcheck",
|
||||||
exception=pytest.helpers.anyvar(int),
|
exception=pytest.helpers.anyvar(int),
|
||||||
cwd=local,
|
cwd=local,
|
||||||
logger=task_ahriman.logger,
|
logger=task_ahriman.logger,
|
||||||
@@ -96,7 +102,11 @@ def test_build_dry_run(task_ahriman: Task, mocker: MockerFixture) -> None:
|
|||||||
|
|
||||||
assert task_ahriman.build(local, dry_run=True) == [task_ahriman.package.base]
|
assert task_ahriman.build(local, dry_run=True) == [task_ahriman.package.base]
|
||||||
check_output_mock.assert_called_once_with(
|
check_output_mock.assert_called_once_with(
|
||||||
"extra-x86_64-build", "-r", str(task_ahriman.paths.chroot), "--", "--", "--skippgpcheck", "--nobuild",
|
"extra-x86_64-build",
|
||||||
|
"-r", str(task_ahriman.paths.chroot),
|
||||||
|
"--", "-D", str(task_ahriman.paths.archive),
|
||||||
|
"--", "--skippgpcheck",
|
||||||
|
"--nobuild",
|
||||||
exception=pytest.helpers.anyvar(int),
|
exception=pytest.helpers.anyvar(int),
|
||||||
cwd=local,
|
cwd=local,
|
||||||
logger=task_ahriman.logger,
|
logger=task_ahriman.logger,
|
||||||
|
|||||||
Reference in New Issue
Block a user