mirror of
https://github.com/renovatebot/renovate.git
synced 2026-10-27 07:50:47 +00:00
97327c3d28
* refactor(linters): add prefer-coerce-array rule Refs #45217 `x ?? []` and `coerceArray(x)` say the same thing, but only the second one is searchable and consistent. The rule flags a `??` whose default is a bare `[]` literal; a non-empty default or an asserted `([] as Foo[])` still passes. Applying it across `lib/` surfaced three spots the helper cannot cover, which keep `?? []` with a disable comment or a narrower fix: - `package-files.ts` destructures a tuple, which `coerceArray()` widens - `generate.spec.ts` defaults `matchAll()`, an iterator rather than an array - `mise/upgradeable-tooling.ts` declares a `Record` return, so its `?? []` fallback was wrong to begin with and becomes `coerceObject()` * refactor(platform/github): hoist the GHE version header lookup `Object.entries(...).find()` returns a tuple, and defaulting it with `?? []` only to destructure the second element reads as an array default when it is not one. Name the found entry instead, which drops the `?? []` rather than routing a tuple through `coerceArray()`.
142 lines
4.4 KiB
TypeScript
142 lines
4.4 KiB
TypeScript
import { isArray, isNullOrUndefined, isString } from '@sindresorhus/is';
|
|
import json5 from 'json5';
|
|
import { coerce, satisfies } from 'semver';
|
|
import { logger } from '../../../logger/index.ts';
|
|
import { coerceArray } from '../../../util/array.ts';
|
|
import { regEx } from '../../../util/regex.ts';
|
|
import { MavenDatasource } from '../../datasource/maven/index.ts';
|
|
import type {
|
|
ExtractConfig,
|
|
PackageDependency,
|
|
PackageFileContent,
|
|
} from '../types.ts';
|
|
import type { Bundle, FeatureModel } from './types.ts';
|
|
|
|
export function extractPackageFile(
|
|
content: string,
|
|
packageFile: string,
|
|
_config?: ExtractConfig,
|
|
): PackageFileContent | null {
|
|
// References:
|
|
// - OSGi compendium release 8 ( https://docs.osgi.org/specification/osgi.cmpn/8.0.0/service.feature.html )
|
|
// - The Sling implementation of the feature model ( https://sling.apache.org/documentation/development/feature-model.html )
|
|
logger.trace(`osgi.extractPackageFile($packageFile)`);
|
|
|
|
const deps: PackageDependency[] = [];
|
|
let featureModel: FeatureModel;
|
|
try {
|
|
// Compendium R8 159.3: JS comments are supported
|
|
featureModel = json5.parse<FeatureModel>(content);
|
|
} catch (err) {
|
|
logger.warn({ packageFile, err }, 'Failed to parse osgi file');
|
|
return null;
|
|
}
|
|
|
|
if (
|
|
// for empty an empty result
|
|
isNullOrUndefined(featureModel) ||
|
|
// Compendium R8 159.9: resource versioning
|
|
!isSupportedFeatureResourceVersion(featureModel, packageFile)
|
|
) {
|
|
return null;
|
|
}
|
|
|
|
// OSGi Compendium R8 159.4: bundles entry
|
|
const allBundles = coerceArray(featureModel.bundles);
|
|
|
|
// The 'execution-environment' key is supported by the Sling/OSGi feature model implementation
|
|
const execEnvFramework =
|
|
featureModel['execution-environment:JSON|false']?.framework;
|
|
if (!isNullOrUndefined(execEnvFramework)) {
|
|
allBundles.push(execEnvFramework);
|
|
}
|
|
|
|
// parse custom sections
|
|
//
|
|
// Note: we do not support artifact list extensions as defined in
|
|
// section 159.7.3 yet. As of 05-12-2022, there is no implementation that
|
|
// supports this
|
|
for (const [section, value] of Object.entries(featureModel)) {
|
|
logger.trace({ fileName: packageFile, section }, 'Parsing section');
|
|
const customSectionEntries = extractArtifactList(section, value);
|
|
allBundles.push(...customSectionEntries);
|
|
}
|
|
|
|
// convert bundles to dependencies
|
|
for (const entry of allBundles) {
|
|
const rawGav = isString(entry) ? entry : entry.id;
|
|
// skip invalid definitions, such as objects without an id set
|
|
if (!rawGav) {
|
|
continue;
|
|
}
|
|
|
|
// both '/' and ':' are valid separators, but the Maven datasource
|
|
// expects the separator to be ':'
|
|
const gav = rawGav.replace(regEx(/\//g), ':');
|
|
|
|
// identifiers support 3-5 parts, see OSGi R8 - 159.2.1 Identifiers
|
|
// groupId ':' artifactId ( ':' type ( ':' classifier )? )? ':' version
|
|
const parts = gav.split(':');
|
|
if (parts.length < 3 || parts.length > 5) {
|
|
deps.push({
|
|
depName: gav,
|
|
skipReason: 'invalid-value',
|
|
});
|
|
continue;
|
|
}
|
|
// parsing should use the last entry for the version
|
|
const currentValue = parts.at(-1)!;
|
|
const result: PackageDependency = {
|
|
datasource: MavenDatasource.id,
|
|
depName: `${parts[0]}:${parts[1]}`,
|
|
};
|
|
if (currentValue.includes('${')) {
|
|
result.skipReason = 'contains-variable';
|
|
} else {
|
|
result.currentValue = currentValue;
|
|
}
|
|
|
|
deps.push(result);
|
|
}
|
|
|
|
return deps.length ? { deps } : null;
|
|
}
|
|
|
|
function isSupportedFeatureResourceVersion(
|
|
featureModel: FeatureModel,
|
|
fileName: string,
|
|
): boolean {
|
|
const resourceVersion = featureModel['feature-resource-version'];
|
|
if (resourceVersion) {
|
|
const resourceSemVer = coerce(resourceVersion);
|
|
if (!resourceSemVer) {
|
|
logger.debug(
|
|
`Skipping file ${fileName} due to invalid feature-resource-version '${resourceVersion}'`,
|
|
);
|
|
return false;
|
|
}
|
|
|
|
// we only support 1.x, although no over version has been defined
|
|
if (!satisfies(resourceSemVer, '^1')) {
|
|
logger.debug(
|
|
`Skipping file ${fileName} due to unsupported feature-resource-version '${resourceVersion}'`,
|
|
);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
function extractArtifactList(
|
|
sectionName: string,
|
|
sectionValue: unknown,
|
|
): Bundle[] {
|
|
// The 'ARTIFACTS' key is supported by the Sling/OSGi feature model implementation
|
|
if (sectionName.includes(':ARTIFACTS|') && isArray(sectionValue)) {
|
|
return sectionValue as Bundle[];
|
|
}
|
|
|
|
return [];
|
|
}
|