Skip to content

Commit

Permalink
Support name-pattern
Browse files Browse the repository at this point in the history
  • Loading branch information
tisoft committed Nov 18, 2023
1 parent 8c1a59c commit c504d2b
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 4 deletions.
7 changes: 6 additions & 1 deletion action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,12 @@ inputs:
names:
description: >-
Names of the packages.
required: true
required: false

name-pattern:
description: >-
Names of the packages.
required: false

semver-pattern:
description: >-
Expand Down
10 changes: 10 additions & 0 deletions src/action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,16 @@ export async function executeAction(input: Input, queryStrategy: QueryStrategy,
warning("No package versions will be actually deleted")
}

if (input.namePattern) {
info("Fetching package names")

input.names = await queryStrategy.queryPackageNames(input)

input.names.forEach((it) => {
info(`${it}`)
})
}

info("Fetching packages")

const packages = await queryStrategy.queryPackages(input)
Expand Down
9 changes: 7 additions & 2 deletions src/input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Input, PackageType } from "./types"
const DEFAULT_KEEP = 2

function getRegExpInput(name: string): RegExp | undefined {
const input = getInput("version-pattern")
const input = getInput(name)

if (input !== "") {
try {
Expand Down Expand Up @@ -50,6 +50,7 @@ function getTypeInput(name: string): PackageType {
export function getActionInput(): Input {
return {
names: getMultilineInput("names"),
namePattern: getRegExpInput("name-pattern"),
versionPattern: getRegExpInput("version-pattern"),
semverPattern: genSemVerInput("semver-pattern"),
keep: Number(getInput("keep") || DEFAULT_KEEP),
Expand All @@ -62,7 +63,11 @@ export function getActionInput(): Input {
}

export function validateInput(input: Input): Input {
if (input.names.length <= 0) {
if (input.namePattern && input.names && input.names.length > 0) {
throw new Error("Only one of name-pattern and names can be specified")
}

if (!input.namePattern && (!input.names || input.names.length <= 0)) {
throw new Error("names cannot be empty")
}

Expand Down
23 changes: 23 additions & 0 deletions src/query/strategies/organization.query.strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ export default class OrganizationQueryStrategy implements QueryStrategy {
constructor(private readonly octokit: InstanceType<typeof GitHub>) {}

async queryPackages(input: RestInput): Promise<Package[]> {
if (!input.names) {
throw new Error("No names specified")
}
return await Promise.all(
input.names.map(async (name) => {
const response = await this.queryPackage(input, name)
Expand All @@ -15,6 +18,26 @@ export default class OrganizationQueryStrategy implements QueryStrategy {
)
}

async queryPackageNames(input: RestInput) {
if (!input.namePattern) {
throw new Error("No name-pattern specified")
}
const namePattern = input.namePattern
try {
const params = {
package_type: input.type,
org: input.organization,
per_page: 100,
}

const packages = await this.octokit.paginate(this.octokit.rest.packages.listPackagesForOrganization, params)

return packages.map((p) => p.name).filter((n) => namePattern.test(n))
} catch (error) {
throw new Error(`Failed to query package name pattern ${input.namePattern}: ${error}`)
}
}

private async queryPackage(input: RestInput, name: string) {
try {
const params = {
Expand Down
23 changes: 23 additions & 0 deletions src/query/strategies/user.query.strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ export default class UserQueryStrategy implements QueryStrategy {
constructor(private readonly octokit: InstanceType<typeof GitHub>) {}

async queryPackages(input: RestInput): Promise<Package[]> {
if (!input.names) {
throw new Error("No names specified")
}
return await Promise.all(
input.names.map(async (name) => {
const response = await this.queryPackage(input, name)
Expand All @@ -15,6 +18,26 @@ export default class UserQueryStrategy implements QueryStrategy {
)
}

async queryPackageNames(input: RestInput) {
if (!input.namePattern) {
throw new Error("No name-pattern specified")
}
const namePattern = input.namePattern
try {
const params = {
package_type: input.type,
username: input.user,
per_page: 100,
}

const packages = await this.octokit.paginate(this.octokit.rest.packages.listPackagesForUser, params)

return packages.map((p) => p.name).filter((n) => namePattern.test(n))
} catch (error) {
throw new Error(`Failed to query package name pattern ${input.namePattern}: ${error}`)
}
}

private async queryPackage(input: RestInput, name: string) {
try {
const params = {
Expand Down
4 changes: 3 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ export enum PackageType {
}

export type Input = {
names: string[]
names?: string[]
namePattern?: RegExp
versionPattern?: RegExp
semverPattern?: Range
keep: number
Expand Down Expand Up @@ -38,6 +39,7 @@ export type PackageVersion = {

export interface QueryStrategy {
queryPackages(input: Input): Promise<Package[]>
queryPackageNames(input: Input): Promise<string[]>
}

export interface DeleteStrategy {
Expand Down

0 comments on commit c504d2b

Please sign in to comment.