Skip to content

Latest commit

 

History

History
656 lines (460 loc) · 27.7 KB

7.Nix-Package-Flake-CustomDerivation-Multiple.md

File metadata and controls

656 lines (460 loc) · 27.7 KB

Birden Çok Paketi Aynı Repo Üzeriden Yayınlamak (Nix Öreniyoruz 7)

Bir önceki yazımızda Nix diline yeni eklenmiş olan Flake kavramı hakkında konuşmuştuk. Bu yazımızda elimizdeki paketleri bir repo üzerinden nasıl yayınlarız onu göreceğiz.

  1. NixOS: İşletim Sistemlerine Fonksiyonel Yaklaşım
  2. Nix Dili ve Özellikleri
  3. Nix Dili ile ilgili Alıştırmalar
  4. Nix Dilinde Builtins Fonksiyonlar
  5. Nix Paket Yöneticisi
  6. Nix Paket Yöneticisi Shell, Profile Kavram ve Komutları
  7. Nix Flake Nedir?
  8. Birden Çok Paketi Aynı Repo Üzeriden Yayınlamak
  9. Override ve Overlay Kavramları
  10. Nix Paket Yöneticisi ile Developer ve Profile Ortamları Oluşturmak
  11. Nix ile NixOs Konfigürasyonu
  12. NixOs Module ve Option Kullanımı
  13. NixOs Kurulumu ve Konfigürasyonu
  14. NixOs'u Cloud ve Uzak Ortamlara Deploy Etmek

Bunun için isterseniz bir kaç paket daha ekleyelim. Yeni paketlerinde eklendiği bu halini multi-app branch'inde bulabilirsiniz. Şu linkten kodları inceleyebilirsiniz.

Repo aynı zamanda farklı paket türlerini de örneklemiş oluyor.

  • default-app: Inline yazılmış bir shell script'ini nasıl paket olarak yayınlayacağımız gösteriyor.
  • default-alt-app: default-app'in alternatif bir versiyonu ancak önemli bir farklı var. Shell script'ini çalıştırmak için kullanılan paketleri de ayrı birer paket olarak yönetmemizi sağlıyor. Böylece daha iyi yonetilebilir paket oluşturabiliyoruz.
  • default-file-app: defaul-alt-app'in alternatif gibi düşünebiliriz. Temel farklı script'i bir dosyadan okuyor olması.
  • nix-app: Nixpkgs'den bir paketin flake içinden çağrılıp başka bir flake olarak sunulmasını gösteren bir örnek.
  • message-app: Daha önce yazmış olduğumuz message-third paketinin aynısı sadece derivation fonksiyonu flake.nix dosyasının içine taşınıdı.
  • test-app: daha önce yazdığımız message-third paketinin aynısı.

Flake dosyalarını biraz açalım.

  • Default-app paketinin flake dosyasında bakacak olursanız derivation ile ilgili bir tanım yok. Doğrudan bir paket oluşturmuyoruz. Ancak sonuçta bir script'imiz var ve bunu çalıştırıyoruz. Ancak Nix'in bir kolaylığı olarak shell'i doğrudan bir uygulamaymış gibi çalıştırma şansımız oluyor. Uygulamadaki writeShellScriptBin fonksiyonu ile bir script file oluşturabiliyoruz. 2 parametre alıyor biri dosya adı diğeride dosyanın içeriği. Örnekle ile iligi daha detaylı bilgi için şu sayfadaki örnkelere ve Nix Cookbook sayfasına göz atabilirsiniz.

  • Default-alt-app ise default-app in yani bir versiyonu. Default-app'de çalıştırdığımız script'ler için gerekli olan paketleri (cowsay ve ddate) sistem kendisi yönetiyor. Yani örneğin override edemiyorum yada fakrlı özelliklerini kontrol edemiyoruz. Ayrıca bütün paketler tek bir paketmiş gibi çalışıyor. Daha iyi yönetebilmemiz için ilgili paketleri de ayrı ayrı bağımlılık olarak kurmak işimize gelecektir. Bu neden flake içinde alttaki gibi bir blok ekledik.

app-buildInputs = with pkgs; [ cowsay ddate ];
      
