Skip to content

Commit 60abf8a

Browse files
committed
pkg: Rework downloading package metadata
Passing the '-refresh' option to 'pkg update' etc was previously causing a fresh download of metadata from the server for each installed package. This changeset fixes that behavior so that passing '-refresh' only causes one new download of metadata, irrespective of the number of installed packages. All changes in directory 'scripts/pkg/': * pkg.m: Preload package metadata, call get_validated_pkg_list() directly. * private/get_pkg_info.m: Remove function calls to update package metadata, change calling form, update documentation to match. * private/get_validated_pkg_list.m: Rework logic to save metadata to cache. * private/search_packages.m: Change calling form, update documentation to match.
1 parent 5faeb10 commit 60abf8a

File tree

4 files changed

+53
-35
lines changed

4 files changed

+53
-35
lines changed

scripts/pkg/pkg.m

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -525,17 +525,24 @@
525525
error ("pkg: search action requires at least one search term or '-all'");
526526
endif
527527

528+
## Pre-load package database (respecting force_refresh flag)
529+
get_validated_pkg_list (force_refresh, verbose);
530+
528531
if (nargout)
529-
local_packages = search_packages (files, want_all_packages, force_refresh, verbose);
532+
local_packages = search_packages (files, want_all_packages, verbose);
530533
else
531-
search_packages (files, want_all_packages, force_refresh, verbose);
534+
search_packages (files, want_all_packages, verbose);
532535
endif
533536

534537
case "install"
535538
if (isempty (files))
536539
error ("pkg: install action requires at least one filename");
537540
endif
538541

542+
## Pre-load package database once (respecting force_refresh flag)
543+
## This ensures package name lookups don't trigger repeated downloads
544+
get_validated_pkg_list (force_refresh, verbose);
545+
539546
local_files = {};
540547
tmp_dir = tempname ();
541548
unwind_protect
@@ -577,7 +584,7 @@
577584
## manually, just in case the package author chooses zip
578585
## or any other archive format? Or will all packages always
579586
## be required to give .tar.gz?
580-
[v, url] = get_pkg_info (file, force_refresh, verbose);
587+
[v, url] = get_pkg_info (file, verbose);
581588
tmp_file = tempname (tmp_dir, [file "-" v "-"]);
582589
tmp_file = [tmp_file, ".tar.gz"];
583590
local_files{end+1} = tmp_file; # so that it gets cleaned up
@@ -777,18 +784,25 @@
777784
installed_pkgs_lst = update_lst;
778785
endif
779786

787+
## Pre-load package database once (respecting force_refresh flag)
788+
## This prevents repeated downloads in the loop below
789+
get_validated_pkg_list (force_refresh, verbose);
790+
780791
for i = 1:numel (installed_pkgs_lst)
781792
installed_pkg_name = installed_pkgs_lst{i}.name;
782793
installed_pkg_version = installed_pkgs_lst{i}.version;
783794
try
784-
online_pkg_version = get_pkg_info (installed_pkg_name, force_refresh, verbose);
795+
## Use already-loaded package database
796+
online_pkg_version = get_pkg_info (installed_pkg_name, verbose);
785797
catch
786798
warning ("pkg: package %s not found on Octave Packages - skipping update\n",
787799
installed_pkg_name);
788800
online_pkg_version = "0";
789801
end_try_catch
790802
if (compare_versions (online_pkg_version, installed_pkg_version, ">"))
803+
## Pass options but exclude -refresh (we already refreshed once above)
791804
options_to_pass = varargin (strncmp (varargin, "-", 1));
805+
options_to_pass(strcmp (options_to_pass, "-refresh")) = [];
792806
feval (@pkg, "install", options_to_pass{:}, installed_pkg_name);
793807
endif
794808
endfor

scripts/pkg/private/get_pkg_info.m

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,13 @@
2525

2626
## -*- texinfo -*-
2727
## @deftypefn {} {[@var{ver}, @var{url}] =} get_pkg_info (@var{name})
28-
## @deftypefnx {} {[@var{ver}, @var{url}] =} get_pkg_info (@var{name}, @var{force_refresh})
29-
## @deftypefnx {} {[@var{ver}, @var{url}] =} get_pkg_info (@var{name}, @var{force_refresh}, @var{verbose})
28+
## @deftypefnx {} {[@var{ver}, @var{url}] =} get_pkg_info (@var{name}, @var{verbose})
3029
## Return the current version and URL of the Octave package @var{name}.
3130
##
32-
## If @var{force_refresh} is true, always download fresh data from the server.
33-
##
3431
## If @var{verbose} is true, print diagnostic messages.
3532
## @end deftypefn
3633

37-
function [ver, url] = get_pkg_info (name, force_refresh = false, verbose = false)
34+
function [ver, url] = get_pkg_info (name, verbose = false)
3835

3936
## Verify that name is valid.
4037
if (! (ischar (name) && rows (name) == 1 && ndims (name) == 2))
@@ -45,7 +42,7 @@
4542

4643
name = lower (name);
4744

