From b350a8c5fb660f036d06ec85a4193fca8585f4a3 Mon Sep 17 00:00:00 2001
From: Sebastian Poxhofer <secustor@users.noreply.github.com>
Date: Wed, 22 Sep 2021 09:21:22 +0200
Subject: [PATCH] feat: option to write discovered repositories to a json
 (#11806)

---
 docs/usage/self-hosted-configuration.md | 10 ++++++++++
 lib/config/options/index.ts             |  7 +++++++
 lib/workers/global/index.spec.ts        | 25 ++++++++++++++++++++++++-
 lib/workers/global/index.ts             | 11 +++++++++++
 4 files changed, 52 insertions(+), 1 deletion(-)

diff --git a/docs/usage/self-hosted-configuration.md b/docs/usage/self-hosted-configuration.md
index 339805bbc3..279077a95f 100644
--- a/docs/usage/self-hosted-configuration.md
+++ b/docs/usage/self-hosted-configuration.md
@@ -487,3 +487,13 @@ This is currently applicable to `npm` and `lerna`/`npm` only, and only used in c
 ## username
 
 Mandatory if a GitHub app token is in use using the CLI.
+
+## writeDiscoveredRepos
+
+Optional parameter which allows to write the discovered repositories into a JSON file instead of renovating them.
+
+Usage: `renovate --write-discovered-repos=/tmp/renovate-repos.json`
+
+```json
+["myOrg/myRepo", "myOrg/anotherRepo"]
+```
diff --git a/lib/config/options/index.ts b/lib/config/options/index.ts
index 622c043907..7a757b04d8 100644
--- a/lib/config/options/index.ts
+++ b/lib/config/options/index.ts
@@ -2051,6 +2051,13 @@ const options: RenovateOptions[] = [
     stage: 'repository',
     globalOnly: true,
   },
+  {
+    name: 'writeDiscoveredRepos',
+    description: 'Writes discovered repositories to a JSON file and then exit.',
+    type: 'string',
+    globalOnly: true,
+    env: false,
+  },
 ];
 
 export function getOptions(): RenovateOptions[] {
diff --git a/lib/workers/global/index.spec.ts b/lib/workers/global/index.spec.ts
index 988d2b352e..13d93bcba4 100644
--- a/lib/workers/global/index.spec.ts
+++ b/lib/workers/global/index.spec.ts
@@ -1,5 +1,6 @@
+import { expect } from '@jest/globals';
 import { ERROR, WARN } from 'bunyan';
-import { logger } from '../../../test/util';
+import { fs, logger } from '../../../test/util';
 import {
   PLATFORM_TYPE_GITHUB,
   PLATFORM_TYPE_GITLAB,
@@ -12,6 +13,7 @@ import * as _limits from './limits';
 import * as globalWorker from '.';
 
 jest.mock('../repository');
+jest.mock('../../util/fs');
 
 // imports are readonly
 const repositoryWorker = _repositoryWorker;
@@ -130,4 +132,25 @@ describe('workers/global/index', () => {
       expect(repositoryWorker.renovateRepository).toHaveBeenCalledTimes(1);
     });
   });
+
+  describe('write repositories to file', () => {
+    it('successfully write file', async () => {
+      configParser.parseConfigs.mockResolvedValueOnce({
+        repositories: ['myOrg/myRepo'],
+        platform: PLATFORM_TYPE_GITHUB,
+        endpoint: 'https://github.com/',
+        writeDiscoveredRepos: '/tmp/renovate-output.json',
+      });
+      fs.writeFile.mockReturnValueOnce(null);
+
+      expect(await globalWorker.start()).toEqual(0);
+      expect(fs.writeFile).toHaveBeenCalledTimes(1);
+      expect(fs.writeFile).toHaveBeenCalledWith(
+        '/tmp/renovate-output.json',
+        '["myOrg/myRepo"]'
+      );
+      expect(configParser.parseConfigs).toHaveBeenCalledTimes(1);
+      expect(repositoryWorker.renovateRepository).toHaveBeenCalledTimes(0);
+    });
+  });
 });
diff --git a/lib/workers/global/index.ts b/lib/workers/global/index.ts
index d683f31866..2c51a573d4 100644
--- a/lib/workers/global/index.ts
+++ b/lib/workers/global/index.ts
@@ -14,6 +14,7 @@ import type {
 } from '../../config/types';
 import { CONFIG_PRESETS_INVALID } from '../../constants/error-messages';
 import { getProblems, logger, setMeta } from '../../logger';
+import { writeFile } from '../../util/fs';
 import * as hostRules from '../../util/host-rules';
 import * as repositoryWorker from '../repository';
 import { autodiscoverRepositories } from './autodiscover';
@@ -97,6 +98,16 @@ export async function start(): Promise<number> {
 
     // autodiscover repositories (needs to come after platform initialization)
     config = await autodiscoverRepositories(config);
+
+    if (is.nonEmptyString(config.writeDiscoveredRepos)) {
+      const content = JSON.stringify(config.repositories);
+      await writeFile(config.writeDiscoveredRepos, content);
+      logger.info(
+        `Written discovered repositories to ${config.writeDiscoveredRepos}`
+      );
+      return 0;
+    }
+
     // Iterate through repositories sequentially
     for (const repository of config.repositories) {
       if (haveReachedLimits()) {
-- 
GitLab