in pkgs.symlinkJoin {
        name = app-name;
        paths = [ app-script ] ++ app-buildInputs; # override
        buildInputs = [ pkgs.makeWrapper ];
        postBuild = "wrapProgram $out/bin/${app-name} --prefix PATH : $out/bin";
      };

Burada kullanılan symlinkJoin kullanılan paketler için kendi paketimiz içinde sembolik linkler oluşturarak bağımlılık paketlerini doğrudan kendi paketimizin bulunduğu dizinde çalıştırılmasını sağlar. postBuild değişkeni, derleme işleminden sonra çalıştırılması gereken bir komut veya işlevi temsil eder. Bu durumda wrapProgram komutu kullanılır ve app-name ile belirtilen uygulamanın bir kopyası oluşturulur. Bu kopya, $out/bin klasörüne yerleştirilir ve PATH ortam değişkenine eklenir. yani wrapProgram fonksiyonu ile programların yapılandırmasını veya isimlerini değiştirmek için kullanabiliriz.

Kodu tekil olarak test etmek için klasör içindeyken nix run .# komutunu kullanabilirsiniz. Ayrıca oluşan paketi ve bağımlılık dosyalarını görmek için aynı dizinde oluşan result dizinini inceleyebilirsiniz.

  • default-file-app ise default-alt-app'in bir versiyonu. Tek farkı script'in bir dosyadan okunuyor olması. Bu durumda dosya okuma işlemi için builtins.readFile fonksiyonu kullanılıyor. Lokal dosyalarla çalışma konusunda nix.dev sayfasındaki şu linke bakabilirsiniz. Burada ayrıca patchShebangs adında bir fonksiyon kullandık. Bu fonksiyon yeni oluşturulacak script dosyasının shebang satırını düzenler.

writeTextFile, writeText, writeTextDir, writeScript, writeScriptBin fonksiyonların hepsi Nix Store'a text dosyası oluşturamak ve metin yazmak için kullanılır. Aynı zamanda script çalıştırabilmemizi de sağlar. Şu sayfadan detayları inceleyebilirsiniz.

Daha overlay ve override kavramlarını görmedik ancak burayı anlamak çok da zor değil. (pkgs.writeScriptBin app-name app-src). fonsksiyonun çıktısı aslında

  app-src = builtins.readFile ./script.sh;
  app-script = (pkgs.writeScriptBin app-name app-src).overrideAttrs(old: {
          buildCommand = "${old.buildCommand}\n patchShebangs $out";
        });
  • nix-app ise nix paket yöneticisinden br paketi alıp tekrar bir paket olarak nasıl sunarız onu gösteriyor.

Ancak son tahlilde amacımız bütün bu farklı paketleri tek bir flake altından kullandırmak. Yani farklı flake'leri tek bir flake altından nasıl sunarız onu görmek istiyoruz. Tabi bunu yapmanın daha güzel yolları da var zaten bir sonraki örneğimiz bunun üzerine olacak ancak illaki salt bir flake nasıl başka bir flake içinden çağrılır buna da ihtiyacımız olabilir diye bu örneği de eklemek istedim.

Bif flake'in sonucunu alıp kullanabilmek için flake'in outputs fonksiyonunu kullanmamız gerekiyor. Output fonksiyonunun çıktılarından biri de bildiğimiz üzere derivative. Onu da kendi flake'imiz içinde bir output derivative'i olarak dışarı açmış oluyoruz.

Tekrar hatırlatıyorum kodun tamamını multi-app branch'inde bulabilirsiniz. Şu linkten kodları inceleyebilirsiniz.

Bunun için kök dizinde yazdığımız flake şu şekilde.

