From 291bcec486da3266efd80ec81749c62b81a950a5 Mon Sep 17 00:00:00 2001 From: JohT <7671054+JohT@users.noreply.github.com> Date: Sun, 11 Aug 2024 08:44:19 +0200 Subject: [PATCH] Fix error when tsconfig has file as reference path. Ref: https://github.com/jqassistant-plugin/jqassistant-typescript-plugin/pull/126 --- scripts/findPathsToScan.sh | 11 ++++ scripts/patchJQAssistantTypescriptPlugin.sh | 37 ++++++++++++++ .../patches/@jqassistant+ts-lce+1.2.0.patch | 50 +++++++++++++++++++ 3 files changed, 98 insertions(+) create mode 100755 scripts/patchJQAssistantTypescriptPlugin.sh create mode 100644 scripts/patches/@jqassistant+ts-lce+1.2.0.patch diff --git a/scripts/findPathsToScan.sh b/scripts/findPathsToScan.sh index a0b93a3a3..ddad159c9 100755 --- a/scripts/findPathsToScan.sh +++ b/scripts/findPathsToScan.sh @@ -3,12 +3,21 @@ # Finds all files and directories to scan and analyze and provides them as comma-separated list. # This includes the scan of Typescript projects that leads to the intermediate json data file for jQAssistant. +# Uses: patchJQAssistantTypescriptPlugin.sh + # Fail on any error ("-e" = exit on first error, "-o pipefail" exist on errors within piped commands) set -o errexit -o pipefail ARTIFACTS_DIRECTORY=${ARTIFACTS_DIRECTORY:-"artifacts"} SOURCE_DIRECTORY=${SOURCE_DIRECTORY:-"source"} +## Get this "scripts" directory if not already set +# Even if $BASH_SOURCE is made for Bourne-like shells it is also supported by others and therefore here the preferred solution. +# CDPATH reduces the scope of the cd command to potentially prevent unintended directory changes. +# This way non-standard tools like readlink aren't needed. +SCRIPTS_DIR=${SCRIPTS_DIR:-$( CDPATH=. cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P )} # Repository directory containing the shell scripts +echo "findPathsToScan SCRIPTS_DIR=${SCRIPTS_DIR}" >&2 + # This function returns the argument followed by a comma (separator) if it is not empty # and just an empty string otherwise. appendNonEmpty() { @@ -31,6 +40,8 @@ fi if [ -d "./${SOURCE_DIRECTORY}" ] ; then if command -v "npx" &> /dev/null ; then + # TODO: Remove patchJQAssistantTypescriptPlugin when issue is resolved: https://github.com/jqassistant-plugin/jqassistant-typescript-plugin/issues/125 + source "${SCRIPTS_DIR}/patchJQAssistantTypescriptPlugin.sh" >&2 echo "findPathsToScan: Scanning Typescript source using @jqassistant/ts-lce..." >&2 ( cd "./${SOURCE_DIRECTORY}" && npx --yes @jqassistant/ts-lce@1.2.0 --extension React >"./../runtime/logs/jqassistant-typescript-scan.log" 2>&1 || exit ) else diff --git a/scripts/patchJQAssistantTypescriptPlugin.sh b/scripts/patchJQAssistantTypescriptPlugin.sh new file mode 100755 index 000000000..d05a33d41 --- /dev/null +++ b/scripts/patchJQAssistantTypescriptPlugin.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +# Patches jQAssistant Typescript Plugin as a workaround for https://github.com/jqassistant-plugin/jqassistant-typescript-plugin/issues/125 + +# Note: As soon as the issue is resolved, this file and its call can be deleted. + +# Requires "apply" + +# Fail on any error ("-e" = exit on first error, "-o pipefail" exist on errors within piped commands) +set -o errexit -o pipefail + +## Get this "scripts" directory if not already set +# Even if $BASH_SOURCE is made for Bourne-like shells it is also supported by others and therefore here the preferred solution. +# CDPATH reduces the scope of the cd command to potentially prevent unintended directory changes. +# This way non-standard tools like readlink aren't needed. +SCRIPTS_DIR=${SCRIPTS_DIR:-$( CDPATH=. cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P )} # Repository directory containing the shell scripts +echo "setupJQAssistant: SCRIPTS_DIR=$SCRIPTS_DIR" + +if ! command -v "npx" &> /dev/null ; then + echo "patchJQAssistantTypescriptPlugin Error: Command npx not found. It's needed to install @jqassistant/ts-lce temporarily." +fi + +echo "patchJQAssistantTypescriptPlugin: Installing jQAssistant Typescript Plugin @jqassistant/ts-lce using npx" +jqassistant_typescript_plugin_installation_path=$(npx --yes --package @jqassistant/ts-lce@1.2.0 which jqa-ts-lce) +echo "patchJQAssistantTypescriptPlugin: jqassistant_typescript_plugin_installation_path=${jqassistant_typescript_plugin_installation_path}" + +jqassistant_typescript_plugin_bin_path=$(dirname -- "${jqassistant_typescript_plugin_installation_path}") +jqassistant_typescript_plugin_utils_file_to_patch_relative="${jqassistant_typescript_plugin_bin_path}/../@jqassistant/ts-lce/dist/src/core/utils/project.utils.js" +echo "patchJQAssistantTypescriptPlugin: jqassistant_typescript_plugin_utils_file_to_patch_relative=${jqassistant_typescript_plugin_utils_file_to_patch_relative}" + +jqassistant_typescript_plugin_utils_path_resolved=$( CDPATH=. cd -- "$(dirname -- "${jqassistant_typescript_plugin_utils_file_to_patch_relative}")" && pwd -P ) +jqassistant_typescript_plugin_utils_file_to_patch="${jqassistant_typescript_plugin_utils_path_resolved}/project.utils.js" +echo "patchJQAssistantTypescriptPlugin: jqassistant_typescript_plugin_utils_file_to_patch=${jqassistant_typescript_plugin_utils_file_to_patch}" + +echo "patchJQAssistantTypescriptPlugin: Patching jQAssistant Typescript Plugin @jqassistant/ts-lce" +patch --forward -p1 "${jqassistant_typescript_plugin_utils_file_to_patch_relative}" -i "${SCRIPTS_DIR}/patches/@jqassistant+ts-lce+1.2.0.patch" || true +echo "patchJQAssistantTypescriptPlugin: Successfully patched jQAssistant Typescript Plugin @jqassistant/ts-lce" \ No newline at end of file diff --git a/scripts/patches/@jqassistant+ts-lce+1.2.0.patch b/scripts/patches/@jqassistant+ts-lce+1.2.0.patch new file mode 100644 index 000000000..e8a2d2736 --- /dev/null +++ b/scripts/patches/@jqassistant+ts-lce+1.2.0.patch @@ -0,0 +1,50 @@ +diff --git a/node_modules/@jqassistant/ts-lce/dist/src/core/utils/project.utils.js b/node_modules/@jqassistant/ts-lce/dist/src/core/utils/project.utils.js +index d1c33c4..672e6a1 100644 +--- a/node_modules/@jqassistant/ts-lce/dist/src/core/utils/project.utils.js ++++ b/node_modules/@jqassistant/ts-lce/dist/src/core/utils/project.utils.js +@@ -35,7 +35,7 @@ class ProjectUtils { + const projectRoot = dirsToScan[0]; + const tsConfigPath = path_1.default.join(projectRoot, "tsconfig.json"); + if (fs_1.default.existsSync(tsConfigPath)) { +- result.push(...this.getProjectInfo(projectRoot)); ++ result.push(...this.getProjectInfo(projectRoot, 'tsconfig.json')); + } + else { + // add all subdirectories as potential project candidates +@@ -61,13 +61,19 @@ class ProjectUtils { + } + }); + } +- static getProjectInfo(projectPath) { ++ static getConfigFileName(rawConfigPath) { ++ const pathIsADirectory = fs_1.default.statSync(rawConfigPath).isDirectory(); ++ const defaultConfigFileName = 'tsconfig.json'; ++ return pathIsADirectory? path_1.default.join(rawConfigPath, defaultConfigFileName) : rawConfigPath; ++ } ++ static getProjectInfo(projectPath, configFileName) { + const result = []; +- const tsConfig = this.parseTsConfig(projectPath); ++ const tsConfig = this.parseTsConfig(projectPath, configFileName); + const subProjectPaths = []; + if (tsConfig.projectReferences) { + for (const ref of tsConfig.projectReferences) { +- const subProjectInfos = this.getProjectInfo(ref.path); ++ const referencedConfigFileName = this.getConfigFileName(ref.path); ++ const subProjectInfos = this.getProjectInfo(path_1.default.dirname(referencedConfigFileName), path_1.default.basename(referencedConfigFileName)); + subProjectPaths.push(...subProjectInfos.map(spi => spi.projectPath.replace(/\\/g, "/"))); + result.push(...subProjectInfos); + } +@@ -85,10 +91,10 @@ class ProjectUtils { + }); + return result; + } +- static parseTsConfig(projectRoot) { +- const tsConfigPath = path_1.default.join(projectRoot, "tsconfig.json"); ++ static parseTsConfig(projectRoot, configFile) { ++ const tsConfigPath = path_1.default.join(projectRoot, configFile); + const configFileText = fs_1.default.readFileSync(tsConfigPath, 'utf8'); +- const configFileSourceFile = (0, typescript_1.createSourceFile)('tsconfig.json', configFileText, typescript_1.ScriptTarget.JSON); ++ const configFileSourceFile = (0, typescript_1.createSourceFile)(configFile, configFileText, typescript_1.ScriptTarget.JSON); + // Parse the tsconfig.json + const parsedCommandLine = (0, typescript_1.parseJsonSourceFileConfigFileContent)(configFileSourceFile, typescript_1.sys, path_1.default.dirname(tsConfigPath)); + // explicitly set rootDir option to default value, if not set manually