@teambit/workspace-config-files 1.0.1159 → 1.0.1161

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.
Files changed (38) hide show
  1. package/dist/outputs/format-skipped-output.d.ts +5 -0
  2. package/dist/outputs/format-skipped-output.js +33 -0
  3. package/dist/outputs/format-skipped-output.js.map +1 -0
  4. package/dist/outputs/format-skipped-output.spec.d.ts +1 -0
  5. package/dist/outputs/format-skipped-output.spec.js +80 -0
  6. package/dist/outputs/format-skipped-output.spec.js.map +1 -0
  7. package/dist/outputs/format-write-output.js +16 -1
  8. package/dist/outputs/format-write-output.js.map +1 -1
  9. package/dist/outputs/index.d.ts +1 -0
  10. package/dist/outputs/index.js +13 -0
  11. package/dist/outputs/index.js.map +1 -1
  12. package/dist/outputs/verbose-format-write-output.js +16 -1
  13. package/dist/outputs/verbose-format-write-output.js.map +1 -1
  14. package/dist/{preview-1788966965383.js → preview-1789144897043.js} +1 -1
  15. package/dist/workspace-config-files.main.runtime.d.ts +16 -0
  16. package/dist/workspace-config-files.main.runtime.js +28 -4
  17. package/dist/workspace-config-files.main.runtime.js.map +1 -1
  18. package/dist/writers/extending-config-files.d.ts +15 -2
  19. package/dist/writers/extending-config-files.js +35 -7
  20. package/dist/writers/extending-config-files.js.map +1 -1
  21. package/dist/writers/extending-config-files.spec.d.ts +1 -0
  22. package/dist/writers/extending-config-files.spec.js +91 -0
  23. package/dist/writers/extending-config-files.spec.js.map +1 -0
  24. package/dist/writers/index.d.ts +2 -2
  25. package/dist/writers/index.js +6 -0
  26. package/dist/writers/index.js.map +1 -1
  27. package/dist/ws-config.cmd.d.ts +1 -0
  28. package/dist/ws-config.cmd.js +5 -3
  29. package/dist/ws-config.cmd.js.map +1 -1
  30. package/outputs/format-skipped-output.spec.ts +51 -0
  31. package/outputs/format-skipped-output.ts +14 -0
  32. package/outputs/format-write-output.ts +4 -1
  33. package/outputs/index.ts +1 -0
  34. package/outputs/verbose-format-write-output.ts +4 -1
  35. package/package.json +4 -4
  36. package/writers/extending-config-files.spec.ts +67 -0
  37. package/writers/extending-config-files.ts +54 -24
  38. package/writers/index.ts +2 -1
