From b063c3dcf85d90f58b55e1a0a525d69fd346c7bf Mon Sep 17 00:00:00 2001 From: Sehsyha Date: Thu, 17 Oct 2019 10:00:42 +0200 Subject: [PATCH] feat: add golang language detector Fixes #82 --- .../Golang/GolangLanguageDetector.spec.ts | 60 +++++++++++++++++++ .../Golang/GolangLanguageDetector.ts | 37 ++++++++++++ 2 files changed, 97 insertions(+) create mode 100644 src/detectors/Golang/GolangLanguageDetector.spec.ts create mode 100644 src/detectors/Golang/GolangLanguageDetector.ts diff --git a/src/detectors/Golang/GolangLanguageDetector.spec.ts b/src/detectors/Golang/GolangLanguageDetector.spec.ts new file mode 100644 index 000000000..3d4c7a412 --- /dev/null +++ b/src/detectors/Golang/GolangLanguageDetector.spec.ts @@ -0,0 +1,60 @@ +import { FileInspector } from '../../inspectors/FileInspector'; +import { ProgrammingLanguage } from '../../model'; +import { FileSystemService } from '../../services/FileSystemService'; +import * as nodePath from 'path'; +import { DirectoryJSON } from 'memfs/lib/volume'; +import { GolangLanguageDetector } from './GolangLanguageDetector'; + +describe('GolangLanguageDetector', () => { + let detector: GolangLanguageDetector; + let virtualFileSystemService: FileSystemService; + + beforeEach(() => { + virtualFileSystemService = new FileSystemService({ isVirtual: true }); + + const fileInspector = new FileInspector(virtualFileSystemService, '/'); + detector = new GolangLanguageDetector(fileInspector); + }); + + afterEach(async () => { + virtualFileSystemService.clearFileSystem(); + }); + + it('detects golang correctly via Gopkg.toml', async () => { + const structure: DirectoryJSON = { + '/Gopkg.toml': '...', + }; + + virtualFileSystemService.setFileSystem(structure); + + const langAtPath = await detector.detectLanguage(); + expect(langAtPath.length).toEqual(1); + expect(langAtPath[0].language).toEqual(ProgrammingLanguage.Go); + expect(langAtPath[0].path).toEqual(nodePath.sep); + }); + + it("detects it's not a golang file", async () => { + const structure: DirectoryJSON = { + '/src/index.none': '...', + }; + + virtualFileSystemService.setFileSystem(structure); + + const langAtPath = await detector.detectLanguage(); + expect(langAtPath.length).toEqual(0); + expect(langAtPath).toEqual([]); + }); + + it('detects golang correctly via go file', async () => { + const structure: DirectoryJSON = { + '/index.go': '...', + }; + + virtualFileSystemService.setFileSystem(structure); + + const langAtPath = await detector.detectLanguage(); + expect(langAtPath.length).toEqual(1); + expect(langAtPath[0].language).toEqual(ProgrammingLanguage.Go); + expect(langAtPath[0].path).toEqual(nodePath.sep); + }); +}); diff --git a/src/detectors/Golang/GolangLanguageDetector.ts b/src/detectors/Golang/GolangLanguageDetector.ts new file mode 100644 index 000000000..43b12d5c4 --- /dev/null +++ b/src/detectors/Golang/GolangLanguageDetector.ts @@ -0,0 +1,37 @@ +import { ILanguageDetector } from '../ILanguageDetector'; +import { injectable, inject } from 'inversify'; +import { LanguageAtPath, ProgrammingLanguage } from '../../model'; +import { IFileInspector } from '../../inspectors/IFileInspector'; +import { Types } from '../../types'; +import { fileNameRegExp, fileExtensionRegExp, sharedSubpath } from '../utils'; +import { uniq } from 'lodash'; +import * as nodePath from 'path'; + +@injectable() +export class GolangLanguageDetector implements ILanguageDetector { + private fileInspector: IFileInspector; + constructor(@inject(Types.IFileInspector) fileInspector: IFileInspector) { + this.fileInspector = fileInspector; + } + + async detectLanguage(): Promise { + const result: LanguageAtPath[] = []; + const packageFiles = await this.fileInspector.scanFor(fileNameRegExp('Gopkg.toml'), '/'); + + if(packageFiles.length > 0) { + for (const path of packageFiles.map((file) => nodePath.dirname(file.path))) { + result.push({ language: ProgrammingLanguage.Go, path }); + } + } else { + const goFiles = await this.fileInspector.scanFor(fileExtensionRegExp(['go']), '/'); + if (goFiles.length === 0) { + return result; + } + const dirsWithProjects = uniq(goFiles.map((f) => nodePath.dirname(f.path))); + // Get the shared subpath + const commonPath = sharedSubpath(dirsWithProjects); + result.push({ language: ProgrammingLanguage.Go, path: commonPath }); + } + return result; + } +}