implement progress bar for fetch-msvc

using deterministic milestones
This commit is contained in:
Manuel Barrio Linares
2026-02-06 12:20:27 -03:00
committed by Christoffer Lerno
parent d07e454dfe
commit 36dfbdff45

View File

@@ -63,6 +63,32 @@ static char *get_sdk_output_path(void)
static int verbose_level = 0;
static void print_progress(int percent)
{
if (verbose_level > 0) return;
int width = 40;
if (percent > 100) percent = 100;
printf("\rDownloading and extracting packages [");
const char *parts[] = { " ", "", "", "", "", "", "", "" };
int total_blocks = width * 8;
int filled_blocks = (percent * total_blocks) / 100;
int full_blocks = filled_blocks / 8;
int partial_block = filled_blocks % 8;
for (int i = 0; i < full_blocks; i++) printf("");
if (full_blocks < width)
{
printf("%s", parts[partial_block]);
for (int i = full_blocks + 1; i < width; i++) printf(" ");
}
printf("] %3d%%", percent);
fflush(stdout);
}
// Minimal dirent-like structure for Windows
#if PLATFORM_WINDOWS
struct dirent
@@ -183,11 +209,6 @@ static bool download_with_verification(const char *url, const char *name,
printf("%s ... downloading", name);
fflush(stdout);
}
else if (verbose_level == 0)
{
printf(".");
fflush(stdout);
}
const char *err = download_file(url, "", dst);
if (err)
{
@@ -563,12 +584,57 @@ void fetch_msvc(BuildOptions *options)
dir_make_recursive(out_root);
dir_make_recursive(dl_root);
if (verbose_level == 0)
JSONObject **checked_pkgs = NULL;
JSONObject *sdk_comp = json_map_get(sdk_paths, sdk_key);
JSONObject *deps_obj = json_map_get(sdk_comp, "dependencies");
if (deps_obj && deps_obj->type == J_OBJECT)
{
printf("Downloading and extracting packages");
fflush(stdout);
FOREACH(const char *, dep, deps_obj->keys)
{
JSONObject *pkg = find_package_by_id(pkgs, dep);
if (pkg)
{
vec_add(checked_pkgs, pkg);
JSONObject *p_deps = json_map_get(pkg, "dependencies");
if (p_deps && p_deps->type == J_OBJECT)
{
FOREACH(const char *, pd_id, p_deps->keys)
{
JSONObject *ppkg = find_package_by_id(pkgs, pd_id);
if (ppkg) vec_add(checked_pkgs, ppkg);
}
}
}
}
}
const char *msi_names[] = {
"Windows SDK for Windows Store Apps Libs-x86_en-us.msi",
"Windows SDK Desktop Libs x64-x86_en-us.msi",
"Universal CRT Headers Libraries and Sources-x86_en-us.msi"};
JSONObject *msi_packages[3] = {NULL};
for (int i = 0; i < ELEMENTLEN(msi_names); i++)
{
FOREACH(JSONObject *, pkg, checked_pkgs)
{
JSONObject *pls = json_map_get(pkg, "payloads");
if (!pls) continue;
FOREACH(JSONObject *, pl, pls->elements)
{
if (STRCASECMP(filename(json_map_get(pl, "fileName")->str), msi_names[i]) == 0)
{
msi_packages[i] = pkg;
break;
}
}
if (msi_packages[i]) break;
}
}
int progress = 0;
if (verbose_level == 0) print_progress(progress);
const char *suffixes[] = {"asan.headers.base", "crt.x64.desktop.base", "crt.x64.store.base", "asan.x64.base"};
for (int i = 0; i < ELEMENTLEN(suffixes); i++)
{
@@ -585,70 +651,36 @@ void fetch_msvc(BuildOptions *options)
extract_msvc_zip(zpath, out_root);
}
}
if (verbose_level == 0)
{
printf(".");
fflush(stdout);
}
}
progress += 10;
print_progress(progress);
}
JSONObject *sdk_comp = json_map_get(sdk_paths, sdk_key);
const char **sdk_pkg_ids = NULL;
JSONObject *deps_obj = json_map_get(sdk_comp, "dependencies");
if (deps_obj && deps_obj->type == J_OBJECT)
{
FOREACH(const char *, dep, deps_obj->keys) vec_add(sdk_pkg_ids, dep);
}
const char *msi_names[] = {
"Windows SDK for Windows Store Apps Libs-x86_en-us.msi",
"Windows SDK Desktop Libs x64-x86_en-us.msi",
"Universal CRT Headers Libraries and Sources-x86_en-us.msi"};
const char **cab_list = NULL;
JSONObject **checked_pkgs = NULL;
FOREACH(const char *, sid, sdk_pkg_ids)
{
JSONObject *pkg = find_package_by_id(pkgs, sid);
if (pkg)
{
vec_add(checked_pkgs, pkg);
JSONObject *p_deps = json_map_get(pkg, "dependencies");
if (p_deps && p_deps->type == J_OBJECT)
{
FOREACH(const char *, pd_id, p_deps->keys)
{
JSONObject *ppkg = find_package_by_id(pkgs, pd_id);
if (ppkg) vec_add(checked_pkgs, ppkg);
}
}
}
}
for (int i = 0; i < ELEMENTLEN(msi_names); i++)
{
FOREACH(JSONObject *, pkg, checked_pkgs)
if (!msi_packages[i]) continue;
JSONObject *pls = json_map_get(msi_packages[i], "payloads");
FOREACH(JSONObject *, pl, pls->elements)
{
JSONObject *pls = json_map_get(pkg, "payloads");
if (!pls) continue;
FOREACH(JSONObject *, pl, pls->elements)
const char *f_name = json_map_get(pl, "fileName")->str;
if (STRCASECMP(filename(f_name), msi_names[i]) == 0)
{
const char *f_name = json_map_get(pl, "fileName")->str;
if (STRCASECMP(filename(f_name), msi_names[i]) == 0)
char *mpath = (char *)file_append_path(dl_root, msi_names[i]);
if (download_with_verification(json_map_get(pl, "url")->str, msi_names[i], mpath))
{
char *mpath = (char *)file_append_path(dl_root, msi_names[i]);
if (download_with_verification(json_map_get(pl, "url")->str, msi_names[i], mpath))
{
get_msi_cab_list(mpath, &cab_list);
}
goto NEXT_MSI;
get_msi_cab_list(mpath, &cab_list);
}
goto NEXT_MSI;
}
}
NEXT_MSI:;
NEXT_MSI:
progress += 10;
print_progress(progress);
}
int cabs_done = 0;
int cab_count = vec_size(cab_list);
FOREACH(const char *, cab, cab_list)
{
FOREACH(JSONObject *, pkg, checked_pkgs)
@@ -665,7 +697,9 @@ void fetch_msvc(BuildOptions *options)
}
}
}
NEXT_CAB:;
NEXT_CAB:
cabs_done++;
if (cab_count > 0) print_progress(70 + (20 * cabs_done) / cab_count);
}
for (int i = 0; i < ELEMENTLEN(msi_names); i++)
@@ -674,16 +708,13 @@ void fetch_msvc(BuildOptions *options)
if (file_exists(mpath))
{
extract_msi(mpath, out_root, dl_root);
if (verbose_level == 0)
{
printf(".");
fflush(stdout);
}
print_progress(90 + (10 * (i + 1)) / ELEMENTLEN(msi_names));
}
}
if (verbose_level == 0)
{
print_progress(100);
printf(" Done.\n");
fflush(stdout);
}