diff --git a/src/commands/gxgames/api/storage.ts b/src/commands/gxgames/api/storage.ts index e7b7d41..ff14d3d 100644 --- a/src/commands/gxgames/api/storage.ts +++ b/src/commands/gxgames/api/storage.ts @@ -30,11 +30,13 @@ const LinkSchema = z.object({ export type GxGamesLink = z.infer; export class LinkStorage { - constructor(private readonly ctx: Context) {} + constructor( + private readonly ctx: Context, + private readonly projectDir?: string, + ) {} async read(): Promise { - const cache = await Cache.initLazy(this.ctx, { type: "infer" }); - const dir = await cache.getSubDirPath(this.ctx, CACHE_SUBDIR); + const dir = await this.cacheDir(); try { const raw = await this.ctx.fs.readFile( this.ctx.path.join(dir, LINK_FILENAME), @@ -50,11 +52,18 @@ export class LinkStorage { async write(link: GxGamesLink): Promise { // TODO: later, we may want to store this as part of the "manifest" file instead under a "tools.gxgames" key. - const cache = await Cache.initLazy(this.ctx, { type: "infer" }); - const dir = await cache.getSubDirPath(this.ctx, CACHE_SUBDIR); + const dir = await this.cacheDir(); await this.ctx.fs.writeFile( this.ctx.path.join(dir, LINK_FILENAME), JSON.stringify(link, null, 2), ); } + + private async cacheDir(): Promise { + const cache = await Cache.initLazy(this.ctx, { + type: "infer", + projectDir: this.projectDir, + }); + return cache.getSubDirPath(this.ctx, CACHE_SUBDIR); + } } diff --git a/src/commands/gxgames/command.ts b/src/commands/gxgames/command.ts index 5698e8f..1879a5f 100644 --- a/src/commands/gxgames/command.ts +++ b/src/commands/gxgames/command.ts @@ -15,11 +15,19 @@ */ import { buildCommand, buildRouteMap } from "@stricli/core"; +import { parseProjectPath } from "~/project"; + +const projectParam = { + brief: "Path to the project .yyp file (defaults to current directory)", + placeholder: "project", + parse: parseProjectPath, + optional: true as const, +}; const gxgamesLinkCommand = buildCommand({ loader: async () => import("./commands/link-impl"), parameters: { - positional: { kind: "tuple", parameters: [] }, + positional: { kind: "tuple", parameters: [projectParam] }, flags: { studioid: { kind: "parsed", @@ -43,17 +51,13 @@ const gxgamesLinkCommand = buildCommand({ const gxgamesUploadCommand = buildCommand({ loader: async () => import("./commands/upload-impl"), parameters: { - positional: { - kind: "tuple", - parameters: [ - { - brief: "Path to the zip file to upload", - placeholder: "file", - parse: String, - }, - ], - }, + positional: { kind: "tuple", parameters: [projectParam] }, flags: { + file: { + kind: "parsed", + parse: String, + brief: "Path to the zip file to upload", + }, version: { kind: "parsed", parse: String, @@ -73,7 +77,7 @@ const gxgamesUploadCommand = buildCommand({ const gxgamesMetaCommand = buildCommand({ loader: async () => import("./commands/meta-impl"), parameters: { - positional: { kind: "tuple", parameters: [] }, + positional: { kind: "tuple", parameters: [projectParam] }, flags: { title: { kind: "parsed", @@ -128,7 +132,7 @@ const gxgamesMetaCommand = buildCommand({ const gxgamesPublishCommand = buildCommand({ loader: async () => import("./commands/publish-impl"), parameters: { - positional: { kind: "tuple", parameters: [] }, + positional: { kind: "tuple", parameters: [projectParam] }, }, docs: { brief: "Make the game public on GX.Games", diff --git a/src/commands/gxgames/commands/link-impl.ts b/src/commands/gxgames/commands/link-impl.ts index 47fe2e9..b98990b 100644 --- a/src/commands/gxgames/commands/link-impl.ts +++ b/src/commands/gxgames/commands/link-impl.ts @@ -17,6 +17,7 @@ import * as p from "@clack/prompts"; import type { Context } from "~/context"; import { KnownError } from "~/error"; +import type { ProjectPath } from "~/project"; import { createAuthManager } from "../auth"; import { getApiClient } from "../api"; @@ -25,6 +26,7 @@ import { LinkStorage } from "../api"; export default async function ( this: Context, flags: { studioid?: string; gameid?: string }, + project?: ProjectPath, ): Promise { let studioId = flags.studioid; let gameId = flags.gameid; @@ -97,6 +99,7 @@ export default async function ( } } - await new LinkStorage(this).write({ studioId, gameId }); + const projectDir = project ? this.path.dirname(project) : undefined; + await new LinkStorage(this, projectDir).write({ studioId, gameId }); p.log.success(`Linked to studio ${studioId}, game ${gameId}`); } diff --git a/src/commands/gxgames/commands/meta-impl.ts b/src/commands/gxgames/commands/meta-impl.ts index 5f76dee..f559310 100644 --- a/src/commands/gxgames/commands/meta-impl.ts +++ b/src/commands/gxgames/commands/meta-impl.ts @@ -16,6 +16,7 @@ import type { Context } from "~/context"; import { KnownError } from "~/error"; +import type { ProjectPath } from "~/project"; import { LinkStorage } from "../api"; import { createAuthManager } from "../auth"; @@ -35,8 +36,13 @@ interface MetaFlags { graphic?: string; } -export default async function (this: Context, flags: MetaFlags): Promise { - const link = await new LinkStorage(this).read(); +export default async function ( + this: Context, + flags: MetaFlags, + project?: ProjectPath, +): Promise { + const projectDir = project ? this.path.dirname(project) : undefined; + const link = await new LinkStorage(this, projectDir).read(); const api = getApiClient(this, createAuthManager(this)); const gameRes = await api.getGameDetails(link.gameId); diff --git a/src/commands/gxgames/commands/publish-impl.ts b/src/commands/gxgames/commands/publish-impl.ts index 152ac36..7f35fb2 100644 --- a/src/commands/gxgames/commands/publish-impl.ts +++ b/src/commands/gxgames/commands/publish-impl.ts @@ -17,6 +17,7 @@ import type { Context } from "~/context"; import * as p from "@clack/prompts"; import { KnownError } from "~/error"; +import type { ProjectPath } from "~/project"; import { LinkStorage } from "../api"; import { createAuthManager } from "../auth"; @@ -25,8 +26,10 @@ import { getApiClient } from "../api"; export default async function ( this: Context, _flags: Record, + project?: ProjectPath, ): Promise { - const link = await new LinkStorage(this).read(); + const projectDir = project ? this.path.dirname(project) : undefined; + const link = await new LinkStorage(this, projectDir).read(); const api = getApiClient(this, createAuthManager(this)); const publishLog = this.makeTaskLogger("Publishing game"); diff --git a/src/commands/gxgames/commands/upload-impl.ts b/src/commands/gxgames/commands/upload-impl.ts index 37dc0e8..5dd014d 100644 --- a/src/commands/gxgames/commands/upload-impl.ts +++ b/src/commands/gxgames/commands/upload-impl.ts @@ -19,15 +19,17 @@ import * as p from "@clack/prompts"; import { getApiClient } from "../api"; import { createAuthManager } from "../auth"; import { KnownError } from "~/error"; +import type { ProjectPath } from "~/project"; import { LinkStorage } from "../api"; export default async function ( this: Context, - flags: { version?: string }, - file: string, + flags: { file: string; version?: string }, + project?: ProjectPath, ): Promise { - const link = await new LinkStorage(this).read(); + const projectDir = project ? this.path.dirname(project) : undefined; + const link = await new LinkStorage(this, projectDir).read(); const api = getApiClient(this, createAuthManager(this)); @@ -60,11 +62,11 @@ export default async function ( } const uploadLog = this.makeTaskLogger("Uploading bundle"); - const fileBuffer = await this.fs.readFile(file); + const fileBuffer = await this.fs.readFile(flags.file); const res = await api.uploadGameBundle( link.gameId, { version }, - { file: new File([fileBuffer], this.path.basename(file)) }, + { file: new File([fileBuffer], this.path.basename(flags.file)) }, ); if (!res.success) { throw new KnownError(res.errors);