diff --git a/releasenotes.md b/releasenotes.md index 5da197867..990f60b9d 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -22,6 +22,7 @@ - Properly support `@deprecated` as contract. - Support deprecating enum values. - Improve error when trying to use an extern const as a compile time constant. #2969 +- `vendor-fetch` command now lists all available packages by default. #2976 ### Stdlib changes - Summarize sort macros as generic function wrappers to reduce the amount of generated code. #2831 diff --git a/src/build/build_options.c b/src/build/build_options.c index 987aa08fa..bdbf8af6e 100644 --- a/src/build/build_options.c +++ b/src/build/build_options.c @@ -445,7 +445,6 @@ static void parse_command(BuildOptions *options) if (arg_match("vendor-fetch")) { options->command = COMMAND_VENDOR_FETCH; - if (at_end() || next_is_opt()) error_exit("error: vendor-fetch needs at least one library."); while (!at_end() && !next_is_opt()) { const char *lib = next_arg(); diff --git a/src/compiler/compiler.c b/src/compiler/compiler.c index 5f3812f84..f7db89da7 100644 --- a/src/compiler/compiler.c +++ b/src/compiler/compiler.c @@ -4,6 +4,7 @@ #include "compiler_internal.h" #include "../build/project.h" +#include "../utils/json.h" #include #include "../utils/whereami.h" #if LLVM_AVAILABLE @@ -1004,6 +1005,50 @@ void vendor_fetch(BuildOptions *options) const char** fetched_libraries = NULL; int total_libraries = (int)vec_size(options->libraries_to_fetch); + if (total_libraries == 0) + { + const char *tmp_dir = dir_make_temp_dir(); + const char *tmp_file = file_append_path(tmp_dir, "vendor_list.json"); + const char *error = download_file("https://api.github.com", "/repos/c3lang/vendor/contents/libraries/", tmp_file); + if (error) + { + error_exit("Failed to fetch library list: %s", error); + } + + size_t size; + char *json_str = file_read_all(tmp_file, &size); + JsonParser parser; + json_init_string(&parser, json_str); + JSONObject *obj = json_parse(&parser); + if (!obj || obj->type != J_ARRAY) + { + error_exit("Failed to parse library list."); + } + + printf("Available vendor libraries:\n"); + FOREACH(JSONObject *, entry, obj->elements) + { + JSONObject *name = json_map_get(entry, "name"); + JSONObject *type = json_map_get(entry, "type"); + if (name && type && str_eq(type->str, "dir")) + { + const char *n = name->str; + if (n[0] == '.') continue; + if (str_has_suffix(n, ".c3l")) + { + printf(" %s\n", str_remove_suffix(n, ".c3l")); + } + else + { + printf(" %s\n", n); + } + } + } + file_delete_file(tmp_file); + file_delete_dir(tmp_dir); + return; + } + for(int i = 0; i < total_libraries; i++) { const char *lib = options->libraries_to_fetch[i]; diff --git a/src/utils/http.c b/src/utils/http.c index 915ec4812..e3394fdf7 100644 --- a/src/utils/http.c +++ b/src/utils/http.c @@ -120,6 +120,7 @@ typedef int CURLoption; #define CURLE_OK 0 #define CURLOPT_URL 10002 +#define CURLOPT_USERAGENT 10018 #define CURLOPT_FOLLOWLOCATION 52 #define CURLOPT_VERBOSE 41 #define CURLOPT_NOPROGRESS 43 @@ -209,6 +210,7 @@ const char *download_file(const char *url, const char *resource, const char *fil const char *total_url = str_printf("%s%s", url, resource); ptr_curl_easy_setopt(curl_handle, CURLOPT_URL, total_url); + ptr_curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "C3C/1.0"); ptr_curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1L); ptr_curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 0L); ptr_curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 1L);