about summary refs log tree commit diff
path: root/pkgs/development/compilers/dotnet/common.nix
blob: 63b3a7de374ef26efc1ab1cac82822a3a5bee40c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# TODO: switch to stdenvNoCC
{ stdenv
, lib
, writeText
, testers
, runCommand
, expect
, curl
}: type: args: stdenv.mkDerivation (finalAttrs: args // {
  doInstallCheck = true;

  # TODO: this should probably be postInstallCheck
  # TODO: send output to /dev/null
  installCheckPhase = args.installCheckPhase or "" + ''
    $out/bin/dotnet --info
  '';

  # TODO: move this to sdk section?
  setupHook = writeText "dotnet-setup-hook" (''
    if [ ! -w "$HOME" ]; then
      export HOME=$(mktemp -d) # Dotnet expects a writable home directory for its configuration files
    fi

    export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 # Dont try to expand NuGetFallbackFolder to disk
    export DOTNET_NOLOGO=1 # Disables the welcome message
    export DOTNET_CLI_TELEMETRY_OPTOUT=1
    export DOTNET_SKIP_WORKLOAD_INTEGRITY_CHECK=1 # Skip integrity check on first run, which fails due to read-only directory
  '' + args.setupHook or "");

} // lib.optionalAttrs (type == "sdk") {
  passthru = {
    tests = let
      mkDotnetTest =
        {
          name,
          template,
          usePackageSource ? false,
          build,
          # TODO: use correct runtimes instead of sdk
          runtime ? finalAttrs.finalPackage,
          runInputs ? [],
          run ? null,
        }:
        let
          built = runCommand "dotnet-test-${name}" { buildInputs = [ finalAttrs.finalPackage ]; } (''
            HOME=$PWD/.home
            dotnet new nugetconfig
            dotnet nuget disable source nuget
          '' + lib.optionalString usePackageSource ''
            dotnet nuget add source ${finalAttrs.finalPackage.packages}
          '' + ''
            dotnet new ${template} -n test -o .
          '' + build);
        in
          if run == null
            then build
          else
            runCommand "${built.name}-run" { src = built; nativeBuildInputs = runInputs; } (
              lib.optionalString (runtime != null) ''
                # TODO: use runtime here
                export DOTNET_ROOT=${runtime}
              '' + run);

      checkConsoleOutput = command: ''
        output="$(${command})"
        # yes, older SDKs omit the comma
        [[ "$output" =~ Hello,?\ World! ]] && touch "$out"
      '';

    in {
      version = testers.testVersion {
        package = finalAttrs.finalPackage;
      };

      console = mkDotnetTest {
        name = "console";
        template = "console";
        build = checkConsoleOutput "dotnet run";
      };

      publish = mkDotnetTest {
        name = "publish";
        template = "console";
        build = "dotnet publish -o $out";
        run = checkConsoleOutput "$src/test";
      };

      single-file = mkDotnetTest {
        name = "single-file";
        template = "console";
        usePackageSource = true;
        build = "dotnet publish --use-current-runtime -p:PublishSingleFile=true -o $out";
        runtime = null;
        run = checkConsoleOutput "$src/test";
      };

      web = mkDotnetTest {
        name = "publish";
        template = "web";
        build = "dotnet publish -o $out";
        runInputs = [ expect curl ];
        run = ''
          expect <<"EOF"
            set status 1
            spawn $env(src)/test
            expect_before default abort
            expect -re {Now listening on: ([^\r]+)\r} {
              set url $expect_out(1,string)
            }
            expect "Application started. Press Ctrl+C to shut down."
            set output [exec curl -sSf $url]
            if {$output != "Hello World!"} {
              send_error "Unexpected output: $output\n"
              exit 1
            }
            send \x03
            catch wait result
            exit [lindex $result 3]
          EOF
          touch $out
        '';
      };
    } // args.passthru.tests or {};
  } // args.passthru or {};
})