···264264Alternatively, set the number of processes to a lower count to avoid rate-limiting.265265266266```sh267267-268267nix-shell -p vimPluginsUpdater --run 'vim-plugins-updater --proc 1'268268+```269269+270270+If you want to update only certain plugins, you can specify them after the `update` command. Note that you must use the same plugin names as the `pkgs/applications/editors/vim/plugins/vim-plugin-names` file.271271+272272+```sh273273+nix-shell -p vimPluginsUpdater --run 'vim-plugins-updater update "nvim-treesitter" "LazyVim"'269274```270275271276## How to maintain an out-of-tree overlay of vim plugins ? {#vim-out-of-tree-overlays}
···388388 fetch_config, args.input_file, editor.deprecated, append=append389389 )390390 plugin, _ = prefetch_plugin(pdesc)391391+392392+ if ( # lua updater doesn't support updating individual plugin393393+ self.name != "lua"394394+ ):395395+ # update generated.nix396396+ update = self.get_update(397397+ args.input_file,398398+ args.outfile,399399+ fetch_config,400400+ [plugin.normalized_name],401401+ )402402+ update()403403+391404 autocommit = not args.no_commit392405 if autocommit:393406 commit(···417404 """CSV spec"""418405 print("the update member function should be overridden in subclasses")419406420420- def get_current_plugins(self, nixpkgs: str) -> List[Plugin]:407407+ def get_current_plugins(408408+ self, config: FetchConfig, nixpkgs: str409409+ ) -> List[Tuple[PluginDesc, Plugin]]:421410 """To fill the cache"""422411 data = run_nix_expr(self.get_plugins, nixpkgs)423412 plugins = []424413 for name, attr in data.items():425425- p = Plugin(name, attr["rev"], attr["submodules"], attr["sha256"])426426- plugins.append(p)414414+ checksum = attr["checksum"]415415+416416+ # https://github.com/NixOS/nixpkgs/blob/8a335419/pkgs/applications/editors/neovim/build-neovim-plugin.nix#L36417417+ # https://github.com/NixOS/nixpkgs/pull/344478#discussion_r1786646055418418+ version = re.search(r"\d\d\d\d-\d\d?-\d\d?", attr["version"])419419+ if version is None:420420+ raise ValueError(f"Cannot parse version: {attr['version']}")421421+ date = datetime.strptime(version.group(), "%Y-%m-%d")422422+423423+ pdesc = PluginDesc.load_from_string(config, f'{attr["homePage"]} as {name}')424424+ p = Plugin(425425+ attr["pname"],426426+ checksum["rev"],427427+ checksum["submodules"],428428+ checksum["sha256"],429429+ date,430430+ )431431+432432+ plugins.append((pdesc, p))427433 return plugins428434429435 def load_plugin_spec(self, config: FetchConfig, plugin_file) -> List[PluginDesc]:···453421 """Returns nothing for now, writes directly to outfile"""454422 raise NotImplementedError()455423456456- def get_update(self, input_file: str, outfile: str, config: FetchConfig):457457- cache: Cache = Cache(self.get_current_plugins(self.nixpkgs), self.cache_file)424424+ def filter_plugins_to_update(425425+ self, plugin: PluginDesc, to_update: List[str]426426+ ) -> bool:427427+ """Function for filtering out plugins, that user doesn't want to update.428428+429429+ It is mainly used for updating only specific plugins, not all of them.430430+ By default it filters out plugins not present in `to_update`,431431+ assuming `to_update` is a list of plugin names (the same as in the432432+ result expression).433433+434434+ This function is never called if `to_update` is empty.435435+ Feel free to override this function in derived classes.436436+437437+ Note:438438+ Known bug: you have to use a deprecated name, instead of new one.439439+ This is because we resolve deprecations later and can't get new440440+ plugin URL before we request info about it.441441+442442+ Although, we could parse deprecated.json, but it's a whole bunch443443+ of spaghetti code, which I don't want to write.444444+445445+ Arguments:446446+ plugin: Plugin on which you decide whether to ignore or not.447447+ to_update:448448+ List of strings passed to via the `--update` command line parameter.449449+ By default, we assume it is a list of URIs identical to what450450+ is in the input file.451451+452452+ Returns:453453+ True if we should update plugin and False if not.454454+ """455455+ return plugin.name.replace(".", "-") in to_update456456+457457+ def get_update(458458+ self,459459+ input_file: str,460460+ output_file: str,461461+ config: FetchConfig,462462+ to_update: Optional[List[str]],463463+ ):464464+ if to_update is None:465465+ to_update = []466466+467467+ current_plugins = self.get_current_plugins(config, self.nixpkgs)468468+ current_plugin_specs = self.load_plugin_spec(config, input_file)469469+470470+ cache: Cache = Cache(471471+ [plugin for _description, plugin in current_plugins], self.cache_file472472+ )458473 _prefetch = functools.partial(prefetch, cache=cache)459474460460- def update() -> dict:461461- plugins = self.load_plugin_spec(config, input_file)475475+ plugins_to_update = (476476+ current_plugin_specs477477+ if len(to_update) == 0478478+ else [479479+ description480480+ for description in current_plugin_specs481481+ if self.filter_plugins_to_update(description, to_update)482482+ ]483483+ )484484+485485+ def update() -> Redirects:486486+ if len(plugins_to_update) == 0:487487+ log.error(488488+ "\n\n\n\nIt seems like you provided some arguments to `--update`:\n"489489+ + ", ".join(to_update)490490+ + "\nBut after filtering, the result list of plugins is empty\n"491491+ "\n"492492+ "Are you sure you provided the same URIs as in your input file?\n"493493+ "(" + str(input_file) + ")\n\n"494494+ )495495+ return {}462496463497 try:464498 pool = Pool(processes=config.proc)465465- results = pool.map(_prefetch, plugins)499499+ results = pool.map(_prefetch, plugins_to_update)466500 finally:467501 cache.store()468502503503+ print(f"{len(results)} of {len(current_plugins)} were checked")504504+ # Do only partial update of out file505505+ if len(results) != len(current_plugins):506506+ results = self.merge_results(current_plugins, results)469507 plugins, redirects = check_results(results)470508471509 plugins = sorted(plugins, key=lambda v: v[1].normalized_name)472472- self.generate_nix(plugins, outfile)510510+ self.generate_nix(plugins, output_file)473511474512 return redirects475513476514 return update515515+516516+ def merge_results(517517+ self,518518+ current: list[Tuple[PluginDesc, Plugin]],519519+ fetched: List[Tuple[PluginDesc, Union[Exception, Plugin], Optional[Repo]]],520520+ ) -> List[Tuple[PluginDesc, Union[Exception, Plugin], Optional[Repo]]]:521521+ # transforming this to dict, so lookup is O(1) instead of O(n) (n is len(current))522522+ result: Dict[523523+ str, Tuple[PluginDesc, Union[Exception, Plugin], Optional[Repo]]524524+ ] = {525525+ # also adding redirect (third item in the result tuple)526526+ pl.normalized_name: (pdesc, pl, None)527527+ for pdesc, pl in current528528+ }529529+530530+ for plugin_desc, plugin, redirect in fetched:531531+ result[plugin.normalized_name] = (plugin_desc, plugin, redirect)532532+533533+ return list(result.values())477534478535 @property479536 def attr_path(self):···665544 description="Update all or a subset of existing plugins",666545 add_help=False,667546 )547547+ pupdate.add_argument(548548+ "update_only",549549+ default=None,550550+ nargs="*",551551+ help="Plugin URLs to update (must be the same as in the input file)",552552+ )668553 pupdate.set_defaults(func=self.update)669554 return main670555···764637 new_pdesc = PluginDesc(redirect, pdesc.branch, pdesc.alias)765638 plugins.append((new_pdesc, result))766639767767- print(f"{len(results) - len(failures)} plugins were checked", end="")768640 if len(failures) == 0:769641 return plugins, redirects770642 else:771771- log.error(f", {len(failures)} plugin(s) could not be downloaded:\n")643643+ log.error(f"{len(failures)} plugin(s) could not be downloaded:\n")772644773645 for plugin, exception in failures:774646 print_download_error(plugin, exception)···928802 )929803930804 fetch_config = FetchConfig(args.proc, args.github_token)931931- update = editor.get_update(args.input_file, args.outfile, fetch_config)805805+ update = editor.get_update(806806+ input_file=args.input_file,807807+ output_file=args.outfile,808808+ config=fetch_config,809809+ to_update=getattr( # if script was called without arguments810810+ args, "update_only", None811811+ ),812812+ )932813933814 start_time = time.time()934815 redirects = update()