Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions pkgs/desktops/gnome/extensions/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# GNOME Shell extensions

All extensions are packaged automatically. They can be found in the `pkgs.gnomeXYExtensions` for XY being a GNOME version. The package names are the extension’s UUID, which can be a bit unwieldy to use. `pkgs.gnomeExtensions` is a set of manually curated extensions that match the current `gnome.gnome-shell` versions. Their name is human-friendly, compared to the other extensions sets. Some of its extensions are manually packaged.

## Automatically packaged extensions

The actual packages are created by `buildGnomeExtensions.nix`, provided the correct arguments are fed into it. The important extension data is stored in `extensions.json`, one line/item per extension. That file is generated by running `update-extensions.py`. Furthermore, the automatic generated names are dumped in `collisions.json` for manual inspection. `extensionRenames.nix` contains provides new names for all extensions that collide.

### Extensions updates

For everyday updates,

1. Run `update-extensions.py`.
2. Update `extensionRenames.nix` according to the comment at the top.

For GNOME updates,

1. Add a new `gnomeXYExtensions` set
2. Remove old ones for GNOME versions we don’t want to support any more
3. Update `supported_versions` in `./update-extensions.py` and re-run it
4. Change `gnomeExtensions` to the new version
5. Update `./extensionsRenames.nix` accordingly

## Manually packaged extensions

Manually packaged extensions overwrite some of the automatically packaged ones in `pkgs.gnomeExtensions`. They are listed in `manuallyPackaged.nix`, every extension has its own sub-folder.
54 changes: 54 additions & 0 deletions pkgs/desktops/gnome/extensions/buildGnomeExtension.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
{ pkgs, lib, stdenv, fetchzip }:

let

buildGnomeExtension = {
# Every gnome extension has a UUID. It's the name of the extension folder once unpacked
# and can always be found in the metadata.json of every extension.
uuid,
name,
pname,
description,
# extensions.gnome.org extension URL
link,
# Extension version numbers are integers
version,
sha256,
# Hex-encoded string of JSON bytes
metadata,
}:

stdenv.mkDerivation {
inherit pname;
version = builtins.toString version;
src = fetchzip {
url = "https://extensions.gnome.org/extension-data/${
builtins.replaceStrings [ "@" ] [ "" ] uuid
}.v${builtins.toString version}.shell-extension.zip";
inherit sha256;
stripRoot = false;
# The download URL may change content over time. This is because the
# metadata.json is automatically generated, and parts of it can be changed
# without making a new release. We simply substitute the possibly changed fields
# with their content from when we last updated, and thus get a deterministic output
# hash.
extraPostFetch = ''
echo "${metadata}" | base64 --decode > $out/metadata.json
'';
};
buildCommand = ''
mkdir -p $out/share/gnome-shell/extensions/
cp -r -T $src $out/share/gnome-shell/extensions/${uuid}
'';
meta = {
description = builtins.head (lib.splitString "\n" description);
longDescription = description;
homepage = link;
license = lib.licenses.gpl2Plus; # https://wiki.gnome.org/Projects/GnomeShell/Extensions/Review#Licensing
maintainers = with lib.maintainers; [ piegames ];
};
# Store the extension's UUID, because we might need it at some places
passthru.extensionUuid = uuid;
};
in
lib.makeOverridable buildGnomeExtension
42 changes: 42 additions & 0 deletions pkgs/desktops/gnome/extensions/collisions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we committing this? Is not this easily derivable from extensions.json?

We might want to add assertion that all collisions are handled in renames either way since instruction in a comment will get easily ignored.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am committing this because the diff is really useful when doing updates. I thought about adding a test that checks for collision handling, but I personally don't need it for maintaining.

"38": {
"applications-menu": [
"apps-menu@gnome-shell-extensions.gcampax.github.com",
"Applications_Menu@rmy.pobox.com"
],
"workspace-indicator": [
"workspace-indicator@gnome-shell-extensions.gcampax.github.com",
"horizontal-workspace-indicator@tty2.io"
],
"lock-keys": [
"lockkeys@vaina.lt",
"lockkeys@fawtytoo"
],
"fuzzy-clock": [
"Fuzzy_Clock@dallagi",
"fuzzy-clock@keepawayfromfire.co.uk"
],
"transparent-window": [
"transparent-window@pbxqdown.github.com",
"transparentwindows.mdirshad07"
],
"floating-dock": [
"floatingDock@sun.wxg@gmail.com",
"floating-dock@nandoferreira_prof@hotmail.com"
]
},
"40": {
"applications-menu": [
"apps-menu@gnome-shell-extensions.gcampax.github.com",
"Applications_Menu@rmy.pobox.com"
],
"workspace-indicator": [
"workspace-indicator@gnome-shell-extensions.gcampax.github.com",
"horizontal-workspace-indicator@tty2.io"
],
"lock-keys": [
"lockkeys@vaina.lt",
"lockkeys@fawtytoo"
]
}
}
73 changes: 73 additions & 0 deletions pkgs/desktops/gnome/extensions/default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
{ lib
, callPackage
, config
}:
let
buildShellExtension = callPackage ./buildGnomeExtension.nix { };

