@lsst/pik-plugin-select 0.6.7 → 0.7.0

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/README.md CHANGED
@@ -43,7 +43,9 @@ pik select set <name> <option> # Set directly
43
43
  ## Marker Syntax
44
44
 
45
45
  - `@pik:select <name>` - Defines a selector group
46
- - `@pik:option <name>` - Marks an option within a selector
46
+ - `@pik:option <name>` - Marks a single-line option within a selector
47
+ - `@pik:block-start <name>` - Starts a multi-line block option
48
+ - `@pik:block-end` - Ends a multi-line block option
47
49
 
48
50
  ### Inline Style
49
51
 
@@ -67,6 +69,28 @@ Marker on its own line, content on the next line (useful for HTML):
67
69
  <!-- <script src="http://localhost:3000/viewer.js"></script> -->
68
70
  ```
69
71
 
72
+ ### Block Style
73
+
74
+ For multi-line options where you need to switch entire blocks of configuration:
75
+
76
+ ```bash
77
+ # @pik:select Environment
78
+ # @pik:block-start Development
79
+ API_URL=http://localhost:3000
80
+ DEBUG=true
81
+ LOG_LEVEL=debug
82
+ # @pik:block-end
83
+ # @pik:block-start Production
84
+ # API_URL=https://api.example.com
85
+ # DEBUG=false
86
+ # LOG_LEVEL=error
87
+ # @pik:block-end
88
+ ```
89
+
90
+ When switching blocks:
91
+ - The selected block's content lines are uncommented
92
+ - All other blocks' content lines are commented out
93
+
70
94
  ## Supported File Types
71
95
 
72
96
  | Extensions | Comment Style |
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Command } from "commander";
2
2
  import pc from "picocolors";
3
3
  import { relative } from "path";
4
- import { Parser, loadConfig, SingleSwitcher } from "@lsst/pik-core";
4
+ import { Parser, loadConfig, BlockSwitcher, SingleSwitcher } from "@lsst/pik-core";
5
5
  import { readFile, writeFile } from "fs/promises";
6
6
  import { glob } from "glob";
7
7
  import { select, Separator } from "@inquirer/prompts";
@@ -27,6 +27,21 @@ class Scanner {
27
27
  return results;
28
28
  }
29
29
  }
30
+ function hasBlockOptions$2(selector) {
31
+ return selector.blockOptions.length > 0;
32
+ }
33
+ function getActiveOptionName$1(selector) {
34
+ if (hasBlockOptions$2(selector)) {
35
+ return selector.blockOptions.find((b) => b.isActive)?.name ?? null;
36
+ }
37
+ return selector.options.find((o) => o.isActive)?.name ?? null;
38
+ }
39
+ function getAllOptions$1(selector) {
40
+ if (hasBlockOptions$2(selector)) {
41
+ return selector.blockOptions.map((b) => ({ name: b.name, isActive: b.isActive }));
42
+ }
43
+ return selector.options.map((o) => ({ name: o.name, isActive: o.isActive }));
44
+ }
30
45
  const listCommand = new Command("list").alias("ls").description("List all selectors and their current state").option("--json", "Output in JSON format").action(async (options) => {
31
46
  const config = await loadConfig();
32
47
  if (!config?.select) {
@@ -45,11 +60,9 @@ const listCommand = new Command("list").alias("ls").description("List all select
45
60
  name: selector.name,
46
61
  file: relative(process.cwd(), file.path),
47
62
  line: selector.line,
48
- activeOption: selector.options.find((o) => o.isActive)?.name ?? null,
49
- options: selector.options.map((o) => ({
50
- name: o.name,
51
- isActive: o.isActive
52
- }))
63
+ activeOption: getActiveOptionName$1(selector),
64
+ isBlock: hasBlockOptions$2(selector),
65
+ options: getAllOptions$1(selector)
53
66
  }))
54
67
  );
55
68
  console.log(JSON.stringify(jsonOutput, null, 2));
@@ -63,10 +76,11 @@ const listCommand = new Command("list").alias("ls").description("List all select
63
76
  const relativePath = relative(process.cwd(), file.path);
64
77
  console.log(pc.cyan(relativePath));
65
78
  for (const selector of file.selectors) {
66
- const activeOption = selector.options.find((o) => o.isActive);
67
- const activeLabel = activeOption ? pc.green(activeOption.name) : pc.yellow("none");
68
- console.log(` ${pc.bold(selector.name)}: ${activeLabel}`);
69
- for (const option of selector.options) {
79
+ const activeOptionName = getActiveOptionName$1(selector);
80
+ const activeLabel = activeOptionName ? pc.green(activeOptionName) : pc.yellow("none");
81
+ const blockIndicator = hasBlockOptions$2(selector) ? pc.dim(" [block]") : "";
82
+ console.log(` ${pc.bold(selector.name)}${blockIndicator}: ${activeLabel}`);
83
+ for (const option of getAllOptions$1(selector)) {
70
84
  const marker = option.isActive ? pc.green("●") : pc.dim("○");
71
85
  console.log(` ${marker} ${option.name}`);
72
86
  }
@@ -74,6 +88,9 @@ const listCommand = new Command("list").alias("ls").description("List all select
74
88
  console.log();
75
89
  }
76
90
  });
91
+ function hasBlockOptions$1(selector) {
92
+ return selector.blockOptions.length > 0;
93
+ }
77
94
  const setCommand = new Command("set").description("Set a specific option for a selector").argument("<selector>", "Selector name").argument("<option>", "Option to activate").action(async (selectorName, optionName) => {
78
95
  const config = await loadConfig();
79
96
  if (!config?.select) {
@@ -87,9 +104,15 @@ const setCommand = new Command("set").description("Set a specific option for a s
87
104
  const selector = file.selectors.find((s) => s.name === selectorName);
88
105
  if (selector) {
89
106
  found = true;
90
- const switcher = SingleSwitcher.forFilePath(file.path);
91
107
  try {
92
- const newContent = switcher.switch(file.content, selector, optionName);
108
+ let newContent;
109
+ if (hasBlockOptions$1(selector)) {
110
+ const switcher = BlockSwitcher.forFilePath(file.path);
111
+ newContent = switcher.switch(file.content, selector, optionName);
112
+ } else {
113
+ const switcher = SingleSwitcher.forFilePath(file.path);
114
+ newContent = switcher.switch(file.content, selector, optionName);
115
+ }
93
116
  await writeFile(file.path, newContent);
94
117
  const relativePath = relative(process.cwd(), file.path);
95
118
  console.log(
@@ -112,6 +135,21 @@ const BACK_VALUE = /* @__PURE__ */ Symbol("back");
112
135
  function isExitPromptError(error) {
113
136
  return error instanceof Error && error.name === "ExitPromptError";
114
137
  }
138
+ function hasBlockOptions(selector) {
139
+ return selector.blockOptions.length > 0;
140
+ }
141
+ function getActiveOptionName(selector) {
142
+ if (hasBlockOptions(selector)) {
143
+ return selector.blockOptions.find((b) => b.isActive)?.name ?? null;
144
+ }
145
+ return selector.options.find((o) => o.isActive)?.name ?? null;
146
+ }
147
+ function getAllOptions(selector) {
148
+ if (hasBlockOptions(selector)) {
149
+ return selector.blockOptions.map((b) => ({ name: b.name, isActive: b.isActive }));
150
+ }
151
+ return selector.options.map((o) => ({ name: o.name, isActive: o.isActive }));
152
+ }
115
153
  const switchCommand = new Command("switch").alias("sw").description("Interactively switch options").action(async () => {
116
154
  const config = await loadConfig();
117
155
  if (!config?.select) {
@@ -138,10 +176,11 @@ const switchCommand = new Command("switch").alias("sw").description("Interactive
138
176
  choices: [
139
177
  ...choices.map((choice) => {
140
178
  const relativePath2 = relative(process.cwd(), choice.file.path);
141
- const activeOption = choice.selector.options.find((o) => o.isActive);
142
- const current = activeOption ? pc.dim(` (${activeOption.name})`) : "";
179
+ const activeOptionName = getActiveOptionName(choice.selector);
180
+ const current = activeOptionName ? pc.dim(` (${activeOptionName})`) : "";
181
+ const blockIndicator = hasBlockOptions(choice.selector) ? pc.dim(" [block]") : "";
143
182
  return {
144
- name: `${choice.selector.name}${current} ${pc.dim(`- ${relativePath2}`)}`,
183
+ name: `${choice.selector.name}${blockIndicator}${current} ${pc.dim(`- ${relativePath2}`)}`,
145
184
  value: choice
146
185
  };
147
186
  }),
@@ -159,11 +198,12 @@ const switchCommand = new Command("switch").alias("sw").description("Interactive
159
198
  return;
160
199
  }
161
200
  let selectedOption;
201
+ const allOptions = getAllOptions(selectedChoice.selector);
162
202
  try {
163
203
  selectedOption = await select({
164
204
  message: `Select option for ${pc.bold(selectedChoice.selector.name)}`,
165
205
  choices: [
166
- ...selectedChoice.selector.options.map((option) => ({
206
+ ...allOptions.map((option) => ({
167
207
  name: option.isActive ? `${option.name} ${pc.green("(current)")}` : option.name,
168
208
  value: option.name
169
209
  })),
@@ -180,12 +220,22 @@ const switchCommand = new Command("switch").alias("sw").description("Interactive
180
220
  if (selectedOption === BACK_VALUE) {
181
221
  continue;
182
222
  }
183
- const switcher = SingleSwitcher.forFilePath(selectedChoice.file.path);
184
- const newContent = switcher.switch(
185
- selectedChoice.file.content,
186
- selectedChoice.selector,
187
- selectedOption
188
- );
223
+ let newContent;
224
+ if (hasBlockOptions(selectedChoice.selector)) {
225
+ const switcher = BlockSwitcher.forFilePath(selectedChoice.file.path);
226
+ newContent = switcher.switch(
227
+ selectedChoice.file.content,
228
+ selectedChoice.selector,
229
+ selectedOption
230
+ );
231
+ } else {
232
+ const switcher = SingleSwitcher.forFilePath(selectedChoice.file.path);
233
+ newContent = switcher.switch(
234
+ selectedChoice.file.content,
235
+ selectedChoice.selector,
236
+ selectedOption
237
+ );
238
+ }
189
239
  await writeFile(selectedChoice.file.path, newContent);
190
240
  const relativePath = relative(process.cwd(), selectedChoice.file.path);
191
241
  console.log(
@@ -1 +1 @@
1
- {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/lib/commands/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,OAAO,aAAa,CAAC;AAMrB,eAAO,MAAM,WAAW,SA6DpB,CAAC"}
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/lib/commands/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,OAAO,aAAa,CAAC;AAiCrB,eAAO,MAAM,WAAW,SA4DpB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"set.d.ts","sourceRoot":"","sources":["../../../src/lib/commands/set.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,OAAO,aAAa,CAAC;AAErB,eAAO,MAAM,UAAU,SA6CnB,CAAC"}
1
+ {"version":3,"file":"set.d.ts","sourceRoot":"","sources":["../../../src/lib/commands/set.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,OAAO,aAAa,CAAC;AASrB,eAAO,MAAM,UAAU,SAqDnB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"switch.d.ts","sourceRoot":"","sources":["../../../src/lib/commands/switch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,OAAO,aAAa,CAAC;AAarB,eAAO,MAAM,aAAa,SAyGtB,CAAC"}
1
+ {"version":3,"file":"switch.d.ts","sourceRoot":"","sources":["../../../src/lib/commands/switch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,OAAO,aAAa,CAAC;AAwCrB,eAAO,MAAM,aAAa,SAuHtB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lsst/pik-plugin-select",
3
- "version": "0.6.7",
3
+ "version": "0.7.0",
4
4
  "description": "Config selector plugin for pik CLI",
5
5
  "type": "module",
6
6
  "license": "MIT",