{
  description = "My Nix Flake";
  inputs = {
      nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
  };
  outputs = { self, nixpkgs }:

  let

      default-app-flake = import ./default-app/flake.nix;
      default-app-output = default-app-flake.outputs {inherit self; inherit nixpkgs;};

      default-alt-app-flake = import ./default-alt-app/flake.nix;
      default-alt-app-output = default-alt-app-flake.outputs {inherit self; inherit nixpkgs;};

      default-file-app-flake = import ./default-file-app/flake.nix;
      default-file-app-output = default-file-app-flake.outputs {inherit self; inherit nixpkgs;};

      message-app-flake = import ./message-app/flake.nix;
      message-app-output = message-app-flake.outputs {inherit self; inherit nixpkgs;};

      test-app-flake = import ./test-app/flake.nix;
      test-app-output = test-app-flake.outputs {inherit self; inherit nixpkgs;};

      nix-app-flake = import ./nix-app/flake.nix;
      nix-app-output = nix-app-flake.outputs {inherit self; inherit nixpkgs;};

  in
    {
      packages.x86_64-linux.default = default-app-output.packages.x86_64-linux.default;

      packages.x86_64-linux.default-alt-app = default-alt-app-output.packages.x86_64-linux.default;

      packages.x86_64-linux.default-file-app = default-file-app-output.packages.x86_64-linux.default;      

      packages.x86_64-linux.test-app = test-app-output.packages.x86_64-linux.default;

      packages.x86_64-linux.message-app = message-app-output.packages.x86_64-linux.default;

      packages.x86_64-linux.nix-app = nix-app-output.packages.x86_64-linux.default;
    };
}

İsteseniz öncelikle nix flake show komutu ile flake'in çıktılarını görelim.

nix flake show

git+file:///home/.........../nix-examples?ref=refs/heads/main&rev=6837ce8a8da4c1e542d5b503f79e1a9733f7ff56
└───packages
    └───x86_64-linux
        ├───default: package 'default-script'
        ├───default-alt-app: package 'default-alt-app'
        ├───default-file-app: package 'default-file-app'
        ├───message-app: package 'message-app'
        ├───nix-app: package 'hello-2.12.1'
        └───test-app: package 'test-app'

Bütün paketlerimizi görebiliyoruz. Şimdi bir paketi çağırıp çalıştıralım.

nix run .#message-app
# sırasıyla sorular sorup ekrana yazdıracak

Bir shell script ile paket oluşturmanın başka yolları da var. Örnekler için şu sayfayı inceleyebilirsiniz. Bir kaçını buraya da taşıdım.

Bu fonksiyonlar mkDerivation fonksiyonunu sarmayalayarak bize kolaylık sağlar.

  • runCommand:
(import <nixpkgs> {}).runCommand "my-example" {} ''
  echo My example command is running

  mkdir $out

  echo I can write data to the Nix store > $out/message

  echo ls
  ls

  echo whoami
  whoami

  echo date
  date
''
  • writeTextFile, writeText, writeTextDir, writeScript, writeScriptBin
# Writes my-file to /nix/store/<store path>
writeTextFile {
  name = "my-file";
  text = ''
    Contents of File
  '';
}
# See also the `writeText` helper function below.

# Writes executable my-file to /nix/store/<store path>/bin/my-file
writeTextFile {
  name = "my-file";
  text = ''
    Contents of File
  '';
  executable = true;
  destination = "/bin/my-file";
}
# Writes contents of file to /nix/store/<store path>
writeText "my-file"
  ''
  Contents of File
  '';
# Writes contents of file to /nix/store/<store path>/share/my-file
writeTextDir "share/my-file"
  ''
  Contents of File
  '';
# Writes my-file to /nix/store/<store path> and makes executable
writeScript "my-file"
  ''
  Contents of File
  '';
# Writes my-file to /nix/store/<store path>/bin/my-file and makes executable.
writeScriptBin "my-file"
  ''
  Contents of File
  '';
# Writes my-file to /nix/store/<store path> and makes executable.
writeShellScript "my-file"
  ''
  Contents of File
  '';
# Writes my-file to /nix/store/<store path>/bin/my-file and makes executable.
writeShellScriptBin "my-file"
  ''
  Contents of File
  '';
  • writeShellApplication:
writeShellApplication {
  name = "show-nixos-org";

  runtimeInputs = [ curl w3m ];

  text = ''
    curl -s 'https://nixos.org' | w3m -dump -T text/html
  '';
}

callPackages Fonksiyonunu kullanarak Birden Fazla Paketi Sunmak