# Index of all scraped extensions (with supported versions)
extensionsIndex = lib.importJSON ./extensions.json;

# A list of UUIDs that have the same pname and we need to rename them
extensionRenames = import ./extensionRenames.nix;

# Take all extensions from the index that match the gnome version, build them and put them into a list of derivations
produceExtensionsList = shell-version:
lib.trivial.pipe extensionsIndex [
# Does a given extension match our current shell version?
(builtins.filter
(extension: (builtins.hasAttr shell-version extension."shell_version_map"))
)
# Take in an `extension` object from the JSON and transform it into the correct args to call `buildShellExtension`
(map
(extension: {
inherit (extension) uuid name description link pname;
inherit (extension.shell_version_map.${shell-version}) version sha256 metadata;
})
)
# Build them
(map buildShellExtension)
];

# Map the list of extensions to an attrset based on the UUID as key
mapUuidNames = extensions:
lib.trivial.pipe extensions [
(map (extension: lib.nameValuePair extension.extensionUuid extension))
builtins.listToAttrs
];

# Map the list of extensions to an attrset based on the pname as key, which is more human readable than the UUID
# We also take care of conflict renaming in here
mapReadableNames = extensionsList: lib.trivial.pipe extensionsList [
# Filter out all extensions that map to null
(lib.filter (extension:
!(
(builtins.hasAttr extension.extensionUuid extensionRenames)
&& ((builtins.getAttr extension.extensionUuid extensionRenames) == null)
)
))
# Map all extensions to their pname, with potential overwrites
(map (extension:
lib.nameValuePair (extensionRenames.${extension.extensionUuid} or extension.pname) extension
))
builtins.listToAttrs
];

in rec {
inherit buildShellExtension;

gnome38Extensions = mapUuidNames (produceExtensionsList "38");
gnome40Extensions = mapUuidNames (produceExtensionsList "40");

gnomeExtensions = lib.recurseIntoAttrs (
(mapReadableNames (produceExtensionsList "40"))
// (callPackage ./manuallyPackaged.nix {})
// lib.optionalAttrs (config.allowAliases or false) {
unite-shell = gnomeExtensions.unite; # added 2021-01-19
arc-menu = gnomeExtensions.arcmenu; # added 2021-02-14

nohotcorner = throw "gnomeExtensions.nohotcorner removed since 2019-10-09: Since 3.34, it is a part of GNOME Shell configurable through GNOME Tweaks.";
mediaplayer = throw "gnomeExtensions.mediaplayer deprecated since 2019-09-23: retired upstream https://github.com/JasonLG1979/gnome-shell-extensions-mediaplayer/blob/master/README.md";
}
);
}
29 changes: 29 additions & 0 deletions pkgs/desktops/gnome/extensions/extensionRenames.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# A list of UUIDs that have the same pname and we need to rename them
# MAINTENANCE:
# - Every item from ./collisions.json (for the respective Shell version) should have an entry in here
# - Set the value to `null` for filtering (duplicate or unmaintained extensions)
# - Sort the entries in order of appearance in the collisions.json
{
"apps-menu@gnome-shell-extensions.gcampax.github.com" = "applications-menu";
"Applications_Menu@rmy.pobox.com" = "frippery-applications-menu";

"workspace-indicator@gnome-shell-extensions.gcampax.github.com" = "workspace-indicator";
"horizontal-workspace-indicator@tty2.io" = "workspace-indicator-2";

"lockkeys@vaina.lt" = "lock-keys";
"lockkeys@fawtytoo" = "lock-keys-2";


# These are conflicts for 3.38 extensions. They will very probably come back
# once more of them support 40.

# See https://github.com/pbxqdown/gnome-shell-extension-transparent-window/issues/12#issuecomment-800765381
#"transparent-window@pbxqdown.github.com" = "transparent-window";
#"transparentwindows.mdirshad07" = null;

#"floatingDock@sun.wxg@gmail.com" = "floating-dock";
#"floating-dock@nandoferreira_prof@hotmail.com" = "floating-dock-2";

# That extension is broken because of https://github.com/NixOS/nixpkgs/issues/118612
#"flypie@schneegans.github.com" = null;
}
Loading