48-
__pkg__ = get_validated_pkg_list (force_refresh, verbose);
45+
__pkg__ = get_validated_pkg_list (false, verbose);
4946
pkgnames = fieldnames (__pkg__); # all the different packages
5047

5148
if (any (strcmp (pkgnames, name))) # named package does exist

scripts/pkg/private/get_validated_pkg_list.m

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,8 @@
218218
endif
219219

220220
## Download fresh data from server
221+
downloaded_fresh_data = false;
222+
221223
if (verbose || force_refresh)
222224
printf ("pkg: downloading latest package database from packages.octave.org...\n");
223225
if (! verbose)
@@ -234,7 +236,7 @@
234236
if (! succ)
235237
## Primary failed, try backup
236238
if (verbose)
237-
printf ("pkg: primary repository unavailable, trying backup...\n");
239+
printf ("pkg: primary repository unavailable, trying backup from gnu-octave.github.io...\n");
238240
endif
239241
[list, succ] = urlread (backup_url);
240242
endif
@@ -272,6 +274,11 @@
272274
else
273275
error ("pkg: could not read URL and no cache available, please verify internet connection");
274276
endif
277+
else
278+
## Download succeeded - capture timestamp
279+
## This reflects actual data freshness, not when we started trying
280+
download_time = now ();
281+
downloaded_fresh_data = true;
275282
endif
276283

277284
if (verbose)
@@ -289,22 +296,24 @@
289296
printf ("pkg: successfully parsed %d packages\n", numel (fieldnames (__pkg__)));
290297
endif
291298

292-
## Save to cache with timestamp in filename
293-
try
294-
## Create cache directory if it doesn't exist
295-
if (! exist (cache_dir, "dir"))
296-
if (verbose)
297-
printf ("pkg: creating cache directory: %s\n", cache_dir);
298-
endif
299-
[success, msg] = mkdir (cache_dir);
300-
if (! success)
301-
warning ("pkg: could not create cache directory: %s", msg);
299+
## Save to cache with timestamp in filename (only if we downloaded fresh data)
300+
if (downloaded_fresh_data)
301+
try
302+
## Create cache directory if it doesn't exist
303+
if (! exist (cache_dir, "dir"))
304+
if (verbose)
305+
printf ("pkg: creating cache directory: %s\n", cache_dir);
306+
endif
307+
[success, msg] = mkdir (cache_dir);
308+
if (! success)
309+
warning ("pkg: could not create cache directory: %s", msg);
310+
endif
302311
endif
303-
endif
304312

305313
## Generate timestamped filename using datestr
306314
## Format: packages_yyyymmddHHMM.json
307-
timestamp_str = datestr (now (), "yyyymmddHHMM");
315+
## Use download_time, not current time, so timestamp reflects data age
316+
timestamp_str = datestr (download_time, "yyyymmddHHMM");
308317
new_cache_file = fullfile (cache_dir, ["packages_" timestamp_str ".json"]);
309318

310319
if (verbose)
@@ -346,12 +355,13 @@
346355
end_try_catch
347356
endfor
348357
endif
349-
else
350-
warning ("pkg: could not write to cache file");
351-
endif
352-
catch
353-
warning ("pkg: error updating cache: %s", lasterr ());
354-
end_try_catch
358+
else
359+
warning ("pkg: could not write to cache file");
360+
endif
361+
catch
362+
warning ("pkg: error updating cache: %s", lasterr ());
363+
end_try_catch
364+
endif ## if (downloaded_fresh_data)
355365

356366
retval = __pkg__;
357367

scripts/pkg/private/search_packages.m

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,7 @@
2525

2626
## -*- texinfo -*-
2727
## @deftypefn {} {@var{retval} =} search_packages (@var{searchterms}, @var{allpackages})
28-
## @deftypefnx {} {@var{retval} =} search_packages (@var{searchterms}, @var{allpackages}, @var{force_refresh})
29-
## @deftypefnx {} {@var{retval} =} search_packages (@var{searchterms}, @var{allpackages}, @var{force_refresh}, @var{verbose})
28+
## @deftypefnx {} {@var{retval} =} search_packages (@var{searchterms}, @var{allpackages}, @var{verbose})
3029
## Search for all packages on the Octave Packages repository whose
3130
## descriptions include @var{searchterms}, then either display the search
3231
## results with brief descriptions, or return the list of matching packages
@@ -36,14 +35,12 @@
3635
## If @var{allpackages} is true, then return / display all packages,
3736
## with no filtering for @var{searchterms}.
3837
##
39-
## If @var{force_refresh} is true, always download fresh data from the server.
40-
##
4138
## If @var{verbose} is true, print diagnostic messages.
4239
## @end deftypefn
4340

44-
function retval = search_packages (searchterms, allpackages, force_refresh = false, verbose = false)
41+
function retval = search_packages (searchterms, allpackages, verbose = false)
4542

46-
__pkg__ = get_validated_pkg_list (force_refresh, verbose);
43+
__pkg__ = get_validated_pkg_list (false, verbose);
4744

4845
pkgnames = fieldnames (__pkg__);
4946

0 commit comments

Comments
 (0)