From b0ae8f6680cfb5a1fff33e6361c156f08b1e77e7 Mon Sep 17 00:00:00 2001
From: zeshuaro <joshuaystang@gmail.com>
Date: Fri, 25 Feb 2022 18:19:19 +1100
Subject: [PATCH] feat: add fvm manager (#14370)

* feat(manager/fvm): add fvm manager

* fix(manager/fvm): add to check for type of version value

* style: update string type check

Co-authored-by: Rhys Arkins <rhys@arkins.net>

* feat: update fvm manager

* chore: add fvm folder to tsconfig.strict.json

Co-authored-by: Rhys Arkins <rhys@arkins.net>
Co-authored-by: Michael Kriese <michael.kriese@visualon.de>
---
 lib/manager/api.ts              |  2 ++
 lib/manager/fvm/extract.spec.ts | 52 +++++++++++++++++++++++++++++++++
 lib/manager/fvm/extract.ts      | 40 +++++++++++++++++++++++++
 lib/manager/fvm/index.ts        | 11 +++++++
 lib/manager/fvm/readme.md       |  1 +
 tsconfig.strict.json            |  2 ++
 6 files changed, 108 insertions(+)
 create mode 100644 lib/manager/fvm/extract.spec.ts
 create mode 100644 lib/manager/fvm/extract.ts
 create mode 100644 lib/manager/fvm/index.ts
 create mode 100644 lib/manager/fvm/readme.md

diff --git a/lib/manager/api.ts b/lib/manager/api.ts
index 76fad55f08..3f45b28b1b 100644
--- a/lib/manager/api.ts
+++ b/lib/manager/api.ts
@@ -21,6 +21,7 @@ import * as dockerCompose from './docker-compose';
 import * as dockerfile from './dockerfile';
 import * as droneci from './droneci';
 import * as flux from './flux';
+import * as fvm from './fvm';
 import * as gitSubmodules from './git-submodules';
 import * as githubActions from './github-actions';
 import * as gitlabci from './gitlabci';
@@ -93,6 +94,7 @@ api.set('docker-compose', dockerCompose);
 api.set('dockerfile', dockerfile);
 api.set('droneci', droneci);
 api.set('flux', flux);
+api.set('fvm', fvm);
 api.set('git-submodules', gitSubmodules);
 api.set('github-actions', githubActions);
 api.set('gitlabci', gitlabci);
diff --git a/lib/manager/fvm/extract.spec.ts b/lib/manager/fvm/extract.spec.ts
new file mode 100644
index 0000000000..18cfcd257b
--- /dev/null
+++ b/lib/manager/fvm/extract.spec.ts
@@ -0,0 +1,52 @@
+import { extractPackageFile } from '.';
+
+const packageFile = 'packageFile';
+
+describe('manager/fvm/extract', () => {
+  describe('extractPackageFile()', () => {
+    it('returns null for invalid json', () => {
+      expect(
+        extractPackageFile('clearly invalid json', packageFile)
+      ).toBeNull();
+    });
+    it('returns null for empty flutter sdk version', () => {
+      expect(extractPackageFile('{}', packageFile)).toBeNull();
+    });
+    it('returns null for non string flutter sdk version', () => {
+      expect(
+        extractPackageFile(
+          '{"flutterSdkVersion": 2.1, "flavors": {}}',
+          packageFile
+        )
+      ).toBeNull();
+    });
+    it('returns a result', () => {
+      const res = extractPackageFile(
+        '{"flutterSdkVersion": "2.10.1", "flavors": {}}',
+        packageFile
+      );
+      expect(res.deps).toEqual([
+        {
+          currentValue: '2.10.1',
+          datasource: 'github-tags',
+          depName: 'flutter',
+          lookupName: 'flutter/flutter',
+        },
+      ]);
+    });
+    it('supports non range', () => {
+      const res = extractPackageFile(
+        '{"flutterSdkVersion": "stable", "flavors": {}}',
+        packageFile
+      );
+      expect(res.deps).toEqual([
+        {
+          currentValue: 'stable',
+          datasource: 'github-tags',
+          depName: 'flutter',
+          lookupName: 'flutter/flutter',
+        },
+      ]);
+    });
+  });
+});
diff --git a/lib/manager/fvm/extract.ts b/lib/manager/fvm/extract.ts
new file mode 100644
index 0000000000..5ecf17dc96
--- /dev/null
+++ b/lib/manager/fvm/extract.ts
@@ -0,0 +1,40 @@
+import is from '@sindresorhus/is';
+import { GithubTagsDatasource } from '../../datasource/github-tags';
+import { logger } from '../../logger';
+import type { PackageDependency, PackageFile } from '../types';
+
+interface FvmConfig {
+  flutterSdkVersion: string;
+}
+
+export function extractPackageFile(
+  content: string,
+  packageFile: string
+): PackageFile | null {
+  let fvmConfig: FvmConfig;
+  try {
+    fvmConfig = JSON.parse(content);
+  } catch (err) {
+    logger.debug({ packageFile, err }, 'Invalid FVM config');
+    return null;
+  }
+
+  if (!fvmConfig.flutterSdkVersion) {
+    logger.debug(
+      { contents: fvmConfig },
+      'FVM config does not have flutterSdkVersion specified'
+    );
+    return null;
+  } else if (!is.string(fvmConfig.flutterSdkVersion)) {
+    logger.debug({ contents: fvmConfig }, 'flutterSdkVersion must be a string');
+    return null;
+  }
+
+  const dep: PackageDependency = {
+    depName: 'flutter',
+    currentValue: fvmConfig.flutterSdkVersion,
+    datasource: GithubTagsDatasource.id,
+    lookupName: 'flutter/flutter',
+  };
+  return { deps: [dep] };
+}
diff --git a/lib/manager/fvm/index.ts b/lib/manager/fvm/index.ts
new file mode 100644
index 0000000000..d656241074
--- /dev/null
+++ b/lib/manager/fvm/index.ts
@@ -0,0 +1,11 @@
+import { GithubTagsDatasource } from '../../datasource/github-tags';
+import * as semverVersioning from '../../versioning/semver';
+
+export { extractPackageFile } from './extract';
+
+export const supportedDatasources = [GithubTagsDatasource.id];
+
+export const defaultConfig = {
+  fileMatch: ['(^|\\/)\\.fvm\\/fvm_config\\.json$'],
+  versioning: semverVersioning.id,
+};
diff --git a/lib/manager/fvm/readme.md b/lib/manager/fvm/readme.md
new file mode 100644
index 0000000000..5d4f3ab310
--- /dev/null
+++ b/lib/manager/fvm/readme.md
@@ -0,0 +1 @@
+Keeps the `.fvm/fvm_config.json` file updated.
diff --git a/tsconfig.strict.json b/tsconfig.strict.json
index c2583384fc..25201cde3a 100644
--- a/tsconfig.strict.json
+++ b/tsconfig.strict.json
@@ -145,6 +145,8 @@
     "lib/manager/flux/artifacts.ts",
     "lib/manager/flux/extract.ts",
     "lib/manager/flux/index.ts",
+    "lib/manager/fvm/extract.ts",
+    "lib/manager/fvm/index.ts",
     "lib/manager/git-submodules/artifacts.ts",
     "lib/manager/git-submodules/extract.ts",
     "lib/manager/git-submodules/index.ts",
-- 
GitLab