nixpkgs mirror (for testing) github.com/NixOS/nixpkgs
nix
fork

Configure Feed

Select the types of activity you want to include in your feed.

pluginupdate.py: add support for adding/updating individual plugins

+203 -45
+6 -1
doc/languages-frameworks/vim.section.md
··· 264 264 Alternatively, set the number of processes to a lower count to avoid rate-limiting. 265 265 266 266 ```sh 267 - 268 267 nix-shell -p vimPluginsUpdater --run 'vim-plugins-updater --proc 1' 268 + ``` 269 + 270 + 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. 271 + 272 + ```sh 273 + nix-shell -p vimPluginsUpdater --run 'vim-plugins-updater update "nvim-treesitter" "LazyVim"' 269 274 ``` 270 275 271 276 ## How to maintain an out-of-tree overlay of vim plugins ? {#vim-out-of-tree-overlays}
+145 -12
maintainers/scripts/pluginupdate-py/pluginupdate.py
··· 388 388 fetch_config, args.input_file, editor.deprecated, append=append 389 389 ) 390 390 plugin, _ = prefetch_plugin(pdesc) 391 + 392 + if ( # lua updater doesn't support updating individual plugin 393 + self.name != "lua" 394 + ): 395 + # update generated.nix 396 + update = self.get_update( 397 + args.input_file, 398 + args.outfile, 399 + fetch_config, 400 + [plugin.normalized_name], 401 + ) 402 + update() 403 + 391 404 autocommit = not args.no_commit 392 405 if autocommit: 393 406 commit( ··· 417 404 """CSV spec""" 418 405 print("the update member function should be overridden in subclasses") 419 406 420 - def get_current_plugins(self, nixpkgs: str) -> List[Plugin]: 407 + def get_current_plugins( 408 + self, config: FetchConfig, nixpkgs: str 409 + ) -> List[Tuple[PluginDesc, Plugin]]: 421 410 """To fill the cache""" 422 411 data = run_nix_expr(self.get_plugins, nixpkgs) 423 412 plugins = [] 424 413 for name, attr in data.items(): 425 - p = Plugin(name, attr["rev"], attr["submodules"], attr["sha256"]) 426 - plugins.append(p) 414 + checksum = attr["checksum"] 415 + 416 + # https://github.com/NixOS/nixpkgs/blob/8a335419/pkgs/applications/editors/neovim/build-neovim-plugin.nix#L36 417 + # https://github.com/NixOS/nixpkgs/pull/344478#discussion_r1786646055 418 + version = re.search(r"\d\d\d\d-\d\d?-\d\d?", attr["version"]) 419 + if version is None: 420 + raise ValueError(f"Cannot parse version: {attr['version']}") 421 + date = datetime.strptime(version.group(), "%Y-%m-%d") 422 + 423 + pdesc = PluginDesc.load_from_string(config, f'{attr["homePage"]} as {name}') 424 + p = Plugin( 425 + attr["pname"], 426 + checksum["rev"], 427 + checksum["submodules"], 428 + checksum["sha256"], 429 + date, 430 + ) 431 + 432 + plugins.append((pdesc, p)) 427 433 return plugins 428 434 429 435 def load_plugin_spec(self, config: FetchConfig, plugin_file) -> List[PluginDesc]: ··· 453 421 """Returns nothing for now, writes directly to outfile""" 454 422 raise NotImplementedError() 455 423 456 - def get_update(self, input_file: str, outfile: str, config: FetchConfig): 457 - cache: Cache = Cache(self.get_current_plugins(self.nixpkgs), self.cache_file) 424 + def filter_plugins_to_update( 425 + self, plugin: PluginDesc, to_update: List[str] 426 + ) -> bool: 427 + """Function for filtering out plugins, that user doesn't want to update. 428 + 429 + It is mainly used for updating only specific plugins, not all of them. 430 + By default it filters out plugins not present in `to_update`, 431 + assuming `to_update` is a list of plugin names (the same as in the 432 + result expression). 433 + 434 + This function is never called if `to_update` is empty. 435 + Feel free to override this function in derived classes. 436 + 437 + Note: 438 + Known bug: you have to use a deprecated name, instead of new one. 439 + This is because we resolve deprecations later and can't get new 440 + plugin URL before we request info about it. 441 + 442 + Although, we could parse deprecated.json, but it's a whole bunch 443 + of spaghetti code, which I don't want to write. 444 + 445 + Arguments: 446 + plugin: Plugin on which you decide whether to ignore or not. 447 + to_update: 448 + List of strings passed to via the `--update` command line parameter. 449 + By default, we assume it is a list of URIs identical to what 450 + is in the input file. 451 + 452 + Returns: 453 + True if we should update plugin and False if not. 454 + """ 455 + return plugin.name.replace(".", "-") in to_update 456 + 457 + def get_update( 458 + self, 459 + input_file: str, 460 + output_file: str, 461 + config: FetchConfig, 462 + to_update: Optional[List[str]], 463 + ): 464 + if to_update is None: 465 + to_update = [] 466 + 467 + current_plugins = self.get_current_plugins(config, self.nixpkgs) 468 + current_plugin_specs = self.load_plugin_spec(config, input_file) 469 + 470 + cache: Cache = Cache( 471 + [plugin for _description, plugin in current_plugins], self.cache_file 472 + ) 458 473 _prefetch = functools.partial(prefetch, cache=cache) 459 474 460 - def update() -> dict: 461 - plugins = self.load_plugin_spec(config, input_file) 475 + plugins_to_update = ( 476 + current_plugin_specs 477 + if len(to_update) == 0 478 + else [ 479 + description 480 + for description in current_plugin_specs 481 + if self.filter_plugins_to_update(description, to_update) 482 + ] 483 + ) 484 + 485 + def update() -> Redirects: 486 + if len(plugins_to_update) == 0: 487 + log.error( 488 + "\n\n\n\nIt seems like you provided some arguments to `--update`:\n" 489 + + ", ".join(to_update) 490 + + "\nBut after filtering, the result list of plugins is empty\n" 491 + "\n" 492 + "Are you sure you provided the same URIs as in your input file?\n" 493 + "(" + str(input_file) + ")\n\n" 494 + ) 495 + return {} 462 496 463 497 try: 464 498 pool = Pool(processes=config.proc) 465 - results = pool.map(_prefetch, plugins) 499 + results = pool.map(_prefetch, plugins_to_update) 466 500 finally: 467 501 cache.store() 468 502 503 + print(f"{len(results)} of {len(current_plugins)} were checked") 504 + # Do only partial update of out file 505 + if len(results) != len(current_plugins): 506 + results = self.merge_results(current_plugins, results) 469 507 plugins, redirects = check_results(results) 470 508 471 509 plugins = sorted(plugins, key=lambda v: v[1].normalized_name) 472 - self.generate_nix(plugins, outfile) 510 + self.generate_nix(plugins, output_file) 473 511 474 512 return redirects 475 513 476 514 return update 515 + 516 + def merge_results( 517 + self, 518 + current: list[Tuple[PluginDesc, Plugin]], 519 + fetched: List[Tuple[PluginDesc, Union[Exception, Plugin], Optional[Repo]]], 520 + ) -> List[Tuple[PluginDesc, Union[Exception, Plugin], Optional[Repo]]]: 521 + # transforming this to dict, so lookup is O(1) instead of O(n) (n is len(current)) 522 + result: Dict[ 523 + str, Tuple[PluginDesc, Union[Exception, Plugin], Optional[Repo]] 524 + ] = { 525 + # also adding redirect (third item in the result tuple) 526 + pl.normalized_name: (pdesc, pl, None) 527 + for pdesc, pl in current 528 + } 529 + 530 + for plugin_desc, plugin, redirect in fetched: 531 + result[plugin.normalized_name] = (plugin_desc, plugin, redirect) 532 + 533 + return list(result.values()) 477 534 478 535 @property 479 536 def attr_path(self): ··· 665 544 description="Update all or a subset of existing plugins", 666 545 add_help=False, 667 546 ) 547 + pupdate.add_argument( 548 + "update_only", 549 + default=None, 550 + nargs="*", 551 + help="Plugin URLs to update (must be the same as in the input file)", 552 + ) 668 553 pupdate.set_defaults(func=self.update) 669 554 return main 670 555 ··· 764 637 new_pdesc = PluginDesc(redirect, pdesc.branch, pdesc.alias) 765 638 plugins.append((new_pdesc, result)) 766 639 767 - print(f"{len(results) - len(failures)} plugins were checked", end="") 768 640 if len(failures) == 0: 769 641 return plugins, redirects 770 642 else: 771 - log.error(f", {len(failures)} plugin(s) could not be downloaded:\n") 643 + log.error(f"{len(failures)} plugin(s) could not be downloaded:\n") 772 644 773 645 for plugin, exception in failures: 774 646 print_download_error(plugin, exception) ··· 928 802 ) 929 803 930 804 fetch_config = FetchConfig(args.proc, args.github_token) 931 - update = editor.get_update(args.input_file, args.outfile, fetch_config) 805 + update = editor.get_update( 806 + input_file=args.input_file, 807 + output_file=args.outfile, 808 + config=fetch_config, 809 + to_update=getattr( # if script was called without arguments 810 + args, "update_only", None 811 + ), 812 + ) 932 813 933 814 start_time = time.time() 934 815 redirects = update()
+20 -18
pkgs/applications/editors/kakoune/plugins/update.py
··· 21 21 ) 22 22 import pluginupdate 23 23 24 - GET_PLUGINS = f"""( 25 - with import <localpkgs> {{ }}; 24 + GET_PLUGINS = f"""with import <localpkgs> {{ }}; 26 25 let 27 26 inherit (kakouneUtils.override {{ }}) buildKakounePluginFrom2Nix; 28 - generated = callPackage {ROOT}/generated.nix {{ 29 - inherit buildKakounePluginFrom2Nix; 30 - }}; 27 + generated = callPackage {ROOT}/generated.nix {{ inherit buildKakounePluginFrom2Nix; }}; 28 + 31 29 hasChecksum = 32 30 value: 33 31 lib.isAttrs value ··· 33 35 "src" 34 36 "outputHash" 35 37 ] value; 36 - getChecksum = 37 - name: value: 38 - if hasChecksum value then 39 - {{ 40 - submodules = value.src.fetchSubmodules or false; 41 - sha256 = value.src.outputHash; 42 - rev = value.src.rev; 43 - }} 44 - else 45 - null; 46 - checksums = lib.mapAttrs getChecksum generated; 38 + 39 + parse = name: value: {{ 40 + pname = value.pname; 41 + version = value.version; 42 + homePage = value.meta.homepage; 43 + checksum = 44 + if hasChecksum value then 45 + {{ 46 + submodules = value.src.fetchSubmodules or false; 47 + sha256 = value.src.outputHash; 48 + rev = value.src.rev; 49 + }} 50 + else 51 + null; 52 + }}; 47 53 in 48 - lib.filterAttrs (n: v: v != null) checksums 49 - )""" 54 + lib.mapAttrs parse generated""" 50 55 51 56 HEADER = "# This file has been @generated by ./pkgs/applications/editors/kakoune/plugins/update.py. Do not edit!" 57 + 52 58 53 59 54 60 class KakouneEditor(pluginupdate.Editor):
+17 -12
pkgs/applications/editors/vim/plugins/get-plugins.nix
··· 6 6 generated = callPackage <localpkgs/pkgs/applications/editors/vim/plugins/generated.nix> { 7 7 inherit buildNeovimPlugin buildVimPlugin; 8 8 } { } { }; 9 + 9 10 hasChecksum = 10 11 value: 11 12 lib.isAttrs value ··· 14 13 "src" 15 14 "outputHash" 16 15 ] value; 17 - getChecksum = 18 - name: value: 19 - if hasChecksum value then 20 - { 21 - submodules = value.src.fetchSubmodules or false; 22 - sha256 = value.src.outputHash; 23 - rev = value.src.rev; 24 - } 25 - else 26 - null; 27 - checksums = lib.mapAttrs getChecksum generated; 16 + 17 + parse = name: value: { 18 + pname = value.pname; 19 + version = value.version; 20 + homePage = value.meta.homepage; 21 + checksum = 22 + if hasChecksum value then 23 + { 24 + submodules = value.src.fetchSubmodules or false; 25 + sha256 = value.src.outputHash; 26 + rev = value.src.rev; 27 + } 28 + else 29 + null; 30 + }; 28 31 in 29 - lib.filterAttrs (n: v: v != null) checksums 32 + lib.mapAttrs parse generated
+15 -2
pkgs/by-name/lu/luarocks-packages-updater/updater.py
··· 25 25 log = logging.getLogger() 26 26 log.addHandler(logging.StreamHandler()) 27 27 28 - ROOT = Path(os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))).parent.parent # type: ignore 28 + ROOT = Path( 29 + os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) 30 + ).parent.parent # type: ignore 29 31 30 32 PKG_LIST = "maintainers/scripts/luarocks-packages.csv" 31 33 TMP_FILE = "$(mktemp)" ··· 123 121 def attr_path(self): 124 122 return "luaPackages" 125 123 126 - def get_update(self, input_file: str, outfile: str, config: FetchConfig): 124 + def get_update( 125 + self, 126 + input_file: str, 127 + outfile: str, 128 + config: FetchConfig, 129 + # TODO: implement support for adding/updating individual plugins 130 + to_update: Optional[List[str]], 131 + ): 132 + if to_update is not None: 133 + raise NotImplementedError( 134 + "For now, lua updater doesn't support updating individual packages." 135 + ) 127 136 _prefetch = generate_pkg_nix 128 137 129 138 def update() -> dict: