Unverified Commit aaccf42b authored by Pol Dellaiera's avatar Pol Dellaiera Committed by GitHub
Browse files

Merge pull request #261432 from yayayayaka/snipe-it-convert-to-buildComposerProject

snipe-it: convert to buildComposerProject
parents 99be59ba d91c530a
Loading
Loading
Loading
Loading
+10 −6
Original line number Diff line number Diff line
@@ -18,15 +18,19 @@ let
  inherit (snipe-it.passthru) phpPackage;

  # shell script for local administration
  artisan = pkgs.writeScriptBin "snipe-it" ''
  artisan = (pkgs.writeScriptBin "snipe-it" ''
    #! ${pkgs.runtimeShell}
    cd ${snipe-it}
    cd "${snipe-it}/share/php/snipe-it"
    sudo=exec
    if [[ "$USER" != ${user} ]]; then
      sudo='exec /run/wrappers/bin/sudo -u ${user}'
    fi
    $sudo ${phpPackage}/bin/php artisan $*
  '';
  '').overrideAttrs (old: {
    meta = old.meta // {
      mainProgram = "snipe-it";
    };
  });
in {
  options.services.snipe-it = {

@@ -357,7 +361,7 @@ in {
    services.nginx = {
      enable = mkDefault true;
      virtualHosts."${cfg.hostName}" = mkMerge [ cfg.nginx {
        root = mkForce "${snipe-it}/public";
        root = mkForce "${snipe-it}/share/php/snipe-it/public";
        extraConfig = optionalString (cfg.nginx.addSSL || cfg.nginx.forceSSL || cfg.nginx.onlySSL || cfg.nginx.enableACME) "fastcgi_param HTTPS on;";
        locations = {
          "/" = {
@@ -394,7 +398,7 @@ in {
        RuntimeDirectory = "snipe-it/cache";
        RuntimeDirectoryMode = "0700";
      };
      path = [ pkgs.replace-secret ];
      path = [ pkgs.replace-secret artisan ];
      script =
        let
          isSecret  = v: isAttrs v && v ? _secret && (isString v._secret || builtins.isPath v._secret);
@@ -451,7 +455,7 @@ in {
          rm "${cfg.dataDir}"/bootstrap/cache/*.php || true

          # migrate db
          ${phpPackage}/bin/php artisan migrate --force
          ${lib.getExe artisan} migrate --force

          # A placeholder file for invalid barcodes
          invalid_barcode_location="${cfg.dataDir}/public/uploads/barcodes/invalid_barcode.gif"
+0 −244
Original line number Diff line number Diff line
# This file originates from composer2nix

{ stdenv, lib, writeTextFile, fetchurl, php, unzip, phpPackages }:

let
  inherit (phpPackages) composer;

  filterSrc = src:
    builtins.filterSource (path: type: type != "directory" || (baseNameOf path != ".git" && baseNameOf path != ".git" && baseNameOf path != ".svn")) src;

  buildZipPackage = { name, src }:
    stdenv.mkDerivation {
      inherit name src;
      nativeBuildInputs = [ unzip ];
      buildCommand = ''
        shopt -s dotglob
        unzip $src
        baseDir=$(find . -type d -mindepth 1 -maxdepth 1)
        cd $baseDir
        mkdir -p $out
        mv * $out
      '';
    };

  buildPackage =
    { name
    , src
    , packages ? {}
    , devPackages ? {}
    , buildInputs ? []
    , symlinkDependencies ? false
    , executable ? false
    , removeComposerArtifacts ? false
    , postInstall ? ""
    , noDev ? false
    , composerExtraArgs ? ""
    , unpackPhase ? "true"
    , buildPhase ? "true"
    , ...}@args:

    let
      reconstructInstalled = writeTextFile {
        name = "reconstructinstalled.php";
        executable = true;
        text = ''
          #! ${php}/bin/php
          <?php
          if(file_exists($argv[1]))
          {
              $composerLockStr = file_get_contents($argv[1]);

              if($composerLockStr === false)
              {
                  fwrite(STDERR, "Cannot open composer.lock contents\n");
                  exit(1);
              }
              else
              {
                  $config = json_decode($composerLockStr, true);

                  if(array_key_exists("packages", $config))
                      $allPackages = $config["packages"];
                  else
                      $allPackages = array();

                  ${lib.optionalString (!noDev) ''
                    if(array_key_exists("packages-dev", $config))
                        $allPackages = array_merge($allPackages, $config["packages-dev"]);
                  ''}

                  $packagesStr = json_encode($allPackages, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
                  print($packagesStr);
              }
          }
          else
              print("[]");
          ?>
        '';
      };

      constructBin = writeTextFile {
        name = "constructbin.php";
        executable = true;
        text = ''
          #! ${php}/bin/php
          <?php
          $composerJSONStr = file_get_contents($argv[1]);

          if($composerJSONStr === false)
          {
              fwrite(STDERR, "Cannot open composer.json contents\n");
              exit(1);
          }
          else
          {
              $config = json_decode($composerJSONStr, true);

              if(array_key_exists("bin-dir", $config))
                  $binDir = $config["bin-dir"];
              else
                  $binDir = "bin";

              if(array_key_exists("bin", $config))
              {
                  if(!file_exists("vendor/".$binDir))
                      mkdir("vendor/".$binDir);

                  foreach($config["bin"] as $bin)
                      symlink("../../".$bin, "vendor/".$binDir."/".basename($bin));
              }
          }
          ?>
        '';
      };

      bundleDependencies = dependencies:
        lib.concatMapStrings (dependencyName:
          let
            dependency = dependencies.${dependencyName};
          in
          ''
            ${if dependency.targetDir == "" then ''
              vendorDir="$(dirname ${dependencyName})"
              mkdir -p "$vendorDir"
              ${if symlinkDependencies then
                ''ln -s "${dependency.src}" "$vendorDir/$(basename "${dependencyName}")"''
                else
                ''cp -av "${dependency.src}" "$vendorDir/$(basename "${dependencyName}")"''
              }
            '' else ''
              namespaceDir="${dependencyName}/$(dirname "${dependency.targetDir}")"
              mkdir -p "$namespaceDir"
              ${if symlinkDependencies then
                ''ln -s "${dependency.src}" "$namespaceDir/$(basename "${dependency.targetDir}")"''
              else
                ''cp -av "${dependency.src}" "$namespaceDir/$(basename "${dependency.targetDir}")"''
              }
            ''}
          '') (builtins.attrNames dependencies);

      extraArgs = removeAttrs args [ "packages" "devPackages" "buildInputs" ];
    in
    stdenv.mkDerivation ({
      buildInputs = [ php composer ] ++ buildInputs;

      inherit unpackPhase buildPhase;

      installPhase = ''
        ${if executable then ''
          mkdir -p $out/share/php
          cp -av $src $out/share/php/$name
          chmod -R u+w $out/share/php/$name
          cd $out/share/php/$name
        '' else ''
          cp -av $src $out
          chmod -R u+w $out
          cd $out
        ''}

        # Remove unwanted files
        rm -f *.nix

        export HOME=$TMPDIR

        # Remove the provided vendor folder if it exists
        rm -Rf vendor

        # If there is no composer.lock file, compose a dummy file.
        # Otherwise, composer attempts to download the package.json file from
        # the registry which we do not want.
        if [ ! -f composer.lock ]
        then
            cat > composer.lock <<EOF
        {
            "packages": []
        }
        EOF
        fi

        # Reconstruct the installed.json file from the lock file
        mkdir -p vendor/composer
        ${php}/bin/php ${reconstructInstalled} composer.lock > vendor/composer/installed.json

        # Copy or symlink the provided dependencies
        cd vendor
        ${bundleDependencies packages}
        ${lib.optionalString (!noDev) (bundleDependencies devPackages)}
        cd ..

        # Reconstruct autoload scripts
        # We use the optimize feature because Nix packages cannot change after they have been built
        # Using the dynamic loader for a Nix package is useless since there is nothing to dynamically reload.
        composer dump-autoload --optimize ${lib.optionalString noDev "--no-dev"} ${composerExtraArgs}

        # Run the install step as a validation to confirm that everything works out as expected
        composer install --optimize-autoloader ${lib.optionalString noDev "--no-dev"} ${composerExtraArgs}

        ${lib.optionalString executable ''
          # Reconstruct the bin/ folder if we deploy an executable project
          ${php}/bin/php ${constructBin} composer.json
          ln -s $(pwd)/vendor/bin $out/bin
        ''}

        ${lib.optionalString (!symlinkDependencies) ''
          # Patch the shebangs if possible
          if [ -d $(pwd)/vendor/bin ]
          then
              # Look for all executables in bin/
              for i in $(pwd)/vendor/bin/*
              do
                  # Look for their location
                  realFile=$(readlink -f "$i")

                  # Restore write permissions
                  chmod u+wx "$(dirname "$realFile")"
                  chmod u+w "$realFile"

                  # Patch shebang
                  sed -e "s|#!/usr/bin/php|#!${php}/bin/php|" \
                      -e "s|#!/usr/bin/env php|#!${php}/bin/php|" \
                      "$realFile" > tmp
                  mv tmp "$realFile"
                  chmod u+x "$realFile"
              done
          fi
        ''}

        if [ "$removeComposerArtifacts" = "1" ]
        then
            # Remove composer stuff
            rm -f composer.json composer.lock
        fi

        # Execute post install hook
        runHook postInstall
    '';
  } // extraArgs);
in
{
  inherit filterSrc;
  composer = lib.makeOverridable composer;
  buildZipPackage = lib.makeOverridable buildZipPackage;
  buildPackage = lib.makeOverridable buildPackage;
}
+0 −15
Original line number Diff line number Diff line
{pkgs ? import <nixpkgs> {
    inherit system;
  }, system ? builtins.currentSystem, noDev ? false, php ? pkgs.php, phpPackages ? pkgs.phpPackages}:

let
  composerEnv = import ./composer-env.nix {
    inherit (pkgs) stdenv lib writeTextFile fetchurl unzip;
    inherit php phpPackages;
  };
in
import ./php-packages.nix {
  inherit composerEnv noDev;
  inherit (pkgs) fetchurl fetchgit fetchhg fetchsvn;
}
+32 −36
Original line number Diff line number Diff line
{ lib
, pkgs
, stdenv
, fetchFromGitHub
, dataDir ? "/var/lib/snipe-it"
, fetchFromGitHub
, mariadb
, nixosTests
, php
, phpPackages
}:

let
  package = (import ./composition.nix {
    inherit pkgs php phpPackages;
    inherit (stdenv.hostPlatform) system;
    noDev = true; # Disable development dependencies
  }).overrideAttrs (attrs : {
    installPhase = attrs.installPhase + ''
php.buildComposerProject (finalAttrs: {
  pname = "snipe-it";
  version = "6.2.2";

  src = fetchFromGitHub {
    owner = "snipe";
    repo = "snipe-it";
    rev = "v${finalAttrs.version}";
    hash = "sha256-EU+teGxo7YZkD7kNXk9jRyARpzWz5OMRmaWqQ6eMKYY=";
  };

  vendorHash = "sha256-JcBcrETbjGJFlG1dH/XXqmb9MlKr0ICdnEx7/61Z5io=";

  postInstall = ''
    snipe_it_out="$out/share/php/snipe-it"

    # Before symlinking the following directories, copy the invalid_barcode.gif
    # to a different location. The `snipe-it-setup` oneshot service will then
    # copy the file back during bootstrap.
    mkdir -p $out/share/snipe-it
      cp $out/public/uploads/barcodes/invalid_barcode.gif $out/share/snipe-it/
    cp $snipe_it_out/public/uploads/barcodes/invalid_barcode.gif $out/share/snipe-it/

      rm -R $out/storage $out/public/uploads $out/bootstrap/cache
      ln -s ${dataDir}/.env $out/.env
      ln -s ${dataDir}/storage $out/
      ln -s ${dataDir}/public/uploads $out/public/uploads
      ln -s ${dataDir}/bootstrap/cache $out/bootstrap/cache
    rm -R $snipe_it_out/storage $snipe_it_out/public/uploads $snipe_it_out/bootstrap/cache
    ln -s ${dataDir}/.env $snipe_it_out/.env
    ln -s ${dataDir}/storage $snipe_it_out/
    ln -s ${dataDir}/public/uploads $snipe_it_out/public/uploads
    ln -s ${dataDir}/bootstrap/cache $snipe_it_out/bootstrap/cache

      chmod +x $out/artisan
    chmod +x $snipe_it_out/artisan

      substituteInPlace config/database.php --replace "env('DB_DUMP_PATH', '/usr/local/bin')" "env('DB_DUMP_PATH', '${mariadb}/bin')"
    substituteInPlace $snipe_it_out/config/database.php --replace "env('DB_DUMP_PATH', '/usr/local/bin')" "env('DB_DUMP_PATH', '${mariadb}/bin')"
  '';
  });

in package.override rec {
  pname = "snipe-it";
  version = "6.2.2";

  src = fetchFromGitHub {
    owner = "snipe";
    repo = pname;
    rev = "v${version}";
    sha256 = "11i9ijkl7am5k48y7r5k6nki2827cd7mw3dr1xj8dvb8diwaskqi";
  passthru = {
    tests = nixosTests.snipe-it;
    phpPackage = php;
  };

  passthru.tests = nixosTests.snipe-it;
  passthru.phpPackage = php;

  meta = with lib; {
    description = "A free open source IT asset/license management system";
    longDescription = ''
@@ -62,4 +58,4 @@ in package.override rec {
    maintainers = with maintainers; [ yayayayaka ];
    platforms = platforms.linux;
  };
}
})
+0 −1708

File deleted.

Preview size limit exceeded, changes collapsed.

Loading