@@ -1 +1 @@
1
- {"version":3,"names":["_chalk","data","_interopRequireDefault","require","_outputs","e","__esModule","default","_defineProperty","r","t","_toPropertyKey","Object","defineProperty","value","enumerable","configurable","writable","i","_toPrimitive","Symbol","toPrimitive","call","TypeError","String","Number","COMMAND_NAME","WsConfigCmd","constructor","report","unrecognizedSubcommand","chalk","red","exports","WsConfigWriteCmd","workspaceConfigFilesMain","_args","flags","results","json","dryRunWithContent","Error","envsNotImplementing","getEnvsNotImplementing","warning","getWarningForNonImplementingEnvs","output","verbose","verboseFormatWriteOutput","formatWriteOutput","clean","silent","noDedupe","writers","dryRun","cleanResults","writeResults","wsDir","writeConfigFiles","dedupe","split","updatedWriteResults","writersResult","map","oneWriterResult","realConfigFiles","forEach","realConfigFile","writtenRealConfigFile","content","extendingConfigFiles","extendingConfigFile","WsConfigCleanCmd","formatCleanOutput","cleanConfigFiles","WsConfigListCmd","formatListOutput","listConfigWriters","length","message","yellow","cyan","join"],"sources":["ws-config.cmd.ts"],"sourcesContent":["/* eslint-disable max-classes-per-file */\n\nimport type { Command, CommandOptions } from '@teambit/cli';\nimport chalk from 'chalk';\nimport type { WorkspaceConfigFilesMain, WriteConfigFilesResult } from './workspace-config-files.main.runtime';\nimport { formatCleanOutput, formatListOutput, formatWriteOutput, verboseFormatWriteOutput } from './outputs';\n\nexport type CleanConfigCmdFlags = {\n dryRun?: boolean;\n silent?: boolean;\n};\n\nexport type WriteConfigCmdFlags = {\n dryRun?: boolean;\n writers?: string;\n noDedupe?: boolean;\n dryRunWithContent?: boolean;\n clean?: boolean;\n silent?: boolean;\n verbose?: boolean;\n};\n\nconst COMMAND_NAME = 'ws-config';\n\nexport class WsConfigCmd implements Command {\n name = `${COMMAND_NAME} <sub-command>`;\n alias = 'workspace-config';\n description = 'generate IDE configuration files';\n extendedDescription = `writes configuration files (tsconfig.json, eslintrc.js, etc.) to your workspace for better IDE support.\nautomatically generates configs based on your components' environments and settings.\nuseful for enabling proper IntelliSense, linting, and type-checking in your IDE.`;\n options = [];\n group = 'workspace-tools';\n commands: Command[] = [];\n // helpUrl = '';\n\n async report([unrecognizedSubcommand]: [string]) {\n return chalk.red(\n `\"${unrecognizedSubcommand}\" is not a subcommand of \"ws-config\", please run \"bit ws-config --help\" to list the subcommands`\n );\n }\n}\n\nexport class WsConfigWriteCmd implements Command {\n name = 'write';\n description = 'write config files in the workspace. useful for IDEs';\n alias = '';\n group = 'workspace-tools';\n options = [\n [\n 'c',\n 'clean',\n 'delete existing config files from the workspace. highly recommended to run it with \"--dry-run\" first',\n ],\n [\n 'w',\n 'writers <writers>',\n `only write config files for the given writers. use comma to separate multiple writers. use ${COMMAND_NAME} list to see all writers`,\n ],\n ['s', 'silent', 'do not prompt for confirmation'],\n ['', 'no-dedupe', \"write configs inside each one of the component's dir, avoid deduping\"],\n ['', 'dry-run', 'show the paths that configs will be written per env'],\n [\n '',\n 'dry-run-with-content',\n 'use with --json flag. show the config content and the paths that will be written per env',\n ],\n ['v', 'verbose', 'showing verbose output for writing'],\n ['j', 'json', 'json format'],\n ] as CommandOptions;\n\n constructor(private workspaceConfigFilesMain: WorkspaceConfigFilesMain) {}\n\n async report(_args, flags: WriteConfigCmdFlags) {\n const results = (await this.json(_args, flags)) as WriteConfigFilesResult;\n if (flags.dryRunWithContent) {\n throw new Error(`use --json flag along with --dry-run-with-content`);\n }\n const envsNotImplementing = this.workspaceConfigFilesMain.getEnvsNotImplementing();\n const warning = getWarningForNonImplementingEnvs(envsNotImplementing);\n const output = flags.verbose ? verboseFormatWriteOutput(results, flags) : formatWriteOutput(results, flags);\n return warning + output;\n }\n\n async json(_args, flags: WriteConfigCmdFlags) {\n const { clean, silent, noDedupe, dryRunWithContent, writers } = flags;\n const dryRun = dryRunWithContent ? true : !!flags.dryRun;\n const { cleanResults, writeResults, wsDir } = await this.workspaceConfigFilesMain.writeConfigFiles({\n clean,\n dedupe: !noDedupe,\n dryRun,\n silent,\n writers: writers?.split(','),\n });\n\n if (dryRun) {\n const updatedWriteResults = writeResults;\n if (!dryRunWithContent) {\n updatedWriteResults.writersResult = updatedWriteResults.writersResult.map((oneWriterResult) => {\n oneWriterResult.realConfigFiles.forEach((realConfigFile) => {\n realConfigFile.writtenRealConfigFile.content = '';\n });\n oneWriterResult.extendingConfigFiles.forEach((extendingConfigFile) => {\n extendingConfigFile.extendingConfigFile.content = '';\n });\n return oneWriterResult;\n });\n }\n\n return {\n wsDir,\n cleanResults,\n writeResults: updatedWriteResults,\n };\n }\n return { wsDir, cleanResults, writeResults };\n }\n}\n\nexport class WsConfigCleanCmd implements Command {\n name = 'clean';\n description = 'clean (delete) written config files in the workspace. useful for IDEs';\n alias = '';\n group = 'workspace-tools';\n options = [\n ['s', 'silent', 'do not prompt for confirmation'],\n [\n 'w',\n 'writers <writers>',\n `only clean config files for the given writers. use comma to separate multiple writers. use ${COMMAND_NAME} list to see all writers`,\n ],\n ['', 'dry-run', 'show the paths of configs that will be cleaned'],\n ['j', 'json', 'json format'],\n ] as CommandOptions;\n\n constructor(private workspaceConfigFilesMain: WorkspaceConfigFilesMain) {}\n\n async report(_args, flags: CleanConfigCmdFlags) {\n const results = await this.json(_args, flags);\n const envsNotImplementing = this.workspaceConfigFilesMain.getEnvsNotImplementing();\n const warning = getWarningForNonImplementingEnvs(envsNotImplementing);\n const output = formatCleanOutput(results, flags);\n return warning + output;\n }\n\n async json(_args, flags: WriteConfigCmdFlags) {\n const { silent, dryRun } = flags;\n const cleanResults = await this.workspaceConfigFilesMain.cleanConfigFiles({\n dryRun,\n silent,\n writers: flags.writers?.split(','),\n });\n return cleanResults;\n }\n}\n\nexport class WsConfigListCmd implements Command {\n name = 'list';\n description = 'list config writers';\n alias = '';\n group = 'workspace-tools';\n options = [['j', 'json', 'json format']] as CommandOptions;\n\n constructor(private workspaceConfigFilesMain: WorkspaceConfigFilesMain) {}\n\n async report() {\n const results = await this.json();\n const envsNotImplementing = this.workspaceConfigFilesMain.getEnvsNotImplementing();\n const warning = getWarningForNonImplementingEnvs(envsNotImplementing);\n const output = formatListOutput(results);\n return warning + output;\n }\n\n async json() {\n const cleanResults = await this.workspaceConfigFilesMain.listConfigWriters();\n return cleanResults;\n }\n}\n\nfunction getWarningForNonImplementingEnvs(envsNotImplementing: string[]) {\n if (!envsNotImplementing.length) return '';\n const message =\n chalk.yellow(`Bit cannot determine the correct contents for the config files to write. this may result in incorrect content.\nThe following environments need to add support for config files: ${chalk.cyan(envsNotImplementing.join(', '))}.\nconsider updating these envs to implement config file writing to improve the dev experience.\n\n`);\n return message;\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_chalk","data","_interopRequireDefault","require","_outputs","e","__esModule","default","_defineProperty","r","t","_toPropertyKey","Object","defineProperty","value","enumerable","configurable","writable","i","_toPrimitive","Symbol","toPrimitive","call","TypeError","String","Number","COMMAND_NAME","WsConfigCmd","constructor","report","unrecognizedSubcommand","chalk","red","exports","WsConfigWriteCmd","workspaceConfigFilesMain","_args","flags","results","json","dryRunWithContent","Error","envsNotImplementing","getEnvsNotImplementing","warning","getWarningForNonImplementingEnvs","output","verbose","verboseFormatWriteOutput","formatWriteOutput","clean","silent","noDedupe","writers","force","dryRun","cleanResults","writeResults","wsDir","writeConfigFiles","dedupe","split","updatedWriteResults","writersResult","map","oneWriterResult","realConfigFiles","forEach","realConfigFile","writtenRealConfigFile","content","extendingConfigFiles","extendingConfigFile","WsConfigCleanCmd","formatCleanOutput","cleanConfigFiles","WsConfigListCmd","formatListOutput","listConfigWriters","length","message","yellow","cyan","join"],"sources":["ws-config.cmd.ts"],"sourcesContent":["/* eslint-disable max-classes-per-file */\n\nimport type { Command, CommandOptions } from '@teambit/cli';\nimport chalk from 'chalk';\nimport type { WorkspaceConfigFilesMain, WriteConfigFilesResult } from './workspace-config-files.main.runtime';\nimport { formatCleanOutput, formatListOutput, formatWriteOutput, verboseFormatWriteOutput } from './outputs';\n\nexport type CleanConfigCmdFlags = {\n dryRun?: boolean;\n silent?: boolean;\n};\n\nexport type WriteConfigCmdFlags = {\n dryRun?: boolean;\n writers?: string;\n noDedupe?: boolean;\n dryRunWithContent?: boolean;\n clean?: boolean;\n silent?: boolean;\n verbose?: boolean;\n force?: boolean;\n};\n\nconst COMMAND_NAME = 'ws-config';\n\nexport class WsConfigCmd implements Command {\n name = `${COMMAND_NAME} <sub-command>`;\n alias = 'workspace-config';\n description = 'generate IDE configuration files';\n extendedDescription = `writes configuration files (tsconfig.json, eslintrc.js, etc.) to your workspace for better IDE support.\nautomatically generates configs based on your components' environments and settings.\nuseful for enabling proper IntelliSense, linting, and type-checking in your IDE.`;\n options = [];\n group = 'workspace-tools';\n commands: Command[] = [];\n // helpUrl = '';\n\n async report([unrecognizedSubcommand]: [string]) {\n return chalk.red(\n `\"${unrecognizedSubcommand}\" is not a subcommand of \"ws-config\", please run \"bit ws-config --help\" to list the subcommands`\n );\n }\n}\n\nexport class WsConfigWriteCmd implements Command {\n name = 'write';\n description = 'write config files in the workspace. useful for IDEs';\n alias = '';\n group = 'workspace-tools';\n options = [\n [\n 'c',\n 'clean',\n 'delete existing config files from the workspace. highly recommended to run it with \"--dry-run\" first',\n ],\n [\n 'w',\n 'writers <writers>',\n `only write config files for the given writers. use comma to separate multiple writers. use ${COMMAND_NAME} list to see all writers`,\n ],\n ['s', 'silent', 'do not prompt for confirmation'],\n [\n 'f',\n 'force',\n 'override config files that already exist in the workspace and were not generated by bit. by default they are left untouched',\n ],\n ['', 'no-dedupe', \"write configs inside each one of the component's dir, avoid deduping\"],\n ['', 'dry-run', 'show the paths that configs will be written per env'],\n [\n '',\n 'dry-run-with-content',\n 'use with --json flag. show the config content and the paths that will be written per env',\n ],\n ['v', 'verbose', 'showing verbose output for writing'],\n ['j', 'json', 'json format'],\n ] as CommandOptions;\n\n constructor(private workspaceConfigFilesMain: WorkspaceConfigFilesMain) {}\n\n async report(_args, flags: WriteConfigCmdFlags) {\n const results = (await this.json(_args, flags)) as WriteConfigFilesResult;\n if (flags.dryRunWithContent) {\n throw new Error(`use --json flag along with --dry-run-with-content`);\n }\n const envsNotImplementing = this.workspaceConfigFilesMain.getEnvsNotImplementing();\n const warning = getWarningForNonImplementingEnvs(envsNotImplementing);\n const output = flags.verbose ? verboseFormatWriteOutput(results, flags) : formatWriteOutput(results, flags);\n return warning + output;\n }\n\n async json(_args, flags: WriteConfigCmdFlags) {\n const { clean, silent, noDedupe, dryRunWithContent, writers, force } = flags;\n const dryRun = dryRunWithContent ? true : !!flags.dryRun;\n const { cleanResults, writeResults, wsDir } = await this.workspaceConfigFilesMain.writeConfigFiles({\n clean,\n dedupe: !noDedupe,\n dryRun,\n silent,\n writers: writers?.split(','),\n force,\n });\n\n if (dryRun) {\n const updatedWriteResults = writeResults;\n if (!dryRunWithContent) {\n updatedWriteResults.writersResult = updatedWriteResults.writersResult.map((oneWriterResult) => {\n oneWriterResult.realConfigFiles.forEach((realConfigFile) => {\n realConfigFile.writtenRealConfigFile.content = '';\n });\n oneWriterResult.extendingConfigFiles.forEach((extendingConfigFile) => {\n extendingConfigFile.extendingConfigFile.content = '';\n });\n return oneWriterResult;\n });\n }\n\n return {\n wsDir,\n cleanResults,\n writeResults: updatedWriteResults,\n };\n }\n return { wsDir, cleanResults, writeResults };\n }\n}\n\nexport class WsConfigCleanCmd implements Command {\n name = 'clean';\n description = 'clean (delete) written config files in the workspace. useful for IDEs';\n alias = '';\n group = 'workspace-tools';\n options = [\n ['s', 'silent', 'do not prompt for confirmation'],\n [\n 'w',\n 'writers <writers>',\n `only clean config files for the given writers. use comma to separate multiple writers. use ${COMMAND_NAME} list to see all writers`,\n ],\n ['', 'dry-run', 'show the paths of configs that will be cleaned'],\n ['j', 'json', 'json format'],\n ] as CommandOptions;\n\n constructor(private workspaceConfigFilesMain: WorkspaceConfigFilesMain) {}\n\n async report(_args, flags: CleanConfigCmdFlags) {\n const results = await this.json(_args, flags);\n const envsNotImplementing = this.workspaceConfigFilesMain.getEnvsNotImplementing();\n const warning = getWarningForNonImplementingEnvs(envsNotImplementing);\n const output = formatCleanOutput(results, flags);\n return warning + output;\n }\n\n async json(_args, flags: WriteConfigCmdFlags) {\n const { silent, dryRun } = flags;\n const cleanResults = await this.workspaceConfigFilesMain.cleanConfigFiles({\n dryRun,\n silent,\n writers: flags.writers?.split(','),\n });\n return cleanResults;\n }\n}\n\nexport class WsConfigListCmd implements Command {\n name = 'list';\n description = 'list config writers';\n alias = '';\n group = 'workspace-tools';\n options = [['j', 'json', 'json format']] as CommandOptions;\n\n constructor(private workspaceConfigFilesMain: WorkspaceConfigFilesMain) {}\n\n async report() {\n const results = await this.json();\n const envsNotImplementing = this.workspaceConfigFilesMain.getEnvsNotImplementing();\n const warning = getWarningForNonImplementingEnvs(envsNotImplementing);\n const output = formatListOutput(results);\n return warning + output;\n }\n\n async json() {\n const cleanResults = await this.workspaceConfigFilesMain.listConfigWriters();\n return cleanResults;\n }\n}\n\nfunction getWarningForNonImplementingEnvs(envsNotImplementing: string[]) {\n if (!envsNotImplementing.length) return '';\n const message =\n chalk.yellow(`Bit cannot determine the correct contents for the config files to write. this may result in incorrect content.\nThe following environments need to add support for config files: ${chalk.cyan(envsNotImplementing.join(', '))}.\nconsider updating these envs to implement config file writing to improve the dev experience.\n\n`);\n return message;\n}\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,51 @@
1
+ import { expect } from 'chai';
2
+ import { join } from 'path';
3
+ import type { WriteConfigFilesResult } from '../workspace-config-files.main.runtime';
4
+ import { formatSkippedOutput } from './format-skipped-output';
5
+ import { formatWriteOutput } from './format-write-output';
6
+ import { verboseFormatWriteOutput } from './verbose-format-write-output';
7
+
8
+ const wsDir = join('/', 'my-workspace');
9
+ const skippedPath = join(wsDir, 'tsconfig.json');
10
+
11
+ function mockWriteConfigFilesResult(skippedPaths: string[]): WriteConfigFilesResult {
12
+ return {
13
+ wsDir,
14
+ writeResults: {
15
+ writersResult: [],
16
+ totalWrittenFiles: 0,
17
+ totalRealConfigFiles: 0,
18
+ totalExtendingConfigFiles: 0,
19
+ skippedPaths,
20
+ },
21
+ };
22
+ }
23
+
24
+ describe('formatSkippedOutput()', () => {
25
+ it('should return an empty string when no file was skipped', () => {
26
+ expect(formatSkippedOutput([], wsDir)).to.equal('');
27
+ });
28
+ it('should show the path relative to the workspace and how to override it', () => {
29
+ const output = formatSkippedOutput([skippedPath], wsDir);
30
+ expect(output).to.have.string('tsconfig.json');
31
+ expect(output).to.not.have.string(wsDir);
32
+ expect(output).to.have.string('--force');
33
+ });
34
+ });
35
+
36
+ describe('write output with skipped files', () => {
37
+ it('should show the skipped files', () => {
38
+ const output = formatWriteOutput(mockWriteConfigFilesResult([skippedPath]), {});
39
+ expect(output).to.have.string('not overridden');
40
+ expect(output).to.have.string('tsconfig.json');
41
+ });
42
+ it('should show the skipped files in verbose mode as well', () => {
43
+ const output = verboseFormatWriteOutput(mockWriteConfigFilesResult([skippedPath]), {});
44
+ expect(output).to.have.string('not overridden');
45
+ expect(output).to.have.string('tsconfig.json');
46
+ });
47
+ it('should not mention skipped files when there are none', () => {
48
+ expect(formatWriteOutput(mockWriteConfigFilesResult([]), {})).to.not.have.string('not overridden');
49
+ expect(verboseFormatWriteOutput(mockWriteConfigFilesResult([]), {})).to.not.have.string('not overridden');
50
+ });
51
+ });
@@ -0,0 +1,14 @@
1
+ import { relative } from 'path';
2
+ import { formatItem, formatSection, warnSymbol } from '@teambit/cli';
3
+
4
+ const SKIPPED_DESCRIPTION = `these files already exist and were not generated by bit, so they were left untouched.
5
+ to have bit write them, delete them first or run "bit ws-config write --force".`;
6
+
7
+ /**
8
+ * config files that bit wanted to write but are authored by the user.
9
+ * returns an empty string when nothing was skipped.
10
+ */
11
+ export function formatSkippedOutput(skippedPaths: string[], wsDir: string): string {
12
+ const items = skippedPaths.map((path) => formatItem(relative(wsDir, path)));
13
+ return formatSection(`${warnSymbol} config files not overridden`, SKIPPED_DESCRIPTION, items);
14
+ }
@@ -1,5 +1,6 @@
1
1
  import chalk from 'chalk';
2
2
  import { relative } from 'path';
3
+ import { joinSections } from '@teambit/cli';
3
4
  import type {
4
5
  OneConfigWriterIdResult,
5
6
  WriteConfigFilesResult,
@@ -7,6 +8,7 @@ import type {
7
8
  } from '../workspace-config-files.main.runtime';
8
9
  import type { WriteConfigCmdFlags } from '../ws-config.cmd';
9
10
  import { formatCleanOutput } from './format-clean-output';
11
+ import { formatSkippedOutput } from './format-skipped-output';
10
12
  import { SUMMARY, WRITE_TITLE } from './write-outputs-texts';
11
13
  import type { EnvsWrittenExtendingConfigFile, EnvsWrittenExtendingConfigFiles } from '../writers';
12
14
 
@@ -17,8 +19,9 @@ export function formatWriteOutput(writeConfigFilesResult: WriteConfigFilesResult
17
19
  const writeResultsOutput = getWriteResultsOutput(writeResults, wsDir, isDryRun);
18
20
 
19
21
  const cleanWriteOutput = cleanResultsOutput ? `${cleanResultsOutput}\n${writeResultsOutput}` : writeResultsOutput;
22
+ const skippedOutput = formatSkippedOutput(writeResults.skippedPaths, wsDir);
20
23
 
21
- return `${cleanWriteOutput}\n\n${SUMMARY}`;
24
+ return joinSections([cleanWriteOutput, skippedOutput, SUMMARY]);
22
25
  }
23
26
 
24
27
  function getWriteResultsOutput(writeResults: WriteResults, wsDir: string, isDryRun: boolean) {
package/outputs/index.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export { formatCleanOutput } from './format-clean-output';
2
+ export { formatSkippedOutput } from './format-skipped-output';
2
3
  export { formatListOutput } from './format-list-output';
3
4
  export { formatWriteOutput } from './format-write-output';
4
5
  export { verboseFormatWriteOutput } from './verbose-format-write-output';
@@ -1,5 +1,6 @@
1
1
  import chalk from 'chalk';
2
2
  import { relative } from 'path';
3
+ import { joinSections } from '@teambit/cli';
3
4
  import type {
4
5
  OneConfigWriterIdResult,
5
6
  WriteConfigFilesResult,
@@ -7,6 +8,7 @@ import type {
7
8
  } from '../workspace-config-files.main.runtime';
8
9
  import type { WriteConfigCmdFlags } from '../ws-config.cmd';
9
10
  import { formatCleanOutput } from './format-clean-output';
11
+ import { formatSkippedOutput } from './format-skipped-output';
10
12
  import { SUMMARY, WRITE_TITLE } from './write-outputs-texts';
11
13
  import type {
12
14
  EnvsWrittenExtendingConfigFile,
@@ -23,8 +25,9 @@ export function verboseFormatWriteOutput(
23
25
  const isDryRun = !!(flags.dryRun || flags.dryRunWithContent);
24
26
  const cleanResultsOutput = formatCleanOutput(cleanResults, { dryRun: isDryRun });
25
27
  const writeResultsOutput = getWriteResultsOutput(writeResults, wsDir, isDryRun);
28
+ const skippedOutput = formatSkippedOutput(writeResults.skippedPaths, wsDir);
26
29
 
27
- return `${cleanResultsOutput}\n${writeResultsOutput}\n\n${SUMMARY}`;
30
+ return joinSections([`${cleanResultsOutput}\n${writeResultsOutput}`, skippedOutput, SUMMARY]);
28
31
  }
29
32
 
30
33
  function getWriteResultsOutput(writeResults: WriteResults, wsDir: string, isDryRun: boolean) {
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@teambit/workspace-config-files",
3
- "version": "1.0.1159",
3
+ "version": "1.0.1161",
4
4
  "homepage": "https://bit.cloud/teambit/workspace/workspace-config-files",
5
5
  "main": "dist/index.js",
6
6
  "componentId": {
7
7
  "scope": "teambit.workspace",
8
8
  "name": "workspace-config-files",
9
- "version": "1.0.1159"
9
+ "version": "1.0.1161"
10
10
  },
11
11
  "dependencies": {
12
12
  "lodash": "4.17.21",
@@ -24,8 +24,8 @@
24
24
  "@teambit/legacy.consumer": "0.0.160",
25
25
  "@teambit/logger": "0.0.1482",
26
26
  "@teambit/toolbox.crypto.sha1": "0.0.21",
27
- "@teambit/envs": "1.0.1159",
28
- "@teambit/workspace": "1.0.1159"
27
+ "@teambit/envs": "1.0.1161",
28
+ "@teambit/workspace": "1.0.1161"
29
29
  },
30
30
  "devDependencies": {
31
31
  "@types/lodash": "4.14.165",
@@ -0,0 +1,67 @@
1
+ import { expect } from 'chai';
2
+ import fs from 'fs-extra';
3
+ import { tmpdir } from 'os';
4
+ import { join } from 'path';
5
+ import type { ConfigWriterEntry } from '../config-writer-entry';
6
+ import { isUserAuthoredConfigFile } from './extending-config-files';
7
+
8
+ const BIT_GENERATED_COMMENT = '// bit-generated-typescript-config';
9
+
10
+ function mockConfigWriter(withIsBitGenerated = true): ConfigWriterEntry {
11
+ const configWriter = {
12
+ id: 'typescript',
13
+ name: 'TypescriptConfigWriter',
14
+ patterns: ['**/tsconfig.json'],
15
+ calcConfigFiles: () => undefined,
16
+ generateExtendingFile: () => undefined,
17
+ } as unknown as ConfigWriterEntry;
18
+ if (withIsBitGenerated) {
19
+ configWriter.isBitGenerated = (filePath: string) =>
20
+ fs.readFileSync(filePath).toString().includes(BIT_GENERATED_COMMENT);
21
+ }
22
+ return configWriter;
23
+ }
24
+
25
+ describe('isUserAuthoredConfigFile()', () => {
26
+ let dir: string;
27
+ before(async () => {
28
+ dir = join(tmpdir(), `bit-ws-config-files-${Date.now()}`);
29
+ await fs.ensureDir(dir);
30
+ await fs.outputFile(join(dir, 'bit-generated.json'), `${BIT_GENERATED_COMMENT}\n{ "extends": "./whatever.json" }`);
31
+ await fs.outputFile(join(dir, 'user-authored.json'), '{ "compilerOptions": { "strict": true } }');
32
+ await fs.ensureDir(join(dir, 'a-directory.json'));
33
+ });
34
+ after(async () => {
35
+ await fs.remove(dir);
36
+ });
37
+
38
+ it('should return false when the file does not exist', async () => {
39
+ const result = await isUserAuthoredConfigFile(join(dir, 'does-not-exist.json'), mockConfigWriter());
40
+ expect(result).to.be.false;
41
+ });
42
+
43
+ it('should return false when the existing file was generated by bit', async () => {
44
+ const result = await isUserAuthoredConfigFile(join(dir, 'bit-generated.json'), mockConfigWriter());
45
+ expect(result).to.be.false;
46
+ });
47
+
48
+ it('should return true when the existing file was not generated by bit', async () => {
49
+ const result = await isUserAuthoredConfigFile(join(dir, 'user-authored.json'), mockConfigWriter());
50
+ expect(result).to.be.true;
51
+ });
52
+
53
+ it('should return false when the writer is unable to tell whether the file was generated by bit', async () => {
54
+ const result = await isUserAuthoredConfigFile(join(dir, 'user-authored.json'), mockConfigWriter(false));
55
+ expect(result).to.be.false;
56
+ });
57
+
58
+ it('should return false when no config writer was given', async () => {
59
+ const result = await isUserAuthoredConfigFile(join(dir, 'user-authored.json'));
60
+ expect(result).to.be.false;
61
+ });
62
+
63
+ it('should return true when the existing file cannot be read', async () => {
64
+ const result = await isUserAuthoredConfigFile(join(dir, 'a-directory.json'), mockConfigWriter());
65
+ expect(result).to.be.true;
66
+ });
67
+ });
@@ -5,7 +5,7 @@ import fs from 'fs-extra';
5
5
  import { dirname, join, relative } from 'path';
6
6
  import pMapSeries from 'p-map-series';
7
7
  import { compact } from 'lodash';
8
- import type { ExtendingConfigFile } from '../config-writer-entry';
8
+ import type { ConfigWriterEntry, ExtendingConfigFile } from '../config-writer-entry';
9
9
  import type { DedupedPaths } from '../dedup-paths';
10
10
  import { dedupePaths } from '../dedup-paths';
11
11
  import type {
@@ -31,6 +31,14 @@ export type ExtendingConfigFilesMap = {
31
31
  extendingConfigFile: Required<ExtendingConfigFile>;
32
32
  };
33
33
  };
34
+ export type HandleExtendingConfigFilesResult = {
35
+ extendingConfigFiles: EnvsWrittenExtendingConfigFiles;
36
+ /**
37
+ * paths of config files that already exist in the workspace and were not generated by bit.
38
+ * they are left untouched, otherwise the user's own configuration would be lost.
39
+ */
40
+ skippedPaths: string[];
41
+ };
34
42
 
35
43
  export async function handleExtendingConfigFiles(
36
44
  envEntries: EnvConfigWriterEntry[],
@@ -40,7 +48,7 @@ export async function handleExtendingConfigFiles(
40
48
  componentsRootDir: string | undefined,
41
49
  workspaceDir: string,
42
50
  opts: WriteConfigFilesOptions
43
- ): Promise<EnvsWrittenExtendingConfigFiles> {
51
+ ): Promise<HandleExtendingConfigFilesResult> {
44
52
  const extendingConfigFilesMap = await buildExtendingConfigFilesMap(
45
53
  envEntries,
46
54
  writtenRealConfigFiles,
@@ -57,13 +65,10 @@ export async function handleExtendingConfigFiles(
57
65
  configsRootDir,
58
66
  workspaceDir
59
67
  );
60
- const envsWrittenExtendingConfigFiles = await writeExtendingConfigFiles(
61
- extendingConfigFilesMap,
62
- fileHashPerDedupedPaths,
63
- workspaceDir,
64
- opts
65
- );
66
- return envsWrittenExtendingConfigFiles;
68
+ // all the entries here share the same writer-id (they're grouped by it before getting here), so any of them
69
+ // knows how to tell whether an existing config file was generated by bit.
70
+ const configWriter = envEntries[0]?.configWriter;
71
+ return writeExtendingConfigFiles(extendingConfigFilesMap, fileHashPerDedupedPaths, workspaceDir, configWriter, opts);
67
72
  }
68
73
 
69
74
  async function buildExtendingConfigFilesMap(
@@ -217,30 +222,55 @@ async function postProcessExtendingConfigFiles(
217
222
  });
218
223
  }
219
224
 
225
+ /**
226
+ * a config file that already exists in the workspace and wasn't generated by bit is a file the user wrote.
227
+ * overriding it silently loses their configuration, so it's skipped unless the caller explicitly asked to force it.
228
+ */
229
+ export async function isUserAuthoredConfigFile(filePath: string, configWriter?: ConfigWriterEntry): Promise<boolean> {
230
+ // without isBitGenerated we have no way to tell the files apart, keep the original behavior of overriding.
231
+ if (!configWriter?.isBitGenerated) return false;
232
+ if (!(await fs.pathExists(filePath))) return false;
233
+ try {
234
+ return !configWriter.isBitGenerated(filePath);
235
+ } catch {
236
+ // the file exists but can't be read. better to leave a file we know nothing about as is.
237
+ return true;
238
+ }
239
+ }
240
+
220
241
  async function writeExtendingConfigFiles(
221
242
  extendingConfigFilesMap: ExtendingConfigFilesMap,
222
243
  fileHashPerDedupedPaths: DedupedPaths,
223
244
  workspaceDir: string,
245
+ configWriter: ConfigWriterEntry | undefined,
224
246
  opts: WriteConfigFilesOptions
225
- ): Promise<EnvsWrittenExtendingConfigFiles> {
226
- const finalResult: EnvsWrittenExtendingConfigFiles = await Promise.all(
247
+ ): Promise<HandleExtendingConfigFilesResult> {
248
+ const skippedPaths: string[] = [];
249
+ const extendingConfigFiles: EnvsWrittenExtendingConfigFiles = await Promise.all(
227
250
  fileHashPerDedupedPaths.map(async ({ fileHash, paths }) => {
228
251
  const envsConfigFile = extendingConfigFilesMap[fileHash];
229
252
  const configFile = envsConfigFile.extendingConfigFile;
230
253
  const hash = configFile.hash || sha1(configFile.content);
231
254
  const name = format(configFile.name, { hash });
232
- const writtenPaths = await Promise.all(
233
- paths.map(async (path) => {
234
- const filePath = join(workspaceDir, path, name);
235
- const targetPath = configFile.useAbsPaths
236
- ? configFile.extendingTarget.filePath
237
- : normalize(`./${relative(dirname(filePath), configFile.extendingTarget.filePath)}`);
238
- const content = configFile.content.replace(`{${configFile.extendingTarget.name}}`, targetPath);
239
- if (!opts.dryRun) {
240
- await fs.outputFile(filePath, content);
241
- }
242
- return filePath;
243
- })
255
+ const writtenPaths = compact(
256
+ await Promise.all(
257
+ paths.map(async (path) => {
258
+ const filePath = join(workspaceDir, path, name);
259
+ const targetPath = configFile.useAbsPaths
260
+ ? configFile.extendingTarget.filePath
261
+ : normalize(`./${relative(dirname(filePath), configFile.extendingTarget.filePath)}`);
262
+ const content = configFile.content.replace(`{${configFile.extendingTarget.name}}`, targetPath);
263
+ // the check runs for dry-run as well, so it reports what will actually happen.
264
+ if (!opts.force && (await isUserAuthoredConfigFile(filePath, configWriter))) {
265
+ skippedPaths.push(filePath);
266
+ return undefined;
267
+ }
268
+ if (!opts.dryRun) {
269
+ await fs.outputFile(filePath, content);
270
+ }
271
+ return filePath;
272
+ })
273
+ )
244
274
  );
245
275
  const res: EnvsWrittenExtendingConfigFile = {
246
276
  envIds: envsConfigFile.envIds,
@@ -255,5 +285,5 @@ async function writeExtendingConfigFiles(
255
285
  return res;
256
286
  })
257
287
  );
258
- return finalResult;
288
+ return { extendingConfigFiles, skippedPaths };
259
289
  }
package/writers/index.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { handleExtendingConfigFiles } from './extending-config-files';
1
+ export { handleExtendingConfigFiles, isUserAuthoredConfigFile } from './extending-config-files';
2
2
  export { handleRealConfigFiles } from './real-config-files';
3
3
 
4
4
  export type { EnvsWrittenRealConfigFiles, EnvsWrittenRealConfigFile, WrittenConfigFile } from './real-config-files';
@@ -6,4 +6,5 @@ export type {
6
6
  EnvsWrittenExtendingConfigFiles,
7
7
  EnvsWrittenExtendingConfigFile,
8
8
  ExtendingConfigFilesMap,
9
+ HandleExtendingConfigFilesResult,
9
10
  } from './extending-config-files';