aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsnermolaev <snermolaev@yandex-team.com>2023-09-25 07:44:33 +0300
committersnermolaev <snermolaev@yandex-team.com>2023-09-25 08:10:23 +0300
commited5f990d30d50a34c949611e6feab5421a24517e (patch)
treed4ccc33e29dd75570636b6b91a6bf8f8ed5590c9
parentba26e92de230bf91efdbefd495b533d35cc3cb75 (diff)
downloadydb-ed5f990d30d50a34c949611e6feab5421a24517e.tar.gz
move TS related stuff to build/internal
-rw-r--r--build/conf/ts/node_modules.conf98
-rw-r--r--build/conf/ts/ts.conf98
-rw-r--r--build/conf/ts/ts_bundle.conf66
-rw-r--r--build/conf/ts/ts_library.conf54
-rw-r--r--build/conf/ts/ts_next.conf71
-rw-r--r--build/conf/ts/ts_package.conf44
-rw-r--r--build/conf/ts/ts_test.conf123
-rw-r--r--build/conf/ts/ts_vite_bundle.conf66
-rw-r--r--build/plugins/lib/nots/__init__.py0
-rw-r--r--build/plugins/lib/nots/a.yaml2
-rw-r--r--build/plugins/lib/nots/erm_json_lite.py102
-rw-r--r--build/plugins/lib/nots/package_manager/__init__.py7
-rw-r--r--build/plugins/lib/nots/package_manager/base/__init__.py20
-rw-r--r--build/plugins/lib/nots/package_manager/base/constants.py8
-rw-r--r--build/plugins/lib/nots/package_manager/base/lockfile.py71
-rw-r--r--build/plugins/lib/nots/package_manager/base/node_modules_bundler.py66
-rw-r--r--build/plugins/lib/nots/package_manager/base/package_json.py198
-rw-r--r--build/plugins/lib/nots/package_manager/base/package_manager.py155
-rw-r--r--build/plugins/lib/nots/package_manager/base/tests/package_json.py201
-rw-r--r--build/plugins/lib/nots/package_manager/base/tests/utils.py15
-rw-r--r--build/plugins/lib/nots/package_manager/base/tests/ya.make14
-rw-r--r--build/plugins/lib/nots/package_manager/base/utils.py29
-rw-r--r--build/plugins/lib/nots/package_manager/base/ya.make23
-rw-r--r--build/plugins/lib/nots/package_manager/pnpm/__init__.py12
-rw-r--r--build/plugins/lib/nots/package_manager/pnpm/constants.py2
-rw-r--r--build/plugins/lib/nots/package_manager/pnpm/lockfile.py151
-rw-r--r--build/plugins/lib/nots/package_manager/pnpm/package_manager.py244
-rw-r--r--build/plugins/lib/nots/package_manager/pnpm/tests/lockfile.py326
-rw-r--r--build/plugins/lib/nots/package_manager/pnpm/tests/workspace.py68
-rw-r--r--build/plugins/lib/nots/package_manager/pnpm/tests/ya.make15
-rw-r--r--build/plugins/lib/nots/package_manager/pnpm/utils.py11
-rw-r--r--build/plugins/lib/nots/package_manager/pnpm/workspace.py81
-rw-r--r--build/plugins/lib/nots/package_manager/pnpm/ya.make24
-rw-r--r--build/plugins/lib/nots/package_manager/ya.make14
-rw-r--r--build/plugins/lib/nots/semver/__init__.py7
-rw-r--r--build/plugins/lib/nots/semver/semver.py244
-rw-r--r--build/plugins/lib/nots/semver/tests/test_version.py269
-rw-r--r--build/plugins/lib/nots/semver/tests/test_version_range.py106
-rw-r--r--build/plugins/lib/nots/semver/tests/ya.make14
-rw-r--r--build/plugins/lib/nots/semver/ya.make14
-rw-r--r--build/plugins/lib/nots/typescript/__init__.py10
-rw-r--r--build/plugins/lib/nots/typescript/tests/test_ts_config.py169
-rw-r--r--build/plugins/lib/nots/typescript/tests/test_ts_glob.py75
-rw-r--r--build/plugins/lib/nots/typescript/tests/ya.make14
-rw-r--r--build/plugins/lib/nots/typescript/ts_config.py252
-rw-r--r--build/plugins/lib/nots/typescript/ts_errors.py10
-rw-r--r--build/plugins/lib/nots/typescript/ts_glob.py77
-rw-r--r--build/plugins/lib/nots/typescript/ya.make20
-rw-r--r--build/plugins/lib/nots/ya.make15
-rw-r--r--build/plugins/nots.py612
-rw-r--r--build/ymake.core.conf1
51 files changed, 0 insertions, 4388 deletions
diff --git a/build/conf/ts/node_modules.conf b/build/conf/ts/node_modules.conf
deleted file mode 100644
index 54d4b8d85e..0000000000
--- a/build/conf/ts/node_modules.conf
+++ /dev/null
@@ -1,98 +0,0 @@
-PNPM_ROOT=
-PNPM_SCRIPT=$PNPM_ROOT/node_modules/pnpm/dist/pnpm.cjs
-NPM_CONTRIBS_PATH=contrib/typescript
-NODE_MODULES_BUNDLE_AS_OUTPUT=
-_NODE_MODULES_INS=
-_NODE_MODULES_OUTS=
-
-# TOUCH_UNIT is required to create module identity file.
-# we can "call" macro as `$_NODE_MODULES(...)`. in this case we will get .CMD from it.
-# this is the only way to process a variable data as an array.
-# ${output;hide:_NODE_MODULES_OUTS} does not produce list of paths, but a single value (space-separeted paths)
-_NODE_MODULES_CMD=$TOUCH_UNIT && $_NODE_MODULES(IN $_NODE_MODULES_INS OUT $_NODE_MODULES_OUTS)
-
-module _NODE_MODULES_BASE: _BARE_UNIT {
- .CMD=_NODE_MODULES_CMD
- # ignore SRCS macro, use TS_FILES instead of FILES
- .ALIASES=SRCS=_NOOP_MACRO FILES=TS_FILES
- # Propagates peers to related modules
- .PEERDIR_POLICY=as_build_from
- .NODE_TYPE=Bundle
-
- # we have several modules in the same dir (.PEERDIRSELF=NODE_MODULES in BUILD)
- # we need different names for module identity file
- # .fake tells builder to not materialize it in results
- SET(MODULE_SUFFIX .n_m.fake)
- # .NODE_TYPE=Bundle is required for peers propagation, but it also affects
- # how merging of pic/nopic graphs. Here we can override this merging behaviour
- SET(MODULE_TYPE LIBRARY)
- # define own tag
- SET(MODULE_TAG NODE_MODULES)
- # what modules it can PEERDIR to
- SET(PEERDIR_TAGS TS NPM_CONTRIBS)
- # do not include it into "results" of graph
- DISABLE(START_TARGET)
-
- # we read package.json and erm-packages.json during configuration
- SET_APPEND(_MAKEFILE_INCLUDE_LIKE_DEPS ${CURDIR}/pnpm-lock.yaml ${CURDIR}/package.json ${ARCADIA_ROOT}/$ERM_PACKAGES_PATH)
-
- PEERDIR($NPM_CONTRIBS_PATH)
- # PEERDIR to the right version of nodejs and pnpm
- _PEERDIR_TS_RESOURCE(nodejs pnpm)
-
- # run py logic
- _NODE_MODULES_CONFIGURE()
-}
-
-# called in on_node_modules_configure
-macro _SET_NODE_MODULES_INS_OUTS(IN{input}[], OUT{output}[]) {
- SET(_NODE_MODULES_INS $IN)
- SET(_NODE_MODULES_OUTS $OUT)
-}
-
-macro _NODE_MODULES(IN{input}[], OUT{output}[]) {
- .CMD=${cwd:BINDIR} $NOTS_TOOL create-node-modules $NOTS_TOOL_BASE_ARGS --pnpm-script $PNPM_SCRIPT --contribs $NPM_CONTRIBS_PATH ${input;hide:IN} ${output;hide:OUT} ${kv;hide:"p NOMO"} ${kv;hide:"pc magenta"}
-}
-
-
-### @usage: NPM_CONTRIBS() # internal
-###
-### Defines special module that provides contrib tarballs from internal npm registry.
-###
-### @see [FROM_NPM_LOCKFILES()](#macro_FROM_NPM_LOCKFILES)
-module NPM_CONTRIBS: _BARE_UNIT {
- .CMD=TOUCH_UNIT
- .PEERDIR_POLICY=as_build_from
- .FINAL_TARGET=no
- .ALLOWED=FROM_NPM_LOCKFILES
- .RESTRICTED=PEERDIR
- .EXTS=_ # Ignore all files, so module is not affected by FROM_NPM output (.EXTS=* is inherited from _BARE_UNIT)
-
- SET(MODULE_TAG NPM_CONTRIBS)
-
- # .fake tells builder to not materialize it in results
- SET(MODULE_SUFFIX .fake)
-}
-
-### @usage: FROM_NPM_LOCKFILES(LOCKFILES...) # internal
-###
-### Defines lockfile list for `NPM_CONTRIBS` module.
-###
-### @see [NPM_CONTRIBS()](#module_NPM_CONTRIBS)
-macro FROM_NPM_LOCKFILES(LOCKFILES...) {
- SET_APPEND(_MAKEFILE_INCLUDE_LIKE_DEPS $LOCKFILES)
- # See implementation in build/plugins/nots.py
- _FROM_NPM_LOCKFILES($LOCKFILES)
-}
-
-FROM_NPM_CWD=$ARCADIA_BUILD_ROOT/$NPM_CONTRIBS_PATH
-macro _FROM_NPM(TARBALL_URL, SKY_ID, INTEGRITY, INTEGRITY_ALGO, TARBALL_PATH) {
- .CMD=${cwd:FROM_NPM_CWD} $YMAKE_PYTHON ${input:"build/scripts/fetch_from_npm.py"} ${input;hide:"build/scripts/fetch_from.py"} ${input;hide:"build/scripts/sky.py"} --tarball-url $TARBALL_URL --sky-id $SKY_ID --integrity $INTEGRITY --integrity-algorithm $INTEGRITY_ALGO --copy-to ${output;noauto:TARBALL_PATH} ${requirements;hide:"network:full"} ${kv;hide:"p NPM"} ${kv;hide:"pc magenta"}
- # we want output to be available for other modules without affecting NPM_CONTRIBS
- # we need to expose it (some details in https://st.yandex-team.ru/YMAKE-34)
- _EXPOSE($TARBALL_PATH)
-}
-
-macro NODE_MODULES() {
- MESSAGE(Remove NODE_MODULES())
-}
diff --git a/build/conf/ts/ts.conf b/build/conf/ts/ts.conf
deleted file mode 100644
index dd2e06ef6c..0000000000
--- a/build/conf/ts/ts.conf
+++ /dev/null
@@ -1,98 +0,0 @@
-NODEJS_ROOT=
-NODEJS_BIN=$NODEJS_ROOT/node
-
-NOTS_TOOL=${tool:"devtools/frontend_build_platform/nots/builder"}
-NOTS_TOOL_BASE_ARGS=--build-root $ARCADIA_BUILD_ROOT --bindir $BINDIR --curdir $CURDIR --nodejs-bin $NODEJS_BIN
-NOTS_TOOL_NODE_MODULES_BUNDLE=$BINDIR/node_modules.tar
-ERM_PACKAGES_PATH=devtools/frontend_build_platform/erm/erm-packages.json
-
-TS_CONFIG_PATH=tsconfig.json
-
-module _TS_BASE_UNIT: _BARE_UNIT {
- # Propagates peers to related modules
- .PEERDIR_POLICY=as_build_from
- .NODE_TYPE=Bundle
- # Needed for DEPENDS in tests to choose right submodule from multimodule
- .FINAL_TARGET=yes
- # use TS_FILES instead of FILES
- .ALIASES=FILES=TS_FILES
-
- # .NODE_TYPE=Bundle is required for peers propagation, but it also affects
- # how merging of pic/nopic graphs. Here we can override this merging behaviour
- SET(MODULE_TYPE LIBRARY)
- # Include processor works only for TS tag
- SET(MODULE_TAG TS)
- # TS should peer to TS
- SET(PEERDIR_TAGS TS)
- # .fake tells builder to not materialize it in results
- SET(MODULE_SUFFIX .ts.fake)
-
- # We read erm-packages.json during configuration, so we have to include it to configuration cache key
- SET_APPEND(_MAKEFILE_INCLUDE_LIKE_DEPS ${ARCADIA_ROOT}/$ERM_PACKAGES_PATH)
-
- # PEERDIR that reads required version of tool from package.json
- _PEERDIR_TS_RESOURCE(nodejs pnpm)
-}
-
-
-# tag:test
-ESLINT_CONFIG_PATH=.eslintrc.js
-_TS_LINT_SRCS_VALUE=
-### _TS_CONFIG_EPILOGUE() # internal
-###
-### This macro executes macros which should be invoked after all user specified macros in the ya.make file
-macro _TS_CONFIG_EPILOGUE() {
- _GLOB(_TS_LINT_SRCS_VALUE ${CURDIR}/**/*.(ts|tsx|js|jsx) EXCLUDE node_modules/**/* build/**/* bundle/**/*)
- _SETUP_EXTRACT_NODE_MODULES_RECIPE(${MODDIR})
-}
-
-# Used as inputs in TS_COMPILE through `$_AS_HIDDEN_INPUTS(IN $TS_INPUT_FILES)`
-TS_INPUT_FILES=
-
-# List of the files, filled in _TS_GLOB. Will be reduced in _TS_CONFIGURE macro to TS_INPUT_FILES.
-TS_GLOB_FILES=
-
-# Hardcoded "include" list (all other files will be ignored)
-TS_GLOB_INCLUDE=**/*
-
-# Hardcoded "exclude" list (reasonable default).
-TS_GLOB_EXCLUDE=$TS_CONFIG_PATH \
- ya.make a.yaml \
- (.vscode|.idea)/**/* \
- (build|dist|bundle|$WEBPACK_OUTPUT_DIR|$TS_NEXT_OUTPUT_DIR|$VITE_OUTPUT_DIR)/**/* \
- node_modules/**/* package.json pnpm-lock.yaml .* \
- tests/**/* **/*.(test|spec).(ts|tsx|js|jsx)
-
-
-### _TS_GLOB() # internal
-###
-### Fill $TS_GLOB_FILES with potential inputs.
-### It will be reduced later in _TS_CONFIGURE based on `tsconfig.json` rules.
-### So it is important to call _TS_CONFIGURE() with _TS_GLOB()!
-macro _TS_GLOB() {
- _GLOB(TS_GLOB_FILES $TS_GLOB_INCLUDE EXCLUDE $TS_GLOB_EXCLUDE)
-}
-
-# Ugly hack for using inputs from the variable
-macro _AS_HIDDEN_INPUTS(IN{input}[]) {
- # "context=TEXT" exclude file from the "include processing"
- .CMD=${input;hide;context=TEXT:IN}
-}
-
-
-_TS_FILES_COPY_CMD=
-
-### TS_FILES(Files...)
-###
-### Adds files to output as is. Similar to FILES but works for TS build modules
-macro TS_FILES(Files...) {
- _TS_FILES($Files)
-}
-
-@import "${CONF_ROOT}/conf/ts/node_modules.conf"
-@import "${CONF_ROOT}/conf/ts/ts_bundle.conf"
-@import "${CONF_ROOT}/conf/ts/ts_library.conf"
-@import "${CONF_ROOT}/conf/ts/ts_next.conf"
-@import "${CONF_ROOT}/conf/ts/ts_package.conf"
-@import "${CONF_ROOT}/conf/ts/ts_test.conf"
-@import "${CONF_ROOT}/conf/ts/ts_vite_bundle.conf"
diff --git a/build/conf/ts/ts_bundle.conf b/build/conf/ts/ts_bundle.conf
deleted file mode 100644
index ae16f09dd6..0000000000
--- a/build/conf/ts/ts_bundle.conf
+++ /dev/null
@@ -1,66 +0,0 @@
-# WEBPACK_ROOT is defined by _PEERDIR_TS_RESOURCE(webpack)
-WEBPACK_ROOT=
-WEBPACK_OUTPUT_DIR=bundle
-WEBPACK_CONFIG_PATH=webpack.config.js
-
-TS_BUNDLE_WEBPACK=$TOUCH_UNIT \
- && $_TS_FILES_COPY_CMD \
- && $ADD_VCS_INFO_FILE_CMD \
- && ${cwd:BINDIR} $NOTS_TOOL bundle-webpack $NOTS_TOOL_BASE_ARGS \
- --moddir $MODDIR \
- --ts-config ${input:TS_CONFIG_PATH} \
- --node-modules-bundle $NOTS_TOOL_NODE_MODULES_BUNDLE $NODE_MODULES_BUNDLE_AS_OUTPUT ${hide:PEERS} \
- --webpack-resource $WEBPACK_ROOT \
- --webpack-config ${input:WEBPACK_CONFIG_PATH} \
- --vcs-info "${VCS_INFO_FILE}" \
- --output-dir ${WEBPACK_OUTPUT_DIR} \
- ${input;hide:"package.json"} ${TS_CONFIG_FILES} $_AS_HIDDEN_INPUTS(IN $TS_INPUT_FILES) \
- ${output;hide:"package.json"} ${output;hide:"output.tar"} \
- ${kv;hide:"p TSWP"} ${kv;hide:"pc magenta"}
-
-### @usage: WEBPACK_OUTPUT(DirName)
-###
-### Macro sets the output directory name for TS_BUNDLE module.
-###
-### - DirName - output directory name ("bundle" by default).
-macro WEBPACK_OUTPUT(DirName) {
- SET(WEBPACK_OUTPUT_DIR $DirName)
-}
-
-### @usage: TS_BUNDLE([name])
-###
-### The Webpack bundle, bundles JavaScript code.
-### Build results are packed as `output.tar`.
-###
-### @example
-###
-### TS_BUNDLE()
-### SRCS(src/index.ts)
-### END()
-###
-multimodule TS_BUNDLE {
- module BUILD: _TS_BASE_UNIT {
- .CMD=TS_BUNDLE_WEBPACK
- .PEERDIRSELF=NODE_MODULES
- # epilogue is not inherited from TS_LIBRARY
- .EPILOGUE=_TS_CONFIG_EPILOGUE
-
- # by default multimodule overrides inherited MODULE_TAG to submodule name (BUILD in this case)
- # but we have to set it to TS for include processor to work
- SET(MODULE_TAG TS)
-
- _PEERDIR_TS_RESOURCE(webpack)
- SET_APPEND(_MAKEFILE_INCLUDE_LIKE_DEPS ${CURDIR}/${TS_CONFIG_PATH} ${CURDIR}/package.json)
- SET(TS_CONFIG_DEDUCE_OUT no)
-
- _TS_GLOB()
- _TS_CONFIGURE($TS_CONFIG_PATH)
-
- # we should set NODE_MODULES_BUNDLE_AS_OUTPUT conditionally,
- # based on whether module has deps or doesn't have
- _SET_NODE_MODULES_BUNDLE_AS_OUTPUT()
- }
-
- module NODE_MODULES: _NODE_MODULES_BASE {
- }
-}
diff --git a/build/conf/ts/ts_library.conf b/build/conf/ts/ts_library.conf
deleted file mode 100644
index 078c933f01..0000000000
--- a/build/conf/ts/ts_library.conf
+++ /dev/null
@@ -1,54 +0,0 @@
-# TYPESCRIPT_ROOT is defined by _PEERDIR_TS_RESOURCE(typescript)
-TYPESCRIPT_ROOT=
-
-TS_COMPILE=$TOUCH_UNIT \
- && $_TS_FILES_COPY_CMD \
- && ${cwd:BINDIR} $NOTS_TOOL compile-ts $NOTS_TOOL_BASE_ARGS \
- --moddir $MODDIR \
- --ts-configs $TS_CONFIG_PATH \
- --node-modules-bundle $NOTS_TOOL_NODE_MODULES_BUNDLE $NODE_MODULES_BUNDLE_AS_OUTPUT ${hide:PEERS} \
- --tsc-resource $TYPESCRIPT_ROOT \
- ${input;hide:"package.json"} ${TS_CONFIG_FILES} $_AS_HIDDEN_INPUTS(IN $TS_INPUT_FILES) \
- ${output;hide:"package.json"} ${output;hide:"output.tar"} \
- ${kv;hide:"p TSC"} ${kv;hide:"pc magenta"}
-
-### @usage: TS_LIBRARY([name])
-###
-### The TypeScript/JavaScript library module, compiles TypeScript sources to JavaScript.
-### Build results are JavaScript files, typings and source mappings (depending on local tsconfig.json settings).
-###
-### @example
-###
-### TS_LIBRARY()
-### SRCS(src/index.ts)
-### END()
-###
-multimodule TS_LIBRARY {
- module BUILD: _TS_BASE_UNIT {
- .CMD=TS_COMPILE
- .PEERDIRSELF=NODE_MODULES
- # epilogue is not inherited from TS_LIBRARY
- .EPILOGUE=_TS_CONFIG_EPILOGUE
-
- # by default multimodule overrides inherited MODULE_TAG to submodule name (BUILD in this case)
- # but we have to set it to TS for include processor to work
- SET(MODULE_TAG TS)
-
- SET_APPEND(_MAKEFILE_INCLUDE_LIKE_DEPS ${CURDIR}/${TS_CONFIG_PATH} ${CURDIR}/package.json)
-
- _PEERDIR_TS_RESOURCE(typescript)
-
- SET(TS_CONFIG_DEDUCE_OUT no)
-
- # we should set NODE_MODULES_BUNDLE_AS_OUTPUT conditionally,
- # based on whether module has deps or doesn't have
- _SET_NODE_MODULES_BUNDLE_AS_OUTPUT()
-
- _TS_GLOB()
-
- _TS_CONFIGURE($TS_CONFIG_PATH)
- }
-
- module NODE_MODULES: _NODE_MODULES_BASE {
- }
-}
diff --git a/build/conf/ts/ts_next.conf b/build/conf/ts/ts_next.conf
deleted file mode 100644
index d88c76e9a9..0000000000
--- a/build/conf/ts/ts_next.conf
+++ /dev/null
@@ -1,71 +0,0 @@
-# NEXT_ROOT is defined by _PEERDIR_TS_RESOURCE(next)
-NEXT_ROOT=
-TS_NEXT_OUTPUT_DIR=.next
-TS_NEXT_CONFIG_PATH=next.config.js
-
-TS_NEXT_CMD=$TOUCH_UNIT \
- && $_TS_FILES_COPY_CMD \
- && $ADD_VCS_INFO_FILE_CMD \
- && ${cwd:BINDIR} $NOTS_TOOL build-nextjs $NOTS_TOOL_BASE_ARGS \
- --moddir $MODDIR \
- --ts-config ${input:TS_CONFIG_PATH} \
- --node-modules-bundle $NOTS_TOOL_NODE_MODULES_BUNDLE $NODE_MODULES_BUNDLE_AS_OUTPUT ${hide:PEERS} \
- --nextjs-resource $NEXT_ROOT \
- --nextjs-config ${input:TS_NEXT_CONFIG_PATH} \
- --vcs-info "${VCS_INFO_FILE}" \
- --output-dir ${TS_NEXT_OUTPUT_DIR} \
- ${input;hide:"package.json"} ${TS_CONFIG_FILES} $_AS_HIDDEN_INPUTS(IN $TS_INPUT_FILES) \
- ${output;hide:"output.tar"} ${output;hide:"package.json"} \
- ${kv;hide:"p TSNEXT"} ${kv;hide:"pc magenta"}
-
-### @usage: TS_NEXT()
-###
-### NextJS app, built with `next build`. Requires sources to be under /src folder.
-### /pages and /app on the root level ar not supported.
-### Build results are output.tar.
-###
-### @example
-###
-### TS_NEXT()
-### END()
-###
-multimodule TS_NEXT {
- module BUILD: _TS_BASE_UNIT {
- .CMD=TS_NEXT_CMD
- .PEERDIRSELF=NODE_MODULES
- # epilogue is not inherited from TS_LIBRARY
- .EPILOGUE=_TS_CONFIG_EPILOGUE
-
- # by default multimodule overrides inherited MODULE_TAG to submodule name (BUILD in this case)
- # but we have to set it to TS for include processor to work
- SET(MODULE_TAG TS)
-
- _PEERDIR_TS_RESOURCE(next)
- SET_APPEND(_MAKEFILE_INCLUDE_LIKE_DEPS ${CURDIR}/${TS_CONFIG_PATH} ${CURDIR}/package.json)
- SET(TS_CONFIG_DEDUCE_OUT no)
-
- _TS_GLOB()
- _TS_CONFIGURE($TS_CONFIG_PATH)
-
- # we should set NODE_MODULES_BUNDLE_AS_OUTPUT conditionally,
- # based on whether module has deps or doesn't have
- _SET_NODE_MODULES_BUNDLE_AS_OUTPUT()
- }
-
- module NODE_MODULES: _NODE_MODULES_BASE {
- }
-}
-
-macro TS_NEXT_CONFIG(Path) {
- SET(TS_NEXT_CONFIG_PATH $Path)
-}
-
-
-### @usage: TS_NEXT_OUTPUT(DirName)
-###
-### Macro sets the output directory name for TS_NEXT module.
-###
-### - DirName - output directory name ("bundle" by default).
-macro TS_NEXT_OUTPUT(DirName) {
- SET(TS_NEXT_OUTPUT_DIR $DirName)
-}
diff --git a/build/conf/ts/ts_package.conf b/build/conf/ts/ts_package.conf
deleted file mode 100644
index 3e94a73d50..0000000000
--- a/build/conf/ts/ts_package.conf
+++ /dev/null
@@ -1,44 +0,0 @@
-_COPY_NODE_MODULES_BUNDLE_CMD=
-
-TS_PACK=$TOUCH_UNIT \
- && $_COPY_NODE_MODULES_BUNDLE_CMD \
- && $COPY_CMD ${input:"package.json"} ${output:"package.json"} \
- && $_TS_FILES_COPY_CMD \
- ${kv;hide:"p TSP"} ${kv;hide:"pc magenta"}
-
-### @usage: TS_PACKAGE()
-###
-### The TypeScript/JavaScript library module, that does not need any compilation,
-### and is just a set of files and NPM dependencies. List required files in TS_FILES macro.
-### `package.json` is included by default.
-###
-### @example
-###
-### TS_PACKAGE()
-### TS_FILES(
-### eslint.config.json
-### prettierrc.json
-### )
-### END()
-###
-multimodule TS_PACKAGE {
- module BUILD: _TS_BASE_UNIT {
- .CMD=TS_PACK
- .PEERDIRSELF=NODE_MODULES
- .ALLOWED=TS_FILES
- .ALIASES=FILES=TS_FILES SRCS=TS_FILES
-
- # by default multimodule overrides inherited MODULE_TAG to submodule name (BUILD in this case)
- # but we have to set it to TS for include processor to work
- SET(MODULE_TAG TS)
-
- # we should set _COPY_NODE_MODULES_BUNDLE_CMD conditionally,
- # based on whether module has deps or doesn't have
- _SET_COPY_NODE_MODULES_BUNDLE_CMD()
- }
-
- module NODE_MODULES: _NODE_MODULES_BASE {
- .ALLOWED=TS_FILES
- .ALIASES=FILES=TS_FILES SRCS=TS_FILES
- }
-}
diff --git a/build/conf/ts/ts_test.conf b/build/conf/ts/ts_test.conf
deleted file mode 100644
index d182472381..0000000000
--- a/build/conf/ts/ts_test.conf
+++ /dev/null
@@ -1,123 +0,0 @@
-TS_TEST_EXTENSION=
-TS_TEST_EXTRA_SRCS_MASK=
-
-TS_TEST_CONFIG_PATH=
-TS_TEST_FOR_MOD=
-TS_TEST_NM=
-
-# We have to rename node_modules.tar to workspace_node_modules.tar,
-# so TS_TEST_JEST module has it's own unique output.
-# TS_TEST_JEST_FOR module has to output all files required for test run.
-TS_TEST_JEST_CMD=$TOUCH_UNIT \
- && ${cwd:BINDIR} $MOVE_FILE ${input:TS_TEST_NM} ${output:"workspace_node_modules.tar"} \
- ${kv;hide:"p TSJEST"} ${kv;hide:"pc magenta"}
-
-### @usage: TS_TEST_JEST_FOR(Path)
-###
-### Defines testing module with jest test runner.
-###
-### @example
-###
-### TS_TEST_JEST_FOR(path/to/module)
-### TS_TEST_SRCS(../src)
-### TS_TEST_CONFIG(../jest.config.js)
-### END()
-###
-module TS_TEST_JEST_FOR: _TS_TEST_BASE {
- .CMD=TS_TEST_JEST_CMD
-
- # for multimodule peers we should choose NODE_MODULES
- SET(PEERDIR_TAGS NODE_MODULES)
-
- # compatibility with old TS_TEST_SRCS
- SET(TS_TEST_EXTENSION test.(ts|tsx|js|jsx))
- SET(TS_TEST_EXTRA_SRCS_MASK /**/__mocks__/*)
-
- _PEERDIR_TS_RESOURCE(nodejs pnpm jest)
- _TS_TEST_FOR_CONFIGURE(jest jest.config.js)
-}
-
-module _TS_TEST_BASE: _BARE_UNIT {
- # ignore SRCS macro
- .ALIASES=SRCS=_NOOP_MACRO
- # use this parser to get module args in $MODULE_ARGS_RAW
- .ARGS_PARSER=Raw
- .NODE_TYPE=Program
-
-
- # .fake tells builder to not materialize it in results
- SET(MODULE_SUFFIX .ts_test.fake)
- # include processor works only for TS tag
- SET(MODULE_TAG TS)
- # we read erm-packages.json during configuration, so we have to include it to configuration cache key
- SET_APPEND(_MAKEFILE_INCLUDE_LIKE_DEPS ${ARCADIA_ROOT}/$ERM_PACKAGES_PATH)
-
- # parse module args
- _TS_TEST_FOR_ARGS($MODULE_ARGS_RAW)
-
- # we don't want to have TS outputs for tests
- DISABLE(TS_CONFIG_DEDUCE_OUT)
-}
-
-macro _TS_TEST_FOR_ARGS(FOR_MOD, RELATIVE?"${CURDIR}":"${ARCADIA_ROOT}") {
- # we read testing modules' package.json during configuration,
- # so we have to include it to configuration cache key
- SET_APPEND(_MAKEFILE_INCLUDE_LIKE_DEPS $RELATIVE/$FOR_MOD/package.json)
- _SET_TS_TEST_FOR_VARS($FOR_MOD)
-}
-
-macro _SETUP_EXTRACT_NODE_MODULES_RECIPE(FOR_PATH) {
- DEPENDS(devtools/frontend_build_platform/nots/recipes/extract_node_modules)
- USE_RECIPE(devtools/frontend_build_platform/nots/recipes/extract_node_modules/recipe $FOR_PATH workspace_node_modules.tar)
-}
-
-macro _SETUP_EXTRACT_PEER_TARS_RECIPE(FOR_PATH) {
- DEPENDS(devtools/frontend_build_platform/nots/recipes/extract_peer_tars)
- USE_RECIPE(devtools/frontend_build_platform/nots/recipes/extract_peer_tars/recipe $FOR_PATH)
-}
-
-
-### @usage: TS_TEST_CONFIG(Path)
-###
-### Macro sets the path to configuration file of the test runner.
-###
-### - Path - path to the config file.
-macro TS_TEST_CONFIG(Path) {
- SET(TS_TEST_CONFIG_PATH $Path)
-}
-
-
-_TS_TEST_SRCS_VALUE=
-_TS_TEST_EXTRA_SRCS_VALUE=
-### @usage: TS_TEST_SRCS(DIRS...)
-###
-### Macro to define directories where the test source files should be located.
-###
-### - DIRS... - directories.
-macro TS_TEST_SRCS(DIRS...) {
- _GLOB(_TS_TEST_SRCS_VALUE ${suf=/**/*.$TS_TEST_EXTENSION:DIRS})
- SRCS($_TS_TEST_SRCS_VALUE)
-
- _GLOB(_TS_TEST_EXTRA_SRCS_VALUE ${suf=$TS_TEST_EXTRA_SRCS_MASK:DIRS})
- SRCS($_TS_TEST_EXTRA_SRCS_VALUE)
-}
-
-
-_TS_TEST_DATA_VALUE=
-_TS_TEST_DATA_DIRS_RENAME_VALUE=
-### @usage: TS_TEST_DATA([RENAME] GLOBS...)
-###
-### Macro to add tests data (i.e. snapshots) used in testing to a bindir from curdir.
-### Creates symbolic links to directories of files found by the specified globs.
-###
-### Parameters:
-### - RENAME - adds ability to rename paths for tests data from curdir to bindir.
-### For example if your tested module located on "module" path and tests data in "module/tests_data".
-### Then you can be able to rename "tests_data" folder to something else - `RENAME tests_data:example`.
-### As a result in your bindir will be created folder - "module/example" which is a symbolic link on "module/tests_data" in curdir.
-### It is possible to specify multiple renaming rules in the following format "dir1:dir2;dir3/foo:dir4/bar", where "dir1" and "dir3" folders in curdir.
-### - GLOBS... - globs to tests data files, symbolic links will be created to their folders. For example - "tests_data/**/*".
-macro TS_TEST_DATA(RENAME="", GLOBS...) {
- _GLOB(_TS_TEST_DATA_VALUE $GLOBS)
- SET(_TS_TEST_DATA_DIRS_RENAME_VALUE $RENAME)
-}
diff --git a/build/conf/ts/ts_vite_bundle.conf b/build/conf/ts/ts_vite_bundle.conf
deleted file mode 100644
index 8b6a610492..0000000000
--- a/build/conf/ts/ts_vite_bundle.conf
+++ /dev/null
@@ -1,66 +0,0 @@
-# VITE_ROOT is defined by _PEERDIR_TS_RESOURCE(vite)
-VITE_ROOT=
-VITE_OUTPUT_DIR=dist
-VITE_CONFIG_PATH=vite.config.ts
-
-TS_BUNDLE_VITE=$TOUCH_UNIT \
- && $_TS_FILES_COPY_CMD \
- && $ADD_VCS_INFO_FILE_CMD \
- && ${cwd:BINDIR} $NOTS_TOOL bundle-vite $NOTS_TOOL_BASE_ARGS \
- --moddir $MODDIR \
- --ts-config ${input:TS_CONFIG_PATH} \
- --node-modules-bundle $NOTS_TOOL_NODE_MODULES_BUNDLE $NODE_MODULES_BUNDLE_AS_OUTPUT ${hide:PEERS} \
- --vite-resource $VITE_ROOT \
- --vite-config ${input:VITE_CONFIG_PATH} \
- --vcs-info "${VCS_INFO_FILE}" \
- --output-dir ${VITE_OUTPUT_DIR} \
- ${input;hide:"package.json"} ${TS_CONFIG_FILES} $_AS_HIDDEN_INPUTS(IN $TS_INPUT_FILES) \
- ${output;hide:"package.json"} ${output;hide:"output.tar"} \
- ${kv;hide:"p TSVB"} ${kv;hide:"pc magenta"}
-
-### @usage: VITE_OUTPUT(DirName)
-###
-### Macro sets the output directory name for TS_VITE_BUNDLE module.
-###
-### - DirName - output directory name ("dist" by default).
-macro VITE_OUTPUT(DirName) {
- SET(VITE_OUTPUT_DIR $DirName)
-}
-
-### @usage: TS_VITE_BUNDLE([name])
-###
-### The Vite bundle, bundles JavaScript code.
-### Build results are packed as `output.tar`.
-###
-### @example
-###
-### TS_VITE_BUNDLE()
-### SRCS(src/index.ts)
-### END()
-###
-multimodule TS_VITE_BUNDLE {
- module BUILD: _TS_BASE_UNIT {
- .CMD=TS_BUNDLE_VITE
- .PEERDIRSELF=NODE_MODULES
- # epilogue is not inherited from TS_LIBRARY
- .EPILOGUE=_TS_CONFIG_EPILOGUE
-
- # by default multimodule overrides inherited MODULE_TAG to submodule name (BUILD in this case)
- # but we have to set it to TS for include processor to work
- SET(MODULE_TAG TS)
-
- _PEERDIR_TS_RESOURCE(vite)
- SET_APPEND(_MAKEFILE_INCLUDE_LIKE_DEPS ${CURDIR}/${TS_CONFIG_PATH} ${CURDIR}/package.json)
- SET(TS_CONFIG_DEDUCE_OUT no)
-
- _TS_GLOB()
- _TS_CONFIGURE($TS_CONFIG_PATH)
-
- # we should set NODE_MODULES_BUNDLE_AS_OUTPUT conditionally,
- # based on whether module has deps or doesn't have
- _SET_NODE_MODULES_BUNDLE_AS_OUTPUT()
- }
-
- module NODE_MODULES: _NODE_MODULES_BASE {
- }
-}
diff --git a/build/plugins/lib/nots/__init__.py b/build/plugins/lib/nots/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/build/plugins/lib/nots/__init__.py
+++ /dev/null
diff --git a/build/plugins/lib/nots/a.yaml b/build/plugins/lib/nots/a.yaml
deleted file mode 100644
index fefc8876d8..0000000000
--- a/build/plugins/lib/nots/a.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-service: frontend_build_platform
-title: Frontend build platform lib/nots
diff --git a/build/plugins/lib/nots/erm_json_lite.py b/build/plugins/lib/nots/erm_json_lite.py
deleted file mode 100644
index dee76302a0..0000000000
--- a/build/plugins/lib/nots/erm_json_lite.py
+++ /dev/null
@@ -1,102 +0,0 @@
-import json
-from functools import cmp_to_key
-
-from lib.nots.semver import Version, VersionRange
-
-
-class ErmJsonLite(object):
- """
- Basic implementation to read `erm-packages.json`.
-
- It doesn't use any models, works with only raw JSON types: lists, dicts, strings
- """
-
- class ResourceType(object):
- NPM_PACKAGE = "NPM_PACKAGE"
- NODE_JS = "NODE_JS"
-
- data = None
-
- @staticmethod
- def get_versions_of(er_resource):
- # type: (dict) -> list[Version]
- """
- Return all versions of the resource in ASC order (from older to latest)
- """
- unsorted = er_resource.get("versions").keys()
- # We have to sort because in python 2 the order of keys in a dict is not guaranteed
- versions = sorted(unsorted, key=cmp_to_key(Version.cmp))
-
- return [Version.from_str(v) for v in versions]
-
- @classmethod
- def load(cls, path):
- # type: (str) -> ErmJsonLite
- erm_json = cls()
-
- with open(path) as f:
- erm_json.data = dict()
- for k, v in json.load(f).items():
- # Ignore comments (when key starts with `_`), used for banner
- if not k.startswith("_"):
- erm_json.data[k] = v
-
- return erm_json
-
- def get_resource(self, resource_name):
- # type: (str) -> dict
- """
- Return resource by his name
- """
- er_resource = self.data.get(resource_name)
- if not er_resource:
- raise Exception("Requested resource {} is not a toolchain item".format(resource_name))
-
- return er_resource
-
- def get_sb_resources(self, resource_name, version):
- # type: (str, Version) -> list[dict]
- """
- Return a list of SB resources for ER version
- """
- er_resource = self.get_resource(resource_name)
-
- return er_resource.get("versions").get(str(version)).get("resources")
-
- def is_resource_multiplatform(self, resource_name):
- # type: (str) -> bool
- """
- Return True if resource is multiplatform, False otherwise
- """
- er_resource = self.get_resource(resource_name)
-
- return er_resource.get("multiplatform", False)
-
- def list_npm_packages(self):
- # type: () -> list[str]
- """
- Returns a list of the names of the npm tools used in the toolchain
- """
- result = []
- for resource_name, resource in self.data.items():
- if resource.get("type") == self.ResourceType.NPM_PACKAGE:
- result.append(resource_name)
-
- return result
-
- def select_version_of(self, resource_name, range_str=None):
- # type: (str, str|None) -> Version|None
- er_resource = self.get_resource(resource_name)
-
- if range_str is None:
- return Version.from_str(er_resource.get("default"))
-
- version_range = VersionRange.from_str(range_str)
-
- # assuming the version list is sorted from the lowest to the highest version,
- # we stop the loop as early as possible and hence return the lowest compatible version
- for version in self.get_versions_of(er_resource):
- if version_range.is_satisfied_by(version):
- return version
-
- return None
diff --git a/build/plugins/lib/nots/package_manager/__init__.py b/build/plugins/lib/nots/package_manager/__init__.py
deleted file mode 100644
index 570231e1e9..0000000000
--- a/build/plugins/lib/nots/package_manager/__init__.py
+++ /dev/null
@@ -1,7 +0,0 @@
-from .pnpm import PnpmPackageManager
-from .base import PackageJson, constants, utils, bundle_node_modules, extract_node_modules
-
-
-manager = PnpmPackageManager
-
-__all__ = ["PackageJson", "constants", "utils", "bundle_node_modules", "extract_node_modules", "manager"]
diff --git a/build/plugins/lib/nots/package_manager/base/__init__.py b/build/plugins/lib/nots/package_manager/base/__init__.py
deleted file mode 100644
index 022d4a960e..0000000000
--- a/build/plugins/lib/nots/package_manager/base/__init__.py
+++ /dev/null
@@ -1,20 +0,0 @@
-from . import constants, utils
-from .lockfile import BaseLockfile, LockfilePackageMeta, LockfilePackageMetaInvalidError
-from .package_json import PackageJson
-from .package_manager import BasePackageManager, PackageManagerError, PackageManagerCommandError
-from .node_modules_bundler import bundle_node_modules, extract_node_modules
-
-
-__all__ = [
- "constants",
- "utils",
- "BaseLockfile",
- "LockfilePackageMeta",
- "LockfilePackageMetaInvalidError",
- "BasePackageManager",
- "PackageManagerError",
- "PackageManagerCommandError",
- "PackageJson",
- "bundle_node_modules",
- "extract_node_modules",
-]
diff --git a/build/plugins/lib/nots/package_manager/base/constants.py b/build/plugins/lib/nots/package_manager/base/constants.py
deleted file mode 100644
index 2c17523314..0000000000
--- a/build/plugins/lib/nots/package_manager/base/constants.py
+++ /dev/null
@@ -1,8 +0,0 @@
-BUILD_DIRNAME = "build"
-BUNDLE_DIRNAME = "bundle"
-OUTPUT_TAR_FILENAME = "output.tar"
-NODE_MODULES_BUNDLE_FILENAME = "node_modules.tar"
-NODE_MODULES_DIRNAME = "node_modules"
-NODE_MODULES_WORKSPACE_BUNDLE_FILENAME = "workspace_node_modules.tar"
-NPM_REGISTRY_URL = "http://npm.yandex-team.ru"
-PACKAGE_JSON_FILENAME = "package.json"
diff --git a/build/plugins/lib/nots/package_manager/base/lockfile.py b/build/plugins/lib/nots/package_manager/base/lockfile.py
deleted file mode 100644
index 10cfcc0fc6..0000000000
--- a/build/plugins/lib/nots/package_manager/base/lockfile.py
+++ /dev/null
@@ -1,71 +0,0 @@
-import os
-
-from abc import ABCMeta, abstractmethod
-from six import add_metaclass
-
-
-class LockfilePackageMeta(object):
- """
- Basic struct representing package meta from lockfile.
- """
-
- __slots__ = ("tarball_url", "sky_id", "integrity", "integrity_algorithm", "tarball_path")
-
- @staticmethod
- def from_str(s):
- return LockfilePackageMeta(*s.strip().split(" "))
-
- def __init__(self, tarball_url, sky_id, integrity, integrity_algorithm):
- # http://npm.yandex-team.ru/@scope%2fname/-/name-0.0.1.tgz
- parts = tarball_url.split("/")
-
- self.tarball_url = tarball_url
- self.sky_id = sky_id
- self.integrity = integrity
- self.integrity_algorithm = integrity_algorithm
- self.tarball_path = "/".join(parts[-3:]) # @scope%2fname/-/name-0.0.1.tgz
-
- def to_str(self):
- return " ".join([self.tarball_url, self.sky_id, self.integrity, self.integrity_algorithm])
-
-
-class LockfilePackageMetaInvalidError(RuntimeError):
- pass
-
-
-@add_metaclass(ABCMeta)
-class BaseLockfile(object):
- @classmethod
- def load(cls, path):
- """
- :param path: lockfile path
- :type path: str
- :rtype: BaseLockfile
- """
- pj = cls(path)
- pj.read()
-
- return pj
-
- def __init__(self, path):
- if not os.path.isabs(path):
- raise TypeError("Absolute path required, given: {}".format(path))
-
- self.path = path
- self.data = None
-
- @abstractmethod
- def read(self):
- pass
-
- @abstractmethod
- def write(self, path=None):
- pass
-
- @abstractmethod
- def get_packages_meta(self, no_files):
- pass
-
- @abstractmethod
- def update_tarball_resolutions(self, fn):
- pass
diff --git a/build/plugins/lib/nots/package_manager/base/node_modules_bundler.py b/build/plugins/lib/nots/package_manager/base/node_modules_bundler.py
deleted file mode 100644
index c835c4d7ca..0000000000
--- a/build/plugins/lib/nots/package_manager/base/node_modules_bundler.py
+++ /dev/null
@@ -1,66 +0,0 @@
-import os
-import tarfile
-
-from io import BytesIO
-
-from .utils import build_nm_path
-
-
-PEERS_DIR = ".peers"
-PEERS_INDEX = "index"
-
-
-def bundle_node_modules(build_root, peers, node_modules_path, bundle_path):
- """
- Creates node_modules bundle.
- Bundle contains node_modules directory, peers' node_modules directories,
- and index file with the list of added peers (\\n delimited).
- :param build_root: arcadia build root
- :type build_root: str
- :param peers: list of peers (arcadia root related)
- :type peers: list of str
- :param node_modules_path: node_modules path
- :type node_modules_path: str
- :param bundle_path: tarball path
- :type bundle_path: str
- """
- with tarfile.open(bundle_path, "w") as tf:
- tf.add(node_modules_path, arcname=".")
-
- # Peers' node_modules.
- added_peers = []
- for p in peers:
- peer_nm_path = build_nm_path(os.path.join(build_root, p))
- peer_bundled_nm_path = build_nm_path(os.path.join(PEERS_DIR, p))
- if not os.path.isdir(peer_nm_path):
- continue
- tf.add(peer_nm_path, arcname=peer_bundled_nm_path)
- added_peers.append(p)
-
- # Peers index.
- peers_index = "\n".join(added_peers)
- ti = tarfile.TarInfo(name=os.path.join(PEERS_DIR, PEERS_INDEX))
- ti.size = len(peers_index)
- tf.addfile(ti, BytesIO(peers_index.encode()))
-
-
-def extract_node_modules(build_root, node_modules_path, bundle_path):
- """
- Extracts node_modules bundle.
- :param build_root: arcadia build root
- :type build_root: str
- :param node_modules_path: node_modules path
- :type node_modules_path: str
- :param bundle_path: tarball path
- :type bundle_path: str
- """
- with tarfile.open(bundle_path) as tf:
- tf.extractall(node_modules_path)
-
- peers = open(os.path.join(node_modules_path, PEERS_DIR, PEERS_INDEX)).read().split("\n")
- for p in peers:
- if not p:
- continue
- bundled_nm_path = build_nm_path(os.path.join(node_modules_path, PEERS_DIR, p))
- nm_path = build_nm_path(os.path.join(build_root, p))
- os.rename(bundled_nm_path, nm_path)
diff --git a/build/plugins/lib/nots/package_manager/base/package_json.py b/build/plugins/lib/nots/package_manager/base/package_json.py
deleted file mode 100644
index d99b1e8254..0000000000
--- a/build/plugins/lib/nots/package_manager/base/package_json.py
+++ /dev/null
@@ -1,198 +0,0 @@
-import json
-import logging
-import os
-
-from six import iteritems
-
-from .utils import build_pj_path
-
-logger = logging.getLogger(__name__)
-
-
-class PackageJsonWorkspaceError(RuntimeError):
- pass
-
-
-class PackageJson(object):
- DEP_KEY = "dependencies"
- DEV_DEP_KEY = "devDependencies"
- PEER_DEP_KEY = "peerDependencies"
- OPT_DEP_KEY = "optionalDependencies"
- DEP_KEYS = (DEP_KEY, DEV_DEP_KEY, PEER_DEP_KEY, OPT_DEP_KEY)
-
- WORKSPACE_SCHEMA = "workspace:"
-
- @classmethod
- def load(cls, path):
- """
- :param path: package.json path
- :type path: str
- :rtype: PackageJson
- """
- pj = cls(path)
- pj.read()
-
- return pj
-
- def __init__(self, path):
- if not os.path.isabs(path):
- raise TypeError("Absolute path required, given: {}".format(path))
-
- self.path = path
- self.data = None
-
- def read(self):
- with open(self.path) as f:
- self.data = json.load(f)
-
- def write(self, path=None):
- """
- :param path: path to store package.json, defaults to original path
- :type path: str
- """
- if path is None:
- path = self.path
-
- directory = os.path.dirname(path)
- if not os.path.exists(directory):
- os.mkdir(directory)
-
- with open(path, "w") as f:
- json.dump(self.data, f, indent=2, ensure_ascii=False)
- f.write('\n') # it's better for diff algorithm in arc
- logger.debug("Written {}".format(path))
-
- def get_name(self):
- name = self.data.get("name")
-
- if not name:
- name = self.path.replace("/", "-")
-
- return name
-
- def get_version(self):
- return self.data["version"]
-
- def get_description(self):
- return self.data.get("description")
-
- def get_nodejs_version(self):
- return self.data.get("engines", {}).get("node")
-
- def get_dep_specifier(self, dep_name):
- for name, spec in self.dependencies_iter():
- if dep_name == name:
- return spec
- return None
-
- def dependencies_iter(self):
- for key in self.DEP_KEYS:
- deps = self.data.get(key)
- if not deps:
- continue
-
- for name, spec in iteritems(deps):
- yield (name, spec)
-
- def has_dependencies(self):
- first_dep = next(self.dependencies_iter(), None)
- return first_dep is not None
-
- def bins_iter(self):
- bins = self.data.get("bin")
- if isinstance(bins, str):
- yield bins
- elif isinstance(bins, dict):
- for bin in bins.values():
- yield bin
-
- def get_workspace_dep_spec_paths(self):
- """
- Returns names and paths from specifiers of the defined workspace dependencies.
- :rtype: list of (str, str)
- """
- spec_paths = []
- schema = self.WORKSPACE_SCHEMA
- schema_len = len(schema)
-
- for name, spec in self.dependencies_iter():
- if not spec.startswith(schema):
- continue
-
- spec_path = spec[schema_len:]
- if not (spec_path.startswith(".") or spec_path.startswith("..")):
- raise PackageJsonWorkspaceError(
- "Expected relative path specifier for workspace dependency, but got '{}' for {} in {}".format(
- spec, name, self.path
- )
- )
-
- spec_paths.append((name, spec_path))
-
- return spec_paths
-
- def get_workspace_dep_paths(self, base_path=None):
- """
- Returns paths of the defined workspace dependencies.
- :param base_path: base path to resolve relative dep paths
- :type base_path: str
- :rtype: list of str
- """
- if base_path is None:
- base_path = os.path.dirname(self.path)
-
- return [os.path.normpath(os.path.join(base_path, p)) for _, p in self.get_workspace_dep_spec_paths()]
-
- def get_workspace_deps(self):
- """
- :rtype: list of PackageJson
- """
- ws_deps = []
- pj_dir = os.path.dirname(self.path)
-
- for name, rel_path in self.get_workspace_dep_spec_paths():
- dep_path = os.path.normpath(os.path.join(pj_dir, rel_path))
- dep_pj = PackageJson.load(build_pj_path(dep_path))
-
- if name != dep_pj.get_name():
- raise PackageJsonWorkspaceError(
- "Workspace dependency name mismatch, found '{}' instead of '{}' in {}".format(
- name, dep_pj.get_name(), self.path
- )
- )
-
- ws_deps.append(dep_pj)
-
- return ws_deps
-
- def get_workspace_map(self, ignore_self=False):
- """
- Returns absolute paths of the workspace dependencies (including transitive) mapped to package.json and depth.
- :param ignore_self: whether path of the current module will be excluded
- :type ignore_self: bool
- :rtype: dict of (PackageJson, int)
- """
- ws_deps = {}
- # list of (pj, depth)
- pj_queue = [(self, 0)]
-
- while len(pj_queue):
- (pj, depth) = pj_queue.pop()
- pj_dir = os.path.dirname(pj.path)
- if pj_dir in ws_deps:
- continue
-
- if not ignore_self or pj != self:
- ws_deps[pj_dir] = (pj, depth)
-
- for dep_pj in pj.get_workspace_deps():
- pj_queue.append((dep_pj, depth + 1))
-
- return ws_deps
-
- def get_dep_paths_by_names(self):
- """
- Returns dict of {dependency_name: dependency_path}
- """
- ws_map = self.get_workspace_map()
- return {pj.get_name(): path for path, (pj, _) in ws_map.items()}
diff --git a/build/plugins/lib/nots/package_manager/base/package_manager.py b/build/plugins/lib/nots/package_manager/base/package_manager.py
deleted file mode 100644
index 6b9faa56e8..0000000000
--- a/build/plugins/lib/nots/package_manager/base/package_manager.py
+++ /dev/null
@@ -1,155 +0,0 @@
-import os
-import sys
-import subprocess
-
-from abc import ABCMeta, abstractmethod
-from six import add_metaclass
-
-from .constants import NPM_REGISTRY_URL
-from .package_json import PackageJson
-from .utils import build_nm_path, build_pj_path
-
-
-class PackageManagerError(RuntimeError):
- pass
-
-
-class PackageManagerCommandError(PackageManagerError):
- def __init__(self, cmd, code, stdout, stderr):
- self.cmd = cmd
- self.code = code
- self.stdout = stdout
- self.stderr = stderr
-
- msg = "package manager exited with code {} while running {}:\n{}\n{}".format(code, cmd, stdout, stderr)
- super(PackageManagerCommandError, self).__init__(msg)
-
-
-@add_metaclass(ABCMeta)
-class BasePackageManager(object):
- def __init__(
- self,
- build_root,
- build_path,
- sources_path,
- nodejs_bin_path,
- script_path,
- contribs_path,
- module_path=None,
- sources_root=None,
- ):
- self.module_path = build_path[len(build_root) + 1 :] if module_path is None else module_path
- self.build_path = build_path
- self.sources_path = sources_path
- self.build_root = build_root
- self.sources_root = sources_path[: -len(self.module_path) - 1] if sources_root is None else sources_root
- self.nodejs_bin_path = nodejs_bin_path
- self.script_path = script_path
- self.contribs_path = contribs_path
-
- @classmethod
- def load_package_json(cls, path):
- """
- :param path: path to package.json
- :type path: str
- :rtype: PackageJson
- """
- return PackageJson.load(path)
-
- @classmethod
- def load_package_json_from_dir(cls, dir_path):
- """
- :param dir_path: path to directory with package.json
- :type dir_path: str
- :rtype: PackageJson
- """
- return cls.load_package_json(build_pj_path(dir_path))
-
- @classmethod
- @abstractmethod
- def load_lockfile(cls, path):
- pass
-
- @classmethod
- @abstractmethod
- def load_lockfile_from_dir(cls, dir_path):
- pass
-
- @abstractmethod
- def create_node_modules(self):
- pass
-
- @abstractmethod
- def calc_node_modules_inouts(self):
- pass
-
- @abstractmethod
- def extract_packages_meta_from_lockfiles(self, lf_paths):
- pass
-
- def get_local_peers_from_package_json(self):
- """
- Returns paths of direct workspace dependencies (source root related).
- :rtype: list of str
- """
- return self.load_package_json_from_dir(self.sources_path).get_workspace_dep_paths(base_path=self.module_path)
-
- def get_peers_from_package_json(self):
- """
- Returns paths of workspace dependencies (source root related).
- :rtype: list of str
- """
- pj = self.load_package_json_from_dir(self.sources_path)
- prefix_len = len(self.sources_root) + 1
-
- return [p[prefix_len:] for p in pj.get_workspace_map(ignore_self=True).keys()]
-
- def _exec_command(self, args, include_defaults=True, script_path=None):
- if not self.nodejs_bin_path:
- raise PackageManagerError("Unable to execute command: nodejs_bin_path is not configured")
-
- cmd = (
- [self.nodejs_bin_path, script_path or self.script_path]
- + args
- + (self._get_default_options() if include_defaults else [])
- )
- p = subprocess.Popen(
- cmd,
- cwd=self.build_path,
- stdin=None,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- )
- stdout, stderr = p.communicate()
-
- if p.returncode != 0:
- self._dump_debug_log()
-
- raise PackageManagerCommandError(cmd, p.returncode, stdout.decode("utf-8"), stderr.decode("utf-8"))
-
- def _nm_path(self, *parts):
- return os.path.join(build_nm_path(self.build_path), *parts)
-
- def _contrib_tarball_path(self, pkg):
- return os.path.join(self.contribs_path, pkg.tarball_path)
-
- def _contrib_tarball_url(self, pkg):
- return "file:" + self._contrib_tarball_path(pkg)
-
- def _get_default_options(self):
- return ["--registry", NPM_REGISTRY_URL]
-
- def _get_debug_log_path(self):
- return None
-
- def _dump_debug_log(self):
- log_path = self._get_debug_log_path()
-
- if not log_path:
- return
-
- try:
- with open(log_path) as f:
- sys.stderr.write("Package manager log {}:\n{}\n".format(log_path, f.read()))
- except Exception:
- sys.stderr.write("Failed to dump package manager log {}.\n".format(log_path))
diff --git a/build/plugins/lib/nots/package_manager/base/tests/package_json.py b/build/plugins/lib/nots/package_manager/base/tests/package_json.py
deleted file mode 100644
index ccf7d4f607..0000000000
--- a/build/plugins/lib/nots/package_manager/base/tests/package_json.py
+++ /dev/null
@@ -1,201 +0,0 @@
-import os
-import pytest
-
-from build.plugins.lib.nots.package_manager.base.package_json import PackageJson, PackageJsonWorkspaceError
-
-
-def test_get_name_exist():
- pj = PackageJson("/packages/foo/package.json")
- pj.data = {
- "name": "package-name",
- }
-
- name = pj.get_name()
-
- assert name == "package-name"
-
-
-def test_get_name_none():
- pj = PackageJson("/packages/foo/package.json")
- pj.data = {}
-
- name = pj.get_name()
-
- assert name == "packages-foo"
-
-
-def test_get_workspace_dep_spec_paths_ok():
- pj = PackageJson("/packages/foo/package.json")
- pj.data = {
- "dependencies": {
- "@yandex-int/bar": "workspace:../bar",
- },
- "devDependencies": {
- "@yandex-int/baz": "workspace:../baz",
- },
- }
-
- ws_dep_spec_paths = pj.get_workspace_dep_spec_paths()
-
- assert ws_dep_spec_paths == [
- ("@yandex-int/bar", "../bar"),
- ("@yandex-int/baz", "../baz"),
- ]
-
-
-def test_get_workspace_dep_spec_paths_invalid_path():
- pj = PackageJson("/packages/foo/package.json")
- pj.data = {
- "dependencies": {
- "@yandex-int/bar": "workspace:*",
- },
- }
-
- with pytest.raises(PackageJsonWorkspaceError) as e:
- pj.get_workspace_dep_spec_paths()
-
- assert (
- str(e.value)
- == "Expected relative path specifier for workspace dependency, but got 'workspace:*' for @yandex-int/bar in /packages/foo/package.json"
- )
-
-
-def test_get_workspace_dep_paths_ok():
- pj = PackageJson("/packages/foo/package.json")
- pj.data = {
- "dependencies": {
- "@yandex-int/bar": "workspace:../bar",
- },
- "devDependencies": {
- "@yandex-int/baz": "workspace:../baz",
- },
- }
-
- ws_dep_paths = pj.get_workspace_dep_paths()
-
- assert ws_dep_paths == [
- "/packages/bar",
- "/packages/baz",
- ]
-
-
-def test_get_dep_specifier():
- pj = PackageJson("/packages/foo/package.json")
- pj.data = {
- "dependencies": {
- "jestify": "0.0.1",
- "eslint": ">= 7.27.0",
- },
- "devDependencies": {
- "jest": "27.1.0",
- "eslinting": "0.0.2",
- },
- }
-
- jest_spec = pj.get_dep_specifier("jest")
- assert jest_spec == "27.1.0", "Got unexpected jest specifier: {}".format(jest_spec)
-
- eslint_spec = pj.get_dep_specifier("eslint")
- assert eslint_spec == ">= 7.27.0", "Got unexpected eslint specifier: {}".format(eslint_spec)
-
-
-def test_get_workspace_dep_paths_with_custom_base_path():
- pj = PackageJson("/packages/foo/package.json")
- pj.data = {
- "dependencies": {
- "@yandex-int/bar": "workspace:../bar",
- },
- "devDependencies": {
- "@yandex-int/baz": "workspace:../baz",
- },
- }
-
- ws_dep_paths = pj.get_workspace_dep_paths(base_path="custom/dir")
-
- assert ws_dep_paths == [
- "custom/bar",
- "custom/baz",
- ]
-
-
-def test_get_workspace_deps_ok():
- pj = PackageJson("/packages/foo/package.json")
- pj.data = {
- "dependencies": {
- "@yandex-int/bar": "workspace:../bar",
- },
- "devDependencies": {
- "@yandex-int/baz": "workspace:../baz",
- },
- }
-
- def load_mock(cls, path):
- p = PackageJson(path)
- p.data = {
- "name": "@yandex-int/{}".format(os.path.basename(os.path.dirname(path))),
- }
- return p
-
- PackageJson.load = classmethod(load_mock)
-
- ws_deps = pj.get_workspace_deps()
-
- assert len(ws_deps) == 2
- assert ws_deps[0].path == "/packages/bar/package.json"
- assert ws_deps[1].path == "/packages/baz/package.json"
-
-
-def test_get_workspace_deps_with_wrong_name():
- pj = PackageJson("/packages/foo/package.json")
- pj.data = {
- "dependencies": {
- "@yandex-int/bar": "workspace:../bar",
- },
- }
-
- def load_mock(cls, path):
- p = PackageJson(path)
- p.data = {
- "name": "@shouldbe/{}".format(os.path.basename(os.path.dirname(path))),
- }
- return p
-
- PackageJson.load = classmethod(load_mock)
-
- with pytest.raises(PackageJsonWorkspaceError) as e:
- pj.get_workspace_deps()
-
- assert (
- str(e.value)
- == "Workspace dependency name mismatch, found '@yandex-int/bar' instead of '@shouldbe/bar' in /packages/foo/package.json"
- )
-
-
-def test_get_workspace_map_ok():
- pj = PackageJson("/packages/foo/package.json")
- pj.data = {
- "dependencies": {
- "@yandex-int/bar": "workspace:../bar",
- },
- }
-
- def load_mock(cls, path):
- name = os.path.basename(os.path.dirname(path))
- p = PackageJson(path)
- p.data = {
- "name": "@yandex-int/{}".format(name),
- "dependencies": ({"@yandex-int/qux": "workspace:../qux"} if name == "bar" else {}),
- }
- return p
-
- PackageJson.load = classmethod(load_mock)
-
- ws_map = pj.get_workspace_map()
-
- assert len(ws_map) == 3
- assert ws_map["/packages/foo"][0].path == "/packages/foo/package.json"
- assert ws_map["/packages/foo"][1] == 0
- assert ws_map["/packages/bar"][0].path == "/packages/bar/package.json"
- assert ws_map["/packages/bar"][1] == 1
- assert ws_map["/packages/qux"][0].path == "/packages/qux/package.json"
- assert ws_map["/packages/qux"][1] == 2
diff --git a/build/plugins/lib/nots/package_manager/base/tests/utils.py b/build/plugins/lib/nots/package_manager/base/tests/utils.py
deleted file mode 100644
index 4287beec47..0000000000
--- a/build/plugins/lib/nots/package_manager/base/tests/utils.py
+++ /dev/null
@@ -1,15 +0,0 @@
-from build.plugins.lib.nots.package_manager.base import utils
-
-
-def test_extract_package_name_from_path():
- happy_checklist = [
- ("@yandex-int/foo-bar-baz/some/path/inside/the/package", "@yandex-int/foo-bar-baz"),
- ("@yandex-int/foo-bar-buzz", "@yandex-int/foo-bar-buzz"),
- ("package-wo-scope", "package-wo-scope"),
- ("p", "p"),
- ("", ""),
- ]
-
- for item in happy_checklist:
- package_name = utils.extract_package_name_from_path(item[0])
- assert package_name == item[1]
diff --git a/build/plugins/lib/nots/package_manager/base/tests/ya.make b/build/plugins/lib/nots/package_manager/base/tests/ya.make
deleted file mode 100644
index 1bece69c33..0000000000
--- a/build/plugins/lib/nots/package_manager/base/tests/ya.make
+++ /dev/null
@@ -1,14 +0,0 @@
-PY23_TEST()
-
-OWNER(g:frontend-build-platform)
-
-TEST_SRCS(
- package_json.py
- utils.py
-)
-
-PEERDIR(
- build/plugins/lib/nots/package_manager/base
-)
-
-END()
diff --git a/build/plugins/lib/nots/package_manager/base/utils.py b/build/plugins/lib/nots/package_manager/base/utils.py
deleted file mode 100644
index 017bf4ca41..0000000000
--- a/build/plugins/lib/nots/package_manager/base/utils.py
+++ /dev/null
@@ -1,29 +0,0 @@
-import os
-
-from .constants import PACKAGE_JSON_FILENAME, NODE_MODULES_DIRNAME, NODE_MODULES_BUNDLE_FILENAME
-
-
-def s_rooted(p):
- return os.path.join("$S", p)
-
-
-def b_rooted(p):
- return os.path.join("$B", p)
-
-
-def build_pj_path(p):
- return os.path.join(p, PACKAGE_JSON_FILENAME)
-
-
-def build_nm_path(p):
- return os.path.join(p, NODE_MODULES_DIRNAME)
-
-
-def build_nm_bundle_path(p):
- return os.path.join(p, NODE_MODULES_BUNDLE_FILENAME)
-
-
-def extract_package_name_from_path(p):
- # if we have scope prefix then we are using the first two tokens, otherwise - only the first one
- parts = p.split("/", 2)
- return "/".join(parts[:2]) if p.startswith("@") else parts[0]
diff --git a/build/plugins/lib/nots/package_manager/base/ya.make b/build/plugins/lib/nots/package_manager/base/ya.make
deleted file mode 100644
index 4b7f22f05a..0000000000
--- a/build/plugins/lib/nots/package_manager/base/ya.make
+++ /dev/null
@@ -1,23 +0,0 @@
-PY23_LIBRARY()
-
-OWNER(g:frontend-build-platform)
-
-PY_SRCS(
- __init__.py
- constants.py
- lockfile.py
- node_modules_bundler.py
- package_json.py
- package_manager.py
- utils.py
-)
-
-PEERDIR(
- contrib/python/six
-)
-
-END()
-
-RECURSE_FOR_TESTS(
- tests
-)
diff --git a/build/plugins/lib/nots/package_manager/pnpm/__init__.py b/build/plugins/lib/nots/package_manager/pnpm/__init__.py
deleted file mode 100644
index b3a3c20c02..0000000000
--- a/build/plugins/lib/nots/package_manager/pnpm/__init__.py
+++ /dev/null
@@ -1,12 +0,0 @@
-from . import constants
-from .lockfile import PnpmLockfile
-from .package_manager import PnpmPackageManager
-from .workspace import PnpmWorkspace
-
-
-__all__ = [
- "constants",
- "PnpmLockfile",
- "PnpmPackageManager",
- "PnpmWorkspace",
-]
diff --git a/build/plugins/lib/nots/package_manager/pnpm/constants.py b/build/plugins/lib/nots/package_manager/pnpm/constants.py
deleted file mode 100644
index e84a78c55e..0000000000
--- a/build/plugins/lib/nots/package_manager/pnpm/constants.py
+++ /dev/null
@@ -1,2 +0,0 @@
-PNPM_WS_FILENAME = "pnpm-workspace.yaml"
-PNPM_LOCKFILE_FILENAME = "pnpm-lock.yaml"
diff --git a/build/plugins/lib/nots/package_manager/pnpm/lockfile.py b/build/plugins/lib/nots/package_manager/pnpm/lockfile.py
deleted file mode 100644
index 5e55a6f661..0000000000
--- a/build/plugins/lib/nots/package_manager/pnpm/lockfile.py
+++ /dev/null
@@ -1,151 +0,0 @@
-import base64
-import binascii
-import yaml
-import os
-
-from six.moves.urllib import parse as urlparse
-from six import iteritems
-
-from ..base import PackageJson, BaseLockfile, LockfilePackageMeta, LockfilePackageMetaInvalidError
-
-
-class PnpmLockfile(BaseLockfile):
- IMPORTER_KEYS = PackageJson.DEP_KEYS + ("specifiers",)
-
- def read(self):
- with open(self.path, "r") as f:
- self.data = yaml.load(f, Loader=yaml.CSafeLoader)
-
- def write(self, path=None):
- """
- :param path: path to store lockfile, defaults to original path
- :type path: str
- """
- if path is None:
- path = self.path
-
- with open(path, "w") as f:
- yaml.dump(self.data, f, Dumper=yaml.CSafeDumper)
-
- def get_packages_meta(self, no_files):
- """
- Extracts packages meta from lockfile.
- :rtype: list of LockfilePackageMeta
- """
- packages = self.data.get("packages", {})
-
- return map(lambda x: _parse_package_meta(x[0], x[1], no_files), iteritems(packages))
-
- def update_tarball_resolutions(self, fn):
- """
- :param fn: maps `LockfilePackageMeta` instance to new `resolution.tarball` value
- :type fn: lambda
- """
- packages = self.data.get("packages", {})
-
- for key, meta in iteritems(packages):
- meta["resolution"]["tarball"] = fn(_parse_package_meta(key, meta, no_files=False))
- packages[key] = meta
-
- def get_importers(self):
- """
- Returns "importers" section from the lockfile or creates similar structure from "dependencies" and "specifiers".
- :rtype: dict of dict of dict of str
- """
- importers = self.data.get("importers")
- if importers is not None:
- return importers
-
- importer = {k: self.data[k] for k in self.IMPORTER_KEYS if k in self.data}
-
- return {".": importer} if importer else {}
-
- def merge(self, lf):
- """
- Merges two lockfiles:
- 1. Converts the lockfile to monorepo-like lockfile with "importers" section instead of "dependencies" and "specifiers".
- 2. Merges `lf`'s dependencies and specifiers to importers.
- 3. Merges `lf`'s packages to the lockfile.
- :param lf: lockfile to merge
- :type lf: PnpmLockfile
- """
- importers = self.get_importers()
- build_path = os.path.dirname(self.path)
-
- for [importer, imports] in iteritems(lf.get_importers()):
- importer_path = os.path.normpath(os.path.join(os.path.dirname(lf.path), importer))
- importer_rel_path = os.path.relpath(importer_path, build_path)
- importers[importer_rel_path] = imports
-
- self.data["importers"] = importers
-
- for k in self.IMPORTER_KEYS:
- self.data.pop(k, None)
-
- packages = self.data.get("packages", {})
- for k, v in iteritems(lf.data.get("packages", {})):
- if k not in packages:
- packages[k] = v
- self.data["packages"] = packages
-
-
-def _parse_package_meta(key, meta, no_files):
- """
- :param key: uniq package key from lockfile
- :type key: string
- :param meta: package meta dict from lockfile
- :type meta: dict
- :rtype: LockfilePackageMetaInvalidError
- """
- try:
- tarball_url = _parse_tarball_url(meta["resolution"]["tarball"], no_files)
- sky_id = _parse_sky_id_from_tarball_url(meta["resolution"]["tarball"])
- integrity_algorithm, integrity = _parse_package_integrity(meta["resolution"]["integrity"])
- except KeyError as e:
- raise TypeError("Invalid package meta for key {}, missing {} key".format(key, e))
- except LockfilePackageMetaInvalidError as e:
- raise TypeError("Invalid package meta for key {}, parse error: {}".format(key, e))
-
- return LockfilePackageMeta(tarball_url, sky_id, integrity, integrity_algorithm)
-
-
-def _parse_tarball_url(tarball_url, no_files):
- if tarball_url.startswith("file:") and no_files:
- raise LockfilePackageMetaInvalidError("tarball cannot point to a file, got {}".format(tarball_url))
- return tarball_url.split("?")[0]
-
-
-def _parse_sky_id_from_tarball_url(tarball_url):
- """
- :param tarball_url: tarball url
- :type tarball_url: string
- :rtype: string
- """
- if tarball_url.startswith("file:"):
- return ""
-
- rbtorrent_param = urlparse.parse_qs(urlparse.urlparse(tarball_url).query).get("rbtorrent")
-
- if rbtorrent_param is None:
- raise LockfilePackageMetaInvalidError("Missing rbtorrent param in tarball url {}".format(tarball_url))
-
- return "rbtorrent:{}".format(rbtorrent_param[0])
-
-
-def _parse_package_integrity(integrity):
- """
- Returns tuple of algorithm and hash (hex).
- :param integrity: package integrity in format "{algo}-{base64_of_hash}"
- :type integrity: string
- :rtype: (str, str)
- """
- algo, hash_b64 = integrity.split("-", 1)
-
- try:
- hash_hex = binascii.hexlify(base64.b64decode(hash_b64))
- except TypeError as e:
- raise LockfilePackageMetaInvalidError(
- "Invalid package integrity encoding, integrity: {}, error: {}".format(integrity, e)
- )
-
- return (algo, hash_hex)
diff --git a/build/plugins/lib/nots/package_manager/pnpm/package_manager.py b/build/plugins/lib/nots/package_manager/pnpm/package_manager.py
deleted file mode 100644
index 3f3e6a98b4..0000000000
--- a/build/plugins/lib/nots/package_manager/pnpm/package_manager.py
+++ /dev/null
@@ -1,244 +0,0 @@
-import os
-import yaml
-
-from six import iteritems
-
-from ..base import BasePackageManager, PackageManagerError
-from ..base.utils import build_pj_path, build_nm_path, build_nm_bundle_path, s_rooted, b_rooted
-from ..base.node_modules_bundler import bundle_node_modules
-from ..base.constants import NODE_MODULES_BUNDLE_FILENAME
-from .lockfile import PnpmLockfile
-from .workspace import PnpmWorkspace
-from .utils import build_lockfile_path, build_ws_config_path
-
-
-class PnpmPackageManager(BasePackageManager):
- _STORE_NM_PATH = os.path.join(".pnpm", "store")
- _VSTORE_NM_PATH = os.path.join(".pnpm", "virtual-store")
- _STORE_VER = "v3"
- _PREBUILDER_PKG = "@yatool/prebuilder"
-
- @classmethod
- def load_lockfile(cls, path):
- """
- :param path: path to lockfile
- :type path: str
- :rtype: PnpmLockfile
- """
- return PnpmLockfile.load(path)
-
- @classmethod
- def load_lockfile_from_dir(cls, dir_path):
- """
- :param dir_path: path to directory with lockfile
- :type dir_path: str
- :rtype: PnpmLockfile
- """
- return cls.load_lockfile(build_lockfile_path(dir_path))
-
- def create_node_modules(self):
- """
- Creates node_modules directory according to the lockfile.
- """
- ws = self._prepare_workspace()
- self._exec_command(
- [
- "install",
- "--offline",
- "--frozen-lockfile",
- "--store-dir",
- self._nm_path(self._STORE_NM_PATH),
- "--virtual-store-dir",
- self._nm_path(self._VSTORE_NM_PATH),
- "--no-verify-store-integrity",
- "--package-import-method",
- "hardlink",
- "--ignore-pnpmfile",
- "--ignore-scripts",
- "--strict-peer-dependencies",
- ]
- )
- self._run_apply_addons()
- self._fix_stores_in_modules_yaml()
-
- bundle_node_modules(
- build_root=self.build_root,
- node_modules_path=self._nm_path(),
- peers=ws.get_paths(base_path=self.module_path, ignore_self=True),
- bundle_path=NODE_MODULES_BUNDLE_FILENAME,
- )
-
- def calc_node_modules_inouts(self):
- """
- Returns input and output paths for command that creates `node_modules` bundle.
- Errors: errors catched while processing lockfiles
- Inputs:
- - source package.json and lockfile,
- - built package.jsons of all deps,
- - merged lockfiles and workspace configs of direct non-leave deps,
- - tarballs.
- Outputs:
- - merged lockfile,
- - generated workspace config,
- - created node_modules bundle.
- :rtype: (list of errors, list of str, list of str)
- """
- ins = [
- s_rooted(build_pj_path(self.module_path)),
- s_rooted(build_lockfile_path(self.module_path)),
- ]
- outs = [
- b_rooted(build_lockfile_path(self.module_path)),
- b_rooted(build_ws_config_path(self.module_path)),
- b_rooted(build_nm_bundle_path(self.module_path)),
- ]
-
- # Source lockfiles are used only to get tarballs info.
- src_lf_paths = [build_lockfile_path(self.sources_path)]
- pj = self.load_package_json_from_dir(self.sources_path)
-
- for [dep_src_path, (_, depth)] in iteritems(pj.get_workspace_map(ignore_self=True)):
- dep_mod_path = dep_src_path[len(self.sources_root) + 1 :]
- # pnpm requires all package.jsons.
- ins.append(b_rooted(build_pj_path(dep_mod_path)))
-
- dep_lf_src_path = build_lockfile_path(dep_src_path)
- if not os.path.isfile(dep_lf_src_path):
- # It is ok for leaves.
- continue
- src_lf_paths.append(dep_lf_src_path)
-
- if depth == 1:
- ins.append(b_rooted(build_ws_config_path(dep_mod_path)))
- ins.append(b_rooted(build_lockfile_path(dep_mod_path)))
-
- errors = []
- try:
- for pkg in self.extract_packages_meta_from_lockfiles(src_lf_paths):
- ins.append(b_rooted(self._contrib_tarball_path(pkg)))
- except Exception as e:
- errors.append(e)
- pass
-
- return (errors, ins, outs)
-
- def extract_packages_meta_from_lockfiles(self, lf_paths, no_files=False):
- """
- :type lf_paths: iterable of BaseLockfile
- :rtype: iterable of LockfilePackageMeta
- """
- tarballs = set()
- errors = []
-
- for lf_path in lf_paths:
- try:
- for pkg in self.load_lockfile(lf_path).get_packages_meta(no_files):
- if pkg.tarball_path not in tarballs:
- tarballs.add(pkg.tarball_path)
- yield pkg
- except Exception as e:
- errors.append("{}: {}".format(lf_path, e))
-
- if errors:
- raise PackageManagerError("Unable to process some lockfiles:\n{}".format("\n".join(errors)))
-
- def _prepare_workspace(self):
- """
- :rtype: PnpmWorkspace
- """
- pj = self._build_package_json()
- ws = PnpmWorkspace(build_ws_config_path(self.build_path))
- ws.set_from_package_json(pj)
- dep_paths = ws.get_paths(ignore_self=True)
- self._build_merged_workspace_config(ws, dep_paths)
- self._build_merged_lockfile(dep_paths)
-
- return ws
-
- def _build_package_json(self):
- """
- :rtype: PackageJson
- """
- pj = self.load_package_json_from_dir(self.sources_path)
-
- if not os.path.exists(self.build_path):
- os.makedirs(self.build_path, exist_ok=True)
-
- pj.path = build_pj_path(self.build_path)
- pj.write()
-
- return pj
-
- def _build_merged_lockfile(self, dep_paths):
- """
- :type dep_paths: list of str
- :rtype: PnpmLockfile
- """
- lf = self.load_lockfile_from_dir(self.sources_path)
- # Change to the output path for correct path calcs on merging.
- lf.path = build_lockfile_path(self.build_path)
-
- for dep_path in dep_paths:
- lf_path = build_lockfile_path(dep_path)
- if os.path.isfile(lf_path):
- lf.merge(self.load_lockfile(lf_path))
-
- lf.update_tarball_resolutions(lambda p: self._contrib_tarball_url(p))
- lf.write()
-
- def _build_merged_workspace_config(self, ws, dep_paths):
- """
- NOTE: This method mutates `ws`.
- :type ws: PnpmWorkspaceConfig
- :type dep_paths: list of str
- """
- for dep_path in dep_paths:
- ws_config_path = build_ws_config_path(dep_path)
- if os.path.isfile(ws_config_path):
- ws.merge(PnpmWorkspace.load(ws_config_path))
-
- ws.write()
-
- def _run_apply_addons(self):
- pj = self.load_package_json_from_dir(self.sources_path)
- prebuilder_version = pj.get_dep_specifier(self._PREBUILDER_PKG)
- if not prebuilder_version:
- return # prebuilder should be in deps
-
- self._exec_command(
- [
- "apply-addons",
- "--virtual-store",
- self._nm_path(self._VSTORE_NM_PATH),
- ],
- include_defaults=False,
- script_path=self._get_prebuilder_bin(),
- )
-
- def _fix_stores_in_modules_yaml(self):
- """
- Ensures that store paths are the same as would be after installing deps in the source dir.
- This is required to reuse `node_modules` after build.
- """
- with open(self._nm_path(".modules.yaml"), "r+") as f:
- data = yaml.load(f, Loader=yaml.CSafeLoader)
- # NOTE: pnpm requires absolute store path here.
- data["storeDir"] = os.path.join(build_nm_path(self.sources_path), self._STORE_NM_PATH, self._STORE_VER)
- data["virtualStoreDir"] = self._VSTORE_NM_PATH
- f.seek(0)
- yaml.dump(data, f, Dumper=yaml.CSafeDumper)
- f.truncate()
-
- def _get_default_options(self):
- return super(PnpmPackageManager, self)._get_default_options() + [
- "--stream",
- "--reporter",
- "append-only",
- "--no-color",
- ]
-
- def _get_debug_log_path(self):
- return self._nm_path(".pnpm-debug.log")
-
- def _get_prebuilder_bin(self):
- return self._nm_path(self._PREBUILDER_PKG, "build", "bin", "prebuilder.js")
diff --git a/build/plugins/lib/nots/package_manager/pnpm/tests/lockfile.py b/build/plugins/lib/nots/package_manager/pnpm/tests/lockfile.py
deleted file mode 100644
index 5985f0261e..0000000000
--- a/build/plugins/lib/nots/package_manager/pnpm/tests/lockfile.py
+++ /dev/null
@@ -1,326 +0,0 @@
-import pytest
-
-from build.plugins.lib.nots.package_manager.pnpm.lockfile import PnpmLockfile
-
-
-def test_lockfile_get_packages_meta_ok():
- lf = PnpmLockfile(path="/pnpm-lock.yaml")
- lf.data = {
- "packages": {
- "/@babel/cli/7.6.2_@babel+core@7.6.2": {
- "resolution": {
- "integrity": "sha512-JDZ+T/br9pPfT2lmAMJypJDTTTHM9ePD/ED10TRjRzJVdEVy+JB3iRlhzYmTt5YkNgHvxWGlUVnLtdv6ruiDrQ==",
- "tarball": "@babel%2fcli/-/cli-7.6.2.tgz?rbtorrent=cb1849da3e4947e56a8f6bde6a1ec42703ddd187",
- },
- },
- },
- }
-
- packages = list(lf.get_packages_meta())
- pkg = packages[0]
-
- assert len(packages) == 1
- assert pkg.name == "@babel/cli"
- assert pkg.version == "7.6.2"
- assert pkg.sky_id == "rbtorrent:cb1849da3e4947e56a8f6bde6a1ec42703ddd187"
- assert (
- pkg.integrity
- == b"24367e4ff6ebf693df4f696600c272a490d34d31ccf5e3c3fc40f5d13463473255744572f89077891961cd8993b796243601efc561a55159cbb5dbfaaee883ad"
- )
- assert pkg.integrity_algorithm == "sha512"
-
-
-def test_lockfile_get_packages_empty():
- lf = PnpmLockfile(path="/pnpm-lock.yaml")
- lf.data = {}
-
- assert len(list(lf.get_packages_meta())) == 0
-
-
-def test_package_meta_invalid_key():
- lf = PnpmLockfile(path="/pnpm-lock.yaml")
- lf.data = {
- "packages": {
- "in/valid": {},
- },
- }
-
- with pytest.raises(TypeError) as e:
- list(lf.get_packages_meta())
-
- assert str(e.value) == "Invalid package meta for key in/valid, parse error: Invalid package key"
-
-
-def test_package_meta_missing_resolution():
- lf = PnpmLockfile(path="/pnpm-lock.yaml")
- lf.data = {
- "packages": {
- "/valid/1.2.3": {},
- },
- }
-
- with pytest.raises(TypeError) as e:
- list(lf.get_packages_meta())
-
- assert str(e.value) == "Invalid package meta for key /valid/1.2.3, missing 'resolution' key"
-
-
-def test_package_meta_missing_tarball():
- lf = PnpmLockfile(path="/pnpm-lock.yaml")
- lf.data = {
- "packages": {
- "/valid/1.2.3": {
- "resolution": {},
- },
- },
- }
-
- with pytest.raises(TypeError) as e:
- list(lf.get_packages_meta())
-
- assert str(e.value) == "Invalid package meta for key /valid/1.2.3, missing 'tarball' key"
-
-
-def test_package_meta_missing_rbtorrent():
- lf = PnpmLockfile(path="/pnpm-lock.yaml")
- lf.data = {
- "packages": {
- "/valid/1.2.3": {
- "resolution": {
- "tarball": "valid-1.2.3.tgz",
- },
- },
- },
- }
-
- with pytest.raises(TypeError) as e:
- list(lf.get_packages_meta())
-
- assert (
- str(e.value)
- == "Invalid package meta for key /valid/1.2.3, parse error: Missing rbtorrent param in tarball url valid-1.2.3.tgz"
- )
-
-
-def test_lockfile_meta_file_tarball():
- lf = PnpmLockfile(path="/pnpm-lock.yaml")
- lf.data = {
- "packages": {
- "/@babel/cli/7.6.2": {
- "resolution": {
- "integrity": "sha512-JDZ+T/br9pPfT2lmAMJypJDTTTHM9ePD/ED10TRjRzJVdEVy+JB3iRlhzYmTt5YkNgHvxWGlUVnLtdv6ruiDrQ==",
- "tarball": "file:/some/abs/path.tgz",
- },
- },
- },
- }
-
- packages = list(lf.get_packages_meta())
- pkg = packages[0]
-
- assert len(packages) == 1
- assert pkg.name == "@babel/cli"
- assert pkg.version == "7.6.2"
- assert pkg.sky_id == ""
-
-
-def test_lockfile_update_tarball_resolutions_ok():
- lf = PnpmLockfile(path="/pnpm-lock.yaml")
- lf.data = {
- "packages": {
- "/@babel/cli/7.6.2_@babel+core@7.6.2": {
- "resolution": {
- "integrity": "sha512-JDZ+T/br9pPfT2lmAMJypJDTTTHM9ePD/ED10TRjRzJVdEVy+JB3iRlhzYmTt5YkNgHvxWGlUVnLtdv6ruiDrQ==",
- "tarball": "@babel%2fcli/-/cli-7.6.2.tgz?rbtorrent=cb1849da3e4947e56a8f6bde6a1ec42703ddd187",
- },
- },
- },
- }
-
- lf.update_tarball_resolutions(lambda p: p.name)
-
- assert lf.data["packages"]["/@babel/cli/7.6.2_@babel+core@7.6.2"]["resolution"]["tarball"] == "@babel/cli"
-
-
-def test_lockfile_merge():
- lf1 = PnpmLockfile(path="/foo/pnpm-lock.yaml")
- lf1.data = {
- "dependencies": {
- "a": "1.0.0",
- },
- "specifiers": {
- "a": "1.0.0",
- },
- "packages": {
- "/a/1.0.0": {},
- },
- }
-
- lf2 = PnpmLockfile(path="/bar/pnpm-lock.yaml")
- lf2.data = {
- "dependencies": {
- "b": "1.0.0",
- },
- "specifiers": {
- "b": "1.0.0",
- },
- "packages": {
- "/b/1.0.0": {},
- },
- }
-
- lf3 = PnpmLockfile(path="/another/baz/pnpm-lock.yaml")
- lf3.data = {
- "importers": {
- ".": {
- "dependencies": {
- "@a/qux": "link:../qux",
- "a": "1.0.0",
- },
- "specifiers": {
- "@a/qux": "workspace:../qux",
- "a": "1.0.0",
- },
- },
- "../qux": {
- "dependencies": {
- "b": "1.0.1",
- },
- "specifiers": {
- "b": "1.0.1",
- },
- },
- },
- "packages": {
- "/a/1.0.0": {},
- "/b/1.0.1": {},
- },
- }
-
- lf4 = PnpmLockfile(path="/another/quux/pnpm-lock.yaml")
- lf4.data = {
- "dependencies": {
- "@a/bar": "link:../../bar",
- },
- "specifiers": {
- "@a/bar": "workspace:../../bar",
- },
- }
-
- lf1.merge(lf2)
- lf1.merge(lf3)
- lf1.merge(lf4)
-
- assert lf1.data == {
- "importers": {
- ".": {
- "dependencies": {
- "a": "1.0.0",
- },
- "specifiers": {
- "a": "1.0.0",
- },
- },
- "../bar": {
- "dependencies": {
- "b": "1.0.0",
- },
- "specifiers": {
- "b": "1.0.0",
- },
- },
- "../another/baz": {
- "dependencies": {
- "@a/qux": "link:../qux",
- "a": "1.0.0",
- },
- "specifiers": {
- "@a/qux": "workspace:../qux",
- "a": "1.0.0",
- },
- },
- "../another/qux": {
- "dependencies": {
- "b": "1.0.1",
- },
- "specifiers": {
- "b": "1.0.1",
- },
- },
- "../another/quux": {
- "dependencies": {
- "@a/bar": "link:../../bar",
- },
- "specifiers": {
- "@a/bar": "workspace:../../bar",
- },
- },
- },
- "packages": {
- "/a/1.0.0": {},
- "/b/1.0.0": {},
- "/b/1.0.1": {},
- },
- }
-
-
-def test_lockfile_merge_dont_overrides_packages():
- lf1 = PnpmLockfile(path="/foo/pnpm-lock.yaml")
- lf1.data = {
- "dependencies": {
- "a": "1.0.0",
- },
- "specifiers": {
- "a": "1.0.0",
- },
- "packages": {
- "/a/1.0.0": {},
- },
- }
-
- lf2 = PnpmLockfile(path="/bar/pnpm-lock.yaml")
- lf2.data = {
- "dependencies": {
- "a": "1.0.0",
- "b": "1.0.0",
- },
- "specifiers": {
- "a": "1.0.0",
- "b": "1.0.0",
- },
- "packages": {
- "/a/1.0.0": {
- "overriden": True,
- },
- "/b/1.0.0": {},
- },
- }
-
- lf1.merge(lf2)
-
- assert lf1.data == {
- "importers": {
- ".": {
- "dependencies": {
- "a": "1.0.0",
- },
- "specifiers": {
- "a": "1.0.0",
- },
- },
- "../bar": {
- "dependencies": {
- "a": "1.0.0",
- "b": "1.0.0",
- },
- "specifiers": {
- "a": "1.0.0",
- "b": "1.0.0",
- },
- },
- },
- "packages": {
- "/a/1.0.0": {},
- "/b/1.0.0": {},
- },
- }
diff --git a/build/plugins/lib/nots/package_manager/pnpm/tests/workspace.py b/build/plugins/lib/nots/package_manager/pnpm/tests/workspace.py
deleted file mode 100644
index ffc010de88..0000000000
--- a/build/plugins/lib/nots/package_manager/pnpm/tests/workspace.py
+++ /dev/null
@@ -1,68 +0,0 @@
-from build.plugins.lib.nots.package_manager.base import PackageJson
-from build.plugins.lib.nots.package_manager.pnpm.workspace import PnpmWorkspace
-
-
-def test_workspace_get_paths():
- ws = PnpmWorkspace(path="/packages/foo/pnpm-workspace.yaml")
- ws.packages = set([".", "../bar", "../../another/baz"])
-
- assert sorted(ws.get_paths()) == [
- "/another/baz",
- "/packages/bar",
- "/packages/foo",
- ]
-
-
-def test_workspace_get_paths_with_custom_base_path_without_self():
- ws = PnpmWorkspace(path="/packages/foo/pnpm-workspace.yaml")
- ws.packages = set([".", "../bar", "../../another/baz"])
-
- assert sorted(ws.get_paths(base_path="some/custom/dir", ignore_self=True)) == [
- "some/another/baz",
- "some/custom/bar",
- ]
-
-
-def test_workspace_set_from_package_json():
- ws = PnpmWorkspace(path="/packages/foo/pnpm-workspace.yaml")
- pj = PackageJson(path="/packages/foo/package.json")
- pj.data = {
- "dependencies": {
- "@a/bar": "workspace:../bar",
- },
- "devDependencies": {
- "@a/baz": "workspace:../../another/baz",
- },
- "peerDependencies": {
- "@a/qux": "workspace:../../another/qux",
- },
- "optionalDependencies": {
- "@a/quux": "workspace:../../another/quux",
- },
- }
-
- ws.set_from_package_json(pj)
-
- assert sorted(ws.get_paths()) == [
- "/another/baz",
- "/another/quux",
- "/another/qux",
- "/packages/bar",
- "/packages/foo",
- ]
-
-
-def test_workspace_merge():
- ws1 = PnpmWorkspace(path="/packages/foo/pnpm-workspace.yaml")
- ws1.packages = set([".", "../bar", "../../another/baz"])
- ws2 = PnpmWorkspace(path="/another/baz/pnpm-workspace.yaml")
- ws2.packages = set([".", "../qux"])
-
- ws1.merge(ws2)
-
- assert sorted(ws1.get_paths()) == [
- "/another/baz",
- "/another/qux",
- "/packages/bar",
- "/packages/foo",
- ]
diff --git a/build/plugins/lib/nots/package_manager/pnpm/tests/ya.make b/build/plugins/lib/nots/package_manager/pnpm/tests/ya.make
deleted file mode 100644
index 44877dfc1b..0000000000
--- a/build/plugins/lib/nots/package_manager/pnpm/tests/ya.make
+++ /dev/null
@@ -1,15 +0,0 @@
-PY23_TEST()
-
-OWNER(g:frontend-build-platform)
-
-TEST_SRCS(
- lockfile.py
- workspace.py
-)
-
-PEERDIR(
- build/plugins/lib/nots/package_manager/base
- build/plugins/lib/nots/package_manager/pnpm
-)
-
-END()
diff --git a/build/plugins/lib/nots/package_manager/pnpm/utils.py b/build/plugins/lib/nots/package_manager/pnpm/utils.py
deleted file mode 100644
index 1fa4291b9d..0000000000
--- a/build/plugins/lib/nots/package_manager/pnpm/utils.py
+++ /dev/null
@@ -1,11 +0,0 @@
-import os
-
-from .constants import PNPM_LOCKFILE_FILENAME, PNPM_WS_FILENAME
-
-
-def build_lockfile_path(p):
- return os.path.join(p, PNPM_LOCKFILE_FILENAME)
-
-
-def build_ws_config_path(p):
- return os.path.join(p, PNPM_WS_FILENAME)
diff --git a/build/plugins/lib/nots/package_manager/pnpm/workspace.py b/build/plugins/lib/nots/package_manager/pnpm/workspace.py
deleted file mode 100644
index e596e20a18..0000000000
--- a/build/plugins/lib/nots/package_manager/pnpm/workspace.py
+++ /dev/null
@@ -1,81 +0,0 @@
-import os
-import yaml
-
-
-class PnpmWorkspace(object):
- @classmethod
- def load(cls, path):
- ws = cls(path)
- ws.read()
-
- return ws
-
- def __init__(self, path):
- if not os.path.isabs(path):
- raise TypeError("Absolute path required, given: {}".format(path))
-
- self.path = path
- # NOTE: pnpm requires relative workspace paths.
- self.packages = set()
-
- def read(self):
- with open(self.path) as f:
- self.packages = set(yaml.load(f, Loader=yaml.CSafeLoader).get("packages", []))
-
- def write(self, path=None):
- if not path:
- path = self.path
-
- with open(path, "w") as f:
- data = {
- "packages": list(self.packages),
- }
- yaml.dump(data, f, Dumper=yaml.CSafeDumper)
-
- def get_paths(self, base_path=None, ignore_self=False):
- """
- Returns absolute paths of the workspace packages.
- :param base_path: base path to resolve relative dep paths
- :type base_path: str
- :param ignore_self: whether path of the current module will be excluded (if present)
- :type ignore_self: bool
- :rtype: list of str
- """
- if base_path is None:
- base_path = os.path.dirname(self.path)
-
- return [
- os.path.normpath(os.path.join(base_path, pkg_path))
- for pkg_path in self.packages
- if not ignore_self or pkg_path != "."
- ]
-
- def set_from_package_json(self, package_json):
- """
- Sets packages to "workspace" deps from given package.json.
- :param package_json: package.json of workspace
- :type package_json: PackageJson
- """
- if os.path.dirname(package_json.path) != os.path.dirname(self.path):
- raise TypeError(
- "package.json should be in workspace directory {}, given: {}".format(
- os.path.dirname(self.path), package_json.path
- )
- )
-
- self.packages = set(path for _, path in package_json.get_workspace_dep_spec_paths())
- # Add relative path to self.
- self.packages.add(".")
-
- def merge(self, ws):
- """
- Adds `ws`'s packages to the workspace.
- :param ws: workspace to merge
- :type ws: PnpmWorkspace
- """
- dir_path = os.path.dirname(self.path)
- ws_dir_path = os.path.dirname(ws.path)
-
- for p_rel_path in ws.packages:
- p_path = os.path.normpath(os.path.join(ws_dir_path, p_rel_path))
- self.packages.add(os.path.relpath(p_path, dir_path))
diff --git a/build/plugins/lib/nots/package_manager/pnpm/ya.make b/build/plugins/lib/nots/package_manager/pnpm/ya.make
deleted file mode 100644
index f57ae4a2ba..0000000000
--- a/build/plugins/lib/nots/package_manager/pnpm/ya.make
+++ /dev/null
@@ -1,24 +0,0 @@
-PY23_LIBRARY()
-
-OWNER(g:frontend-build-platform)
-
-PY_SRCS(
- __init__.py
- constants.py
- lockfile.py
- package_manager.py
- workspace.py
- utils.py
-)
-
-PEERDIR(
- build/plugins/lib/nots/package_manager/base
- contrib/python/PyYAML
- contrib/python/six
-)
-
-END()
-
-RECURSE_FOR_TESTS(
- tests
-)
diff --git a/build/plugins/lib/nots/package_manager/ya.make b/build/plugins/lib/nots/package_manager/ya.make
deleted file mode 100644
index 3ac1ea9103..0000000000
--- a/build/plugins/lib/nots/package_manager/ya.make
+++ /dev/null
@@ -1,14 +0,0 @@
-PY23_LIBRARY()
-
-OWNER(g:frontend-build-platform)
-
-PY_SRCS(
- __init__.py
-)
-
-PEERDIR(
- build/plugins/lib/nots/package_manager/base
- build/plugins/lib/nots/package_manager/pnpm
-)
-
-END()
diff --git a/build/plugins/lib/nots/semver/__init__.py b/build/plugins/lib/nots/semver/__init__.py
deleted file mode 100644
index be4319f9f3..0000000000
--- a/build/plugins/lib/nots/semver/__init__.py
+++ /dev/null
@@ -1,7 +0,0 @@
-from .semver import Version, Operator, VersionRange
-
-__all__ = [
- "Version",
- "Operator",
- "VersionRange",
-]
diff --git a/build/plugins/lib/nots/semver/semver.py b/build/plugins/lib/nots/semver/semver.py
deleted file mode 100644
index 1398da8586..0000000000
--- a/build/plugins/lib/nots/semver/semver.py
+++ /dev/null
@@ -1,244 +0,0 @@
-import re
-
-
-class Version:
- """
- This class is intended to provide utility methods to work with semver ranges.
- Right now it is limited to the simplest case: a ">=" operator followed by an exact version with no prerelease or build specification.
- Example: ">= 1.2.3"
- """
-
- @classmethod
- def from_str(cls, input):
- """
- :param str input: save exact formatted version e.g. 1.2.3
- :rtype: Version
- :raises: ValueError
- """
- parts = input.strip().split(".", 2)
- major = int(parts[0])
- minor = int(parts[1])
- patch = int(parts[2])
-
- return cls(major, minor, patch)
-
- STABLE_VERSION_RE = re.compile(r'^\d+\.\d+\.\d+$')
-
- @classmethod
- def is_stable(cls, v):
- """
- Verifies that the version is in a supported format.
-
- :param v:string with the version
- :return: bool
- """
- return cls.STABLE_VERSION_RE.match(v) is not None
-
- @classmethod
- def cmp(cls, a, b):
- """
- Compare two versions. Should be used with "cmp_to_key" wrapper in sorted(), min(), max()...
-
- For example:
- sorted(["1.2.3", "2.4.2", "1.2.7"], key=cmp_to_key(Version.cmp))
-
- :param a:string with version or Version instance
- :param b:string with version or Version instance
- :return: int
- :raises: ValueError
- """
- a_version = a if isinstance(a, cls) else cls.from_str(a)
- b_version = b if isinstance(b, cls) else cls.from_str(b)
-
- if a_version > b_version:
- return 1
- elif a_version < b_version:
- return -1
- else:
- return 0
-
- __slots__ = "_values"
-
- def __init__(self, major, minor, patch):
- """
- :param int major
- :param int minor
- :param int patch
- :raises ValueError
- """
- version_parts = {
- "major": major,
- "minor": minor,
- "patch": patch,
- }
-
- for name, value in version_parts.items():
- value = int(value)
- version_parts[name] = value
- if value < 0:
- raise ValueError("{!r} is negative. A version can only be positive.".format(name))
-
- self._values = (version_parts["major"], version_parts["minor"], version_parts["patch"])
-
- def __str__(self):
- return "{}.{}.{}".format(self._values[0], self._values[1], self._values[2])
-
- def __repr__(self):
- return '<Version({})>'.format(self)
-
- def __eq__(self, other):
- """
- :param Version|str other
- :rtype: bool
- """
- if isinstance(other, str):
- if self.is_stable(other):
- other = self.from_str(other)
- else:
- return False
-
- return self.as_tuple() == other.as_tuple()
-
- def __ne__(self, other):
- return not self == other
-
- def __gt__(self, other):
- """
- :param Version other
- :rtype: bool
- """
- return self.as_tuple() > other.as_tuple()
-
- def __ge__(self, other):
- """
- :param Version other
- :rtype: bool
- """
- return self.as_tuple() >= other.as_tuple()
-
- def __lt__(self, other):
- """
- :param Version other
- :rtype: bool
- """
- return self.as_tuple() < other.as_tuple()
-
- def __le__(self, other):
- """
- :param Version other
- :rtype: bool
- """
- return self.as_tuple() <= other.as_tuple()
-
- @property
- def major(self):
- """The major part of the version (read-only)."""
- return self._values[0]
-
- @major.setter
- def major(self, value):
- raise AttributeError("Attribute 'major' is readonly")
-
- @property
- def minor(self):
- """The minor part of the version (read-only)."""
- return self._values[1]
-
- @minor.setter
- def minor(self, value):
- raise AttributeError("Attribute 'minor' is readonly")
-
- @property
- def patch(self):
- """The patch part of the version (read-only)."""
- return self._values[2]
-
- @patch.setter
- def patch(self, value):
- raise AttributeError("Attribute 'patch' is readonly")
-
- def as_tuple(self):
- """
- :rtype: tuple
- """
- return self._values
-
-
-class Operator:
- EQ = "="
- GT = ">"
- GE = ">="
- LT = "<"
- LE = "<="
-
-
-class VersionRange:
- @classmethod
- def operator_is_ok(self, operator):
- return [Operator.GE, Operator.EQ, None].count(operator)
-
- @classmethod
- def from_str(cls, input):
- """
- :param str input
- :rtype: VersionRange
- :raises: ValueError
- """
- m = re.match(r"^\s*([<>=]+)?\s*(\d+\.\d+\.\d+)\s*$", input)
- res = m.groups() if m else None
- if not res or not cls.operator_is_ok(res[0]):
- raise ValueError(
- "Unsupported version range: '{}'. Currently we only support ranges with stable versions and GE / EQ: '>= 1.2.3' / '= 1.2.3' / '1.2.3'".format(
- input
- )
- )
-
- version = Version.from_str(res[1])
-
- return cls(res[0], version)
-
- __slots__ = ("_operator", "_version")
-
- def __init__(self, operator, version):
- """
- :param str operator
- :raises: ValueError
- """
- if not self.operator_is_ok(operator):
- raise ValueError("Unsupported range operator '{}'".format(operator))
-
- # None defaults to Operator.EQ
- self._operator = operator or Operator.EQ
- self._version = version
-
- @property
- def operator(self):
- """The comparison operator to be used (read-only)."""
- return self._operator
-
- @operator.setter
- def operator(self, value):
- raise AttributeError("Attribute 'operator' is readonly")
-
- @property
- def version(self):
- """Version to be used with the operator (read-only)."""
- return self._version
-
- @version.setter
- def version(self, value):
- raise AttributeError("Attribute 'version' is readonly")
-
- def is_satisfied_by(self, version):
- """
- :param Version version
- :rtype: bool
- :raises: ValueError
- """
- if self._operator == Operator.GE:
- return version >= self._version
-
- if self._operator == Operator.EQ:
- return version == self._version
-
- raise ValueError("Unsupported operator '{}'".format(self._operator))
diff --git a/build/plugins/lib/nots/semver/tests/test_version.py b/build/plugins/lib/nots/semver/tests/test_version.py
deleted file mode 100644
index e6c0e44225..0000000000
--- a/build/plugins/lib/nots/semver/tests/test_version.py
+++ /dev/null
@@ -1,269 +0,0 @@
-from functools import cmp_to_key
-
-from build.plugins.lib.nots.semver import Version
-
-
-def test_from_str():
- # arrange
- version_str = "1.2.3"
-
- # act
- version = Version.from_str(version_str)
-
- # assert
- assert version.major == 1
- assert version.minor == 2
- assert version.patch == 3
-
-
-def test_from_str_bad_version():
- # arrange
- version_str = "best version imaginable"
- error = None
-
- # act
- try:
- Version.from_str(version_str)
- except Exception as exception:
- error = exception
-
- # assert
- assert error is not None
-
-
-def test_is_stable_true():
- # arrange
- version_str = "1.2.3"
-
- # act + assert
- assert Version.is_stable(version_str)
-
-
-def test_is_stable_false():
- # arrange
- version_str = "1.2.3-beta1"
-
- # act + assert
- assert not Version.is_stable(version_str)
-
-
-def test_is_stable_incorrect():
- # arrange
- version_str = "v1.2.3"
-
- # act + assert
- assert not Version.is_stable(version_str)
-
-
-def test_cmp_lt():
- # arrange
- a = Version.from_str("1.2.3")
- b = Version.from_str("1.2.5")
-
- # act + assert
- assert Version.cmp(a, b) == -1
-
-
-def test_cmp_gt():
- # arrange
- a = Version.from_str("1.2.3")
- b = Version.from_str("1.2.2")
-
- # act + assert
- assert Version.cmp(a, b) == 1
-
-
-def test_cmp_eq():
- # arrange
- a = Version.from_str("1.2.3")
- b = Version.from_str("1.2.3")
-
- # act + assert
- assert Version.cmp(a, b) == 0
-
-
-def test_cmp_lt_str():
- # arrange
- a = "1.2.3"
- b = "1.2.5"
-
- # act + assert
- assert Version.cmp(a, b) == -1
-
-
-def test_cmp_gt_str():
- # arrange
- a = "1.2.3"
- b = "1.2.2"
-
- # act + assert
- assert Version.cmp(a, b) == 1
-
-
-def test_cmp_eq_str():
- # arrange
- a = "1.2.3"
- b = "1.2.3"
-
- # act + assert
- assert Version.cmp(a, b) == 0
-
-
-def test_cmp_usage_in_sorted_asc():
- # arrange
- unsorted = ["1.2.3", "2.4.2", "1.2.7"]
-
- # act + assert
- assert sorted(unsorted, key=cmp_to_key(Version.cmp)) == ["1.2.3", "1.2.7", "2.4.2"]
-
-
-def test_cmp_usage_in_sorted_desc():
- # arrange
- unsorted = ["1.2.3", "2.4.2", "1.2.7"]
-
- # act + assert
- assert sorted(unsorted, key=cmp_to_key(Version.cmp), reverse=True) == ["2.4.2", "1.2.7", "1.2.3"]
-
-
-def test_init_negative_numbers():
- # arrange
- major = 1
- minor = -2
- patch = 3
-
- error = None
-
- # act
- try:
- Version(major, minor, patch)
- except Exception as exception:
- error = exception
-
- # assert
- assert isinstance(error, ValueError)
- assert str(error) == "'minor' is negative. A version can only be positive."
-
-
-def test_eq():
- # arrange
- version_a = Version.from_str("1.2.3")
- version_b = Version.from_str("1.2.3")
-
- # act + assert
- assert version_a == version_b
-
-
-def test_eq_negative():
- # arrange
- version_a = Version.from_str("1.2.3")
- version_b = Version.from_str("3.2.1")
-
- # act + assert
- assert not version_a == version_b
-
-
-def test_eq_with_str():
- # arrange
- version = Version.from_str("1.2.3")
-
- # act + assert
- assert version == "1.2.3"
- assert not version == "1.2.4"
-
-
-def test_eq_with_invalid_str():
- # arrange
- version = Version.from_str("1.2.3")
-
- # act + assert
- assert not version == "bla-bla"
- assert not version == "1.2.3-beta"
-
-
-def test_ne():
- # arrange
- version_a = Version.from_str("3.2.1")
- version_b = Version.from_str("1.2.3")
-
- # act + assert
- assert version_a != version_b
-
-
-def test_ne_negative():
- # arrange
- version_a = Version.from_str("1.2.3")
- version_b = Version.from_str("1.2.3")
-
- # act + assert
- assert not version_a != version_b
-
-
-def test_ne_with_str():
- # arrange
- version = Version.from_str("1.2.3")
-
- # act + assert
- assert version != "1.2.4"
- assert not version != "1.2.3"
-
-
-def test_gt():
- # arrange
- version_a = Version.from_str("3.2.1")
- version_b = Version.from_str("1.2.3")
-
- # act + assert
- assert version_a > version_b
-
-
-def test_ge_equals():
- # arrange
- version_a = Version.from_str("1.2.3")
- version_b = Version.from_str("1.2.3")
-
- # act + assert
- assert version_a >= version_b
-
-
-def test_ge_exceeds():
- # arrange
- version_a = Version.from_str("3.2.1")
- version_b = Version.from_str("1.2.3")
-
- # act + assert
- assert version_a >= version_b
-
-
-def test_lt():
- # arrange
- version_a = Version.from_str("1.2.3")
- version_b = Version.from_str("3.2.1")
-
- # act + assert
- assert version_a < version_b
-
-
-def test_le_equals():
- # arrange
- version_a = Version.from_str("1.2.3")
- version_b = Version.from_str("1.2.3")
-
- # act + assert
- assert version_a <= version_b
-
-
-def test_le_is_less():
- # arrange
- version_a = Version.from_str("1.2.3")
- version_b = Version.from_str("3.2.1")
-
- # act + assert
- assert version_a <= version_b
-
-
-def test_to_tuple():
- # arrange
- version = Version.from_str("1.2.3")
-
- # act + assert
- assert version.as_tuple() == (1, 2, 3)
diff --git a/build/plugins/lib/nots/semver/tests/test_version_range.py b/build/plugins/lib/nots/semver/tests/test_version_range.py
deleted file mode 100644
index eb36d5d598..0000000000
--- a/build/plugins/lib/nots/semver/tests/test_version_range.py
+++ /dev/null
@@ -1,106 +0,0 @@
-from build.plugins.lib.nots.semver import Version, Operator, VersionRange
-
-
-def test_from_str():
- checklist = [
- (">= 1.2.3", VersionRange, Operator.GE),
- (">=1.2.3", VersionRange, Operator.GE),
- (">= 1.2.3", VersionRange, Operator.GE),
- (" >= 1.2.3 ", VersionRange, Operator.GE),
- ("= 1.2.3", VersionRange, Operator.EQ),
- ("=1.2.3", VersionRange, Operator.EQ),
- ("= 1.2.3", VersionRange, Operator.EQ),
- (" = 1.2.3 ", VersionRange, Operator.EQ),
- (" 1.2.3", VersionRange, Operator.EQ),
- ("1.2.3", VersionRange, Operator.EQ),
- (" 1.2.3", VersionRange, Operator.EQ),
- (" 1.2.3 ", VersionRange, Operator.EQ),
- ]
-
- for range_str, expected_class, expected_operator in checklist:
- range = VersionRange.from_str(range_str)
-
- assert isinstance(range, expected_class), f"unexpected class for '{range_str}': '{type(range)}'"
- assert range.operator == expected_operator, f"unexpected operator for '{range_str}': '{range.operator}'"
-
-
-def test_from_str_error():
- error_template = "Unsupported version range: '{}'. Currently we only support ranges with stable versions and GE / EQ: '>= 1.2.3' / '= 1.2.3' / '1.2.3'"
- checklist = [
- (r"¯\_(ツ)_/¯", ValueError, error_template),
- ("<= 1.2.3", ValueError, error_template),
- ("<=1.2.3", ValueError, error_template),
- ("<= 1.2.3", ValueError, error_template),
- (" <= 1.2.3 ", ValueError, error_template),
- ("< 1.2.3", ValueError, error_template),
- ("<1.2.3", ValueError, error_template),
- ("< 1.2.3", ValueError, error_template),
- (" < 1.2.3 ", ValueError, error_template),
- ("> 1.2.3", ValueError, error_template),
- (">1.2.3", ValueError, error_template),
- ("> 1.2.3", ValueError, error_template),
- (" > 1.2.3 ", ValueError, error_template),
- ("0.0.1-beta", ValueError, error_template),
- ]
-
- for range_str, expected_class, expected_msg_template in checklist:
- try:
- VersionRange.from_str(range_str)
- except Exception as exception:
- error = exception
-
- assert isinstance(error, expected_class), f"unexpected error class for '{range_str}': '{type(error)}'"
- assert str(error) == expected_msg_template.format(
- range_str
- ), f"unexpected error message for '{range_str}': '{error}'"
-
-
-def test_init():
- checklist = [
- (Operator.GE, "1.2.3", Operator.GE, Version(1, 2, 3)),
- (Operator.GE, " 1.2.3 ", Operator.GE, Version(1, 2, 3)),
- (Operator.GE, "0.0.1", Operator.GE, Version(0, 0, 1)),
- (Operator.EQ, "1.2.3", Operator.EQ, Version(1, 2, 3)),
- (Operator.EQ, " 1.2.3 ", Operator.EQ, Version(1, 2, 3)),
- (Operator.EQ, "0.0.1", Operator.EQ, Version(0, 0, 1)),
- (None, "1.2.3", Operator.EQ, Version(1, 2, 3)),
- (None, " 1.2.3 ", Operator.EQ, Version(1, 2, 3)),
- (None, "0.0.1", Operator.EQ, Version(0, 0, 1)),
- ]
-
- for operator_provided, version_provided, expected_operator, expected_version in checklist:
- range = VersionRange(operator_provided, Version.from_str(version_provided))
-
- assert (
- range.operator == expected_operator
- ), f"unexpected operator for '{operator_provided}', '{version_provided}': '{range.operator}'"
- assert (
- range.version == expected_version
- ), f"unexpected result version for '{operator_provided}', '{version_provided}': '{range.version}'"
-
-
-def test_is_satisfied():
- checklist = [
- (">= 1.2.3", "1.2.3", True),
- (">= 1.2.3", "1.2.4", True),
- (">= 1.2.3", "1.3.0", True),
- (">= 1.2.3", "2.0.0", True),
- (">= 1.2.3", "5.8.2", True),
- (">= 1.2.3", "1.2.2", False),
- (">= 1.2.3", "0.100.200", False),
- ("= 1.2.3", "1.2.3", True),
- ("1.2.3", "1.2.3", True),
- ("1.2.3", "1.2.2", False),
- ("1.2.3", "1.3.3", False),
- ("1.2.3", "2.2.3", False),
- ("12345.45634.456234", "12345.45634.456234", True),
- ("0.0.0", "0.0.0", True),
- ]
-
- for range_provided, version_provided, expected_result in checklist:
- version = Version.from_str(version_provided)
- range = VersionRange.from_str(range_provided)
-
- assert (
- range.is_satisfied_by(version) == expected_result
- ), f"Unexpected is_satisfied_by result for '{range_provided}', '{version_provided}': {(not expected_result)}"
diff --git a/build/plugins/lib/nots/semver/tests/ya.make b/build/plugins/lib/nots/semver/tests/ya.make
deleted file mode 100644
index b7605505f3..0000000000
--- a/build/plugins/lib/nots/semver/tests/ya.make
+++ /dev/null
@@ -1,14 +0,0 @@
-PY3TEST()
-
-OWNER(g:frontend-build-platform)
-
-PEERDIR(
- build/plugins/lib/nots/semver
-)
-
-TEST_SRCS(
- test_version_range.py
- test_version.py
-)
-
-END()
diff --git a/build/plugins/lib/nots/semver/ya.make b/build/plugins/lib/nots/semver/ya.make
deleted file mode 100644
index 7d2be228f2..0000000000
--- a/build/plugins/lib/nots/semver/ya.make
+++ /dev/null
@@ -1,14 +0,0 @@
-PY23_LIBRARY()
-
-OWNER(g:frontend-build-platform)
-
-PY_SRCS(
- __init__.py
- semver.py
-)
-
-END()
-
-RECURSE_FOR_TESTS(
- tests
-)
diff --git a/build/plugins/lib/nots/typescript/__init__.py b/build/plugins/lib/nots/typescript/__init__.py
deleted file mode 100644
index e0b3ee901c..0000000000
--- a/build/plugins/lib/nots/typescript/__init__.py
+++ /dev/null
@@ -1,10 +0,0 @@
-from .ts_config import DEFAULT_TS_CONFIG_FILE, TsConfig
-from .ts_errors import TsError, TsValidationError
-
-
-__all__ = [
- "DEFAULT_TS_CONFIG_FILE",
- "TsConfig",
- "TsError",
- "TsValidationError",
-]
diff --git a/build/plugins/lib/nots/typescript/tests/test_ts_config.py b/build/plugins/lib/nots/typescript/tests/test_ts_config.py
deleted file mode 100644
index 9cd3a7a184..0000000000
--- a/build/plugins/lib/nots/typescript/tests/test_ts_config.py
+++ /dev/null
@@ -1,169 +0,0 @@
-import pytest
-
-from build.plugins.lib.nots.typescript import TsConfig, TsValidationError
-
-
-def test_ts_config_validate_valid():
- cfg = TsConfig(path="/tsconfig.json")
- cfg.data = {
- "compilerOptions": {
- "rootDir": "./src",
- "outDir": "./build",
- },
- }
-
- cfg.validate()
-
-
-def test_ts_config_validate_empty():
- cfg = TsConfig(path="/tsconfig.json")
-
- with pytest.raises(TsValidationError) as e:
- cfg.validate()
-
- assert e.value.errors == [
- "'rootDir' option is required",
- "'outDir' option is required",
- ]
-
-
-def test_ts_config_validate_invalid_common():
- cfg = TsConfig(path="/tsconfig.json")
- cfg.data = {
- "compilerOptions": {
- "preserveSymlinks": True,
- "rootDirs": [],
- "outFile": "./foo.js",
- },
- "references": [],
- "files": [],
- "include": [],
- "exclude": [],
- }
-
- with pytest.raises(TsValidationError) as e:
- cfg.validate()
-
- assert e.value.errors == [
- "'rootDir' option is required",
- "'outDir' option is required",
- "'outFile' option is not supported",
- "'preserveSymlinks' option is not supported due to pnpm limitations",
- "'rootDirs' option is not supported, relative imports should have single root",
- "'files' option is not supported, use 'include'",
- "composite builds are not supported, use peerdirs in ya.make instead of 'references' option",
- ]
-
-
-def test_ts_config_validate_invalid_subdirs():
- cfg = TsConfig(path="/foo/tsconfig.json")
- cfg.data = {
- "compilerOptions": {
- "rootDir": "/bar/src",
- "outDir": "../bar/build",
- },
- }
-
- with pytest.raises(TsValidationError) as e:
- cfg.validate()
-
- assert e.value.errors == [
- "'outDir' should be a subdirectory of the module",
- ]
-
-
-def test_ts_config_compiler_options():
- cfg = TsConfig(path="/tsconfig.json")
-
- assert cfg.compiler_option("invalid") is None
-
- cfg.data = {
- "compilerOptions": {
- "rootDir": "src",
- },
- }
-
- assert cfg.compiler_option("rootDir") == "src"
-
-
-class TestTsConfigMerge:
- def test_merge_paths(self):
- # arrange
- cfg_main = TsConfig(path="/foo/tsconfig.json")
- cfg_main.data = {"compilerOptions": {"paths": {"path1": ["src/path1"], "path2": ["src/path2"]}}}
-
- cfg_common = TsConfig(path="/foo/tsconfig.common.json")
- cfg_common.data = {
- "compilerOptions": {"paths": {"path0": ["src/path0"]}},
- }
-
- # act
- cfg_main.merge(".", cfg_common)
-
- # assert
- assert cfg_main.data == {
- "compilerOptions": {"paths": {"path1": ["src/path1"], "path2": ["src/path2"]}},
- }
-
- def test_create_compiler_options(self):
- # arrange
- cfg_main = TsConfig(path="/foo/tsconfig.json")
- cfg_main.data = {}
-
- cfg_common = TsConfig(path="/foo/config/tsconfig.common.json")
- cfg_common.data = {
- "compilerOptions": {
- "moduleResolution": "node",
- },
- }
-
- # act
- cfg_main.merge("config", cfg_common)
-
- # assert
- assert cfg_main.data == {
- "compilerOptions": {
- "moduleResolution": "node",
- },
- }
-
- def test_merge_compiler_options(self):
- # arrange
- cfg_main = TsConfig(path="/foo/tsconfig.json")
- cfg_main.data = {
- "compilerOptions": {
- "esModuleInterop": True,
- "moduleResolution": "nodenext",
- "rootDir": "./src",
- },
- "extraField1": False,
- "sameField": False,
- }
-
- cfg_common = TsConfig(path="/foo/config/tsconfig.common.json")
- cfg_common.data = {
- "compilerOptions": {
- "moduleResolution": "node",
- "outDir": "./out",
- "strict": True,
- },
- "extraField2": True,
- "sameField": True,
- }
-
- # act
- cfg_main.merge("config", cfg_common)
-
- # assert
- assert cfg_main.data == {
- "compilerOptions": {
- "esModuleInterop": True, # own value
- "moduleResolution": "nodenext", # replaced value
- "outDir": "config/out", # resolved path
- "rootDir": "./src", # own path value (untouched)
- "strict": True, # inherited value
- },
- "extraField1": False, # own root field
- "extraField2": True, # inherited root field
- "sameField": False, # prefer own value
- }
diff --git a/build/plugins/lib/nots/typescript/tests/test_ts_glob.py b/build/plugins/lib/nots/typescript/tests/test_ts_glob.py
deleted file mode 100644
index 9d38a8d80f..0000000000
--- a/build/plugins/lib/nots/typescript/tests/test_ts_glob.py
+++ /dev/null
@@ -1,75 +0,0 @@
-from build.plugins.lib.nots.typescript.ts_glob import ts_glob, TsGlobConfig
-
-
-class TestTsGlobIncluding:
- ts_glob_config = TsGlobConfig(
- root_dir="src", out_dir="build", include=["src/module_a/**/*", "src/module_b/**/*", "src/module_x"]
- )
-
- def test_dir_include(self):
- # arrange
- all_files = [
- "src/module_x/index.ts",
- ]
-
- # act + arrange
- assert ts_glob(self.ts_glob_config, all_files) == [
- "src/module_x/index.ts",
- ]
-
- def test_deep_include(self):
- # arrange
- all_files = [
- "src/module_a/index.ts",
- "src/module_b/index.ts",
- "src/module_c/index.ts",
- ]
-
- # act + arrange
- assert ts_glob(self.ts_glob_config, all_files) == [
- "src/module_a/index.ts",
- "src/module_b/index.ts",
- ]
-
-
-class TestTsGlobExcluding:
- ts_glob_config = TsGlobConfig(root_dir="src", out_dir="build", include=["src/**/*"])
-
- def test_only_in_root_dir(self):
- # arrange
- all_files = [
- "CHANGELOG.md",
- "fake-src/one-more-src.ts",
- "src/index.ts",
- ]
-
- # act + assert
- assert ts_glob(self.ts_glob_config, all_files) == ["src/index.ts"]
-
- def test_exclude_out_dir(self):
- # arrange
- all_files = ["build/index.js"]
-
- # act + assert
- assert ts_glob(self.ts_glob_config, all_files) == []
-
- def test_exclude_out_dir_none(self):
- # arrange
- all_files = ["build/index.js"]
- ts_glob_config = TsGlobConfig(root_dir=".", out_dir=None)
-
- # act + assert
- assert ts_glob(ts_glob_config, all_files) == ["build/index.js"]
-
- def test_complex(self):
- # arrange
- all_files = [
- "CHANGELOG.md",
- "fake-src/one-more-src.ts",
- "src/baz.ts",
- "src/index.ts",
- "src/required_file.ts",
- ]
-
- # act + assert
- assert ts_glob(self.ts_glob_config, all_files) == ["src/baz.ts", "src/index.ts", "src/required_file.ts"]
diff --git a/build/plugins/lib/nots/typescript/tests/ya.make b/build/plugins/lib/nots/typescript/tests/ya.make
deleted file mode 100644
index 20fc215686..0000000000
--- a/build/plugins/lib/nots/typescript/tests/ya.make
+++ /dev/null
@@ -1,14 +0,0 @@
-PY23_TEST()
-
-OWNER(g:frontend-build-platform)
-
-TEST_SRCS(
- test_ts_config.py
- test_ts_glob.py
-)
-
-PEERDIR(
- build/plugins/lib/nots/typescript
-)
-
-END()
diff --git a/build/plugins/lib/nots/typescript/ts_config.py b/build/plugins/lib/nots/typescript/ts_config.py
deleted file mode 100644
index afe7578013..0000000000
--- a/build/plugins/lib/nots/typescript/ts_config.py
+++ /dev/null
@@ -1,252 +0,0 @@
-import copy
-import json
-import os
-
-from .ts_errors import TsError, TsValidationError
-from .ts_glob import ts_glob, TsGlobConfig
-from ..package_manager.base import utils
-
-DEFAULT_TS_CONFIG_FILE = "tsconfig.json"
-
-
-class RootFields:
- extends = 'extends'
-
- exclude = 'exclude'
- files = 'files'
- include = 'include'
-
- compilerOptions = 'compilerOptions'
-
- PATH_LIST_FIELDS = {
- exclude,
- files,
- include,
- }
-
-
-class CompilerOptionsFields:
- baseUrl = 'baseUrl'
- outDir = 'outDir'
- rootDir = 'rootDir'
-
- PATH_FIELDS = {
- baseUrl,
- outDir,
- rootDir,
- }
-
-
-class TsConfig(object):
- @classmethod
- def load(cls, path):
- """
- :param path: tsconfig.json path
- :type path: str
- :rtype: TsConfig
- """
- tsconfig = cls(path)
- tsconfig.read()
-
- return tsconfig
-
- def __init__(self, path):
- if not os.path.isabs(path):
- raise TypeError("Absolute path required, given: {}".format(path))
-
- self.path = path
- self.data = {}
-
- def read(self):
- try:
- with open(self.path) as f:
- self.data = json.load(f)
- except Exception as e:
- raise TsError("Failed to read tsconfig {}: {}".format(self.path, e))
-
- def merge(self, rel_path, base_tsconfig):
- # type: (TsConfig, str, TsConfig) -> None
- """
- :param rel_path: relative path to the configuration file we are merging in.
- It is required to set the relative paths correctly.
-
- :param base_tsconfig: base TsConfig we are merging with our TsConfig instance
- """
- if not base_tsconfig.data:
- return
-
- # 'data' from the file in 'extends'
- base_data = copy.deepcopy(base_tsconfig.data)
-
- def relative_path(p):
- return os.path.normpath(os.path.join(rel_path, p))
-
- for root_field, root_value in base_data.items():
- # extends
- if root_field == RootFields.extends:
- # replace itself to its own `extends` (for multi level extends)
- self.data[RootFields.extends] = relative_path(root_value)
-
- # exclude, files, include
- elif root_field in RootFields.PATH_LIST_FIELDS:
- if root_field not in self.data:
- self.data[root_field] = [relative_path(p) for p in root_value]
-
- # compilerOptions
- elif root_field == RootFields.compilerOptions:
- for option, option_value in root_value.items():
- is_path_field = option in CompilerOptionsFields.PATH_FIELDS
-
- if not self.has_compiler_option(option):
- new_value = relative_path(option_value) if is_path_field else option_value
- self.set_compiler_option(option, new_value)
-
- # other fields (just copy if it has not existed)
- elif root_field not in self.data:
- self.data[root_field] = root_value
- pass
-
- def inline_extend(self, dep_paths):
- """
- Merges the tsconfig parameters from configuration file referred by "extends" if any.
- Relative paths are adjusted, current parameter values are prioritized higer than
- those coming from extension file (according to TSC mergin rules).
- Returns list of file paths for config files merged into the current configuration
- :param dep_paths: dict of dependency names to their paths
- :type dep_paths: dict
- :rtype: list of str
- """
- ext_value = self.data.get(RootFields.extends)
- if not ext_value:
- return []
-
- if ext_value.startswith("."):
- base_config_path = ext_value
-
- else:
- dep_name = utils.extract_package_name_from_path(ext_value)
- # the rest part is the ext config path
- file_path_start = len(dep_name) + 1
- file_path = ext_value[file_path_start:]
- dep_path = dep_paths.get(dep_name)
- if dep_path is None:
- raise Exception(
- "referenceing from {}, data: {}\n: Dependency '{}' not found in dep_paths: {}".format(
- self.path, str(self.data), dep_name, dep_paths
- )
- )
- base_config_path = os.path.join(dep_path, file_path)
-
- rel_path = os.path.dirname(base_config_path)
- tsconfig_curdir_path = os.path.join(os.path.dirname(self.path), base_config_path)
- if os.path.isdir(tsconfig_curdir_path):
- base_config_path = os.path.join(base_config_path, DEFAULT_TS_CONFIG_FILE)
-
- # processing the base file recursively
- base_config = TsConfig.load(os.path.join(os.path.dirname(self.path), base_config_path))
- paths = [base_config_path] + base_config.inline_extend(dep_paths)
-
- self.merge(rel_path, base_config)
- del self.data[RootFields.extends]
-
- return paths
-
- def get_or_create_compiler_options(self):
- """
- Returns ref to the "compilerOptions" dict.
- :rtype: dict
- """
- if RootFields.compilerOptions not in self.data:
- self.data[RootFields.compilerOptions] = {}
-
- return self.data[RootFields.compilerOptions]
-
- def compiler_option(self, name, default=None):
- """
- :param name: option key
- :type name: str
- :param default: default value
- :type default: mixed
- :rtype: mixed
- """
- return self.get_or_create_compiler_options().get(name, default)
-
- def has_compiler_option(self, name):
- # type: (str) -> bool
- compiler_options = self.data.get(RootFields.compilerOptions, {})
-
- return name in compiler_options
-
- def set_compiler_option(self, name, value):
- # type: (str, Any) -> None
- compiler_options = self.get_or_create_compiler_options()
- compiler_options[name] = value
-
- def validate(self):
- """
- Checks whether the config is compatible with current toolchain.
- """
- opts = self.get_or_create_compiler_options()
- errors = []
- root_dir = opts.get(CompilerOptionsFields.rootDir)
- out_dir = opts.get(CompilerOptionsFields.outDir)
- config_dir = os.path.dirname(self.path)
-
- def is_mod_subdir(p):
- return not os.path.isabs(p) and os.path.normpath(os.path.join(config_dir, p)).startswith(config_dir)
-
- if root_dir is None:
- errors.append("'rootDir' option is required")
-
- if out_dir is None:
- errors.append("'outDir' option is required")
- elif not is_mod_subdir(out_dir):
- errors.append("'outDir' should be a subdirectory of the module")
-
- if opts.get("outFile") is not None:
- errors.append("'outFile' option is not supported")
-
- if opts.get("preserveSymlinks"):
- errors.append("'preserveSymlinks' option is not supported due to pnpm limitations")
-
- if opts.get("rootDirs") is not None:
- errors.append("'rootDirs' option is not supported, relative imports should have single root")
-
- if self.data.get("files") is not None:
- errors.append("'files' option is not supported, use 'include'")
-
- if self.data.get("references") is not None:
- errors.append("composite builds are not supported, use peerdirs in ya.make instead of 'references' option")
-
- if len(errors):
- raise TsValidationError(self.path, errors)
-
- def write(self, path=None, indent=None):
- """
- :param path: tsconfig path, defaults to original path
- :type path: str
- """
- if path is None:
- path = self.path
-
- with open(path, "w") as f:
- json.dump(self.data, f, indent=indent)
-
- def filter_files(self, all_files):
- # type: (list[str]) -> list[str]
- """
- Filters all the files by the rules from this tsconig.json. The result will be used as input entries in `ya make`.
-
- Known limits:
-
- - `files` nots supported, use `include` (see `self.validate()`)
- - `exclude` not implemented, because `tsc` still uses "excluded" files as declaration files (for typing and referencing)
- """
-
- ts_glob_config = TsGlobConfig(
- root_dir=self.compiler_option(CompilerOptionsFields.rootDir),
- out_dir=self.compiler_option(CompilerOptionsFields.outDir),
- include=self.data.get(RootFields.include),
- )
-
- return ts_glob(ts_glob_config, all_files)
diff --git a/build/plugins/lib/nots/typescript/ts_errors.py b/build/plugins/lib/nots/typescript/ts_errors.py
deleted file mode 100644
index 105851d9ec..0000000000
--- a/build/plugins/lib/nots/typescript/ts_errors.py
+++ /dev/null
@@ -1,10 +0,0 @@
-class TsError(RuntimeError):
- pass
-
-
-class TsValidationError(TsError):
- def __init__(self, path, errors):
- self.path = path
- self.errors = errors
-
- super(TsValidationError, self).__init__("Invalid tsconfig {}:\n{}".format(path, "\n".join(errors)))
diff --git a/build/plugins/lib/nots/typescript/ts_glob.py b/build/plugins/lib/nots/typescript/ts_glob.py
deleted file mode 100644
index b81e8774a5..0000000000
--- a/build/plugins/lib/nots/typescript/ts_glob.py
+++ /dev/null
@@ -1,77 +0,0 @@
-import fnmatch
-import os.path
-
-
-class TsGlobConfig:
- def __init__(self, root_dir, out_dir=None, include=None):
- # type: (TsGlobConfig, str, str, list[str], list[str]) -> None
-
- self.root_dir = root_dir # Required
- self.out_dir = out_dir
-
- self.include = include or ["**/*"]
-
-
-def __path_to_match_rule(path):
- # type: (str) -> str
-
- # already a rule
-
- # convert "**/*" to "*" (python compatible with fnmatch)
- if path.endswith('**/*'):
- return path[:-3] # /**/* -> /*
-
- if path.endswith("*") or ('*' in path or '?' in path):
- return path
-
- # special cases
- if path == ".":
- return "*"
-
- # filename
- root, ext = os.path.splitext(path)
- if ext:
- return path
-
- # dirname ?
- return os.path.join(path, '*')
-
-
-def __filter_files(files, path_or_rule):
- # type: (set[str], str) -> set[str]
-
- rule = __path_to_match_rule(path_or_rule)
-
- result = set()
- for path in files:
- py_rule = __path_to_match_rule(rule)
- if path == rule or fnmatch.fnmatch(path, py_rule):
- result.add(path)
-
- return result
-
-
-def ts_glob(glob_config, all_files):
- # type: (TsGlobConfig, list[str]) -> list[str]
-
- result = set(all_files)
-
- # only in `root_dir`
- result &= __filter_files(result, glob_config.root_dir)
-
- # only listed by `include` option
- include_only = set()
- for include_path in glob_config.include:
- include_only |= __filter_files(result, include_path)
-
- result &= include_only # keep only intersection (common in both sets)
-
- skip_files = set()
-
- # exclude out_dir
- if glob_config.out_dir:
- skip_files |= __filter_files(result, glob_config.out_dir)
-
- result -= skip_files # keep only differences (the elements in `result` that not exist in `skip_files`)
-
- return sorted(result)
diff --git a/build/plugins/lib/nots/typescript/ya.make b/build/plugins/lib/nots/typescript/ya.make
deleted file mode 100644
index ac31196472..0000000000
--- a/build/plugins/lib/nots/typescript/ya.make
+++ /dev/null
@@ -1,20 +0,0 @@
-PY23_LIBRARY()
-
-OWNER(g:frontend-build-platform)
-
-PY_SRCS(
- __init__.py
- ts_errors.py
- ts_glob.py
- ts_config.py
-)
-
-PEERDIR(
- build/plugins/lib/nots/package_manager
-)
-
-END()
-
-RECURSE_FOR_TESTS(
- tests
-)
diff --git a/build/plugins/lib/nots/ya.make b/build/plugins/lib/nots/ya.make
deleted file mode 100644
index b24c534033..0000000000
--- a/build/plugins/lib/nots/ya.make
+++ /dev/null
@@ -1,15 +0,0 @@
-PY23_LIBRARY()
-
-OWNER(g:frontend-build-platform)
-
-PY_SRCS(
- __init__.py
-)
-
-PEERDIR(
- build/plugins/lib/nots/package_manager
- build/plugins/lib/nots/semver
- build/plugins/lib/nots/typescript
-)
-
-END()
diff --git a/build/plugins/nots.py b/build/plugins/nots.py
deleted file mode 100644
index 9aaf110ca2..0000000000
--- a/build/plugins/nots.py
+++ /dev/null
@@ -1,612 +0,0 @@
-import fnmatch
-import os
-import re
-
-import ymake
-import ytest
-from _common import get_norm_unit_path, rootrel_arc_src, to_yesno
-
-# 1 is 60 files per chunk for TIMEOUT(60) - default timeout for SIZE(SMALL)
-# 0.5 is 120 files per chunk for TIMEOUT(60) - default timeout for SIZE(SMALL)
-# 0.2 is 300 files per chunk for TIMEOUT(60) - default timeout for SIZE(SMALL)
-ESLINT_FILE_PROCESSING_TIME_DEFAULT = 0.2 # seconds per file
-
-
-class PluginLogger(object):
- def __init__(self):
- self.unit = None
- self.prefix = ""
-
- def reset(self, unit, prefix=""):
- self.unit = unit
- self.prefix = prefix
-
- def get_state(self):
- return (self.unit, self.prefix)
-
- def _stringify_messages(self, messages):
- parts = []
- for m in messages:
- if m is None:
- parts.append("None")
- else:
- parts.append(m if isinstance(m, str) else repr(m))
-
- # cyan color (code 36) for messages
- return "\033[0;32m{}\033[0;49m \033[0;36m{}\033[0;49m".format(self.prefix, " ".join(parts))
-
- def info(self, *messages):
- if self.unit:
- self.unit.message(["INFO", self._stringify_messages(messages)])
-
- def warn(self, *messages):
- if self.unit:
- self.unit.message(["WARN", self._stringify_messages(messages)])
-
- def error(self, *messages):
- if self.unit:
- self.unit.message(["ERROR", self._stringify_messages(messages)])
-
- def print_vars(self, *variables):
- if self.unit:
- values = ["{}={}".format(v, self.unit.get(v)) for v in variables]
- self.info(values)
-
-
-logger = PluginLogger()
-
-
-def _with_report_configure_error(fn):
- def _wrapper(*args, **kwargs):
- last_state = logger.get_state()
- unit = args[0]
- logger.reset(unit if unit.get("TS_LOG") == "yes" else None, fn.__name__)
- try:
- fn(*args, **kwargs)
- except Exception as exc:
- ymake.report_configure_error(str(exc))
- if unit.get("TS_RAISE") == "yes":
- raise
- else:
- unit.message(["WARN", "Configure error is reported. Add -DTS_RAISE to see actual exception"])
- finally:
- logger.reset(*last_state)
-
- return _wrapper
-
-
-def _canonize_resource_name(name):
- # type: (str) -> str
- return re.sub(r"\W+", "_", name).strip("_").upper()
-
-
-def _build_cmd_input_paths(paths, hide=False, disable_include_processor=False):
- # type: (list[str]|tuple[str], bool) -> str
- input_part = "input"
- hide_part = "hide" if hide else ""
- disable_ip_part = "context=TEXT" if disable_include_processor else ""
-
- parts = [p for p in [input_part, hide_part, disable_ip_part] if p]
-
- input_expressions = ["${{{parts}:\"{path}\"}}".format(parts=";".join(parts), path=path) for path in paths]
-
- return " ".join(input_expressions)
-
-
-def _create_pm(unit):
- from lib.nots.package_manager import manager
-
- sources_path = unit.path()
- module_path = unit.get("MODDIR")
- if unit.get("TS_TEST_FOR"):
- sources_path = unit.get("TS_TEST_FOR_DIR")
- module_path = unit.get("TS_TEST_FOR_PATH")
-
- return manager(
- sources_path=unit.resolve(sources_path),
- build_root="$B",
- build_path=unit.path().replace("$S", "$B", 1),
- contribs_path=unit.get("NPM_CONTRIBS_PATH"),
- nodejs_bin_path=None,
- script_path=None,
- module_path=module_path,
- )
-
-
-def _create_erm_json(unit):
- from lib.nots.erm_json_lite import ErmJsonLite
-
- erm_packages_path = unit.get("ERM_PACKAGES_PATH")
- path = unit.resolve(unit.resolve_arc_path(erm_packages_path))
-
- return ErmJsonLite.load(path)
-
-
-@_with_report_configure_error
-def on_from_npm_lockfiles(unit, *args):
- pm = _create_pm(unit)
- lf_paths = []
-
- for lf_path in args:
- abs_lf_path = unit.resolve(unit.resolve_arc_path(lf_path))
- if abs_lf_path:
- lf_paths.append(abs_lf_path)
- elif unit.get("TS_STRICT_FROM_NPM_LOCKFILES") == "yes":
- ymake.report_configure_error("lockfile not found: {}".format(lf_path))
-
- try:
- for pkg in pm.extract_packages_meta_from_lockfiles(lf_paths, no_files=True):
- unit.on_from_npm(
- [pkg.tarball_url, pkg.sky_id, pkg.integrity, pkg.integrity_algorithm, pkg.tarball_path]
- )
- except Exception as e:
- if unit.get("TS_RAISE") == "yes":
- raise e
- else:
- unit.message(["WARN", "on_from_npm_lockfiles exception: {}".format(e)])
- pass
-
-def _check_nodejs_version(unit, major):
- if major < 14:
- raise Exception(
- "Node.js {} is unsupported. Update Node.js please. See https://nda.ya.ru/t/joB9Mivm6h4znu".format(
- major
- )
- )
-
- if major < 18:
- unit.message(
- [
- "WARN",
- "Node.js {} is deprecated. Update Node.js please. See https://nda.ya.ru/t/joB9Mivm6h4znu".format(
- major
- ),
- ]
- )
-
-@_with_report_configure_error
-def on_peerdir_ts_resource(unit, *resources):
- pm = _create_pm(unit)
- pj = pm.load_package_json_from_dir(pm.sources_path)
- erm_json = _create_erm_json(unit)
- dirs = []
-
- nodejs_version = _select_matching_version(erm_json, "nodejs", pj.get_nodejs_version())
-
- _check_nodejs_version(unit, nodejs_version.major)
-
- for tool in resources:
- if tool == "nodejs":
- dirs.append(os.path.join("build", "platform", tool, str(nodejs_version)))
- _set_resource_vars(unit, erm_json, "nodejs", nodejs_version)
- elif erm_json.is_resource_multiplatform(tool):
- v = _select_matching_version(erm_json, tool, pj.get_dep_specifier(tool))
- sb_resources = [
- sbr for sbr in erm_json.get_sb_resources(tool, v) if sbr.get("nodejs") == nodejs_version.major
- ]
- nodejs_dir = "NODEJS_{}".format(nodejs_version.major)
- if len(sb_resources) > 0:
- dirs.append(os.path.join("build", "external_resources", tool, str(v), nodejs_dir))
- _set_resource_vars(unit, erm_json, tool, v, nodejs_version.major)
- else:
- unit.message(["WARN", "Missing {}@{} for {}".format(tool, str(v), nodejs_dir)])
- else:
- v = _select_matching_version(erm_json, tool, pj.get_dep_specifier(tool))
- dirs.append(os.path.join("build", "external_resources", tool, str(v)))
- _set_resource_vars(unit, erm_json, tool, v, nodejs_version.major)
-
- unit.onpeerdir(dirs)
-
-
-@_with_report_configure_error
-def on_ts_configure(unit, *tsconfig_paths):
- # type: (Unit, *str) -> None
- from lib.nots.package_manager.base import PackageJson
- from lib.nots.package_manager.base.utils import build_pj_path
- from lib.nots.typescript import TsConfig
-
- __set_append(unit, "TS_CONFIG_FILES", _build_cmd_input_paths(tsconfig_paths, hide=True, disable_include_processor=True))
-
- mod_dir = unit.get("MODDIR")
- cur_dir = unit.get("TS_TEST_FOR_PATH") if unit.get("TS_TEST_FOR") else mod_dir
- pj_path = build_pj_path(unit.resolve(unit.resolve_arc_path(cur_dir)))
- dep_paths = PackageJson.load(pj_path).get_dep_paths_by_names()
-
- # reversed for using the first tsconfig as the config for include processor (legacy)
- for tsconfig_path in reversed(tsconfig_paths):
- abs_tsconfig_path = unit.resolve(unit.resolve_arc_path(tsconfig_path))
- if not abs_tsconfig_path:
- raise Exception("tsconfig not found: {}".format(tsconfig_path))
-
- tsconfig = TsConfig.load(abs_tsconfig_path)
- config_files = tsconfig.inline_extend(dep_paths)
- config_files = _resolve_module_files(unit, mod_dir, config_files)
- tsconfig.validate()
-
- # for use in CMD as inputs
- __set_append(unit, "TS_CONFIG_FILES", _build_cmd_input_paths(config_files, hide=True, disable_include_processor=True))
-
- # region include processor
- unit.set(["TS_CONFIG_ROOT_DIR", tsconfig.compiler_option("rootDir")]) # also for hermione
- unit.set(["TS_CONFIG_OUT_DIR", tsconfig.compiler_option("outDir")]) # also for hermione
-
- unit.set(["TS_CONFIG_SOURCE_MAP", to_yesno(tsconfig.compiler_option("sourceMap"))])
- unit.set(["TS_CONFIG_DECLARATION", to_yesno(tsconfig.compiler_option("declaration"))])
- unit.set(["TS_CONFIG_DECLARATION_MAP", to_yesno(tsconfig.compiler_option("declarationMap"))])
- unit.set(["TS_CONFIG_PRESERVE_JSX", to_yesno(tsconfig.compiler_option("jsx") == "preserve")])
- # endregion
-
- _filter_inputs_by_rules_from_tsconfig(unit, tsconfig)
-
- _setup_eslint(unit)
-
-
-def __set_append(unit, var_name, value):
- # type: (Unit, str, str|list[str]|tuple[str]) -> None
- """
- SET_APPEND() python naive implementation - append value/values to the list of values
- """
- previous_value = unit.get(var_name) or ""
- value_in_str = " ".join(value) if isinstance(value, list) or isinstance(value, tuple) else value
- new_value = previous_value + " " + value_in_str
-
- unit.set([var_name, new_value])
-
-
-def __strip_prefix(prefix, line):
- # type: (str, str) -> str
- if line.startswith(prefix):
- prefix_len = len(prefix)
- return line[prefix_len:]
-
- return line
-
-
-def _filter_inputs_by_rules_from_tsconfig(unit, tsconfig):
- """
- Reduce file list from the TS_GLOB_FILES variable following tsconfig.json rules
- """
- mod_dir = unit.get("MODDIR")
- target_path = "${ARCADIA_ROOT}/" + mod_dir + "/"
-
- all_files = [__strip_prefix(target_path, f) for f in unit.get("TS_GLOB_FILES").split(" ")]
- filtered_files = tsconfig.filter_files(all_files)
-
- __set_append(unit, "TS_INPUT_FILES", [target_path + f for f in filtered_files])
-
-
-def _get_ts_test_data_dirs(unit):
- return list(
- set(
- [
- os.path.dirname(rootrel_arc_src(p, unit))
- for p in (ytest.get_values_list(unit, "_TS_TEST_DATA_VALUE") or [])
- ]
- )
- )
-
-
-def _resolve_config_path(unit, test_runner, rel_to):
- config_path = unit.get("ESLINT_CONFIG_PATH") if test_runner == "eslint" else unit.get("TS_TEST_CONFIG_PATH")
- arc_config_path = unit.resolve_arc_path(config_path)
- abs_config_path = unit.resolve(arc_config_path)
- if not abs_config_path:
- raise Exception("{} config not found: {}".format(test_runner, config_path))
-
- unit.onsrcs([arc_config_path])
- abs_rel_to = unit.resolve(unit.resolve_arc_path(unit.get(rel_to)))
- return os.path.relpath(abs_config_path, start=abs_rel_to)
-
-
-def _is_tests_enabled(unit):
- if unit.get("TIDY") == "yes":
- return False
-
- return True
-
-
-def _get_test_runner_handlers():
- return {
- "jest": _add_jest_ts_test,
- "hermione": _add_hermione_ts_test,
- }
-
-
-def _add_jest_ts_test(unit, test_runner, test_files, deps, test_record):
- test_record.update(
- {
- "CONFIG-PATH": _resolve_config_path(unit, test_runner, rel_to="TS_TEST_FOR_PATH"),
- }
- )
- _add_test(unit, test_runner, test_files, deps, test_record)
-
-
-def _add_hermione_ts_test(unit, test_runner, test_files, deps, test_record):
- unit.on_ts_configure(unit.get("TS_CONFIG_PATH"))
- test_tags = list(set(["ya:fat", "ya:external"] + ytest.get_values_list(unit, "TEST_TAGS_VALUE")))
- test_requirements = list(set(["network:full"] + ytest.get_values_list(unit, "TEST_REQUIREMENTS_VALUE")))
-
- test_record.update(
- {
- "TS-ROOT-DIR": unit.get("TS_CONFIG_ROOT_DIR"),
- "TS-OUT-DIR": unit.get("TS_CONFIG_OUT_DIR"),
- "SIZE": "LARGE",
- "TAG": ytest.serialize_list(test_tags),
- "REQUIREMENTS": ytest.serialize_list(test_requirements),
- "CONFIG-PATH": _resolve_config_path(unit, test_runner, rel_to="MODDIR"),
- }
- )
-
- if not len(test_record["TS-TEST-DATA-DIRS"]):
- _add_default_hermione_test_data(unit, test_record)
-
- _add_test(unit, test_runner, test_files, deps, test_record)
-
-
-def _add_default_hermione_test_data(unit, test_record):
- mod_dir = unit.get("MODDIR")
- root_dir = test_record["TS-ROOT-DIR"]
- out_dir = test_record["TS-OUT-DIR"]
- test_for_path = test_record["TS-TEST-FOR-PATH"]
-
- abs_root_dir = os.path.normpath(os.path.join(unit.resolve(unit.path()), root_dir))
- file_paths = _find_file_paths(abs_root_dir, "**/screens/*/*/*.png")
- file_dirs = [os.path.dirname(f) for f in file_paths]
-
- rename_from, rename_to = [
- os.path.relpath(os.path.normpath(os.path.join(mod_dir, d)), test_for_path) for d in [root_dir, out_dir]
- ]
-
- test_record.update(
- {
- "TS-TEST-DATA-DIRS": ytest.serialize_list(_resolve_module_files(unit, mod_dir, file_dirs)),
- "TS-TEST-DATA-DIRS-RENAME": "{}:{}".format(rename_from, rename_to),
- }
- )
-
-
-def _setup_eslint(unit):
- if not _is_tests_enabled(unit):
- return
-
- if unit.get("_NO_LINT_VALUE") == "none":
- return
-
- lint_files = ytest.get_values_list(unit, "_TS_LINT_SRCS_VALUE")
- if not lint_files:
- return
-
- unit.on_peerdir_ts_resource("eslint")
-
- mod_dir = unit.get("MODDIR")
- lint_files = _resolve_module_files(unit, mod_dir, lint_files)
- deps = _create_pm(unit).get_peers_from_package_json()
- test_record = {
- "ESLINT-ROOT-VAR-NAME": unit.get("ESLINT-ROOT-VAR-NAME"),
- "ESLINT_CONFIG_PATH": _resolve_config_path(unit, "eslint", rel_to="MODDIR"),
- "LINT-FILE-PROCESSING-TIME": str(ESLINT_FILE_PROCESSING_TIME_DEFAULT),
- }
-
- _add_test(unit, "eslint", lint_files, deps, test_record, mod_dir)
-
-
-def _resolve_module_files(unit, mod_dir, file_paths):
- resolved_files = []
-
- for path in file_paths:
- resolved = rootrel_arc_src(path, unit)
- if resolved.startswith(mod_dir):
- mod_dir_with_sep_len = len(mod_dir) + 1
- resolved = resolved[mod_dir_with_sep_len:]
- resolved_files.append(resolved)
-
- return resolved_files
-
-
-def _find_file_paths(abs_path, pattern):
- file_paths = []
- _, ext = os.path.splitext(pattern)
-
- for root, _, filenames in os.walk(abs_path):
- if not any(f.endswith(ext) for f in filenames):
- continue
-
- abs_file_paths = [os.path.join(root, f) for f in filenames]
-
- for file_path in fnmatch.filter(abs_file_paths, pattern):
- file_paths.append(file_path)
-
- return file_paths
-
-
-def _add_test(unit, test_type, test_files, deps=None, test_record=None, test_cwd=None):
- from lib.nots.package_manager import constants
-
- def sort_uniq(text):
- return list(sorted(set(text)))
-
- if deps:
- unit.ondepends(sort_uniq(deps))
-
- test_dir = get_norm_unit_path(unit)
- full_test_record = {
- "TEST-NAME": test_type.lower(),
- "TEST-TIMEOUT": unit.get("TEST_TIMEOUT") or "",
- "TEST-ENV": ytest.prepare_env(unit.get("TEST_ENV_VALUE")),
- "TESTED-PROJECT-NAME": os.path.splitext(unit.filename())[0],
- "TEST-RECIPES": ytest.prepare_recipes(unit.get("TEST_RECIPES_VALUE")),
- "SCRIPT-REL-PATH": test_type,
- "SOURCE-FOLDER-PATH": test_dir,
- "BUILD-FOLDER-PATH": test_dir,
- "BINARY-PATH": os.path.join(test_dir, unit.filename()),
- "SPLIT-FACTOR": unit.get("TEST_SPLIT_FACTOR") or "",
- "FORK-MODE": unit.get("TEST_FORK_MODE") or "",
- "SIZE": unit.get("TEST_SIZE_NAME") or "",
- "TEST-FILES": ytest.serialize_list(test_files),
- "TEST-CWD": test_cwd or "",
- "TAG": ytest.serialize_list(ytest.get_values_list(unit, "TEST_TAGS_VALUE")),
- "REQUIREMENTS": ytest.serialize_list(ytest.get_values_list(unit, "TEST_REQUIREMENTS_VALUE")),
- "NODEJS-ROOT-VAR-NAME": unit.get("NODEJS-ROOT-VAR-NAME"),
- "NODE-MODULES-BUNDLE-FILENAME": constants.NODE_MODULES_WORKSPACE_BUNDLE_FILENAME,
- "CUSTOM-DEPENDENCIES": " ".join(sort_uniq((deps or []) + ytest.get_values_list(unit, "TEST_DEPENDS_VALUE"))),
- }
-
- if test_record:
- full_test_record.update(test_record)
-
- for k, v in full_test_record.items():
- if not isinstance(v, str):
- logger.warn(k, "expected 'str', got:", type(v))
-
- data = ytest.dump_test(unit, full_test_record)
- if data:
- unit.set_property(["DART_DATA", data])
-
-
-def _set_resource_vars(unit, erm_json, resource_name, version, nodejs_major=None):
- # type: (any, ErmJsonLite, Version, str|None, int|None) -> None
-
- # example: hermione -> HERMIONE, super-package -> SUPER_PACKAGE
- canon_resource_name = _canonize_resource_name(resource_name)
-
- # example: NODEJS_12_18_4 | HERMIONE_7_0_4_NODEJS_18
- version_str = str(version).replace(".", "_")
- yamake_resource_name = "{}_{}".format(canon_resource_name, version_str)
-
- if erm_json.is_resource_multiplatform(resource_name):
- yamake_resource_name += "_NODEJS_{}".format(nodejs_major)
-
- yamake_resource_var = "{}_RESOURCE_GLOBAL".format(yamake_resource_name)
-
- unit.set(["{}_ROOT".format(canon_resource_name), "${}".format(yamake_resource_var)])
- unit.set(["{}-ROOT-VAR-NAME".format(canon_resource_name), yamake_resource_var])
-
-
-def _select_matching_version(erm_json, resource_name, range_str):
- # type: (ErmJsonLite, str, str) -> Version
- try:
- version = erm_json.select_version_of(resource_name, range_str)
- if version:
- return version
-
- raise ValueError("There is no allowed version to satisfy this range: '{}'".format(range_str))
- except Exception as error:
- toolchain_versions = erm_json.get_versions_of(erm_json.get_resource(resource_name))
-
- raise Exception(
- "Requested {} version range '{}' could not be satisfied. \n"
- "Please use a range that would include one of the following: {}. \n"
- "For further details please visit the link: {} \nOriginal error: {} \n".format(
- resource_name,
- range_str,
- map(str, toolchain_versions),
- "https://docs.yandex-team.ru/ya-make/manual/typescript/toolchain",
- str(error),
- )
- )
-
-
-@_with_report_configure_error
-def on_node_modules_configure(unit):
- pm = _create_pm(unit)
- pj = pm.load_package_json_from_dir(pm.sources_path)
-
- if pj.has_dependencies():
- unit.onpeerdir(pm.get_local_peers_from_package_json())
- message_level = "ERROR" if unit.get("TS_RAISE") == "yes" else "WARN"
- errors, ins, outs = pm.calc_node_modules_inouts()
-
- for err in errors:
- unit.message([message_level, "calc_node_modules_inouts exception: {}".format(err)])
-
- unit.on_set_node_modules_ins_outs(["IN"] + sorted(ins) + ["OUT"] + sorted(outs))
- else:
- # default "noop" command
- unit.set(["_NODE_MODULES_CMD", "$TOUCH_UNIT"])
-
-
-@_with_report_configure_error
-def on_set_node_modules_bundle_as_output(unit):
- pm = _create_pm(unit)
- pj = pm.load_package_json_from_dir(pm.sources_path)
- if pj.has_dependencies():
- unit.set(["NODE_MODULES_BUNDLE_AS_OUTPUT", '${output;hide:"workspace_node_modules.tar"}'])
-
-
-@_with_report_configure_error
-def on_ts_test_for_configure(unit, test_runner, default_config):
- if not _is_tests_enabled(unit):
- return
-
- if unit.enabled('TS_COVERAGE'):
- unit.on_peerdir_ts_resource("nyc")
-
- for_mod_path = unit.get("TS_TEST_FOR_PATH")
- unit.onpeerdir([for_mod_path])
- unit.on_setup_extract_node_modules_recipe([for_mod_path])
- unit.on_setup_extract_peer_tars_recipe([for_mod_path])
-
- unit.set(["TS_TEST_NM", os.path.join(("$B"), for_mod_path, "node_modules.tar")])
-
- config_path = unit.get("TS_TEST_CONFIG_PATH")
- if not config_path:
- config_path = os.path.join(for_mod_path, default_config)
- unit.set(["TS_TEST_CONFIG_PATH", config_path])
-
- test_record = _add_ts_resources_to_test_record(
- unit,
- {
- "TS-TEST-FOR-PATH": for_mod_path,
- "TS-TEST-DATA-DIRS": ytest.serialize_list(_get_ts_test_data_dirs(unit)),
- "TS-TEST-DATA-DIRS-RENAME": unit.get("_TS_TEST_DATA_DIRS_RENAME_VALUE"),
- },
- )
-
- test_files = ytest.get_values_list(unit, "_TS_TEST_SRCS_VALUE")
- test_files = _resolve_module_files(unit, unit.get("MODDIR"), test_files)
- if not test_files:
- ymake.report_configure_error("No tests found")
- return
-
- deps = _create_pm(unit).get_peers_from_package_json()
- add_ts_test = _get_test_runner_handlers()[test_runner]
- add_ts_test(unit, test_runner, test_files, deps, test_record)
-
-
-@_with_report_configure_error
-def on_set_ts_test_for_vars(unit, for_mod):
- unit.set(["TS_TEST_FOR", "yes"])
- unit.set(["TS_TEST_FOR_DIR", unit.resolve_arc_path(for_mod)])
- unit.set(["TS_TEST_FOR_PATH", rootrel_arc_src(for_mod, unit)])
-
-
-def _add_ts_resources_to_test_record(unit, test_record):
- erm_json = _create_erm_json(unit)
- for tool in erm_json.list_npm_packages():
- tool_resource_label = "{}-ROOT-VAR-NAME".format(tool.upper())
- tool_resource_value = unit.get(tool_resource_label)
- if tool_resource_value:
- test_record[tool_resource_label] = tool_resource_value
- return test_record
-
-
-@_with_report_configure_error
-def on_ts_files(unit, *files):
- new_cmds = ['$COPY_CMD ${{input;context=TEXT:"{0}"}} ${{output;noauto:"{0}"}}'.format(f) for f in files]
- all_cmds = unit.get("_TS_FILES_COPY_CMD")
- if all_cmds:
- new_cmds.insert(0, all_cmds)
- unit.set(["_TS_FILES_COPY_CMD", " && ".join(new_cmds)])
-
-
-@_with_report_configure_error
-def on_set_copy_node_modules_bundle_cmd(unit):
- pm = _create_pm(unit)
- pj = pm.load_package_json_from_dir(pm.sources_path)
- if pj.has_dependencies():
- unit.set(
- [
- "_COPY_NODE_MODULES_BUNDLE_CMD",
- '$COPY_CMD ${input:"node_modules.tar"} ${output:"workspace_node_modules.tar"}',
- ]
- )
diff --git a/build/ymake.core.conf b/build/ymake.core.conf
index 08fc4fdf6f..41c5aaaa23 100644
--- a/build/ymake.core.conf
+++ b/build/ymake.core.conf
@@ -48,7 +48,6 @@ MODULE_SUFFIX=
@import "${CONF_ROOT}/conf/opensource.conf"
@import "${CONF_ROOT}/conf/sysincl.conf"
@import "${CONF_ROOT}/conf/license.conf"
-@import "${CONF_ROOT}/conf/ts/ts.conf"
@import "${CONF_ROOT}/conf/docs.conf"
@import "${CONF_ROOT}/conf/swig.conf"
@import "${CONF_ROOT}/conf/proto.conf"