From d847715d2c7b3f7efdb10937acbc7e09e143c5f5 Mon Sep 17 00:00:00 2001
From: Sergei Zharinov <zharinov@users.noreply.github.com>
Date: Mon, 2 Oct 2023 01:56:00 -0300
Subject: [PATCH] refactor(helm): More idiomatic schema usage (#24934)

---
 lib/modules/manager/helmfile/artifacts.ts | 17 +++++++++--------
 lib/modules/manager/helmfile/extract.ts   |  2 +-
 lib/modules/manager/helmfile/schema.ts    | 21 +++++++++++++--------
 lib/modules/manager/helmfile/types.ts     | 16 ----------------
 lib/modules/manager/helmfile/utils.ts     | 20 ++++----------------
 5 files changed, 27 insertions(+), 49 deletions(-)
 delete mode 100644 lib/modules/manager/helmfile/types.ts

diff --git a/lib/modules/manager/helmfile/artifacts.ts b/lib/modules/manager/helmfile/artifacts.ts
index 447fa645fe..d8ecb91348 100644
--- a/lib/modules/manager/helmfile/artifacts.ts
+++ b/lib/modules/manager/helmfile/artifacts.ts
@@ -12,14 +12,12 @@ import {
 } from '../../../util/fs';
 import { getFile } from '../../../util/git';
 import { regEx } from '../../../util/regex';
+import { Result } from '../../../util/result';
+import { Yaml } from '../../../util/schema-utils';
 import { generateHelmEnvs } from '../helmv3/common';
 import type { UpdateArtifact, UpdateArtifactsResult } from '../types';
-import {
-  generateRegistryLoginCmd,
-  isOCIRegistry,
-  parseDoc,
-  parseLock,
-} from './utils';
+import { Doc, LockVersion } from './schema';
+import { generateRegistryLoginCmd, isOCIRegistry } from './utils';
 
 export async function updateArtifacts({
   packageFileName,
@@ -58,7 +56,7 @@ export async function updateArtifacts({
         toolName: 'helmfile',
         constraint:
           config.constraints?.helmfile ??
-          parseLock(existingLockFileContent).version,
+          Result.parse(existingLockFileContent, LockVersion).unwrapOrNull(),
       },
     ];
     const needKustomize = updatedDeps.some(
@@ -72,7 +70,10 @@ export async function updateArtifacts({
     }
 
     const cmd: string[] = [];
-    const doc = parseDoc(newPackageFileContent);
+    const doc = Result.parse(
+      newPackageFileContent,
+      Yaml.pipe(Doc)
+    ).unwrapOrThrow();
 
     for (const value of coerceArray(doc.repositories).filter(isOCIRegistry)) {
       const loginCmd = await generateRegistryLoginCmd(
diff --git a/lib/modules/manager/helmfile/extract.ts b/lib/modules/manager/helmfile/extract.ts
index 2c20598920..8726c90e7d 100644
--- a/lib/modules/manager/helmfile/extract.ts
+++ b/lib/modules/manager/helmfile/extract.ts
@@ -9,7 +9,7 @@ import type {
   PackageDependency,
   PackageFileContent,
 } from '../types';
-import type { Doc } from './types';
+import type { Doc } from './schema';
 import {
   kustomizationsKeysUsed,
   localChartHasKustomizationsYaml,
diff --git a/lib/modules/manager/helmfile/schema.ts b/lib/modules/manager/helmfile/schema.ts
index dd4ac7ff2f..1ff9e67b80 100644
--- a/lib/modules/manager/helmfile/schema.ts
+++ b/lib/modules/manager/helmfile/schema.ts
@@ -1,12 +1,14 @@
 import { z } from 'zod';
+import { Yaml } from '../../../util/schema-utils';
 
-export const RepositorySchema = z.object({
+export const HelmRepository = z.object({
   name: z.string(),
   url: z.string(),
   oci: z.boolean().optional(),
 });
+export type HelmRepository = z.infer<typeof HelmRepository>;
 
-export const ReleaseSchema = z.object({
+export const HelmRelease = z.object({
   name: z.string(),
   chart: z.string(),
   version: z.string(),
@@ -14,12 +16,15 @@ export const ReleaseSchema = z.object({
   jsonPatches: z.unknown().optional(),
   transformers: z.unknown().optional(),
 });
+export type HelmRelease = z.infer<typeof HelmRelease>;
 
-export const DocSchema = z.object({
-  releases: z.array(ReleaseSchema).optional(),
-  repositories: z.array(RepositorySchema).optional(),
+export const Doc = z.object({
+  releases: z.array(HelmRelease).optional(),
+  repositories: z.array(HelmRepository).optional(),
 });
+export type Doc = z.infer<typeof Doc>;
 
-export const LockSchema = z.object({
-  version: z.string(),
-});
+export const LockVersion = Yaml.pipe(
+  z.object({ version: z.string() }).transform(({ version }) => version)
+);
+export type LockVersion = z.infer<typeof LockVersion>;
diff --git a/lib/modules/manager/helmfile/types.ts b/lib/modules/manager/helmfile/types.ts
deleted file mode 100644
index a5bd8e60cf..0000000000
--- a/lib/modules/manager/helmfile/types.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import type { z } from 'zod';
-
-import type {
-  DocSchema,
-  LockSchema,
-  ReleaseSchema,
-  RepositorySchema,
-} from './schema';
-
-export type Release = z.infer<typeof ReleaseSchema>;
-
-export type Repository = z.infer<typeof RepositorySchema>;
-
-export type Doc = z.infer<typeof DocSchema>;
-
-export type Lock = z.infer<typeof LockSchema>;
diff --git a/lib/modules/manager/helmfile/utils.ts b/lib/modules/manager/helmfile/utils.ts
index 76234764b8..db427892ba 100644
--- a/lib/modules/manager/helmfile/utils.ts
+++ b/lib/modules/manager/helmfile/utils.ts
@@ -1,4 +1,3 @@
-import yaml from 'js-yaml';
 import upath from 'upath';
 
 import { getParentDir, localPathExists } from '../../../util/fs';
@@ -7,11 +6,10 @@ import { DockerDatasource } from '../../datasource/docker';
 import { generateLoginCmd } from '../helmv3/common';
 import type { RepositoryRule } from '../helmv3/types';
 
-import { DocSchema, LockSchema } from './schema';
-import type { Doc, Lock, Release, Repository } from './types';
+import type { HelmRelease, HelmRepository } from './schema';
 
 /** Returns true if a helmfile release contains kustomize specific keys **/
-export function kustomizationsKeysUsed(release: Release): boolean {
+export function kustomizationsKeysUsed(release: HelmRelease): boolean {
   return (
     release.strategicMergePatches !== undefined ||
     release.jsonPatches !== undefined ||
@@ -22,7 +20,7 @@ export function kustomizationsKeysUsed(release: Release): boolean {
 /** Returns true if a helmfile release uses a local chart with a kustomization.yaml file **/
 // eslint-disable-next-line require-await
 export async function localChartHasKustomizationsYaml(
-  release: Release,
+  release: HelmRelease,
   helmFileYamlFileName: string
 ): Promise<boolean> {
   const helmfileYamlParentDir = getParentDir(helmFileYamlFileName) || '';
@@ -31,17 +29,7 @@ export async function localChartHasKustomizationsYaml(
   );
 }
 
-export function parseDoc(packageFileContent: string): Doc {
-  const doc = yaml.load(packageFileContent);
-  return DocSchema.parse(doc);
-}
-
-export function parseLock(lockFileContent: string): Lock {
-  const lock = yaml.load(lockFileContent);
-  return LockSchema.parse(lock);
-}
-
-export function isOCIRegistry(repository: Repository): boolean {
+export function isOCIRegistry(repository: HelmRepository): boolean {
   return repository.oci === true;
 }
 
-- 
GitLab