From 5b292903a9c97ec3cd25a84312aee26ea41d7f25 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Krist=C3=B3f=20Marussy?= <kristof@marussy.com>
Date: Sat, 29 Jan 2022 18:07:12 +0100
Subject: [PATCH] [Depfu] Add support for Gitlab (#7475)

* [Depfu] Add support for Gitlab

Fixes #7474

* [Depfu] Add tests for Gitlab

Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
---
 services/depfu/depfu.service.js | 38 +++++++++++++++++++++------
 services/depfu/depfu.tester.js  | 46 ++++++++++++++++++++++++++++++---
 2 files changed, 72 insertions(+), 12 deletions(-)

diff --git a/services/depfu/depfu.service.js b/services/depfu/depfu.service.js
index b35daf9f90..fd26a9e429 100644
--- a/services/depfu/depfu.service.js
+++ b/services/depfu/depfu.service.js
@@ -1,18 +1,22 @@
 import Joi from 'joi'
-import { BaseJsonService } from '../index.js'
+import { BaseJsonService, InvalidParameter, redirector } from '../index.js'
 
 const depfuSchema = Joi.object({
   text: Joi.string().required(),
   colorscheme: Joi.string().required(),
 }).required()
 
-export default class Depfu extends BaseJsonService {
+class Depfu extends BaseJsonService {
   static category = 'dependencies'
-  static route = { base: 'depfu', pattern: ':user/:repo' }
+  static route = {
+    base: 'depfu/dependencies',
+    pattern: ':vcsType(github|gitlab)/:project+',
+  }
+
   static examples = [
     {
       title: 'Depfu',
-      namedParams: { user: 'depfu', repo: 'example-ruby' },
+      namedParams: { vcsType: 'github', project: 'depfu/example-ruby' },
       staticPreview: this.render({
         text: 'recent',
         colorscheme: 'brightgreen',
@@ -29,13 +33,31 @@ export default class Depfu extends BaseJsonService {
     }
   }
 
-  async fetch({ user, repo }) {
-    const url = `https://depfu.com/github/shields/${user}/${repo}`
+  async fetch({ vcsType, project }) {
+    const separatorPosition = project.lastIndexOf('/')
+    if (separatorPosition < 0) {
+      throw new InvalidParameter()
+    }
+    const user = encodeURIComponent(project.substr(0, separatorPosition))
+    const repo = project.substr(separatorPosition)
+    const url = `https://depfu.com/${vcsType}/shields/${user}/${repo}`
     return this._requestJson({ url, schema: depfuSchema })
   }
 
-  async handle({ user, repo }) {
-    const { text, colorscheme } = await this.fetch({ user, repo })
+  async handle({ vcsType, project }) {
+    const { text, colorscheme } = await this.fetch({ vcsType, project })
     return this.constructor.render({ text, colorscheme })
   }
 }
+
+const legacyRoutes = [
+  redirector({
+    category: 'dependencies',
+    route: { base: 'depfu', pattern: ':user/:repo' },
+    transformPath: ({ user, repo }) =>
+      `/depfu/dependencies/github/${user}/${repo}`,
+    dateAdded: new Date('2022-01-11'),
+  }),
+]
+
+export default { ...legacyRoutes, Depfu }
diff --git a/services/depfu/depfu.tester.js b/services/depfu/depfu.tester.js
index 04aeaf2b02..36b8b23757 100644
--- a/services/depfu/depfu.tester.js
+++ b/services/depfu/depfu.tester.js
@@ -10,13 +10,51 @@ const isDependencyStatus = Joi.string().valid(
 
 export const t = new ServiceTester({ id: 'depfu', title: 'Depfu' })
 
-t.create('depfu dependencies (valid)')
-  .get('/depfu/example-ruby.json')
+t.create('depfu Github dependencies (valid)')
+  .get('/dependencies/github/depfu/example-ruby.json')
   .expectBadge({
     label: 'dependencies',
     message: isDependencyStatus,
   })
 
-t.create('depfu dependencies (repo not found)')
-  .get('/pyvesb/emptyrepo.json')
+t.create('depfu Github dependencies (repo not found)')
+  .get('/dependencies/github/pyvesb/emptyrepo.json')
   .expectBadge({ label: 'dependencies', message: 'not found' })
+
+t.create('depfu Gitlab dependencies (valid)')
+  .get('/dependencies/gitlab/depfu/example-ruby.json')
+  .expectBadge({
+    label: 'dependencies',
+    message: isDependencyStatus,
+  })
+
+t.create('depfu Github dependencies (no separator)')
+  .get('/dependencies/github/example-ruby.json')
+  .expectBadge({
+    label: 'dependencies',
+    message: 'invalid parameter',
+  })
+
+t.create('depfu Gitlab dependencies (valid with subgroup)')
+  .get(
+    '/dependencies/gitlab/shields-example-group/subgroup/example-nodejs.json'
+  )
+  .expectBadge({
+    label: 'dependencies',
+    message: isDependencyStatus,
+  })
+
+t.create('depfu Gitlab dependencies (repo not found)')
+  .get('/dependencies/gitlab/fdroid/nonexistant.json')
+  .expectBadge({ label: 'dependencies', message: 'not found' })
+
+t.create('depfu Gitlab dependencies (no separator)')
+  .get('/dependencies/gitlab/example-ruby.json')
+  .expectBadge({
+    label: 'dependencies',
+    message: 'invalid parameter',
+  })
+
+t.create('legacy route (assume "github" as a default VCS)')
+  .get('/depfu/example-ruby.svg')
+  .expectRedirect('/depfu/dependencies/github/depfu/example-ruby.svg')
-- 
GitLab