Eğer amacımız tamamen kendi yazdığımız paketleri tek bir yerden yayınlamaksa bunu daha uygun bir yolla yapmalıyız. En çok kullanılan tekniklerden biri callPackages. Nixpkgs'i de inceleyecek olursanız bu fonksiyonunu çok sık görebilirsiniz. Hatta en iyi örneğini bütün paketlerin tek bir yerden yüklenmesini sağlayan Nixpkgs GitHub sayfasındaki pkgs/top-evel/all-packages.nix sayfasıdır. Bu sayfada yaklaşık 40 bin paket callPackages fonksiyomnu ile yüklenmiştir. Detaylı bakacak olursanız bütün repo içinde 3-5 adet flake dosyası görebilirsiniz.

Ancak bu hali bize çok daha genişletilebilir (extendible), maintable ve daha modüler bir yapı sağlıyor.

  • Sağladığı en önemli fayda artık derivation'ınımıza parametre geçebiliyoruz. Bu sayede aynı kod bloğunu farklı versiyonlar için de kullanabileceğiz. Tabi bu sadece bir örnek, neler yapabileceğimizi anlayabilmek için bir örnek. Eğer bir uygulamanın farklı versiyonlarını sunacaksanız (ki bu çok çok nadiren olacak bir durumdur) o zaman her birini ayrı ayrı sunmak daha mantıklı olacaktır. Örneğin Resmi paket yöneticisinde kontrol ederseniz bir programlama dilinin veya bir SDK'in farklı versiyonlarının farklı dosyalarla yayınlandığını görebilirsiniz.
  • İkinci önemli faydası ise bu haliyle paketi override etmek için daha esnek yapı sunması. Bunu henüz görmedik ancak sadece bilgi vermek için yazıyorum. İleride göreceğiz.

Basit bir örnekle başlayalım. Daha sonra bütün repo'muzu bu fonksiyonla nasıl yönetebileceğimizi göreceğiz.

message-app adında bir klasör oluşturup içine default.nix dosyası oluşturuyoruz. Alttaki kodu içine kopyalıyoruz. Kod dikkat ederseniz artık bir flake değil. Sadece bir derivation döndüren fonksiyon. Ben de callPackage-first adından bir klasör içinde bu işlemleri yapıyorum. Github hesabımda kodları görebilirsiniz.

{version ? "v1.0"}:
    let

      # bu bile paketimizin özellikle kullandığı bir versiyon varsa ona göre yüklenebilir.
      nixpkgs = import <nixpkgs> {};

      selectedVersion = {version = "${version}";};

      simpleMessageAppSrc = "https://github.com/muratcabuk/simple-message-app-with-c/archive/refs/tags/${selectedVersion.version}.tar.gz";

      shaSet = {v10="sha256:1aai9xdkgq2vd0ch10gxhg53qfv4ny2x3jgxlq4r9nrn4g9r8s1z";
                v20="sha256:11p3c793yjpm4z4j9shlidbii7wd0kf9qflx8jqhhnwwhqf93mam";
                v30="sha256:1a4a2i32da9shc2d3i1ndarmla97bald7lgs1vjmwyjlry0mk4m7";};

      shaVer = builtins.concatStringsSep "" (nixpkgs.lib.strings.splitString "." "${selectedVersion.version}");

      versionSha = builtins.getAttr shaVer shaSet;

      # Simple Message App'in kaynak dizini
      src = builtins.fetchTarball {
        url = simpleMessageAppSrc;
        sha256 = versionSha;
      };

    in

        nixpkgs.stdenv.mkDerivation (finalAttrs: {
              name = "message-app";
              version = "${selectedVersion.version}";

              src = src;

              buildInputs = [ nixpkgs.gcc ];
              buildPhase = "gcc -o message-app ${src}/message.c";
              installPhase = "mkdir -p $out/bin; install -t $out/bin message-app";

              meta = with nixpkgs.lib; {
                    description = "Simple Message App with C";
                    license = licenses.mit;
                    version =  "${selectedVersion.version}";
                };
        })

Eğer callPackage fonksiyonunu kullanmasaydık alttaki gibi bir flake dosyası yazacaktık.

{
  description = "Flake için örnek paketler";
  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
  };

  outputs ={ self, nixpkgs, ... }:
    let

        packages = rec {

            x86_64-linux.default = import ./message-app {version = "v3.0";};
            x86_64-linux.message-app = x86_64-linux.default;

            aarch64-linux.message-app =  import ./message-app {version = "v3.0";};
        };

    in
    {
    packages = packages;
    };
}

