From 33e865c8a865f3313a82e6941be6bfbd87805fe2 Mon Sep 17 00:00:00 2001 From: Turiiya <34311583+ttytm@users.noreply.github.com> Date: Fri, 10 Nov 2023 13:04:13 +0100 Subject: [PATCH] tools: require the presence of a `v.mod` file, to install external urls via vpm (#19825) --- cmd/tools/vpm/common.v | 23 +++++++++++++++++++++++ cmd/tools/vpm/install_test.v | 11 +++++++++++ 2 files changed, 34 insertions(+) diff --git a/cmd/tools/vpm/common.v b/cmd/tools/vpm/common.v index 2561e02c29..00ec8154ea 100644 --- a/cmd/tools/vpm/common.v +++ b/cmd/tools/vpm/common.v @@ -56,6 +56,10 @@ fn parse_query(query []string) ([]Module, []Module) { errors++ continue } + if !has_vmod(ident) { + errors++ + continue + } Module{ name: name url: ident @@ -93,6 +97,25 @@ fn parse_query(query []string) ([]Module, []Module) { return vpm_modules, extended_modules } +fn has_vmod(url string) bool { + head_branch := os.execute_opt('git ls-remote --symref ${url} HEAD') or { + vpm_error('failed to find git HEAD for `${url}`.', details: err.msg()) + return false + }.output.all_after_last('/').all_before(' ').all_before('\t') + url_ := if url.ends_with('.git') { url.replace('.git', '') } else { url } + manifest_url := '${url_}/blob/${head_branch}/v.mod' + vpm_log(@FILE_LINE, @FN, 'manifest_url: ${manifest_url}') + has_vmod := http.head(manifest_url) or { + vpm_error('failed to retrieve module data for `${url}`.') + return false + }.status_code == 200 + if !has_vmod { + vpm_error('failed to find `v.mod` for `${url}`.') + return false + } + return true +} + fn get_mod_date_info(mut pp pool.PoolProcessor, idx int, wid int) &ModuleDateInfo { mut result := &ModuleDateInfo{ name: pp.get_item[string](idx) diff --git a/cmd/tools/vpm/install_test.v b/cmd/tools/vpm/install_test.v index 983dba8490..56f782089e 100644 --- a/cmd/tools/vpm/install_test.v +++ b/cmd/tools/vpm/install_test.v @@ -1,5 +1,7 @@ // vtest flaky: true // vtest retry: 3 +module main + import os import v.vmod @@ -108,3 +110,12 @@ fn test_missing_repo_name_in_url() { assert res.exit_code == 1 assert res.output.contains('failed to retrieve module name for `${incomplete_url}`') } + +fn test_missing_vmod_in_url() { + assert has_vmod('https://github.com/vlang/v') // head branch == `master`. + assert has_vmod('https://github.com/v-analyzer/v-analyzer') // head branch == `main`. + assert !has_vmod('https://github.com/octocat/octocat.github.io') // not a V module. + res := os.execute('${v} install https://github.com/octocat/octocat.github.io') + assert res.exit_code == 1 + assert res.output.contains('failed to find `v.mod` for `https://github.com/octocat/octocat.github.io`'), res.output +}