@clafoutis/cli 1.2.0 → 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +155 -68
- package/dist/index.js.map +1 -1
- package/dist/templates/tokens/colors/components.dark.json +12 -12
- package/dist/templates/tokens/colors/components.json +12 -12
- package/package.json +2 -2
- package/src/templates/tokens/colors/components.dark.json +12 -12
- package/src/templates/tokens/colors/components.json +12 -12
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import * as p2 from '@clack/prompts';
|
|
3
3
|
import { Command } from 'commander';
|
|
4
4
|
import fs from 'fs';
|
|
5
|
-
import
|
|
5
|
+
import path from 'path';
|
|
6
6
|
import { logger } from '@clafoutis/shared';
|
|
7
7
|
import { generate } from '@clafoutis/generators/figma';
|
|
8
8
|
import { generate as generate$1 } from '@clafoutis/generators/tailwind';
|
|
@@ -88,6 +88,28 @@ function tokensDirNotFoundError(tokensDir) {
|
|
|
88
88
|
);
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
+
// src/utils/cwd.ts
|
|
92
|
+
function resolveCommandCwd(cwdOverride) {
|
|
93
|
+
const cwd = cwdOverride?.trim() ? cwdOverride : process.cwd();
|
|
94
|
+
return path.resolve(cwd);
|
|
95
|
+
}
|
|
96
|
+
function resolveInCwd(commandCwd, targetPath) {
|
|
97
|
+
return path.isAbsolute(targetPath) ? path.resolve(targetPath) : path.resolve(commandCwd, targetPath);
|
|
98
|
+
}
|
|
99
|
+
function displayPath(commandCwd, absolutePath) {
|
|
100
|
+
const rel = path.relative(commandCwd, absolutePath);
|
|
101
|
+
return rel && !rel.startsWith("..") ? rel : absolutePath;
|
|
102
|
+
}
|
|
103
|
+
function validateCwdOption(cwdOverride) {
|
|
104
|
+
if (cwdOverride !== void 0 && cwdOverride.trim() === "") {
|
|
105
|
+
throw new ClafoutisError(
|
|
106
|
+
"Invalid --cwd value",
|
|
107
|
+
"--cwd cannot be empty",
|
|
108
|
+
"Provide a valid directory path, for example: --cwd ./packages/design-system"
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
91
113
|
// src/commands/format.ts
|
|
92
114
|
function loadTokenFiles(dirPath) {
|
|
93
115
|
const files = [];
|
|
@@ -96,7 +118,7 @@ function loadTokenFiles(dirPath) {
|
|
|
96
118
|
return;
|
|
97
119
|
}
|
|
98
120
|
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
99
|
-
const fullPath =
|
|
121
|
+
const fullPath = path.join(dir, entry.name);
|
|
100
122
|
const relativePath = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
101
123
|
if (entry.isDirectory()) {
|
|
102
124
|
walk(fullPath, relativePath);
|
|
@@ -120,7 +142,9 @@ function formatJson(content) {
|
|
|
120
142
|
return JSON.stringify(parsed, null, 2) + "\n";
|
|
121
143
|
}
|
|
122
144
|
function formatCommand(options) {
|
|
123
|
-
|
|
145
|
+
validateCwdOption(options.cwd);
|
|
146
|
+
const commandCwd = resolveCommandCwd(options.cwd);
|
|
147
|
+
const tokensDir = resolveInCwd(commandCwd, options.tokens || "./tokens");
|
|
124
148
|
if (!fs.existsSync(tokensDir)) {
|
|
125
149
|
throw tokensDirNotFoundError(tokensDir);
|
|
126
150
|
}
|
|
@@ -260,8 +284,8 @@ function findUnknownFields(config, schemaProperties, prefix = "") {
|
|
|
260
284
|
}
|
|
261
285
|
return unknown;
|
|
262
286
|
}
|
|
263
|
-
function hasField(config,
|
|
264
|
-
const parts =
|
|
287
|
+
function hasField(config, path8) {
|
|
288
|
+
const parts = path8.split(".");
|
|
265
289
|
let current = config;
|
|
266
290
|
for (const part of parts) {
|
|
267
291
|
if (current && typeof current === "object" && part in current) {
|
|
@@ -590,11 +614,11 @@ function getConsumerGitignore() {
|
|
|
590
614
|
`;
|
|
591
615
|
}
|
|
592
616
|
var __filename$1 = fileURLToPath(import.meta.url);
|
|
593
|
-
var __dirname$1 =
|
|
617
|
+
var __dirname$1 = path.dirname(__filename$1);
|
|
594
618
|
function getTokensDir() {
|
|
595
|
-
const devPath =
|
|
619
|
+
const devPath = path.resolve(__dirname$1, "tokens");
|
|
596
620
|
if (fs.existsSync(devPath)) return devPath;
|
|
597
|
-
const distPath =
|
|
621
|
+
const distPath = path.resolve(__dirname$1, "templates", "tokens");
|
|
598
622
|
if (fs.existsSync(distPath)) return distPath;
|
|
599
623
|
throw new Error(
|
|
600
624
|
`Starter token templates not found. Searched:
|
|
@@ -605,8 +629,8 @@ function getTokensDir() {
|
|
|
605
629
|
function walkTokensDir(dir, base = "") {
|
|
606
630
|
const result = [];
|
|
607
631
|
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
608
|
-
const relPath = base ?
|
|
609
|
-
const fullPath =
|
|
632
|
+
const relPath = base ? path.join(base, entry.name) : entry.name;
|
|
633
|
+
const fullPath = path.join(dir, entry.name);
|
|
610
634
|
if (entry.isDirectory()) {
|
|
611
635
|
result.push(...walkTokensDir(fullPath, relPath));
|
|
612
636
|
} else if (entry.name.endsWith(".json")) {
|
|
@@ -632,6 +656,7 @@ on:
|
|
|
632
656
|
branches: [main]
|
|
633
657
|
paths:
|
|
634
658
|
- 'tokens/**'
|
|
659
|
+
- '.clafoutis/producer.json'
|
|
635
660
|
|
|
636
661
|
jobs:
|
|
637
662
|
release:
|
|
@@ -657,6 +682,18 @@ jobs:
|
|
|
657
682
|
- name: Generate tokens
|
|
658
683
|
run: npx clafoutis generate
|
|
659
684
|
|
|
685
|
+
- name: Commit generated build artifacts
|
|
686
|
+
run: |
|
|
687
|
+
if [ -z "$(git status --porcelain build)" ]; then
|
|
688
|
+
echo "No build changes to commit"
|
|
689
|
+
exit 0
|
|
690
|
+
fi
|
|
691
|
+
git config user.name "github-actions[bot]"
|
|
692
|
+
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
693
|
+
git add build
|
|
694
|
+
git commit -m "chore: update generated build artifacts"
|
|
695
|
+
git push
|
|
696
|
+
|
|
660
697
|
- name: Get next version
|
|
661
698
|
id: version
|
|
662
699
|
run: |
|
|
@@ -740,15 +777,17 @@ async function initCommand(options) {
|
|
|
740
777
|
"Choose one: --producer for design system repos, --consumer for application repos"
|
|
741
778
|
);
|
|
742
779
|
}
|
|
780
|
+
validateCwdOption(options.cwd);
|
|
781
|
+
const commandCwd = resolveCommandCwd(options.cwd);
|
|
743
782
|
const isInteractive = !options.nonInteractive && process.stdin.isTTY;
|
|
744
783
|
const isDryRun = options.dryRun ?? false;
|
|
745
784
|
if (isInteractive) {
|
|
746
|
-
await runInteractiveInit(options, isDryRun);
|
|
785
|
+
await runInteractiveInit(options, isDryRun, commandCwd);
|
|
747
786
|
} else {
|
|
748
|
-
await runNonInteractiveInit(options, isDryRun);
|
|
787
|
+
await runNonInteractiveInit(options, isDryRun, commandCwd);
|
|
749
788
|
}
|
|
750
789
|
}
|
|
751
|
-
async function runInteractiveInit(options, isDryRun) {
|
|
790
|
+
async function runInteractiveInit(options, isDryRun, commandCwd) {
|
|
752
791
|
showIntro(isDryRun);
|
|
753
792
|
let mode;
|
|
754
793
|
if (options.producer) {
|
|
@@ -768,13 +807,23 @@ async function runInteractiveInit(options, isDryRun) {
|
|
|
768
807
|
if (!answers) {
|
|
769
808
|
return;
|
|
770
809
|
}
|
|
771
|
-
await createProducerConfig(
|
|
810
|
+
await createProducerConfig(
|
|
811
|
+
answers,
|
|
812
|
+
options.force ?? false,
|
|
813
|
+
isDryRun,
|
|
814
|
+
commandCwd
|
|
815
|
+
);
|
|
772
816
|
} else {
|
|
773
817
|
const answers = await runConsumerWizard();
|
|
774
818
|
if (!answers) {
|
|
775
819
|
return;
|
|
776
820
|
}
|
|
777
|
-
await createConsumerConfig(
|
|
821
|
+
await createConsumerConfig(
|
|
822
|
+
answers,
|
|
823
|
+
options.force ?? false,
|
|
824
|
+
isDryRun,
|
|
825
|
+
commandCwd
|
|
826
|
+
);
|
|
778
827
|
}
|
|
779
828
|
if (isDryRun) {
|
|
780
829
|
showOutro("No files were written. Remove --dry-run to apply changes.");
|
|
@@ -782,7 +831,7 @@ async function runInteractiveInit(options, isDryRun) {
|
|
|
782
831
|
showOutro("Setup complete!");
|
|
783
832
|
}
|
|
784
833
|
}
|
|
785
|
-
async function runNonInteractiveInit(options, isDryRun) {
|
|
834
|
+
async function runNonInteractiveInit(options, isDryRun, commandCwd) {
|
|
786
835
|
if (!options.producer && !options.consumer) {
|
|
787
836
|
throw new ClafoutisError(
|
|
788
837
|
"Mode required",
|
|
@@ -805,7 +854,12 @@ async function runNonInteractiveInit(options, isDryRun) {
|
|
|
805
854
|
output: options.output ?? "./build",
|
|
806
855
|
workflow: options.workflow ?? true
|
|
807
856
|
};
|
|
808
|
-
await createProducerConfig(
|
|
857
|
+
await createProducerConfig(
|
|
858
|
+
answers,
|
|
859
|
+
options.force ?? false,
|
|
860
|
+
isDryRun,
|
|
861
|
+
commandCwd
|
|
862
|
+
);
|
|
809
863
|
} else {
|
|
810
864
|
const errors = validateConsumerFlags(options);
|
|
811
865
|
if (errors.length > 0) {
|
|
@@ -859,11 +913,16 @@ async function runNonInteractiveInit(options, isDryRun) {
|
|
|
859
913
|
repo: options.repo,
|
|
860
914
|
files
|
|
861
915
|
};
|
|
862
|
-
await createConsumerConfig(
|
|
916
|
+
await createConsumerConfig(
|
|
917
|
+
answers,
|
|
918
|
+
options.force ?? false,
|
|
919
|
+
isDryRun,
|
|
920
|
+
commandCwd
|
|
921
|
+
);
|
|
863
922
|
}
|
|
864
923
|
}
|
|
865
|
-
async function createProducerConfig(answers, force, dryRun) {
|
|
866
|
-
const configPath = ".clafoutis/producer.json";
|
|
924
|
+
async function createProducerConfig(answers, force, dryRun, commandCwd) {
|
|
925
|
+
const configPath = resolveInCwd(commandCwd, ".clafoutis/producer.json");
|
|
867
926
|
if (!force && await fileExists(configPath)) {
|
|
868
927
|
throw new ClafoutisError(
|
|
869
928
|
"Configuration already exists",
|
|
@@ -896,7 +955,10 @@ async function createProducerConfig(answers, force, dryRun) {
|
|
|
896
955
|
];
|
|
897
956
|
const starterTokens = getAllStarterTokens();
|
|
898
957
|
for (const token of starterTokens) {
|
|
899
|
-
const tokenPath =
|
|
958
|
+
const tokenPath = resolveInCwd(
|
|
959
|
+
commandCwd,
|
|
960
|
+
path.join(answers.tokens, token.path)
|
|
961
|
+
);
|
|
900
962
|
if (!force && await fileExists(tokenPath)) {
|
|
901
963
|
continue;
|
|
902
964
|
}
|
|
@@ -907,7 +969,7 @@ async function createProducerConfig(answers, force, dryRun) {
|
|
|
907
969
|
});
|
|
908
970
|
}
|
|
909
971
|
if (answers.workflow) {
|
|
910
|
-
const workflowPath = getWorkflowPath();
|
|
972
|
+
const workflowPath = resolveInCwd(commandCwd, getWorkflowPath());
|
|
911
973
|
if (force || !await fileExists(workflowPath)) {
|
|
912
974
|
filesToCreate.push({
|
|
913
975
|
path: workflowPath,
|
|
@@ -916,22 +978,23 @@ async function createProducerConfig(answers, force, dryRun) {
|
|
|
916
978
|
});
|
|
917
979
|
}
|
|
918
980
|
}
|
|
919
|
-
|
|
981
|
+
const gitignorePath = resolveInCwd(commandCwd, ".gitignore");
|
|
982
|
+
if (force || !await fileExists(gitignorePath)) {
|
|
920
983
|
filesToCreate.push({
|
|
921
|
-
path:
|
|
984
|
+
path: gitignorePath,
|
|
922
985
|
content: getProducerGitignore(),
|
|
923
986
|
description: "Ignore build artifacts and release-assets"
|
|
924
987
|
});
|
|
925
988
|
}
|
|
926
989
|
if (dryRun) {
|
|
927
|
-
showDryRunOutput(filesToCreate);
|
|
990
|
+
showDryRunOutput(filesToCreate, commandCwd);
|
|
928
991
|
} else {
|
|
929
|
-
await writeFiles(filesToCreate);
|
|
992
|
+
await writeFiles(filesToCreate, commandCwd);
|
|
930
993
|
showNextSteps("producer", answers);
|
|
931
994
|
}
|
|
932
995
|
}
|
|
933
|
-
async function createConsumerConfig(answers, force, dryRun) {
|
|
934
|
-
const configPath = ".clafoutis/consumer.json";
|
|
996
|
+
async function createConsumerConfig(answers, force, dryRun, commandCwd) {
|
|
997
|
+
const configPath = resolveInCwd(commandCwd, ".clafoutis/consumer.json");
|
|
935
998
|
if (!force && await fileExists(configPath)) {
|
|
936
999
|
throw new ClafoutisError(
|
|
937
1000
|
"Configuration already exists",
|
|
@@ -951,7 +1014,7 @@ async function createConsumerConfig(answers, force, dryRun) {
|
|
|
951
1014
|
description: `repo: "${answers.repo}"`
|
|
952
1015
|
}
|
|
953
1016
|
];
|
|
954
|
-
const gitignorePath = ".gitignore";
|
|
1017
|
+
const gitignorePath = resolveInCwd(commandCwd, ".gitignore");
|
|
955
1018
|
const consumerIgnore = getConsumerGitignore();
|
|
956
1019
|
if (await fileExists(gitignorePath)) {
|
|
957
1020
|
const existingContent = await fs2.readFile(gitignorePath, "utf-8");
|
|
@@ -970,30 +1033,30 @@ async function createConsumerConfig(answers, force, dryRun) {
|
|
|
970
1033
|
});
|
|
971
1034
|
}
|
|
972
1035
|
if (dryRun) {
|
|
973
|
-
showDryRunOutput(filesToCreate);
|
|
1036
|
+
showDryRunOutput(filesToCreate, commandCwd);
|
|
974
1037
|
} else {
|
|
975
|
-
await writeFiles(filesToCreate);
|
|
1038
|
+
await writeFiles(filesToCreate, commandCwd);
|
|
976
1039
|
showNextSteps("consumer", answers);
|
|
977
1040
|
}
|
|
978
1041
|
}
|
|
979
|
-
function showDryRunOutput(files) {
|
|
1042
|
+
function showDryRunOutput(files, commandCwd) {
|
|
980
1043
|
log3.message("");
|
|
981
1044
|
log3.step("Would create the following files:");
|
|
982
1045
|
log3.message("");
|
|
983
1046
|
for (const file of files) {
|
|
984
|
-
log3.message(` ${file.path}`);
|
|
1047
|
+
log3.message(` ${displayPath(commandCwd, file.path)}`);
|
|
985
1048
|
if (file.description) {
|
|
986
1049
|
log3.message(` \u2514\u2500 ${file.description}`);
|
|
987
1050
|
}
|
|
988
1051
|
}
|
|
989
1052
|
log3.message("");
|
|
990
1053
|
}
|
|
991
|
-
async function writeFiles(files) {
|
|
1054
|
+
async function writeFiles(files, commandCwd) {
|
|
992
1055
|
for (const file of files) {
|
|
993
|
-
const dir =
|
|
1056
|
+
const dir = path.dirname(file.path);
|
|
994
1057
|
await fs2.mkdir(dir, { recursive: true });
|
|
995
1058
|
await fs2.writeFile(file.path, file.content);
|
|
996
|
-
log3.success(`Created ${file.path}`);
|
|
1059
|
+
log3.success(`Created ${displayPath(commandCwd, file.path)}`);
|
|
997
1060
|
}
|
|
998
1061
|
}
|
|
999
1062
|
function showNextSteps(mode, answers) {
|
|
@@ -1018,15 +1081,20 @@ function showNextSteps(mode, answers) {
|
|
|
1018
1081
|
}
|
|
1019
1082
|
|
|
1020
1083
|
// src/commands/generate.ts
|
|
1021
|
-
async function loadPlugin(pluginPath) {
|
|
1022
|
-
const absolutePath =
|
|
1084
|
+
async function loadPlugin(pluginPath, commandCwd) {
|
|
1085
|
+
const absolutePath = resolveInCwd(commandCwd, pluginPath);
|
|
1023
1086
|
if (pluginPath.endsWith(".ts")) {
|
|
1024
1087
|
register();
|
|
1025
1088
|
}
|
|
1026
1089
|
return import(pathToFileURL(absolutePath).href);
|
|
1027
1090
|
}
|
|
1028
1091
|
async function generateCommand(options) {
|
|
1029
|
-
|
|
1092
|
+
validateCwdOption(options.cwd);
|
|
1093
|
+
const commandCwd = resolveCommandCwd(options.cwd);
|
|
1094
|
+
const configPath = resolveInCwd(
|
|
1095
|
+
commandCwd,
|
|
1096
|
+
options.config || ".clafoutis/producer.json"
|
|
1097
|
+
);
|
|
1030
1098
|
let config = await readProducerConfig(configPath);
|
|
1031
1099
|
if (!config) {
|
|
1032
1100
|
if (await fileExists(configPath)) {
|
|
@@ -1039,7 +1107,7 @@ async function generateCommand(options) {
|
|
|
1039
1107
|
if (process.stdin.isTTY) {
|
|
1040
1108
|
const shouldRunWizard = await offerWizard("producer");
|
|
1041
1109
|
if (shouldRunWizard) {
|
|
1042
|
-
await initCommand({ producer: true });
|
|
1110
|
+
await initCommand({ producer: true, cwd: commandCwd });
|
|
1043
1111
|
config = await readProducerConfig(configPath);
|
|
1044
1112
|
if (!config) {
|
|
1045
1113
|
throw configNotFoundError(configPath, false);
|
|
@@ -1065,8 +1133,8 @@ async function generateCommand(options) {
|
|
|
1065
1133
|
if (options.output) {
|
|
1066
1134
|
config.output = options.output;
|
|
1067
1135
|
}
|
|
1068
|
-
const tokensDir =
|
|
1069
|
-
const outputDir =
|
|
1136
|
+
const tokensDir = resolveInCwd(commandCwd, config.tokens || "./tokens");
|
|
1137
|
+
const outputDir = resolveInCwd(commandCwd, config.output || "./build");
|
|
1070
1138
|
if (!await fileExists(tokensDir)) {
|
|
1071
1139
|
throw tokensDirNotFoundError(tokensDir);
|
|
1072
1140
|
}
|
|
@@ -1092,7 +1160,7 @@ async function generateCommand(options) {
|
|
|
1092
1160
|
let generatorModule;
|
|
1093
1161
|
if (typeof value === "string") {
|
|
1094
1162
|
try {
|
|
1095
|
-
generatorModule = await loadPlugin(value);
|
|
1163
|
+
generatorModule = await loadPlugin(value, commandCwd);
|
|
1096
1164
|
} catch (err) {
|
|
1097
1165
|
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
1098
1166
|
throw pluginLoadError(value, errorMessage);
|
|
@@ -1105,8 +1173,12 @@ async function generateCommand(options) {
|
|
|
1105
1173
|
}
|
|
1106
1174
|
} else {
|
|
1107
1175
|
const builtInGenerators = {
|
|
1108
|
-
tailwind: {
|
|
1109
|
-
|
|
1176
|
+
tailwind: {
|
|
1177
|
+
generate: async (ctx) => generate$1(commandCwd, ctx.outputDir)
|
|
1178
|
+
},
|
|
1179
|
+
figma: {
|
|
1180
|
+
generate: async (ctx) => generate(commandCwd, ctx.outputDir)
|
|
1181
|
+
}
|
|
1110
1182
|
};
|
|
1111
1183
|
if (!builtInGenerators[name]) {
|
|
1112
1184
|
throw generatorNotFoundError(name);
|
|
@@ -1115,7 +1187,7 @@ async function generateCommand(options) {
|
|
|
1115
1187
|
}
|
|
1116
1188
|
const context = {
|
|
1117
1189
|
tokensDir,
|
|
1118
|
-
outputDir:
|
|
1190
|
+
outputDir: path.join(outputDir, name),
|
|
1119
1191
|
config,
|
|
1120
1192
|
StyleDictionary
|
|
1121
1193
|
};
|
|
@@ -1139,10 +1211,18 @@ async function generateCommand(options) {
|
|
|
1139
1211
|
logger.success("Generation complete");
|
|
1140
1212
|
}
|
|
1141
1213
|
var CACHE_DIR = ".clafoutis";
|
|
1142
|
-
var CACHE_FILE =
|
|
1143
|
-
|
|
1214
|
+
var CACHE_FILE = "cache";
|
|
1215
|
+
function getCachePaths(commandCwd) {
|
|
1216
|
+
const dir = path.resolve(commandCwd, CACHE_DIR);
|
|
1217
|
+
return {
|
|
1218
|
+
dir,
|
|
1219
|
+
file: path.join(dir, CACHE_FILE)
|
|
1220
|
+
};
|
|
1221
|
+
}
|
|
1222
|
+
async function readCache(commandCwd = process.cwd()) {
|
|
1223
|
+
const { file } = getCachePaths(commandCwd);
|
|
1144
1224
|
try {
|
|
1145
|
-
return (await fs2.readFile(
|
|
1225
|
+
return (await fs2.readFile(file, "utf-8")).trim();
|
|
1146
1226
|
} catch (err) {
|
|
1147
1227
|
if (err instanceof Error && err.code === "ENOENT") {
|
|
1148
1228
|
return null;
|
|
@@ -1150,9 +1230,10 @@ async function readCache() {
|
|
|
1150
1230
|
throw err;
|
|
1151
1231
|
}
|
|
1152
1232
|
}
|
|
1153
|
-
async function writeCache(version) {
|
|
1154
|
-
|
|
1155
|
-
await fs2.
|
|
1233
|
+
async function writeCache(version, commandCwd = process.cwd()) {
|
|
1234
|
+
const { dir, file } = getCachePaths(commandCwd);
|
|
1235
|
+
await fs2.mkdir(dir, { recursive: true });
|
|
1236
|
+
await fs2.writeFile(file, version);
|
|
1156
1237
|
}
|
|
1157
1238
|
async function downloadRelease(config) {
|
|
1158
1239
|
const token = process.env.CLAFOUTIS_REPO_TOKEN;
|
|
@@ -1218,18 +1299,23 @@ async function downloadRelease(config) {
|
|
|
1218
1299
|
}
|
|
1219
1300
|
|
|
1220
1301
|
// src/commands/sync.ts
|
|
1221
|
-
async function writeOutput(config, files) {
|
|
1302
|
+
async function writeOutput(config, files, commandCwd) {
|
|
1222
1303
|
for (const [assetName, content] of files) {
|
|
1223
1304
|
const configPath = config.files[assetName];
|
|
1224
1305
|
if (!configPath) continue;
|
|
1225
|
-
const outputPath =
|
|
1226
|
-
await fs2.mkdir(
|
|
1306
|
+
const outputPath = resolveInCwd(commandCwd, configPath);
|
|
1307
|
+
await fs2.mkdir(path.dirname(outputPath), { recursive: true });
|
|
1227
1308
|
await fs2.writeFile(outputPath, content);
|
|
1228
1309
|
logger.success(`Written: ${outputPath}`);
|
|
1229
1310
|
}
|
|
1230
1311
|
}
|
|
1231
1312
|
async function syncCommand(options) {
|
|
1232
|
-
|
|
1313
|
+
validateCwdOption(options.cwd);
|
|
1314
|
+
const commandCwd = resolveCommandCwd(options.cwd);
|
|
1315
|
+
const configPath = resolveInCwd(
|
|
1316
|
+
commandCwd,
|
|
1317
|
+
options.config || ".clafoutis/consumer.json"
|
|
1318
|
+
);
|
|
1233
1319
|
let config = await readConfig(configPath);
|
|
1234
1320
|
if (!config) {
|
|
1235
1321
|
if (await fileExists(configPath)) {
|
|
@@ -1242,7 +1328,7 @@ async function syncCommand(options) {
|
|
|
1242
1328
|
if (process.stdin.isTTY) {
|
|
1243
1329
|
const shouldRunWizard = await offerWizard("consumer");
|
|
1244
1330
|
if (shouldRunWizard) {
|
|
1245
|
-
await initCommand({ consumer: true });
|
|
1331
|
+
await initCommand({ consumer: true, cwd: commandCwd });
|
|
1246
1332
|
config = await readConfig(configPath);
|
|
1247
1333
|
if (!config) {
|
|
1248
1334
|
throw configNotFoundError(configPath, true);
|
|
@@ -1255,7 +1341,7 @@ async function syncCommand(options) {
|
|
|
1255
1341
|
}
|
|
1256
1342
|
}
|
|
1257
1343
|
validateConsumerConfig(config);
|
|
1258
|
-
const cachedVersion = await readCache();
|
|
1344
|
+
const cachedVersion = await readCache(commandCwd);
|
|
1259
1345
|
const isLatest = config.version === "latest";
|
|
1260
1346
|
logger.info(`Repo: ${config.repo}`);
|
|
1261
1347
|
logger.info(`Pinned: ${config.version}`);
|
|
@@ -1269,7 +1355,7 @@ async function syncCommand(options) {
|
|
|
1269
1355
|
}
|
|
1270
1356
|
return;
|
|
1271
1357
|
}
|
|
1272
|
-
const resolveOutputPaths = () => Object.values(config.files).map((p5) =>
|
|
1358
|
+
const resolveOutputPaths = () => Object.values(config.files).map((p5) => resolveInCwd(commandCwd, p5));
|
|
1273
1359
|
if (!isLatest && !options.force && config.version === cachedVersion) {
|
|
1274
1360
|
const outputPaths = resolveOutputPaths();
|
|
1275
1361
|
const existsResults = await Promise.all(
|
|
@@ -1294,14 +1380,14 @@ async function syncCommand(options) {
|
|
|
1294
1380
|
return;
|
|
1295
1381
|
}
|
|
1296
1382
|
}
|
|
1297
|
-
await writeOutput(config, files);
|
|
1298
|
-
await writeCache(resolvedTag);
|
|
1383
|
+
await writeOutput(config, files, commandCwd);
|
|
1384
|
+
await writeCache(resolvedTag, commandCwd);
|
|
1299
1385
|
logger.success(`Synced to ${resolvedTag}`);
|
|
1300
1386
|
if (config.postSync) {
|
|
1301
|
-
await runPostSync(config.postSync);
|
|
1387
|
+
await runPostSync(config.postSync, commandCwd);
|
|
1302
1388
|
}
|
|
1303
1389
|
}
|
|
1304
|
-
async function runPostSync(command) {
|
|
1390
|
+
async function runPostSync(command, commandCwd) {
|
|
1305
1391
|
logger.info(`Running postSync: ${command}`);
|
|
1306
1392
|
const isWindows = process.platform === "win32";
|
|
1307
1393
|
const shell = isWindows ? "cmd.exe" : "/bin/sh";
|
|
@@ -1309,7 +1395,8 @@ async function runPostSync(command) {
|
|
|
1309
1395
|
return new Promise((resolve, reject) => {
|
|
1310
1396
|
const child = spawn(shell, shellArgs, {
|
|
1311
1397
|
stdio: ["inherit", "pipe", "pipe"],
|
|
1312
|
-
env: process.env
|
|
1398
|
+
env: process.env,
|
|
1399
|
+
cwd: commandCwd
|
|
1313
1400
|
});
|
|
1314
1401
|
let stdout = "";
|
|
1315
1402
|
let stderr = "";
|
|
@@ -1406,23 +1493,23 @@ program.command("generate").description("Generate platform outputs from design t
|
|
|
1406
1493
|
"-c, --config <path>",
|
|
1407
1494
|
"Path to config file",
|
|
1408
1495
|
".clafoutis/producer.json"
|
|
1409
|
-
).option("--tailwind", "Generate Tailwind output").option("--figma", "Generate Figma variables").option("-o, --output <dir>", "Output directory", "./build").option("--dry-run", "Preview changes without writing files").action(withErrorHandling(generateCommand));
|
|
1496
|
+
).option("--tailwind", "Generate Tailwind output").option("--figma", "Generate Figma variables").option("-o, --output <dir>", "Output directory", "./build").option("--cwd <path>", "Run command as if from this directory").option("--dry-run", "Preview changes without writing files").action(withErrorHandling(generateCommand));
|
|
1410
1497
|
program.command("sync").description("Sync design tokens from GitHub Release (for consumers)").option("-f, --force", "Force sync even if versions match").option(
|
|
1411
1498
|
"-c, --config <path>",
|
|
1412
1499
|
"Path to config file",
|
|
1413
1500
|
".clafoutis/consumer.json"
|
|
1414
|
-
).option("--dry-run", "Preview changes without writing files").action(withErrorHandling(syncCommand));
|
|
1501
|
+
).option("--cwd <path>", "Run command as if from this directory").option("--dry-run", "Preview changes without writing files").action(withErrorHandling(syncCommand));
|
|
1415
1502
|
program.command("init").description("Initialize Clafoutis configuration").option("--producer", "Set up as a design token producer").option("--consumer", "Set up as a design token consumer").option("-r, --repo <repo>", "GitHub repo for consumer mode (org/name)").option("-t, --tokens <path>", "Token directory path (default: ./tokens)").option("-o, --output <path>", "Output directory path (default: ./build)").option(
|
|
1416
1503
|
"-g, --generators <list>",
|
|
1417
1504
|
"Comma-separated generators: tailwind, figma"
|
|
1418
1505
|
).option("--workflow", "Create GitHub Actions workflow (default: true)").option("--no-workflow", "Skip GitHub Actions workflow").option(
|
|
1419
1506
|
"--files <mapping>",
|
|
1420
1507
|
"File mappings for consumer: asset:dest,asset:dest"
|
|
1421
|
-
).option("--force", "Overwrite existing configuration").option("--dry-run", "Preview changes without writing files").option("--non-interactive", "Skip prompts, use defaults or flags").action(withErrorHandling(initCommand));
|
|
1508
|
+
).option("--force", "Overwrite existing configuration").option("--dry-run", "Preview changes without writing files").option("--non-interactive", "Skip prompts, use defaults or flags").option("--cwd <path>", "Run command as if from this directory").action(withErrorHandling(initCommand));
|
|
1422
1509
|
program.command("format").description("Format token JSON files for consistent formatting").option("-t, --tokens <path>", "Token directory path", "./tokens").option(
|
|
1423
1510
|
"--check",
|
|
1424
1511
|
"Check formatting without modifying files (fails if unformatted)"
|
|
1425
|
-
).option("--dry-run", "Preview changes without writing files").action(withErrorHandling(formatCommand));
|
|
1512
|
+
).option("--cwd <path>", "Run command as if from this directory").option("--dry-run", "Preview changes without writing files").action(withErrorHandling(formatCommand));
|
|
1426
1513
|
program.parse();
|
|
1427
1514
|
//# sourceMappingURL=index.js.map
|
|
1428
1515
|
//# sourceMappingURL=index.js.map
|