CallPackage fonksiyonu ile yazmak için Message-app klasörü ile aynı dizinde flake.nix dosyası oluşturup içine alttaki kodları kopyalıyoruz. Dikkat ederseniz artık istediğimiz versiyonu flake üzerinden geçebiliyoruz. Tabi bu yetenek ileride override ve overlay işlemlerimizde de işimize yarayacak.

Koddaki diğer bir farklılıkta artık sadece x86_64-linux değil aynı zamanda aarch64-linux için de paket sunuyoruz.

{
  description = "Flake için örnek paketler";
  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
  };

  outputs ={ self, nixpkgs, ... }:
    let
        pkgs = import <nixpkgs> { };
        packages = rec {

            x86_64-linux.default = pkgs.callPackage ./message-app {version = "v3.0";};
            x86_64-linux.message-app = x86_64-linux.default;

            aarch64-linux.message-app =  pkgs.callPackage ./message-app {version = "v3.0";};
        };

    in
    {
    packages = packages;
    };
}

Öncelikle paket detaylarını görelim.

nix flake show --impure --all-systems
path:/home/..../callPackage-first?lastModified=1707332288&narHash=sha256-FaBT3XCD%2BhhbvH2JkYuSbo1GjNrohFaTWE1YY%2B5pqDo%3D
└───packages
├───aarch64-linux
│   └───message-app: package 'message-app'
└───x86_64-linux
├───default: package 'message-app'
└───message-app: package 'message-app'

Şimdi versiyon numarasını flake.nix içinden v3.0 olarak değiştirip çalıştıralım. V3'de kodda hatırlarsanız 3 adet soru soruyordu.

nix run .# --impure

Devam etmeden önce çok kullanışlı bir paketi daha inceleyelim.

Flake Yönetimi için Framework'ler

En çok bilinenler

  • Flake-Utils
  • Flake-Utils-Plus
  • Flake-Part
  • Flakelight

Flake-Utils'i kullanmak zorundan değiliz ancak eğer geliştirdiğiniz paket hakikaten bir çok sistemde tamamen aynı konfigürasyon ve kurguyla çalışıyorsa kod tekrarından kurtulmak ve daha okunabilir bir kod için faydalı olacaktır.

callPackage-second klasörüne önceki dosyaları kopyalayalım ve flake.nix'i alttaki gibi değiştirelim.

{
  description = "Flake utils demo";

  inputs.flake-utils.url = "github:numtide/flake-utils";

  outputs = { self, nixpkgs, flake-utils }:
    flake-utils.lib.eachDefaultSystem (system:
      let pkgs = nixpkgs.legacyPackages.${system}; in
      {
        packages = rec {
          default =pkgs.callPackage ./message-app { version = "v3.0"; };
          message-app = default;
        };

      }
    );
}

Detaylarını bi görelim.

nix flake show --impure --all-systems
path:/home/.../callPackage-first?lastModified=1707332163&narHash=sha256-szc%2Bl9PZNAgwaH%2B7oSITJUTLIECgMn/GhuT/XT5d6HY%3D
└───packages
├───aarch64-darwin
│   ├───default: package 'message-app'
│   └───message-app: package 'message-app'
├───aarch64-linux
│   ├───default: package 'message-app'
│   └───message-app: package 'message-app'
├───x86_64-darwin
│   ├───default: package 'message-app'
│   └───message-app: package 'message-app'
└───x86_64-linux
├───default: package 'message-app'
└───message-app: package 'message-app'

Tabi bu arada sadece bu kadarla kalmıyor başka yetenekleri de var. Özellikle bu projeden fokr'lanarak geliştirilen flake-utils plus'ı da incelemenizi tavsiye ederim. Birden fazla channel (registry) ile çalışabilme, host aylarını dinamik değiştirme, input'lar üzerinden dinamik flake oluşturma vb bir çok yetenek kazandırıyor. Resmi Github sayfasından örnekleri incelebilirsiniz.

Plus'ın sayfasındaki örnekleri olduğu gibi taşıyorum. Fikir vermesi için çok güzel örnekler vermişler.

let
  inherit (builtins) removeAttrs;
  mkApp = utils.lib.mkApp;
  # Eğer nixpkgs'ye doğrudan bir referans almak gerekiyorsa,
  pkgs = self.pkgs.x86_64-linux.nixpkgs;
