-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Migrate existing adapter projects (#712)
- Loading branch information
1 parent
63b1d1c
commit c46c9eb
Showing
6 changed files
with
457 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
import { expect } from "chai"; | ||
import { MigrationContext } from "./migrationContext"; | ||
import path = require("path"); | ||
|
||
describe("directoryExists()", () => { | ||
it("should return true if the directory exists", async () => { | ||
const context = new MigrationContext(__dirname); | ||
expect(await context.directoryExists(".")).to.be.true; | ||
expect(await context.directoryExists("../..")).to.be.true; | ||
expect(await context.directoryExists("../../test")).to.be.true; | ||
}); | ||
|
||
it("should return false if the directory doesn't exists", async () => { | ||
const context = new MigrationContext(__dirname); | ||
expect(await context.directoryExists("foo")).to.be.false; | ||
expect(await context.directoryExists("../bar")).to.be.false; | ||
}); | ||
|
||
it("should return false if it isn't a directory", async () => { | ||
const context = new MigrationContext(__dirname); | ||
expect(await context.directoryExists("../../package.json")).to.be.false; | ||
expect(await context.directoryExists("../cli.ts")).to.be.false; | ||
}); | ||
}); | ||
|
||
describe("fileExists()", () => { | ||
it("should return true if the file exists", async () => { | ||
const context = new MigrationContext(__dirname); | ||
expect(await context.fileExists("../../package.json")).to.be.true; | ||
expect(await context.fileExists("../cli.ts")).to.be.true; | ||
}); | ||
|
||
it("should return false if the file doesn't exists", async () => { | ||
const context = new MigrationContext(__dirname); | ||
expect(await context.fileExists("../foo.ts")).to.be.false; | ||
expect(await context.fileExists("../../bar.txt")).to.be.false; | ||
}); | ||
|
||
it("should return false if it isn't a file", async () => { | ||
const context = new MigrationContext(__dirname); | ||
expect(await context.fileExists("../..")).to.be.false; | ||
expect(await context.fileExists("../../test")).to.be.false; | ||
}); | ||
}); | ||
|
||
describe("hasFilesWithExtension()", () => { | ||
it("should return true if files exist", async () => { | ||
const context = new MigrationContext(__dirname); | ||
expect(await context.hasFilesWithExtension("../..", ".json")).to.be | ||
.true; | ||
expect(await context.hasFilesWithExtension("..", ".ts")).to.be.true; | ||
expect( | ||
await context.hasFilesWithExtension( | ||
"..", | ||
".ts", | ||
(f) => !f.endsWith("cli.ts"), | ||
), | ||
).to.be.true; | ||
}); | ||
|
||
it("should return false if no files exist", async () => { | ||
const context = new MigrationContext(__dirname); | ||
expect(await context.hasFilesWithExtension("..", ".xls")).to.be.false; | ||
expect(await context.hasFilesWithExtension("..", ".dts")).to.be.false; | ||
expect( | ||
await context.hasFilesWithExtension( | ||
"..", | ||
".ts", | ||
(f) => !f.includes("i"), | ||
), | ||
).to.be.false; | ||
}); | ||
|
||
it("should return false if the directory doesn't exist", async () => { | ||
const context = new MigrationContext(__dirname); | ||
expect(await context.hasFilesWithExtension("foo", ".json")).to.be.false; | ||
expect(await context.hasFilesWithExtension("../bar", ".ts")).to.be | ||
.false; | ||
}); | ||
}); | ||
|
||
describe("hasDevDependency()", () => { | ||
it("should return true if the dependency exists", () => { | ||
const context = new MigrationContext(__dirname); | ||
context.packageJson = { | ||
devDependencies: { | ||
gulp: "^3.9.1", | ||
mocha: "^4.1.0", | ||
chai: "^4.1.2", | ||
}, | ||
}; | ||
expect(context.hasDevDependency("gulp")).to.be.true; | ||
expect(context.hasDevDependency("mocha")).to.be.true; | ||
expect(context.hasDevDependency("chai")).to.be.true; | ||
}); | ||
|
||
it("should return false if the dependency doesn't exists", () => { | ||
const context = new MigrationContext(__dirname); | ||
context.packageJson = { | ||
devDependencies: { | ||
gulp: "^3.9.1", | ||
mocha: "^4.1.0", | ||
chai: "^4.1.2", | ||
}, | ||
}; | ||
expect(context.hasDevDependency("coffee")).to.be.false; | ||
expect(context.hasDevDependency("chia")).to.be.false; | ||
}); | ||
}); | ||
|
||
describe("getMainFileContent()", () => { | ||
if (!process.env.CI) { | ||
// not working in GH action as we don't compile the JS code there | ||
it("should return the contents of the TS file if a main JS file is found with a corresponding TS file", async () => { | ||
const baseDir = path.resolve(__dirname, "../.."); | ||
const context = new MigrationContext(baseDir); | ||
context.packageJson = { | ||
main: "build/src/cli.js", | ||
}; | ||
expect(await context.getMainFileContent()).not.to.be.empty; | ||
expect(await context.getMainFileContent()).to.contain( | ||
"import * as yargs", | ||
); | ||
}); | ||
} | ||
|
||
it("should return the contents of the main file if a main file is found with no corresponding TS file", async () => { | ||
const baseDir = path.resolve(__dirname, "../.."); | ||
const context = new MigrationContext(baseDir); | ||
context.packageJson = { | ||
main: "bin/create-adapter.js", | ||
}; | ||
expect(await context.getMainFileContent()).not.to.be.empty; | ||
expect(await context.getMainFileContent()).to.contain( | ||
"#!/usr/bin/env node", | ||
); | ||
}); | ||
|
||
it("should return an empty string if no main file is found", async () => { | ||
const baseDir = path.resolve(__dirname, "../.."); | ||
const context = new MigrationContext(baseDir); | ||
context.packageJson = { | ||
main: "foo/bar.js", | ||
}; | ||
expect(await context.getMainFileContent()).to.be.empty; | ||
}); | ||
}); | ||
|
||
// not working in GH action - but you can still use this test locally | ||
describe("analyzeCode()", () => { | ||
if (!process.env.CI) { | ||
// not working in GH action as we don't compile the JS code there | ||
it("should return true the first string occurs more than the second", async () => { | ||
const baseDir = path.resolve(__dirname, "../.."); | ||
const context = new MigrationContext(baseDir); | ||
context.packageJson = { | ||
main: "build/src/cli.js", | ||
}; | ||
expect(await context.analyzeCode("\t", " ")).to.be.true; | ||
expect(await context.analyzeCode('"', "'")).to.be.true; | ||
}); | ||
it("should return false the first string occurs less often than the second", async () => { | ||
const baseDir = path.resolve(__dirname, "../.."); | ||
const context = new MigrationContext(baseDir); | ||
context.packageJson = { | ||
main: "build/src/cli.js", | ||
}; | ||
expect(await context.analyzeCode(" ", "\t")).to.be.false; | ||
expect(await context.analyzeCode("'", '"')).to.be.false; | ||
}); | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
import { existsSync, readdir, readFile, readJson, stat } from "fs-extra"; | ||
import path = require("path"); | ||
|
||
export class MigrationContext { | ||
public packageJson: any; | ||
public ioPackageJson: any; | ||
|
||
constructor(private readonly baseDir: string) {} | ||
|
||
public async load(): Promise<void> { | ||
this.packageJson = await this.readJsonFile("package.json"); | ||
this.ioPackageJson = await this.readJsonFile("io-package.json"); | ||
} | ||
|
||
public async readJsonFile<T>(fileName: string): Promise<T> { | ||
return (await readJson(path.join(this.baseDir, fileName))) as T; | ||
} | ||
|
||
public async directoryExists(dirName: string): Promise<boolean> { | ||
const fullPath = path.join(this.baseDir, dirName); | ||
return existsSync(fullPath) && (await stat(fullPath)).isDirectory(); | ||
} | ||
|
||
public async fileExists(dirName: string): Promise<boolean> { | ||
const fullPath = path.join(this.baseDir, dirName); | ||
return existsSync(fullPath) && (await stat(fullPath)).isFile(); | ||
} | ||
|
||
public async hasFilesWithExtension( | ||
dirName: string, | ||
extension: string, | ||
filter?: (fileName: string) => boolean, | ||
): Promise<boolean> { | ||
return ( | ||
(await this.directoryExists(dirName)) && | ||
(await readdir(path.join(this.baseDir, dirName))).some( | ||
(f) => | ||
(!filter || filter(f)) && | ||
f.toLowerCase().endsWith(extension.toLowerCase()), | ||
) | ||
); | ||
} | ||
|
||
public hasDevDependency(packageName: string): boolean { | ||
return this.packageJson.devDependencies?.hasOwnProperty(packageName); | ||
} | ||
|
||
public async getMainFileContent(): Promise<string> { | ||
if ( | ||
!this.packageJson.main || | ||
!this.packageJson.main.endsWith(".js") || | ||
!(await this.fileExists(this.packageJson.main)) | ||
) { | ||
// we don't have a main JavaScript file, it will be impossible to find code | ||
return ""; | ||
} | ||
|
||
try { | ||
const tsMains = [ | ||
path.join( | ||
this.baseDir, | ||
"src", | ||
this.packageJson.main.replace(/\.js$/, ".ts"), | ||
), | ||
path.join( | ||
this.baseDir, | ||
this.packageJson.main | ||
.replace(/\.js$/, ".ts") | ||
.replace(/^dist([\\/])/, "src$1"), | ||
), | ||
path.join( | ||
this.baseDir, | ||
this.packageJson.main | ||
.replace(/\.js$/, ".ts") | ||
.replace(/^build([\\/])/, "src$1"), | ||
), | ||
path.join( | ||
this.baseDir, | ||
this.packageJson.main | ||
.replace(/\.js$/, ".ts") | ||
.replace(/^(build|dist)[\\/]/, ""), | ||
), | ||
]; | ||
for (let i = 0; i < tsMains.length; i++) { | ||
const tsMain = tsMains[i]; | ||
if (existsSync(tsMain)) { | ||
// most probably TypeScript | ||
return readFile(tsMain, { encoding: "utf8" }); | ||
} | ||
} | ||
|
||
return readFile(path.join(this.baseDir, this.packageJson.main), { | ||
encoding: "utf8", | ||
}); | ||
} catch { | ||
// we don't want this to crash, so just return an empty string | ||
return ""; | ||
} | ||
} | ||
|
||
public async analyzeCode(either: string, or: string): Promise<boolean> { | ||
const content = await this.getMainFileContent(); | ||
const eitherCount = (content.match(new RegExp(either, "g")) || []) | ||
.length; | ||
const orCount = (content.match(new RegExp(or, "g")) || []).length; | ||
return eitherCount >= orCount; | ||
} | ||
} |
Oops, something went wrong.