1
- import * as path from 'path'
1
+ import * as path from 'path' ;
2
+ import * as fs from 'fs' ;
3
+ import os from 'os' ;
2
4
import { chmod } from 'fs/promises' ;
3
5
4
6
import tc from '@actions/tool-cache' ;
@@ -27,11 +29,13 @@ const ghcup_os_map: Map<Platform, GHCupOS> = new Map([
27
29
[ 'freebsd' , 'portbld-freebsd' ]
28
30
] ) ;
29
31
30
- function ghcup_url ( version : string , arch : GHCupArch , os : GHCupOS ) : string {
32
+ const hook_url : string = 'https://www.haskell.org/ghcup/sh/hooks/stack/ghc-install.sh' ;
33
+
34
+ function ghcup_url ( version : string , arch : GHCupArch , gos : GHCupOS ) : string {
31
35
if ( version == 'latest' ) {
32
- return `https://downloads.haskell.org/ghcup/${ arch } -${ os } -ghcup${ ext } ` ;
36
+ return `https://downloads.haskell.org/ghcup/${ arch } -${ gos } -ghcup${ ext } ` ;
33
37
} else {
34
- return `https://downloads.haskell.org/ghcup/${ version } /${ arch } -${ os } -ghcup-${ version } ${ ext } ` ;
38
+ return `https://downloads.haskell.org/ghcup/${ version } /${ arch } -${ gos } -ghcup-${ version } ${ ext } ` ;
35
39
}
36
40
}
37
41
@@ -46,12 +50,12 @@ async function ghcup(version: string) {
46
50
throw `GHCup does not support architecture ${ platform . arch } ` ;
47
51
}
48
52
49
- const os = ghcup_os_map . get ( platform . platform ) ;
50
- if ( os == undefined ) {
53
+ const gos = ghcup_os_map . get ( platform . platform ) ;
54
+ if ( gos == undefined ) {
51
55
throw `GHCup does not support platform ${ platform . platform } ` ;
52
56
}
53
57
54
- const url = ghcup_url ( version , arch , os ) ;
58
+ const url = ghcup_url ( version , arch , gos ) ;
55
59
56
60
const tempDirectory = process . env [ 'RUNNER_TEMP' ] || '' ;
57
61
const ghcupExeName = `ghcup${ ext } ` ;
@@ -69,9 +73,45 @@ async function ghcup(version: string) {
69
73
}
70
74
}
71
75
76
+ function getStackRoot ( ) {
77
+ if ( platform . isWindows ) {
78
+ const appdata = process . env [ 'APPDATA' ] || '' ;
79
+ return process . env [ 'STACK_ROOT' ] ?? path . join ( appdata , 'stack' ) ;
80
+ } else {
81
+ const hdir = os . homedir ( ) ;
82
+ return process . env [ 'STACK_ROOT' ] ?? path . join ( hdir , '.stack' ) ;
83
+ }
84
+ }
85
+
86
+ async function installStackHook ( ) {
87
+ const stack_root = getStackRoot ( ) ;
88
+ const hook_dest = path . join ( stack_root , 'hooks' , 'ghc-install.sh' )
89
+ fs . rmSync ( hook_dest , {
90
+ force : true ,
91
+ } ) ;
92
+ // we do not cache, it isn't versioned
93
+ const hookPath = await tc . downloadTool ( hook_url , hook_dest ) ;
94
+ if ( ! ( platform . isWindows ) ) {
95
+ await chmod ( hook_dest , "0765" ) ;
96
+ }
97
+ core . debug ( `stack ghcup hook is at ${ hookPath } ` ) ;
98
+ }
99
+
100
+ export function parseYAMLBoolean ( name : string , val : string ) : boolean {
101
+ const trueValue = [ 'true' , 'True' , 'TRUE' ] ;
102
+ const falseValue = [ 'false' , 'False' , 'FALSE' ] ;
103
+ if ( trueValue . includes ( val ) ) return true ;
104
+ if ( falseValue . includes ( val ) ) return false ;
105
+ throw new TypeError (
106
+ `Action input "${ name } " does not meet YAML 1.2 "Core Schema" specification: \n` +
107
+ `Supported boolean values: \`true | True | TRUE | false | False | FALSE\``
108
+ ) ;
109
+ }
110
+
72
111
export type Opts = {
73
112
version : string ,
74
- release_channels : string [ ]
113
+ release_channels : string [ ] ,
114
+ stack_hook : boolean
75
115
}
76
116
77
117
export async function main ( opts : Opts ) {
@@ -94,7 +134,12 @@ export async function main(opts: Opts) {
94
134
core . debug ( `GHCUP_MSYS2 is ${ ghcup_msys2 } ` ) ;
95
135
}
96
136
137
+ if ( opts . stack_hook ) {
138
+ installStackHook ( )
139
+ }
140
+
97
141
await exec . exec ( ghcupPath , [
98
142
'config' , 'set' , 'url-source' , JSON . stringify ( opts . release_channels )
99
143
] ) ;
100
144
}
145
+
0 commit comments