in flake-utils-plus.lib.mkFlake {


  # `self` ve `inputs` argümanları GEREKLİDİR!
  inherit self inputs;

  # Paketler, uygulamalar, devShell ve diğer tanımlamalar için kullanılan desteklenen sistemler. Varsayılan olarak `flake-utils.lib.defaultSystems`.
  supportedSystems = [ "x86_64-linux" ];


  ################
  ### channels / registry ###
  ################

  # Tüm kanallar arasında paylaşılan yapılandırma.
  channelsConfig = { allowBroken = true; };

  # Tüm kanallara uygulanan katmanlar.
  sharedOverlays = [ nur.overlay ];

  # Kanallar için nixpkgs flake referansı. 
  # Varsayılan olarak `inputs` tarafından otomatik olarak oluşturulur.
  channels.<isim>.input = nixpkgs;

  # Kanala özgü yapılandırma seçenekleri.
  channels.<isim>.config = { allowUnfree = true; };

  # Seçilen kanala uygulanacak yamalar.
  channels.<isim>.patches = [ ./someAwesomePatch.patch ];

  # Seçilen kanala uygulanacak katmanlar.
  channels.<isim>.overlaysBuilder = channels: [
    (final: prev: { inherit (channels.unstable) neovim; })
  ];


  ####################
  ### hostDefaults ###
  ####################

  # Tüm hostlar için kullanılacak varsayılan mimari, varsayılan olarak "x86_64-linux".
  hostDefaults.system = "x86_64-linux";

  # Tüm hostlara aktarılacak varsayılan modüller.
  hostDefaults.modules = [ ./module.nix ./module2 ];

  # Host'lar tarafından kullanılacak varsayılan kanalın referansı olarak `channels.<isim>.*`. Varsayılan olarak "nixpkgs".
  hostDefaults.channelName = "unstable";

  # Tüm modüllere aktarılacak ek argümanlar. Hostların  extraArgs ile  birleştirilir.
  hostDefaults.extraArgs = { inherit utils inputs; foo = "foo"; };


  #############
  ### Hosts ###
  #############

  # Sistem mimarisi. Varsayılan olarak `defaultSystem` argümanı.
  hosts.<hostname>.system = "aarch64-linux";

  # Kullanılacak kanalın <isim>. Varsayılan olarak `nixpkgs`;
  hosts.<hostname>.channelName = "unstable";

  # Modüllere aktarılacak ek argümanlar.
  hosts.<hostname>.extraArgs = { abc = 123; };

  # Modüller için bunlar modül sisteminin bir parçası olmadığından, 
  # modüllere 'imports' satırlarında sonsuz döngü olmadan kullanılabilir.
  hosts.<hostname>.specialArgs = { thing = "abc"; };

  # Host a özgü yapılandırma.
  hosts.<hostname>.modules = [ ./configuration.nix ];

  # Yapılandırma için flake çıktısı. Varsayılan olarak `nixosConfigurations`.
  hosts.<hostname>.output = "darwinConfigurations";

  # Sistem oluşturucusu. Varsayılan olarak `channels.<isim>.input.lib.nixosSystem`.
  hosts.<hostname>.builder = nix-darwin.lib.darwinSystem;


#############################
  ### flake outputs builder ###
  #############################


  outputsBuilder = channels: {
    # `apps.<sistem>.custom-neovim = utils.lib.mkApp { drv = ...; exePath = ...; };` olarak değerlendirilir.
    apps = {
      custom-neovim = mkApp {
        drv = fancy-neovim;
        exePath = "/bin/nvim";
      };
    };

    # `packages.<sistem>.package-from-overlays = <unstable-nixpkgs-reference>.package-from-overlays` olarak değerlendirilir.
    packages = { inherit (channels.unstable) package-from-overlays; };

    # `apps.<sistem>.firefox = utils.lib.mkApp { drv = ...; };` olarak değerlendirilir.
    defaultApp = mkApp { drv = channels.nixpkgs.firefox; };

    # `defaultPackage.<sistem>.neovim = <nixpkgs-channel-reference>.neovim` olarak değerlendirilir.
    defaultPackage = channels.nixpkgs.neovim;

    # `devShell.<sistem> = <nixpkgs-channel-reference>.mkShell { name = "devShell"; };` olarak değerlendirilir.
    devShell = channels.nixpkgs.mkShell { name = "devShell"; };
  };


  #########################################################
  ### Diğer tüm özellikler flake'e aktarılır ###
  #########################################################

  checks.x86_64-linux.someCheck = pkgs.hello;
  packages.x86_64-linux.somePackage = pkgs.hello;
  overlay = import ./overlays;
  abc = 132;
  • Bunların haricinde birde CircleCI'ın geliştirdiği flake-part var. Onu resmi GitHub sayfasından inceleyebilirsiniz. Temel amacı flake'leri daha modüler ve daha okunabilir bir yapıya kavuşturmak ve system bazında yönetimini saplamak.
  • Flakelight ise flake oluşturma süreçlerini otomatikleştirme, ortak yapılandırma ve flake'leri daha modüler hale getirme gibi özellikler sunuyor.

Hemen hemen hepsinde mkFlake, mkApp fonksiyonları bulunuyor. Hepsinin de sistemleri yönetmek için yapılar mevcut.Temel amaçları flake 'laı daha parçalı hala getirmek böylece çok karmaşık flake'leri yönetmek daha kolay olmuş oluyor.

Şu sayfada Flakelight ve Flake-Part'ı karşılaştıran güzel örnekler var.

Şimdi asıl konumuza dönelim. Bu vakte kadar öğrendiklerimizle kendi repo'muzu hem diğer sistemlerde de çalışacak hale getirelim hem de callPackage ile paketlerimizi yükleyelim.

Repommuzu callPackege fonksiyonu ile Yeniden Yazıyoruz.

Github'daki projemizi değiştiriyoruz. Yeni flake dosyamız alttaki gibi olacak. Tabi yazdığımız kodu da değiştirdik. Önceki versiyonda hatırlarsanız uygulama klasörlerimizde flake oluşturmuştuk. Ama artık module olarak değiştirdik. Artık daha okunaklılar. Ayrıca bu yeni versiyonda çalıştırılabilir (executable) modüller yazdığımız için her birini apps adında bir klasör oluşturup hepsini tek bir yere toplamış olduk. Bunun bir amacıda ileride ekleyeceğimiz diğer klasör ve dosyalarla karışmamalarını sağlamak.

Tüm kodlara multi-app-with-callpackages branch'inden erişebilirsiniz.

Dikkat ederseniz eachSystem fonksiyonu iki parametre alıyor birincisi bir liste (systems) ikincisi ise fonksiyon.

{
  description = "Flake için örnek paketler";
  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
    flake-utils.url = "github:numtide/flake-utils";

  };

  outputs ={ self, nixpkgs, flake-utils, ... }:

  let

    systems = ["x86_64-linux" "x86_64-darwin"];

  in

    flake-utils.lib.eachSystem systems (system:
      let pkgs = nixpkgs.legacyPackages.${system}; in
      {
        packages = rec {
            default = pkgs.callPackage ./apps/default { pkgs = pkgs;};
            defaultalt = pkgs.callPackage ./apps/defaultalt {pkgs = pkgs;};
            defaultfile = pkgs.callPackage ./apps/defaultfile {pkgs = pkgs;};
            message = pkgs.callPackage ./apps/message { version = "v3.0"; pkgs = pkgs;};
            nixapp = pkgs.callPackage ./apps/nixapp {pkgs = pkgs;};
            testapp = pkgs.callPackage ./apps/testapp {version = "v2.0"; pkgs = pkgs;};
        };
      }
    );

}

Evet artık basit anlamda kendi repo'muzu oluşturduk ve birden fazla paketi aynı andan yayınladık. Şimdi de bence yeni öğrenenlerin en çok zorlandığı konulardan birine başlatalım. Override ve Overlay konuları kendi adıma beni en çok zorlayan konu oldu. Büyük ihtimal siz okurken kolay gibi gelecek ancak doküman yetersizliğinden dolayı anlama noktasına gelmek baya vaktimi almıştı. Zaten araştırırken de göreceksiniz en çok sorulan konulardan biri de bu.

Bu konuya da bir sonraki yazımızda devam edelim.

Kaynaklar