From 795ed23b356dc044cfb497a6189d588604a6c335 Mon Sep 17 00:00:00 2001 From: Nathan Whitaker <17734409+nathanwhit@users.noreply.github.com> Date: Wed, 24 Jul 2024 16:37:13 -0700 Subject: [PATCH] fix(future): Emit `deno install` warning less often, suggest `deno install` in error message (#24706) Two small changes: - In our BYONM errors, suggest running `deno install` instead of `npm install` if `DENO_FUTURE` is set - Only emit warning about `deno install` changes if you do `deno install ` with deno_future unset --- cli/npm/byonm.rs | 7 +- cli/resolver.rs | 9 +- cli/tools/installer.rs | 8 +- tests/integration/install_tests.rs | 2 +- tests/integration/npm_tests.rs | 132 ------------------ tests/specs/compile/npmrc_byonm/install.out | 1 - .../future_install_local_add_deno/install.out | 1 - .../future_install_local_add_npm/install.out | 1 - .../future_install_local_deno/install.out | 1 - .../future_install_node_modules/corrupted.out | 1 - .../future_install_node_modules/install.out | 1 - .../install_lockfile.out | 1 - .../frozen_package_json_changed_install.out | 1 - .../npm/bin_entries_prefer_closer/install.out | 1 - tests/specs/npm/byonm/__test__.jsonc | 52 +++++++ .../npm/byonm/future_invalid_sub_path.out | 2 + .../specs/npm/byonm/future_not_installed.out | 2 + tests/specs/npm/byonm/invalid_sub_path.out | 2 + tests/specs/npm/byonm/invalid_sub_path.ts | 1 + tests/specs/npm/byonm/not_installed.out | 2 + tests/specs/npm/byonm/not_installed.ts | 2 + tests/specs/npm/byonm/package.json | 6 + .../future_install_all_lifecycles.out | 1 - .../future_install_all_lifecycles_not_run.out | 1 - tests/specs/npm/npmrc/install.out | 1 - .../npm/npmrc_bad_registry_config/main.out | 1 - tests/specs/npm/npmrc_bad_token/main.out | 1 - tests/specs/npm/npmrc_basic_auth/install.out | 1 - tests/specs/npm/npmrc_homedir/install.out | 1 - 29 files changed, 87 insertions(+), 156 deletions(-) create mode 100644 tests/specs/npm/byonm/__test__.jsonc create mode 100644 tests/specs/npm/byonm/future_invalid_sub_path.out create mode 100644 tests/specs/npm/byonm/future_not_installed.out create mode 100644 tests/specs/npm/byonm/invalid_sub_path.out create mode 100644 tests/specs/npm/byonm/invalid_sub_path.ts create mode 100644 tests/specs/npm/byonm/not_installed.out create mode 100644 tests/specs/npm/byonm/not_installed.ts create mode 100644 tests/specs/npm/byonm/package.json diff --git a/cli/npm/byonm.rs b/cli/npm/byonm.rs index d10bb6b2ab..86c9badac0 100644 --- a/cli/npm/byonm.rs +++ b/cli/npm/byonm.rs @@ -286,9 +286,14 @@ impl CliNpmResolver for ByonmCliNpmResolver { concat!( "Could not find \"{}\" in a node_modules folder. ", "Deno expects the node_modules/ directory to be up to date. ", - "Did you forget to run `npm install`?" + "Did you forget to run `{}`?" ), alias, + if *crate::args::DENO_FUTURE { + "deno install" + } else { + "npm install" + } ); } diff --git a/cli/resolver.rs b/cli/resolver.rs index c1bb8a0a57..c9940b406c 100644 --- a/cli/resolver.rs +++ b/cli/resolver.rs @@ -233,8 +233,13 @@ impl CliNodeResolver { let package_json_path = package_folder.join("package.json"); if !self.fs.exists_sync(&package_json_path) { return Err(anyhow!( - "Could not find '{}'. Deno expects the node_modules/ directory to be up to date. Did you forget to run `npm install`?", - package_json_path.display() + "Could not find '{}'. Deno expects the node_modules/ directory to be up to date. Did you forget to run `{}`?", + package_json_path.display(), + if *crate::args::DENO_FUTURE { + "deno install" + } else { + "npm install" + }, )); } } diff --git a/cli/tools/installer.rs b/cli/tools/installer.rs index 01ed367118..d1beb79bba 100644 --- a/cli/tools/installer.rs +++ b/cli/tools/installer.rs @@ -283,12 +283,12 @@ pub async fn install_command( flags: Arc, install_flags: InstallFlags, ) -> Result<(), AnyError> { - if !install_flags.global { - log::warn!("⚠️ `deno install` behavior will change in Deno 2. To preserve the current behavior use the `-g` or `--global` flag."); - } - match install_flags.kind { InstallKind::Global(global_flags) => { + if !install_flags.global { + log::warn!("⚠️ `deno install` behavior will change in Deno 2. To preserve the current behavior use the `-g` or `--global` flag."); + } + install_global(flags, global_flags).await } InstallKind::Local(maybe_add_flags) => { diff --git a/tests/integration/install_tests.rs b/tests/integration/install_tests.rs index 32c0e9080c..744f97493d 100644 --- a/tests/integration/install_tests.rs +++ b/tests/integration/install_tests.rs @@ -109,7 +109,7 @@ fn install_basic_global() { let output_text = output.combined_output(); assert_not_contains!( output_text, - "`deno install` behavior will change in Deno 2. To preserve the current behavior use `-g` or `--global` flag." + "`deno install` behavior will change in Deno 2. To preserve the current behavior use the `-g` or `--global` flag." ); // no lockfile should be created locally diff --git a/tests/integration/npm_tests.rs b/tests/integration/npm_tests.rs index e721633a63..6be0298d89 100644 --- a/tests/integration/npm_tests.rs +++ b/tests/integration/npm_tests.rs @@ -2453,138 +2453,6 @@ fn byonm_package_specifier_not_installed_and_invalid_subpath() { output.assert_exit_code(1); } -#[test] -fn future_byonm_package_specifier_not_installed_and_invalid_subpath() { - let test_context = TestContextBuilder::for_npm() - .env("DENO_FUTURE", "1") - .use_temp_cwd() - .build(); - let dir = test_context.temp_dir(); - dir.path().join("package.json").write_json(&json!({ - "dependencies": { - "chalk": "4", - "@denotest/conditional-exports-strict": "1" - } - })); - dir.write( - "main.ts", - "import chalk from 'chalk'; console.log(chalk.green('hi'));", - ); - - // no npm install has been run, so this should give an informative error - let output = test_context.new_command().args("run main.ts").run(); - output.assert_matches_text( - r#"error: Could not resolve "chalk", but found it in a package.json. Deno expects the node_modules/ directory to be up to date. Did you forget to run `npm install`? - at file:///[WILDCARD]/main.ts:1:19 -"#, - ); - output.assert_exit_code(1); - - // now test for an invalid sub path after doing an npm install - dir.write( - "main.ts", - "import '@denotest/conditional-exports-strict/test';", - ); - - test_context.run_npm("install"); - - let output = test_context.new_command().args("run main.ts").run(); - output.assert_matches_text( - r#"error: [ERR_PACKAGE_PATH_NOT_EXPORTED] Package subpath './test' is not defined by "exports" in '[WILDCARD]' imported from '[WILDCARD]main.ts' - at file:///[WILDCARD]/main.ts:1:8 -"#, - ); - output.assert_exit_code(1); -} - -#[test] -fn byonm_package_npm_specifier_not_installed_and_invalid_subpath() { - let test_context = TestContextBuilder::for_npm() - .env("DENO_UNSTABLE_BYONM", "1") - .use_temp_cwd() - .build(); - let dir = test_context.temp_dir(); - dir.path().join("package.json").write_json(&json!({ - "dependencies": { - "chalk": "4", - "@denotest/conditional-exports-strict": "1" - } - })); - dir.write( - "main.ts", - "import chalk from 'npm:chalk'; console.log(chalk.green('hi'));", - ); - - // no npm install has been run, so this should give an informative error - let output = test_context.new_command().args("run main.ts").run(); - output.assert_matches_text( - r#"error: Could not find "chalk" in a node_modules folder. Deno expects the node_modules/ directory to be up to date. Did you forget to run `npm install`? - at file:///[WILDCARD]/main.ts:1:19 -"#, - ); - output.assert_exit_code(1); - - // now test for an invalid sub path after doing an npm install - dir.write( - "main.ts", - "import 'npm:@denotest/conditional-exports-strict/test';", - ); - - test_context.run_npm("install"); - - let output = test_context.new_command().args("run main.ts").run(); - output.assert_matches_text( - r#"error: [ERR_PACKAGE_PATH_NOT_EXPORTED] Package subpath './test' is not defined by "exports" in '[WILDLINE]package.json' imported from '[WILDLINE]main.ts' - at file:///[WILDLINE]/main.ts:1:8 -"#, - ); - output.assert_exit_code(1); -} - -#[test] -fn future_byonm_package_npm_specifier_not_installed_and_invalid_subpath() { - let test_context = TestContextBuilder::for_npm() - .env("DENO_FUTURE", "1") - .use_temp_cwd() - .build(); - let dir = test_context.temp_dir(); - dir.path().join("package.json").write_json(&json!({ - "dependencies": { - "chalk": "4", - "@denotest/conditional-exports-strict": "1" - } - })); - dir.write( - "main.ts", - "import chalk from 'npm:chalk'; console.log(chalk.green('hi'));", - ); - - // no npm install has been run, so this should give an informative error - let output = test_context.new_command().args("run main.ts").run(); - output.assert_matches_text( - r#"error: Could not find "chalk" in a node_modules folder. Deno expects the node_modules/ directory to be up to date. Did you forget to run `npm install`? - at file:///[WILDCARD]/main.ts:1:19 -"#, - ); - output.assert_exit_code(1); - - // now test for an invalid sub path after doing an npm install - dir.write( - "main.ts", - "import 'npm:@denotest/conditional-exports-strict/test';", - ); - - test_context.run_npm("install"); - - let output = test_context.new_command().args("run main.ts").run(); - output.assert_matches_text( - r#"error: [ERR_PACKAGE_PATH_NOT_EXPORTED] Package subpath './test' is not defined by "exports" in '[WILDLINE]package.json' imported from '[WILDLINE]main.ts' - at file:///[WILDLINE]/main.ts:1:8 -"#, - ); - output.assert_exit_code(1); -} - #[test] fn byonm_npm_workspaces() { let test_context = TestContextBuilder::for_npm().use_temp_cwd().build(); diff --git a/tests/specs/compile/npmrc_byonm/install.out b/tests/specs/compile/npmrc_byonm/install.out index 5c2ff35629..30643527e6 100644 --- a/tests/specs/compile/npmrc_byonm/install.out +++ b/tests/specs/compile/npmrc_byonm/install.out @@ -1,4 +1,3 @@ -⚠️ `deno install` behavior will change in Deno 2. To preserve the current behavior use the `-g` or `--global` flag. [UNORDERED_START] Download http://localhost:4261/@denotest/basic Download http://localhost:4262/@denotest2/basic diff --git a/tests/specs/install/future_install_local_add_deno/install.out b/tests/specs/install/future_install_local_add_deno/install.out index df58284fc8..0c87a04aac 100644 --- a/tests/specs/install/future_install_local_add_deno/install.out +++ b/tests/specs/install/future_install_local_add_deno/install.out @@ -1,4 +1,3 @@ -⚠️ `deno install` behavior will change in Deno 2. To preserve the current behavior use the `-g` or `--global` flag. Add @denotest/esm-basic - npm:@denotest/esm-basic@^1.0.0 Download http://localhost:4260/@denotest/esm-basic Download http://localhost:4260/@denotest/esm-basic/1.0.0.tgz diff --git a/tests/specs/install/future_install_local_add_npm/install.out b/tests/specs/install/future_install_local_add_npm/install.out index d9c23abf00..76939659f2 100644 --- a/tests/specs/install/future_install_local_add_npm/install.out +++ b/tests/specs/install/future_install_local_add_npm/install.out @@ -1,4 +1,3 @@ -⚠️ `deno install` behavior will change in Deno 2. To preserve the current behavior use the `-g` or `--global` flag. Add @denotest/esm-basic - npm:@denotest/esm-basic@^1.0.0 Download http://localhost:4260/@denotest/esm-basic Download http://localhost:4260/@denotest/esm-basic/1.0.0.tgz diff --git a/tests/specs/install/future_install_local_deno/install.out b/tests/specs/install/future_install_local_deno/install.out index 713507f029..eecba12991 100644 --- a/tests/specs/install/future_install_local_deno/install.out +++ b/tests/specs/install/future_install_local_deno/install.out @@ -1,4 +1,3 @@ -⚠️ `deno install` behavior will change in Deno 2. To preserve the current behavior use the `-g` or `--global` flag. [UNORDERED_START] Download http://localhost:4545/v1/extensionless Download http://localhost:4545/subdir/mod1.ts diff --git a/tests/specs/install/future_install_node_modules/corrupted.out b/tests/specs/install/future_install_node_modules/corrupted.out index 9943c1ce9f..ade0757447 100644 --- a/tests/specs/install/future_install_node_modules/corrupted.out +++ b/tests/specs/install/future_install_node_modules/corrupted.out @@ -1,3 +1,2 @@ -[WILDCARD] error: Integrity check failed for package: "npm:@denotest/esm-basic@1.0.0".[WILDCARD] Use the --lock-write flag to regenerate the lockfile at [WILDCARD] \ No newline at end of file diff --git a/tests/specs/install/future_install_node_modules/install.out b/tests/specs/install/future_install_node_modules/install.out index 22574688aa..b8114c12a0 100644 --- a/tests/specs/install/future_install_node_modules/install.out +++ b/tests/specs/install/future_install_node_modules/install.out @@ -1,4 +1,3 @@ -⚠️ `deno install` behavior will change in Deno 2. To preserve the current behavior use the `-g` or `--global` flag. Download http://localhost:4260/@denotest/esm-basic Download http://localhost:4260/@denotest/esm-basic/1.0.0.tgz Initialize @denotest/esm-basic@1.0.0 diff --git a/tests/specs/install/future_install_node_modules/install_lockfile.out b/tests/specs/install/future_install_node_modules/install_lockfile.out index 3e27e3d207..05a104a3ad 100644 --- a/tests/specs/install/future_install_node_modules/install_lockfile.out +++ b/tests/specs/install/future_install_node_modules/install_lockfile.out @@ -1,2 +1 @@ -⚠️ `deno install` behavior will change in Deno 2. To preserve the current behavior use the `-g` or `--global` flag. Initialize @denotest/esm-basic@1.0.0 diff --git a/tests/specs/lockfile/frozen_lockfile/frozen_package_json_changed_install.out b/tests/specs/lockfile/frozen_lockfile/frozen_package_json_changed_install.out index 14530d573b..6b7d1dc5fd 100644 --- a/tests/specs/lockfile/frozen_lockfile/frozen_package_json_changed_install.out +++ b/tests/specs/lockfile/frozen_lockfile/frozen_package_json_changed_install.out @@ -1,4 +1,3 @@ -⚠️ `deno install` behavior will change in Deno 2. To preserve the current behavior use the `-g` or `--global` flag. error: The lockfile is out of date. Run `deno cache --frozen=false`, `deno install --frozen=false`, or rerun with `--frozen=false` to update it. changes: 5 | - "npm:@denotest/add@1": "npm:@denotest/add@1.0.0" diff --git a/tests/specs/npm/bin_entries_prefer_closer/install.out b/tests/specs/npm/bin_entries_prefer_closer/install.out index 25e06db992..1d3a995b80 100644 --- a/tests/specs/npm/bin_entries_prefer_closer/install.out +++ b/tests/specs/npm/bin_entries_prefer_closer/install.out @@ -1,4 +1,3 @@ -⚠️ `deno install` behavior will change in Deno 2. To preserve the current behavior use the `-g` or `--global` flag. [UNORDERED_START] Download http://localhost:4260/@denotest/transitive-bin Download http://localhost:4260/@denotest/bin diff --git a/tests/specs/npm/byonm/__test__.jsonc b/tests/specs/npm/byonm/__test__.jsonc new file mode 100644 index 0000000000..8edb6b0bf6 --- /dev/null +++ b/tests/specs/npm/byonm/__test__.jsonc @@ -0,0 +1,52 @@ +{ + "tempDir": true, + "tests": { + "future_not_installed": { + "envs": { + "DENO_FUTURE": "1" + }, + "steps": [{ + "args": "run -A not_installed.ts", + "output": "future_not_installed.out", + "exitCode": 1 + }] + }, + "future_invalid_sub_path": { + "envs": { + "DENO_FUTURE": "1" + }, + "steps": [{ + "args": "install", + "output": "[WILDCARD]" + }, { + "args": "run -A invalid_sub_path.ts", + "output": "invalid_sub_path.out", + "exitCode": 1 + }] + }, + "not_installed": { + "envs": { + "DENO_UNSTABLE_BYONM": "1" + }, + "steps": [{ + "args": "run -A not_installed.ts", + "output": "not_installed.out", + "exitCode": 1 + }] + }, + "invalid_sub_path": { + "envs": { + "DENO_UNSTABLE_BYONM": "1" + }, + "steps": [{ + "args": "install", + "commandName": "npm", + "output": "[WILDCARD]" + }, { + "args": "run -A invalid_sub_path.ts", + "output": "invalid_sub_path.out", + "exitCode": 1 + }] + } + } +} diff --git a/tests/specs/npm/byonm/future_invalid_sub_path.out b/tests/specs/npm/byonm/future_invalid_sub_path.out new file mode 100644 index 0000000000..36ced4708f --- /dev/null +++ b/tests/specs/npm/byonm/future_invalid_sub_path.out @@ -0,0 +1,2 @@ +error: [ERR_PACKAGE_PATH_NOT_EXPORTED] Package subpath './test' is not defined by "exports" in '[WILDLINE]package.json' imported from '[WILDLINE]invalid_sub_path.ts' + at file:///[WILDLINE]/invalid_sub_path.ts:1:8 diff --git a/tests/specs/npm/byonm/future_not_installed.out b/tests/specs/npm/byonm/future_not_installed.out new file mode 100644 index 0000000000..2e608c37e0 --- /dev/null +++ b/tests/specs/npm/byonm/future_not_installed.out @@ -0,0 +1,2 @@ +error: Could not find "chalk" in a node_modules folder. Deno expects the node_modules/ directory to be up to date. Did you forget to run `deno install`? + at file:///[WILDCARD]/not_installed.ts:1:19 diff --git a/tests/specs/npm/byonm/invalid_sub_path.out b/tests/specs/npm/byonm/invalid_sub_path.out new file mode 100644 index 0000000000..36ced4708f --- /dev/null +++ b/tests/specs/npm/byonm/invalid_sub_path.out @@ -0,0 +1,2 @@ +error: [ERR_PACKAGE_PATH_NOT_EXPORTED] Package subpath './test' is not defined by "exports" in '[WILDLINE]package.json' imported from '[WILDLINE]invalid_sub_path.ts' + at file:///[WILDLINE]/invalid_sub_path.ts:1:8 diff --git a/tests/specs/npm/byonm/invalid_sub_path.ts b/tests/specs/npm/byonm/invalid_sub_path.ts new file mode 100644 index 0000000000..bed8754d56 --- /dev/null +++ b/tests/specs/npm/byonm/invalid_sub_path.ts @@ -0,0 +1 @@ +import "npm:@denotest/conditional-exports-strict/test"; diff --git a/tests/specs/npm/byonm/not_installed.out b/tests/specs/npm/byonm/not_installed.out new file mode 100644 index 0000000000..29f8651407 --- /dev/null +++ b/tests/specs/npm/byonm/not_installed.out @@ -0,0 +1,2 @@ +error: Could not find "chalk" in a node_modules folder. Deno expects the node_modules/ directory to be up to date. Did you forget to run `npm install`? + at file:///[WILDCARD]/not_installed.ts:1:19 diff --git a/tests/specs/npm/byonm/not_installed.ts b/tests/specs/npm/byonm/not_installed.ts new file mode 100644 index 0000000000..4cd4b83f6e --- /dev/null +++ b/tests/specs/npm/byonm/not_installed.ts @@ -0,0 +1,2 @@ +import chalk from "npm:chalk"; +console.log(chalk.green("hi")); diff --git a/tests/specs/npm/byonm/package.json b/tests/specs/npm/byonm/package.json new file mode 100644 index 0000000000..8d3b59104b --- /dev/null +++ b/tests/specs/npm/byonm/package.json @@ -0,0 +1,6 @@ +{ + "dependencies": { + "chalk": "4", + "@denotest/conditional-exports-strict": "1" + } +} diff --git a/tests/specs/npm/lifecycle_scripts/future_install_all_lifecycles.out b/tests/specs/npm/lifecycle_scripts/future_install_all_lifecycles.out index 059afdfaac..f62079d3fe 100644 --- a/tests/specs/npm/lifecycle_scripts/future_install_all_lifecycles.out +++ b/tests/specs/npm/lifecycle_scripts/future_install_all_lifecycles.out @@ -1,4 +1,3 @@ -⚠️ `deno install` behavior will change in Deno 2. To preserve the current behavior use the `-g` or `--global` flag. preinstall deno preinstall.js node preinstall.js diff --git a/tests/specs/npm/lifecycle_scripts/future_install_all_lifecycles_not_run.out b/tests/specs/npm/lifecycle_scripts/future_install_all_lifecycles_not_run.out index 8db36055f8..7d432ead90 100644 --- a/tests/specs/npm/lifecycle_scripts/future_install_all_lifecycles_not_run.out +++ b/tests/specs/npm/lifecycle_scripts/future_install_all_lifecycles_not_run.out @@ -1,4 +1,3 @@ -⚠️ `deno install` behavior will change in Deno 2. To preserve the current behavior use the `-g` or `--global` flag. [UNORDERED_START] Download http://localhost:4260/@denotest/node-lifecycle-scripts Download http://localhost:4260/@denotest/bin diff --git a/tests/specs/npm/npmrc/install.out b/tests/specs/npm/npmrc/install.out index 5c2ff35629..30643527e6 100644 --- a/tests/specs/npm/npmrc/install.out +++ b/tests/specs/npm/npmrc/install.out @@ -1,4 +1,3 @@ -⚠️ `deno install` behavior will change in Deno 2. To preserve the current behavior use the `-g` or `--global` flag. [UNORDERED_START] Download http://localhost:4261/@denotest/basic Download http://localhost:4262/@denotest2/basic diff --git a/tests/specs/npm/npmrc_bad_registry_config/main.out b/tests/specs/npm/npmrc_bad_registry_config/main.out index 17619e5cea..990d4a47fa 100644 --- a/tests/specs/npm/npmrc_bad_registry_config/main.out +++ b/tests/specs/npm/npmrc_bad_registry_config/main.out @@ -1,4 +1,3 @@ -⚠️ `deno install` behavior will change in Deno 2. To preserve the current behavior use the `-g` or `--global` flag. Download http://localhost:4261/@denotest/basic error: Error getting response at http://localhost:4261/@denotest/basic for package "@denotest/basic": Bad response: 401 [WILDCARD] \ No newline at end of file diff --git a/tests/specs/npm/npmrc_bad_token/main.out b/tests/specs/npm/npmrc_bad_token/main.out index 17619e5cea..990d4a47fa 100644 --- a/tests/specs/npm/npmrc_bad_token/main.out +++ b/tests/specs/npm/npmrc_bad_token/main.out @@ -1,4 +1,3 @@ -⚠️ `deno install` behavior will change in Deno 2. To preserve the current behavior use the `-g` or `--global` flag. Download http://localhost:4261/@denotest/basic error: Error getting response at http://localhost:4261/@denotest/basic for package "@denotest/basic": Bad response: 401 [WILDCARD] \ No newline at end of file diff --git a/tests/specs/npm/npmrc_basic_auth/install.out b/tests/specs/npm/npmrc_basic_auth/install.out index 5c2ff35629..30643527e6 100644 --- a/tests/specs/npm/npmrc_basic_auth/install.out +++ b/tests/specs/npm/npmrc_basic_auth/install.out @@ -1,4 +1,3 @@ -⚠️ `deno install` behavior will change in Deno 2. To preserve the current behavior use the `-g` or `--global` flag. [UNORDERED_START] Download http://localhost:4261/@denotest/basic Download http://localhost:4262/@denotest2/basic diff --git a/tests/specs/npm/npmrc_homedir/install.out b/tests/specs/npm/npmrc_homedir/install.out index 5c2ff35629..30643527e6 100644 --- a/tests/specs/npm/npmrc_homedir/install.out +++ b/tests/specs/npm/npmrc_homedir/install.out @@ -1,4 +1,3 @@ -⚠️ `deno install` behavior will change in Deno 2. To preserve the current behavior use the `-g` or `--global` flag. [UNORDERED_START] Download http://localhost:4261/@denotest/basic Download http://localhost:4262/@denotest2/basic