Skip to content

Commit c10c9fb

Browse files
authored
feat(store,world): add option to codegen tables into namespace dirs (#2840)
1 parent 1e43543 commit c10c9fb

35 files changed

+365
-139
lines changed

.changeset/eleven-lobsters-play.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@latticexyz/store": patch
3+
---
4+
5+
Internal `tablegen` function (exported from `@latticexyz/store/codegen`) now expects an object of options with a `configPath` to use as a base path to resolve other relative paths from.

.changeset/great-ducks-search.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
"@latticexyz/store": patch
3+
"@latticexyz/world": patch
4+
---
5+
6+
Added `sourceDirectory` as a top-level config option for specifying contracts source (i.e. Solidity) directory relative to the MUD config. This is used to resolve other paths in the config, like codegen and user types. Like `foundry.toml`, this defaults to `src` and should be kept in sync with `foundry.toml`.
7+
8+
Also added a `codegen.namespaceDirectories` option to organize codegen output (table libraries, etc.) into directories by namespace. For example, a `Counter` table in the `app` namespace will have codegen at `codegen/app/tables/Counter.sol`. If not set, defaults to `true` when using top-level `namespaces` key, `false` otherwise.

packages/cli/scripts/generate-test-tables.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1-
import path from "path";
21
import { tablegen } from "@latticexyz/store/codegen";
32
import { defineStore } from "@latticexyz/store";
4-
import { getRemappings, getSrcDirectory } from "@latticexyz/common/foundry";
3+
import { getRemappings } from "@latticexyz/common/foundry";
4+
import { fileURLToPath } from "node:url";
5+
6+
const configPath = fileURLToPath(import.meta.url);
57

68
// This config is used only for tests.
79
// Aside from avoiding `mud.config.ts` in cli package (could cause issues),
810
// this also tests that mudConfig and tablegen can work as standalone functions
911
const config = defineStore({
12+
sourceDirectory: "../contracts/src",
1013
enums: {
1114
Enum1: ["E1", "E2", "E3"],
1215
Enum2: ["E1"],
@@ -92,7 +95,6 @@ const config = defineStore({
9295
},
9396
});
9497

95-
const srcDirectory = await getSrcDirectory();
9698
const remappings = await getRemappings();
9799

98-
await tablegen(config, path.join(srcDirectory, config.codegen.outputDirectory), remappings);
100+
await tablegen({ configPath, config, remappings });

packages/cli/src/build.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,34 @@ import path from "node:path";
22
import { tablegen } from "@latticexyz/store/codegen";
33
import { worldgen } from "@latticexyz/world/node";
44
import { World as WorldConfig } from "@latticexyz/world";
5-
import { worldToV1 } from "@latticexyz/world/config/v2";
65
import { forge, getRemappings } from "@latticexyz/common/foundry";
76
import { getExistingContracts } from "./utils/getExistingContracts";
87
import { execa } from "execa";
98

109
type BuildOptions = {
1110
foundryProfile?: string;
1211
srcDir: string;
12+
/**
13+
* Path to `mud.config.ts`. We use this as the "project root" to resolve other relative paths.
14+
*
15+
* Defaults to finding the nearest `mud.config.ts`, looking in `process.cwd()` and moving up the directory tree.
16+
*/
17+
configPath: string;
1318
config: WorldConfig;
1419
};
1520

1621
export async function build({
17-
config: configV2,
22+
configPath,
23+
config,
1824
srcDir,
1925
foundryProfile = process.env.FOUNDRY_PROFILE,
2026
}: BuildOptions): Promise<void> {
21-
const config = worldToV1(configV2);
22-
const outPath = path.join(srcDir, config.codegenDirectory);
27+
const outPath = path.join(srcDir, config.codegen.outputDirectory);
2328
const remappings = await getRemappings(foundryProfile);
2429

2530
await Promise.all([
26-
tablegen(configV2, outPath, remappings),
27-
worldgen(configV2, getExistingContracts(srcDir), outPath),
31+
tablegen({ configPath, config, remappings }),
32+
worldgen(config, getExistingContracts(srcDir), outPath),
2833
]);
2934

3035
await forge(["build"], { profile: foundryProfile });

packages/cli/src/commands/build.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { CommandModule } from "yargs";
2-
import { loadConfig } from "@latticexyz/config/node";
2+
import { loadConfig, resolveConfigPath } from "@latticexyz/config/node";
33
import { World as WorldConfig } from "@latticexyz/world";
44

55
import { getSrcDirectory } from "@latticexyz/common/foundry";
@@ -22,11 +22,12 @@ const commandModule: CommandModule<Options, Options> = {
2222
});
2323
},
2424

25-
async handler({ configPath, profile }) {
25+
async handler(opts) {
26+
const configPath = await resolveConfigPath(opts.configPath);
2627
const config = (await loadConfig(configPath)) as WorldConfig;
2728
const srcDir = await getSrcDirectory();
2829

29-
await build({ config, srcDir, foundryProfile: profile });
30+
await build({ configPath, config, srcDir, foundryProfile: opts.profile });
3031

3132
process.exit(0);
3233
},

packages/cli/src/commands/tablegen.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
import path from "path";
21
import type { CommandModule } from "yargs";
3-
import { loadConfig } from "@latticexyz/config/node";
2+
import { loadConfig, resolveConfigPath } from "@latticexyz/config/node";
43
import { Store as StoreConfig } from "@latticexyz/store";
54
import { tablegen } from "@latticexyz/store/codegen";
6-
import { getRemappings, getSrcDirectory } from "@latticexyz/common/foundry";
5+
import { getRemappings } from "@latticexyz/common/foundry";
76

87
type Options = {
98
configPath?: string;
@@ -20,12 +19,12 @@ const commandModule: CommandModule<Options, Options> = {
2019
});
2120
},
2221

23-
async handler({ configPath }) {
22+
async handler(opts) {
23+
const configPath = await resolveConfigPath(opts.configPath);
2424
const config = (await loadConfig(configPath)) as StoreConfig;
25-
const srcDir = await getSrcDirectory();
2625
const remappings = await getRemappings();
2726

28-
await tablegen(config, path.join(srcDir, config.codegen.outputDirectory), remappings);
27+
await tablegen({ configPath, config, remappings });
2928

3029
process.exit(0);
3130
},

packages/cli/src/runDeploy.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { InferredOptionTypes, Options } from "yargs";
44
import { deploy } from "./deploy/deploy";
55
import { createWalletClient, http, Hex, isHex } from "viem";
66
import { privateKeyToAccount } from "viem/accounts";
7-
import { loadConfig } from "@latticexyz/config/node";
7+
import { loadConfig, resolveConfigPath } from "@latticexyz/config/node";
88
import { World as WorldConfig } from "@latticexyz/world";
99
import { worldToV1 } from "@latticexyz/world/config/v2";
1010
import { getOutDirectory, getRpcUrl, getSrcDirectory } from "@latticexyz/common/foundry";
@@ -64,7 +64,8 @@ export async function runDeploy(opts: DeployOptions): Promise<WorldDeploy> {
6464

6565
const profile = opts.profile ?? process.env.FOUNDRY_PROFILE;
6666

67-
const configV2 = (await loadConfig(opts.configPath)) as WorldConfig;
67+
const configPath = await resolveConfigPath(opts.configPath);
68+
const configV2 = (await loadConfig(configPath)) as WorldConfig;
6869
const config = worldToV1(configV2);
6970
if (opts.printConfig) {
7071
console.log(chalk.green("\nResolved config:\n"), JSON.stringify(config, null, 2));
@@ -82,7 +83,7 @@ export async function runDeploy(opts: DeployOptions): Promise<WorldDeploy> {
8283

8384
// Run build
8485
if (!opts.skipBuild) {
85-
await build({ config: configV2, srcDir, foundryProfile: profile });
86+
await build({ configPath, config: configV2, srcDir, foundryProfile: profile });
8687
}
8788

8889
const resolvedConfig = resolveConfig({ config, forgeSourceDir: srcDir, forgeOutDir: outDir });

packages/store/mud.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ export default defineStore({
44
codegen: {
55
storeImportPath: "../../",
66
},
7-
namespace: "store" as const,
7+
namespace: "store",
88
userTypes: {
99
ResourceId: { filePath: "./src/ResourceId.sol", type: "bytes32" },
1010
FieldLayout: { filePath: "./src/FieldLayout.sol", type: "bytes32" },

packages/store/test/codegen/tables/Callbacks.sol

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/store/test/codegen/tables/KeyEncoding.sol

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)