Skip to content

Commit e7ee536

Browse files
Parse boolean inputs in main.ts
1 parent d062893 commit e7ee536

File tree

7 files changed

+56
-143
lines changed

7 files changed

+56
-143
lines changed

README.md

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -189,19 +189,17 @@ jobs:
189189
| `ghc-version` | GHC version to use, e.g. `9.2` or `9.2.5`. | `string` | `latest` |
190190
| `cabal-version` | Cabal version to use, e.g. `3.6`. | `string` | `latest` |
191191
| `stack-version` | Stack version to use, e.g. `latest`. Stack will only be installed if `enable-stack` is set. | `string` | `latest` |
192-
| `enable-stack` | If set, will setup Stack. | "boolean" | false/unset |
193-
| `stack-no-global` | If set, `enable-stack` must be set. Prevents installing GHC and Cabal globally. | "boolean" | false/unset |
194-
| `stack-setup-ghc` | If set, `enable-stack` must be set. Runs stack setup to install the specified GHC. (Note: setting this does _not_ imply `stack-no-global`.) | "boolean" | false/unset |
195-
| `disable-matcher` | If set, disables match messages from GHC as GitHub CI annotations. | "boolean" | false/unset |
192+
| `enable-stack` | If set, will setup Stack. | `Toggle` | false/unset |
193+
| `stack-no-global` | If set, `enable-stack` must be set. Prevents installing GHC and Cabal globally. | `Toggle` | false/unset |
194+
| `stack-setup-ghc` | If set, `enable-stack` must be set. Runs stack setup to install the specified GHC. (Note: setting this does _not_ imply `stack-no-global`.) | `Toggle` | false/unset |
195+
| `disable-matcher` | If set, disables match messages from GHC as GitHub CI annotations. | `Toggle` | false/unset |
196196
| `cabal-update` | If set to `false`, skip `cabal update` step. | `boolean` | `true` |
197197
| `ghcup-release-channels` | If set, add [release channels](https://www.haskell.org/ghcup/guide/#pre-release-channels) to ghcup. | `URL[]` | none |
198198

199199
Notes:
200200

201-
- "boolean" types are set/unset, not true/false. That is, setting any "boolean" to a value other than the empty string (`""`) will be considered true/set.
202-
However, to avoid confusion and for forward compatibility, it is still recommended to **only use value `true` to set a "boolean" flag.**
203-
204-
In contrast, a proper `boolean` input like `cabal-update` only accepts values `true` and `false`.
201+
- `Toggle` inputs are booleans that are false when set as the empty string and true when set to _anything_.
202+
However, to avoid confusion and for forward compatibility, it is still recommended to **only use value `true` to set a `Toggle` input.**
205203

206204
- Inputs that can take multiple values (like `ghcup-release-channels`) should be specified as a comma separated list, e.g.
207205

__tests__/find-haskell.test.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ describe('haskell/actions/setup', () => {
4646
it('Setting disable-matcher to true disables matcher', () => {
4747
forAllOS(os => {
4848
const options = getOpts(def(os), os, {
49-
disableMatcher: 'true'
49+
disableMatcher: true
5050
});
5151
expect(options.general.matcher.enable).toBe(false);
5252
});
@@ -70,7 +70,7 @@ describe('haskell/actions/setup', () => {
7070
const v = {ghc: '8.6.5', cabal: '3.4.1.0', stack: '1.9.3'};
7171
forAllOS(os => {
7272
const options = getOpts(def(os), os, {
73-
enableStack: 'true',
73+
enableStack: true,
7474
stackVersion: '1',
7575
ghcVersion: '8.6',
7676
cabalVersion: '3.4'
@@ -82,7 +82,7 @@ describe('haskell/actions/setup', () => {
8282
it('"latest" Versions resolve correctly', () => {
8383
forAllOS(os => {
8484
const options = getOpts(def(os), os, {
85-
enableStack: 'true',
85+
enableStack: true,
8686
stackVersion: 'latest',
8787
ghcVersion: 'latest',
8888
cabalVersion: 'latest'
@@ -100,7 +100,7 @@ describe('haskell/actions/setup', () => {
100100
const v = {ghc: '8.10.7', cabal: '2.4.1.0', stack: '2.1.3'};
101101
forAllOS(os => {
102102
const options = getOpts(def(os), os, {
103-
enableStack: 'true',
103+
enableStack: true,
104104
stackVersion: '2.1',
105105
ghcVersion: '8.10',
106106
cabalVersion: '2'
@@ -112,7 +112,7 @@ describe('haskell/actions/setup', () => {
112112
it('Enabling stack does not disable GHC or Cabal', () => {
113113
forAllOS(os => {
114114
const {ghc, cabal, stack} = getOpts(def(os), os, {
115-
enableStack: 'true'
115+
enableStack: true
116116
});
117117
expect({
118118
ghc: ghc.enable,
@@ -137,8 +137,8 @@ describe('haskell/actions/setup', () => {
137137
it('Enabling stack-no-global disables GHC and Cabal', () => {
138138
forAllOS(os => {
139139
const {ghc, cabal, stack} = getOpts(def(os), os, {
140-
enableStack: 'true',
141-
stackNoGlobal: 'true'
140+
enableStack: true,
141+
stackNoGlobal: true
142142
});
143143
expect({
144144
ghc: ghc.enable,
@@ -150,13 +150,13 @@ describe('haskell/actions/setup', () => {
150150

151151
it('Enabling stack-no-global without setting enable-stack errors', () => {
152152
forAllOS(os =>
153-
expect(() => getOpts(def(os), os, {stackNoGlobal: 'true'})).toThrow()
153+
expect(() => getOpts(def(os), os, {stackNoGlobal: true})).toThrow()
154154
);
155155
});
156156

157157
it('Enabling stack-setup-ghc without setting enable-stack errors', () => {
158158
forAllOS(os =>
159-
expect(() => getOpts(def(os), os, {stackNoGlobal: 'true'})).toThrow()
159+
expect(() => getOpts(def(os), os, {stackNoGlobal: true})).toThrow()
160160
);
161161
});
162162
});

dist/index.js

Lines changed: 12 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -13666,17 +13666,18 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
1366613666
Object.defineProperty(exports, "__esModule", ({ value: true }));
1366713667
const core = __importStar(__nccwpck_require__(2186));
1366813668
const setup_haskell_1 = __importDefault(__nccwpck_require__(9351));
13669+
const getToggleInput = (name) => core.getInput(name) !== '';
1366913670
(0, setup_haskell_1.default)({
1367013671
ghcVersion: core.getInput('ghc-version'),
1367113672
cabalVersion: core.getInput('cabal-version'),
1367213673
stackVersion: core.getInput('stack-version'),
13673-
enableStack: core.getInput('enable-stack'),
13674-
stackNoGlobal: core.getInput('stack-no-global'),
13675-
stackSetupGhc: core.getInput('stack-setup-ghc'),
13676-
cabalUpdate: core.getInput('cabal-update'),
13674+
enableStack: getToggleInput('enable-stack'),
13675+
stackNoGlobal: getToggleInput('stack-no-global'),
13676+
stackSetupGhc: getToggleInput('stack-setup-ghc'),
13677+
cabalUpdate: core.getBooleanInput('cabal-update'),
1367713678
ghcupReleaseChannels: core.getInput('ghcup-release-channels'),
1367813679
ghcupReleaseChannel: core.getInput('ghcup-release-channel'),
13679-
disableMatcher: core.getInput('disable-matcher')
13680+
disableMatcher: getToggleInput('disable-matcher')
1368013681
});
1368113682

1368213683

@@ -13711,7 +13712,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
1371113712
return result;
1371213713
};
1371313714
Object.defineProperty(exports, "__esModule", ({ value: true }));
13714-
exports.getOpts = exports.parseYAMLBoolean = exports.releaseRevision = exports.getDefaults = exports.yamlInputs = exports.ghcup_version = exports.supported_versions = exports.release_revisions = void 0;
13715+
exports.getOpts = exports.releaseRevision = exports.getDefaults = exports.yamlInputs = exports.ghcup_version = exports.supported_versions = exports.release_revisions = void 0;
1371513716
const core = __importStar(__nccwpck_require__(2186));
1371613717
const fs_1 = __nccwpck_require__(7147);
1371713718
const js_yaml_1 = __nccwpck_require__(1917);
@@ -13790,27 +13791,6 @@ function releaseRevision(version, tool, os) {
1379013791
return result;
1379113792
}
1379213793
exports.releaseRevision = releaseRevision;
13793-
/**
13794-
* Convert a string input to a boolean according to the YAML 1.2 "core schema" specification.
13795-
* Supported boolean renderings: `true | True | TRUE | false | False | FALSE` .
13796-
* ref: https://yaml.org/spec/1.2/spec.html#id2804923
13797-
* Adapted from: https://github.com/actions/toolkit/commit/fbdf27470cdcb52f16755d32082f1fee0bfb7d6d#diff-f63fb32fca85d8e177d6400ce078818a4815b80ac7a3319b60d3507354890992R94-R115
13798-
*
13799-
* @param name name of the input
13800-
* @param val supposed string representation of a boolean
13801-
* @returns boolean
13802-
*/
13803-
function parseYAMLBoolean(name, val) {
13804-
const trueValue = ['true', 'True', 'TRUE'];
13805-
const falseValue = ['false', 'False', 'FALSE'];
13806-
if (trueValue.includes(val))
13807-
return true;
13808-
if (falseValue.includes(val))
13809-
return false;
13810-
throw new TypeError(`Action input "${name}" does not meet YAML 1.2 "Core Schema" specification: \n` +
13811-
`Supported boolean values: \`true | True | TRUE | false | False | FALSE\``);
13812-
}
13813-
exports.parseYAMLBoolean = parseYAMLBoolean;
1381413794
/**
1381513795
* Parse a string as a comma-separated list.
1381613796
*/
@@ -13822,10 +13802,11 @@ function parseCSV(val) {
1382213802
}
1382313803
function getOpts({ ghc, cabal, stack }, os, inputs) {
1382413804
core.debug(`Inputs are: ${JSON.stringify(inputs)}`);
13825-
const stackNoGlobal = (inputs.stackNoGlobal ?? '') !== '';
13826-
const stackSetupGhc = (inputs.stackSetupGhc ?? '') !== '';
13827-
const stackEnable = (inputs.enableStack ?? '') !== '';
13828-
const matcherDisable = (inputs.disableMatcher ?? '') !== '';
13805+
const stackNoGlobal = inputs.stackNoGlobal ?? false;
13806+
const stackSetupGhc = inputs.stackSetupGhc ?? false;
13807+
const stackEnable = inputs.enableStack ?? false;
13808+
const cabalUpdate = inputs.cabalUpdate ?? true;
13809+
const matcherDisable = inputs.disableMatcher ?? false;
1382913810
if (inputs.ghcupReleaseChannel) {
1383013811
core.warning('ghcup-release-channel is deprecated in favor of ghcup-release-channels');
1383113812
inputs.ghcupReleaseChannels = inputs.ghcupReleaseChannel;
@@ -13838,11 +13819,6 @@ function getOpts({ ghc, cabal, stack }, os, inputs) {
1383813819
throw new TypeError(`Not a valid URL: ${v}`);
1383913820
}
1384013821
});
13841-
// Andreas, 2023-01-05, issue #29:
13842-
// 'cabal-update' has a default value, so we should get a proper boolean always.
13843-
// Andreas, 2023-01-06: This is not true if we use the action as a library.
13844-
// Thus, need to patch with default value here.
13845-
const cabalUpdate = parseYAMLBoolean('cabal-update', inputs.cabalUpdate ?? 'true');
1384613822
core.debug(`${stackNoGlobal}/${stackSetupGhc}/${stackEnable}`);
1384713823
const verInpt = {
1384813824
ghc: inputs.ghcVersion || ghc.version,

lib/opts.d.ts

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -74,28 +74,17 @@ export declare const yamlInputs: Record<string, {
7474
}>;
7575
export declare function getDefaults(os: OS): Defaults;
7676
export declare function releaseRevision(version: string, tool: Tool, os: OS): string;
77-
/**
78-
* Convert a string input to a boolean according to the YAML 1.2 "core schema" specification.
79-
* Supported boolean renderings: `true | True | TRUE | false | False | FALSE` .
80-
* ref: https://yaml.org/spec/1.2/spec.html#id2804923
81-
* Adapted from: https://github.com/actions/toolkit/commit/fbdf27470cdcb52f16755d32082f1fee0bfb7d6d#diff-f63fb32fca85d8e177d6400ce078818a4815b80ac7a3319b60d3507354890992R94-R115
82-
*
83-
* @param name name of the input
84-
* @param val supposed string representation of a boolean
85-
* @returns boolean
86-
*/
87-
export declare function parseYAMLBoolean(name: string, val: string): boolean;
8877
export type RawInputs = {
8978
ghcVersion?: string;
9079
cabalVersion?: string;
9180
stackVersion?: string;
92-
enableStack?: string;
93-
stackNoGlobal?: string;
94-
stackSetupGhc?: string;
95-
cabalUpdate?: string;
81+
enableStack?: boolean;
82+
stackNoGlobal?: boolean;
83+
stackSetupGhc?: boolean;
84+
cabalUpdate?: boolean;
9685
ghcupReleaseChannels?: string;
9786
ghcupReleaseChannel?: string;
98-
disableMatcher?: string;
87+
disableMatcher?: boolean;
9988
};
10089
export declare function getOpts({ ghc, cabal, stack }: Defaults, os: OS, inputs: RawInputs): Options;
10190
export {};

lib/opts.js

Lines changed: 6 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
2323
return result;
2424
};
2525
Object.defineProperty(exports, "__esModule", { value: true });
26-
exports.getOpts = exports.parseYAMLBoolean = exports.releaseRevision = exports.getDefaults = exports.yamlInputs = exports.ghcup_version = exports.supported_versions = exports.release_revisions = void 0;
26+
exports.getOpts = exports.releaseRevision = exports.getDefaults = exports.yamlInputs = exports.ghcup_version = exports.supported_versions = exports.release_revisions = void 0;
2727
const core = __importStar(require("@actions/core"));
2828
const fs_1 = require("fs");
2929
const js_yaml_1 = require("js-yaml");
@@ -102,27 +102,6 @@ function releaseRevision(version, tool, os) {
102102
return result;
103103
}
104104
exports.releaseRevision = releaseRevision;
105-
/**
106-
* Convert a string input to a boolean according to the YAML 1.2 "core schema" specification.
107-
* Supported boolean renderings: `true | True | TRUE | false | False | FALSE` .
108-
* ref: https://yaml.org/spec/1.2/spec.html#id2804923
109-
* Adapted from: https://github.com/actions/toolkit/commit/fbdf27470cdcb52f16755d32082f1fee0bfb7d6d#diff-f63fb32fca85d8e177d6400ce078818a4815b80ac7a3319b60d3507354890992R94-R115
110-
*
111-
* @param name name of the input
112-
* @param val supposed string representation of a boolean
113-
* @returns boolean
114-
*/
115-
function parseYAMLBoolean(name, val) {
116-
const trueValue = ['true', 'True', 'TRUE'];
117-
const falseValue = ['false', 'False', 'FALSE'];
118-
if (trueValue.includes(val))
119-
return true;
120-
if (falseValue.includes(val))
121-
return false;
122-
throw new TypeError(`Action input "${name}" does not meet YAML 1.2 "Core Schema" specification: \n` +
123-
`Supported boolean values: \`true | True | TRUE | false | False | FALSE\``);
124-
}
125-
exports.parseYAMLBoolean = parseYAMLBoolean;
126105
/**
127106
* Parse a string as a comma-separated list.
128107
*/
@@ -134,10 +113,11 @@ function parseCSV(val) {
134113
}
135114
function getOpts({ ghc, cabal, stack }, os, inputs) {
136115
core.debug(`Inputs are: ${JSON.stringify(inputs)}`);
137-
const stackNoGlobal = (inputs.stackNoGlobal ?? '') !== '';
138-
const stackSetupGhc = (inputs.stackSetupGhc ?? '') !== '';
139-
const stackEnable = (inputs.enableStack ?? '') !== '';
140-
const matcherDisable = (inputs.disableMatcher ?? '') !== '';
116+
const stackNoGlobal = inputs.stackNoGlobal ?? false;
117+
const stackSetupGhc = inputs.stackSetupGhc ?? false;
118+
const stackEnable = inputs.enableStack ?? false;
119+
const cabalUpdate = inputs.cabalUpdate ?? true;
120+
const matcherDisable = inputs.disableMatcher ?? false;
141121
if (inputs.ghcupReleaseChannel) {
142122
core.warning('ghcup-release-channel is deprecated in favor of ghcup-release-channels');
143123
inputs.ghcupReleaseChannels = inputs.ghcupReleaseChannel;
@@ -150,11 +130,6 @@ function getOpts({ ghc, cabal, stack }, os, inputs) {
150130
throw new TypeError(`Not a valid URL: ${v}`);
151131
}
152132
});
153-
// Andreas, 2023-01-05, issue #29:
154-
// 'cabal-update' has a default value, so we should get a proper boolean always.
155-
// Andreas, 2023-01-06: This is not true if we use the action as a library.
156-
// Thus, need to patch with default value here.
157-
const cabalUpdate = parseYAMLBoolean('cabal-update', inputs.cabalUpdate ?? 'true');
158133
core.debug(`${stackNoGlobal}/${stackSetupGhc}/${stackEnable}`);
159134
const verInpt = {
160135
ghc: inputs.ghcVersion || ghc.version,

src/main.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
import * as core from '@actions/core';
22
import run from './setup-haskell';
33

4+
const getToggleInput = (name: string) => core.getInput(name) !== '';
5+
46
run({
57
ghcVersion: core.getInput('ghc-version'),
68
cabalVersion: core.getInput('cabal-version'),
79
stackVersion: core.getInput('stack-version'),
8-
enableStack: core.getInput('enable-stack'),
9-
stackNoGlobal: core.getInput('stack-no-global'),
10-
stackSetupGhc: core.getInput('stack-setup-ghc'),
11-
cabalUpdate: core.getInput('cabal-update'),
10+
enableStack: getToggleInput('enable-stack'),
11+
stackNoGlobal: getToggleInput('stack-no-global'),
12+
stackSetupGhc: getToggleInput('stack-setup-ghc'),
13+
cabalUpdate: core.getBooleanInput('cabal-update'),
1214
ghcupReleaseChannels: core.getInput('ghcup-release-channels'),
1315
ghcupReleaseChannel: core.getInput('ghcup-release-channel'),
14-
disableMatcher: core.getInput('disable-matcher')
16+
disableMatcher: getToggleInput('disable-matcher')
1517
});

src/opts.ts

Lines changed: 11 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -117,27 +117,6 @@ export function releaseRevision(version: string, tool: Tool, os: OS): string {
117117
return result;
118118
}
119119

120-
/**
121-
* Convert a string input to a boolean according to the YAML 1.2 "core schema" specification.
122-
* Supported boolean renderings: `true | True | TRUE | false | False | FALSE` .
123-
* ref: https://yaml.org/spec/1.2/spec.html#id2804923
124-
* Adapted from: https://github.com/actions/toolkit/commit/fbdf27470cdcb52f16755d32082f1fee0bfb7d6d#diff-f63fb32fca85d8e177d6400ce078818a4815b80ac7a3319b60d3507354890992R94-R115
125-
*
126-
* @param name name of the input
127-
* @param val supposed string representation of a boolean
128-
* @returns boolean
129-
*/
130-
export function parseYAMLBoolean(name: string, val: string): boolean {
131-
const trueValue = ['true', 'True', 'TRUE'];
132-
const falseValue = ['false', 'False', 'FALSE'];
133-
if (trueValue.includes(val)) return true;
134-
if (falseValue.includes(val)) return false;
135-
throw new TypeError(
136-
`Action input "${name}" does not meet YAML 1.2 "Core Schema" specification: \n` +
137-
`Supported boolean values: \`true | True | TRUE | false | False | FALSE\``
138-
);
139-
}
140-
141120
/**
142121
* Parse a string as a comma-separated list.
143122
*/
@@ -152,13 +131,13 @@ export type RawInputs = {
152131
ghcVersion?: string;
153132
cabalVersion?: string;
154133
stackVersion?: string;
155-
enableStack?: string;
156-
stackNoGlobal?: string;
157-
stackSetupGhc?: string;
158-
cabalUpdate?: string;
134+
enableStack?: boolean;
135+
stackNoGlobal?: boolean;
136+
stackSetupGhc?: boolean;
137+
cabalUpdate?: boolean;
159138
ghcupReleaseChannels?: string;
160139
ghcupReleaseChannel?: string;
161-
disableMatcher?: string;
140+
disableMatcher?: boolean;
162141
};
163142

164143
export function getOpts(
@@ -167,10 +146,12 @@ export function getOpts(
167146
inputs: RawInputs
168147
): Options {
169148
core.debug(`Inputs are: ${JSON.stringify(inputs)}`);
170-
const stackNoGlobal = (inputs.stackNoGlobal ?? '') !== '';
171-
const stackSetupGhc = (inputs.stackSetupGhc ?? '') !== '';
172-
const stackEnable = (inputs.enableStack ?? '') !== '';
173-
const matcherDisable = (inputs.disableMatcher ?? '') !== '';
149+
150+
const stackNoGlobal = inputs.stackNoGlobal ?? false;
151+
const stackSetupGhc = inputs.stackSetupGhc ?? false;
152+
const stackEnable = inputs.enableStack ?? false;
153+
const cabalUpdate = inputs.cabalUpdate ?? true;
154+
const matcherDisable = inputs.disableMatcher ?? false;
174155

175156
if (inputs.ghcupReleaseChannel) {
176157
core.warning(
@@ -189,14 +170,6 @@ export function getOpts(
189170
}
190171
);
191172

192-
// Andreas, 2023-01-05, issue #29:
193-
// 'cabal-update' has a default value, so we should get a proper boolean always.
194-
// Andreas, 2023-01-06: This is not true if we use the action as a library.
195-
// Thus, need to patch with default value here.
196-
const cabalUpdate = parseYAMLBoolean(
197-
'cabal-update',
198-
inputs.cabalUpdate ?? 'true'
199-
);
200173
core.debug(`${stackNoGlobal}/${stackSetupGhc}/${stackEnable}`);
201174
const verInpt = {
202175
ghc: inputs.ghcVersion || ghc.version,

0 commit comments

Comments
 (0)