-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(gradle-lite): JS-based Gradle manager (#7521)
- Loading branch information
Showing
17 changed files
with
1,875 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`manager/gradle-lite/parser parses fixture from "gradle" manager 1`] = ` | ||
Array [ | ||
Object { | ||
"currentValue": "1.5.2.RELEASE", | ||
"depName": "org.springframework.boot:spring-boot-gradle-plugin", | ||
"groupName": "springBootVersion", | ||
"managerData": Object { | ||
"fileReplacePosition": 53, | ||
"packageFile": "build.gradle", | ||
}, | ||
}, | ||
Object { | ||
"currentValue": "1.2.3", | ||
"depName": "com.github.jengelman.gradle.plugins:shadow", | ||
"managerData": Object { | ||
"fileReplacePosition": 388, | ||
"packageFile": "build.gradle", | ||
}, | ||
}, | ||
Object { | ||
"currentValue": "0.1", | ||
"depName": "com.fkorotkov:gradle-libraries-plugin", | ||
"managerData": Object { | ||
"fileReplacePosition": 452, | ||
"packageFile": "build.gradle", | ||
}, | ||
}, | ||
Object { | ||
"currentValue": "0.2.3", | ||
"depName": "gradle.plugin.se.patrikerdes:gradle-use-latest-versions-plugin", | ||
"managerData": Object { | ||
"fileReplacePosition": 539, | ||
"packageFile": "build.gradle", | ||
}, | ||
}, | ||
Object { | ||
"currentValue": "3.1.1", | ||
"depName": "org.apache.openjpa:openjpa", | ||
"managerData": Object { | ||
"fileReplacePosition": 592, | ||
"packageFile": "build.gradle", | ||
}, | ||
}, | ||
Object { | ||
"currentValue": "6.0.9.RELEASE", | ||
"depName": "org.grails:gorm-hibernate5-spring-boot", | ||
"managerData": Object { | ||
"fileReplacePosition": 1785, | ||
"packageFile": "build.gradle", | ||
}, | ||
}, | ||
Object { | ||
"currentValue": "6.0.5", | ||
"depName": "mysql:mysql-connector-java", | ||
"managerData": Object { | ||
"fileReplacePosition": 1841, | ||
"packageFile": "build.gradle", | ||
}, | ||
}, | ||
Object { | ||
"currentValue": "1.0-groovy-2.4", | ||
"depName": "org.spockframework:spock-spring", | ||
"managerData": Object { | ||
"fileReplacePosition": 1899, | ||
"packageFile": "build.gradle", | ||
}, | ||
}, | ||
Object { | ||
"currentValue": "1.3", | ||
"depName": "org.hamcrest:hamcrest-core", | ||
"managerData": Object { | ||
"fileReplacePosition": 2004, | ||
"packageFile": "build.gradle", | ||
}, | ||
}, | ||
Object { | ||
"currentValue": "3.1", | ||
"depName": "cglib:cglib-nodep", | ||
"managerData": Object { | ||
"fileReplacePosition": 2092, | ||
"packageFile": "build.gradle", | ||
}, | ||
}, | ||
Object { | ||
"currentValue": "3.1.1", | ||
"depName": "org.apache.openjpa:openjpa", | ||
"managerData": Object { | ||
"fileReplacePosition": 2198, | ||
"packageFile": "build.gradle", | ||
}, | ||
}, | ||
] | ||
`; |
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,100 @@ | ||
import { PackageDependency } from '../common'; | ||
|
||
export interface ManagerData { | ||
fileReplacePosition: number; | ||
packageFile?: string; | ||
} | ||
|
||
export interface VariableData extends ManagerData { | ||
key: string; | ||
value: string; | ||
} | ||
|
||
export type PackageVariables = Record<string, VariableData>; | ||
export type VariableRegistry = Record<string, PackageVariables>; | ||
|
||
export enum TokenType { | ||
Space = 'space', | ||
LineComment = 'lineComment', | ||
MultiComment = 'multiComment', | ||
Newline = 'newline', | ||
|
||
Semicolon = 'semicolon', | ||
Colon = 'colon', | ||
Dot = 'dot', | ||
Comma = 'comma', | ||
Operator = 'operator', | ||
|
||
Assignment = 'assignment', | ||
|
||
Word = 'word', | ||
|
||
LeftParen = 'leftParen', | ||
RightParen = 'rightParen', | ||
|
||
LeftBracket = 'leftBracket', | ||
RightBracket = 'rightBracket', | ||
|
||
LeftBrace = 'leftBrace', | ||
RightBrace = 'rightBrace', | ||
|
||
SingleQuotedStart = 'singleQuotedStart', | ||
SingleQuotedFinish = 'singleQuotedFinish', | ||
|
||
DoubleQuotedStart = 'doubleQuotedStart', | ||
StringInterpolation = 'interpolation', | ||
IgnoredInterpolationStart = 'ignoredInterpolation', | ||
Variable = 'variable', | ||
DoubleQuotedFinish = 'doubleQuotedFinish', | ||
|
||
TripleSingleQuotedStart = 'tripleQuotedStart', | ||
TripleDoubleQuotedStart = 'tripleDoubleQuotedStart', | ||
TripleQuotedFinish = 'tripleQuotedFinish', | ||
|
||
Char = 'char', | ||
EscapedChar = 'escapedChar', | ||
String = 'string', | ||
|
||
UnknownLexeme = 'unknownChar', | ||
UnknownFragment = 'unknownFragment', | ||
} | ||
|
||
export interface Token { | ||
type: TokenType; | ||
value: string; | ||
offset: number; | ||
} | ||
|
||
export interface StringInterpolation extends Token { | ||
type: TokenType.StringInterpolation; | ||
children: Token[]; // Tokens inside double-quoted string that are subject of interpolation | ||
isComplete: boolean; // True if token has parsed completely | ||
isValid: boolean; // False if string contains something unprocessable | ||
} | ||
|
||
// Matcher on single token | ||
export interface SyntaxMatcher { | ||
matchType: TokenType | TokenType[]; | ||
matchValue?: string | string[]; | ||
lookahead?: boolean; | ||
tokenMapKey?: string; | ||
} | ||
|
||
export type TokenMap = Record<string, Token>; | ||
|
||
export interface SyntaxHandlerInput { | ||
packageFile: string; | ||
variables: PackageVariables; | ||
tokenMap: TokenMap; | ||
} | ||
|
||
export type SyntaxHandlerOutput = { | ||
deps?: PackageDependency<ManagerData>[]; | ||
vars?: PackageVariables; | ||
urls?: string[]; | ||
} | null; | ||
|
||
export interface SyntaxMatchConfig { | ||
matchers: SyntaxMatcher[]; | ||
handler: (MatcherHandlerInput) => SyntaxHandlerOutput; | ||
} |
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,69 @@ | ||
import { fs } from '../../../test/util'; | ||
import { extractAllPackageFiles } from '.'; | ||
|
||
jest.mock('../../util/fs'); | ||
|
||
function mockFs(files: Record<string, string>): void { | ||
fs.readLocalFile.mockImplementation( | ||
(fileName: string): Promise<string> => { | ||
const content = files?.[fileName]; | ||
return typeof content === 'string' | ||
? Promise.resolve(content) | ||
: Promise.reject(`File not found: ${fileName}`); | ||
} | ||
); | ||
} | ||
|
||
describe('manager/gradle-lite/extract', () => { | ||
beforeAll(() => {}); | ||
afterAll(() => { | ||
jest.resetAllMocks(); | ||
}); | ||
|
||
it('returns null', async () => { | ||
mockFs({ | ||
'gradle.properties': '', | ||
'build.gradle': '', | ||
}); | ||
|
||
const res = await extractAllPackageFiles({} as never, [ | ||
'build.gradle', | ||
'gradle.properties', | ||
]); | ||
|
||
expect(res).toBeNull(); | ||
}); | ||
|
||
it('works', async () => { | ||
mockFs({ | ||
'gradle.properties': 'baz=1.2.3', | ||
'build.gradle': 'url "https://example.com"; "foo:bar:$baz"', | ||
'settings.gradle': null, | ||
}); | ||
|
||
const res = await extractAllPackageFiles({} as never, [ | ||
'build.gradle', | ||
'gradle.properties', | ||
'settings.gradle', | ||
]); | ||
|
||
expect(res).toMatchObject([ | ||
{ | ||
packageFile: 'gradle.properties', | ||
deps: [ | ||
{ | ||
depName: 'foo:bar', | ||
currentValue: '1.2.3', | ||
registryUrls: ['https://example.com'], | ||
}, | ||
], | ||
}, | ||
{ packageFile: 'build.gradle', deps: [] }, | ||
{ | ||
datasource: 'maven', | ||
deps: [], | ||
packageFile: 'settings.gradle', | ||
}, | ||
]); | ||
}); | ||
}); |
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,72 @@ | ||
import * as upath from 'upath'; | ||
import * as datasourceMaven from '../../datasource/maven'; | ||
import { logger } from '../../logger'; | ||
import { readLocalFile } from '../../util/fs'; | ||
import { ExtractConfig, PackageDependency, PackageFile } from '../common'; | ||
import { ManagerData, VariableRegistry } from './common'; | ||
import { parseGradle, parseProps } from './parser'; | ||
import { | ||
getVars, | ||
isGradleFile, | ||
isPropsFile, | ||
reorderFiles, | ||
toAbsolutePath, | ||
} from './utils'; | ||
|
||
export async function extractAllPackageFiles( | ||
config: ExtractConfig, | ||
packageFiles: string[] | ||
): Promise<PackageFile[] | null> { | ||
const extractedDeps: PackageDependency<ManagerData>[] = []; | ||
const registry: VariableRegistry = {}; | ||
const packageFilesByName: Record<string, PackageFile> = {}; | ||
const registryUrls = []; | ||
for (const packageFile of reorderFiles(packageFiles)) { | ||
packageFilesByName[packageFile] = { | ||
packageFile, | ||
datasource: datasourceMaven.id, | ||
deps: [], | ||
}; | ||
|
||
try { | ||
const content = await readLocalFile(packageFile, 'utf8'); | ||
const dir = upath.dirname(toAbsolutePath(packageFile)); | ||
if (isPropsFile(packageFile)) { | ||
const { vars, deps } = parseProps(content, packageFile); | ||
registry[dir] = vars; | ||
extractedDeps.push(...deps); | ||
} else if (isGradleFile(packageFile)) { | ||
const vars = getVars(registry, dir); | ||
const { deps, urls } = parseGradle(content, vars, packageFile); | ||
urls.forEach((url) => { | ||
if (!registryUrls.includes(url)) { | ||
registryUrls.push(url); | ||
} | ||
}); | ||
extractedDeps.push(...deps); | ||
} | ||
} catch (e) { | ||
logger.warn( | ||
{ config, packageFile }, | ||
`Failed to process Gradle file: ${packageFile}` | ||
); | ||
} | ||
} | ||
|
||
if (!extractedDeps.length) { | ||
return null; | ||
} | ||
|
||
extractedDeps.forEach((dep) => { | ||
const key = dep.managerData.packageFile; | ||
const pkgFile: PackageFile = packageFilesByName[key]; | ||
const { deps } = pkgFile; | ||
deps.push({ | ||
...dep, | ||
registryUrls: [...(dep.registryUrls || []), ...registryUrls], | ||
}); | ||
packageFilesByName[key] = pkgFile; | ||
}); | ||
|
||
return Object.values(packageFilesByName); | ||
} |
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,10 @@ | ||
import * as gradleVersioning from '../../versioning/gradle'; | ||
|
||
export { extractAllPackageFiles } from './extract'; | ||
export { updateDependency } from './update'; | ||
|
||
export const defaultConfig = { | ||
fileMatch: ['(^|/)gradle.properties$', '\\.gradle(\\.kts)?$'], | ||
versioning: gradleVersioning.id, | ||
enabled: false, | ||
}; |
Oops, something went wrong.