-
Notifications
You must be signed in to change notification settings - Fork 155
feat: add method for janus-cli package metadata
; generate updates to package.json for all plugins listed in plugins/plugin-metadata.json
#1627
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from 18 commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
9947a6c
feat: RHIDP-1502 add method for janus-cli package metadata
nickboldt 7a4e11f
include individual plugin/*/package.json updates
nickboldt 40fc957
feat: RHIDP-1502 add method for janus-cli package metadata
nickboldt 1bf9b73
add missing type declaration for gitconfiglocal
nickboldt 952ffc1
add missing copyright / fix date
nickboldt 1791960
process all 42 plugins in the repo
nickboldt 26b1a9d
process all 42 plugins in the repo
nickboldt 6ff5cab
fix invalid author fields and add metadata to more plugins
nickboldt d9ebf26
sonarlint fixes and refactorings
nickboldt 8ef425b
Rhidp 1502 (#1641)
schultzp2020 153b43b
hide pointless ts2307-cannot-find-module error; clean up more sonarli…
nickboldt 58d35e5
remove plugins/plugin-metadata.json and plugins/plugin-metadata.sh - …
nickboldt ad88536
prettier . -w
nickboldt 35f5699
prettier tweaks
nickboldt 89b3cd1
updated yarn lock again
nickboldt bcd2321
more prettier changes?
nickboldt 98b892c
yarn lock regen again
nickboldt 0801f75
remove weird extra lines
nickboldt 3d3e486
Update packages/cli/src/types.d.ts
nickboldt File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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 hidden or 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 hidden or 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 hidden or 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,223 @@ | ||
/* | ||
* Copyright 2024 The Backstage Authors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
// test with ./packages/cli/bin/janus-cli package metadata --help | ||
|
||
// @ts-ignore | ||
import Codeowners from 'codeowners'; | ||
import { OptionValues } from 'commander'; | ||
import gitconfig from 'gitconfiglocal'; | ||
|
||
import * as fs from 'fs'; | ||
import { readFileSync, writeFileSync } from 'node:fs'; | ||
import { join } from 'node:path'; | ||
import process from 'node:process'; | ||
import { promisify } from 'node:util'; | ||
|
||
const pGitconfig = promisify(gitconfig); | ||
|
||
export async function command(opts: OptionValues): Promise<void> { | ||
const config = await pGitconfig(process.cwd()); | ||
updatePackageMetadata(opts, config?.remote?.origin?.url); | ||
} | ||
|
||
interface Repository { | ||
type: string; | ||
url: string; | ||
directory: string; | ||
} | ||
|
||
interface PackageJson { | ||
name: string; | ||
version: string; | ||
main: string; | ||
types: string; | ||
license: string; | ||
author: string; | ||
configschema: string; | ||
|
||
homepage: URL; | ||
bugs: URL; | ||
|
||
sideEffects: boolean; | ||
|
||
publishConfig: {}; | ||
backstage: { | ||
role: string; | ||
'supported-versions': string; | ||
}; | ||
scripts: {}; | ||
dependencies: {}; | ||
peerDependencies: {}; | ||
devDependencies: {}; | ||
scalprum: {}; | ||
repository: Repository; | ||
|
||
files: string[]; | ||
maintainers: string[]; | ||
keywords: string[]; | ||
} | ||
|
||
const path = { | ||
/** | ||
* @method resolveRelativeFromAbsolute resolves a relative path from an absolute path | ||
* @param {string} DotDotPath relative path | ||
* @returns {string} resolved absolutePath | ||
*/ | ||
resolveRelativeFromAbsolute(DotDotPath: string): string[] { | ||
const pathsArray = DotDotPath.replaceAll(/[/|\\]/g, '/').split('/'); | ||
const map = pathsArray.reduce( | ||
(acc, e) => acc.set(e, (acc.get(e) || 0) + 1), | ||
new Map(), | ||
); | ||
// console.log(` @ ${DotDotPath} => ${pathsArray} (${map.get("..")} backs)`) | ||
const rootDir = pathsArray.slice(0, -(map.get('..') * 2)).join('/'); | ||
// console.log(` @ root dir: ${rootdir}`) | ||
const relativeDir = process.cwd().replaceAll(`${rootDir}/`, ''); | ||
return [rootDir, relativeDir]; | ||
}, | ||
}; | ||
|
||
function findCodeowners(element: string) { | ||
if (fs.existsSync(`${element}/.github/CODEOWNERS`)) { | ||
return element; // found the root dir | ||
} | ||
return findCodeowners(`${element}/..`); | ||
} | ||
|
||
function separateKeywords(array: string[]): { | ||
keywords: string[]; | ||
lifecycle?: string; | ||
support?: string; | ||
} { | ||
return array.reduce( | ||
(prev, keyword) => { | ||
// separate lifecycle keyword | ||
if (keyword.startsWith('lifecycle:')) { | ||
return { ...prev, lifecycle: keyword }; | ||
} | ||
|
||
// separate support keyword | ||
if (keyword.startsWith('support:')) { | ||
return { ...prev, support: keyword }; | ||
} | ||
|
||
// keep the remaining keywords together | ||
prev.keywords.push(keyword); | ||
return prev; | ||
}, | ||
{ keywords: [] } as { | ||
keywords: string[]; | ||
lifecycle?: string; | ||
support?: string; | ||
}, | ||
); | ||
} | ||
|
||
export function updatePackageMetadata( | ||
opts: OptionValues, | ||
gitconfigRemoteOriginUrl: string, | ||
) { | ||
// load the package.json from the specified (or current) folder | ||
const workingDir = `${process.cwd()}/${opts.dir}`; | ||
console.log(`Updating ${workingDir} / package.json`); | ||
|
||
// compute the root dir and relative path to the current dir | ||
const [rootDir, relativePath] = opts.dir | ||
? [process.cwd(), opts.dir] | ||
: path.resolveRelativeFromAbsolute(findCodeowners(`${process.cwd()}`)); | ||
// console.log(` @ rootdir = ${rootdir}, relative_path = ${relative_path}`) | ||
|
||
const packageJSONPath = join(workingDir, 'package.json'); | ||
const packageJSON = JSON.parse( | ||
readFileSync(packageJSONPath, 'utf8'), | ||
) as PackageJson; | ||
|
||
/* now let's change some values */ | ||
|
||
// 1. add backstage version matching the current value of backstage.json in this repo | ||
if (fs.existsSync(join(rootDir, '/backstage.json'))) { | ||
packageJSON.backstage['supported-versions'] = JSON.parse( | ||
readFileSync(join(rootDir, '/backstage.json'), 'utf8'), | ||
).version; | ||
} | ||
|
||
// 2. set up repository values and the current path as repo.directory | ||
const repo = {} as Repository; | ||
repo.type = 'git'; | ||
repo.url = gitconfigRemoteOriginUrl | ||
.toString() | ||
.replaceAll('[email protected]:', 'https://github.com/') | ||
.replaceAll('.git', '') | ||
.trim(); | ||
repo.directory = relativePath; | ||
packageJSON.repository = repo; | ||
|
||
// 3. load owners from CODEOWNERS file, using this package.json's repository.directory field to compute maintainer groups | ||
let owners: string[] = []; | ||
if (packageJSON.repository.directory) { | ||
const repos = new Codeowners(); | ||
owners = repos.getOwner(relativePath); | ||
} else { | ||
console.log( | ||
` ! Could not load .github/CODEOWNERS file, so cannot update maintainers in package.json`, | ||
); | ||
} | ||
packageJSON.maintainers = owners; | ||
|
||
// 4. set some hardcoded values based on commandline flags | ||
packageJSON.author = opts.author; | ||
packageJSON.license = opts.license; | ||
packageJSON.homepage = new URL(opts.homepage); | ||
packageJSON.bugs = new URL(opts.bugs); | ||
|
||
// initialize empty string array if not already present | ||
if (!packageJSON.keywords) { | ||
packageJSON.keywords = []; | ||
} | ||
|
||
// if already have keywords, replace lifecycle and support with new values (if defined) | ||
// we can only have ONE lifecycle and one support keyword, so remove replace any existing values | ||
const { | ||
keywords: oldKeywords, | ||
lifecycle: oldLifecycle, | ||
support: oldSupport, | ||
} = separateKeywords(packageJSON.keywords); | ||
|
||
const { | ||
keywords: optsKeywords, | ||
lifecycle: optsLifecycle, | ||
support: optsSupport, | ||
} = separateKeywords(opts.keywords.split(',')); | ||
|
||
const newKeywords = oldKeywords.concat(optsKeywords); | ||
|
||
// if there is a lifecycle keyword, push to the beginning of the array | ||
if (oldLifecycle || optsLifecycle) { | ||
newKeywords.unshift(optsLifecycle ?? oldLifecycle ?? ''); | ||
} | ||
|
||
// if there is a support keyword, push to the beginning of the array | ||
if (oldSupport || optsSupport) { | ||
newKeywords.unshift(optsSupport ?? oldSupport ?? ''); | ||
} | ||
|
||
// dedupe new keywords | ||
packageJSON.keywords = Array.from(new Set(newKeywords)); | ||
|
||
// write changes to file | ||
writeFileSync(packageJSONPath, JSON.stringify(packageJSON, null, 2), 'utf8'); | ||
} |
This file contains hidden or 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,17 @@ | ||
/* | ||
* Copyright 2024 The Backstage Authors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
export { command } from './command'; |
This file contains hidden or 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
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.