11import { Either , error , isOk , ok } from "./either" ;
2- import type { RepositorySlug , SemanticVersion } from "./types" ;
2+ import type { SemanticVersion , Sha1Hash , TargetRelease } from "./types" ;
3+
4+ const regexes = {
5+ owner : / \S + / ,
6+ repository : / \S + / ,
7+ majorSemanticVersion : / v ( 0 | [ 1 - 9 ] \d * ) / ,
8+ majorMinorSemanticVersion : / v ( 0 | [ 1 - 9 ] \d * ) \. ( 0 | [ 1 - 9 ] \d * ) / ,
9+ exactSemanticVersion :
10+ / v ( 0 | [ 1 - 9 ] \d * ) \. ( 0 | [ 1 - 9 ] \d * ) \. ( 0 | [ 1 - 9 ] \d * ) (?: - ( (?: 0 | [ 1 - 9 ] \d * | \d * [ a - z A - Z - ] [ 0 - 9 a - z A - Z - ] * ) (?: \. (?: 0 | [ 1 - 9 ] \d * | \d * [ a - z A - Z - ] [ 0 - 9 a - z A - Z - ] * ) ) * ) ) ? (?: \+ ( [ 0 - 9 a - z A - Z - ] + (?: \. [ 0 - 9 a - z A - Z - ] + ) * ) ) ? / ,
11+ sha1Hash : / [ 0 - 9 a - f ] { 40 } / ,
12+ } ;
313
414export function parseEnvironmentVariable ( envVarName : string ) : Either < string > {
515 const value = process . env [ envVarName ] ;
@@ -23,49 +33,45 @@ export function parseToken(value: string): Either<string> {
2333 return ok ( value ) ;
2434}
2535
26- export type TargetRelease = {
27- slug : RepositorySlug ;
28- tag : SemanticVersion ;
29- } ;
30-
31- function parseTargetRelease ( value : string ) : Either < TargetRelease > {
32- const errors : string [ ] = [ ] ;
33- const repo_regex = / ^ ( \S + ) \/ ( \S + ) $ / ;
34- if ( repo_regex . test ( value ) === null ) {
35- errors . push (
36- "input.repo does not describe a GitHub repository -- expected {owner}/{repository}@{tag} format (example: EricCrosson/git-disjoint@v2)"
37- ) ;
38- }
39- const tag_regex = / ^ ( \S + ) @ v ( \S + ) $ / ;
40- if ( tag_regex . test ( value ) === null ) {
41- errors . push (
42- "input.repo does not describe a tag version -- expected {owner}/{repository}@{tag} format (example: EricCrosson/git-disjoint@v2)"
43- ) ;
44- }
45- if ( errors . length > 0 ) {
46- return error ( errors ) ;
47- }
48-
49- const regex = / ^ ( \S + ) \/ ( \S + ) @ ( v \S + ) $ / ;
36+ function parseTargetReleaseVersion ( value : string ) : Either < TargetRelease > {
37+ const {
38+ owner,
39+ repository,
40+ majorSemanticVersion,
41+ majorMinorSemanticVersion,
42+ exactSemanticVersion,
43+ sha1Hash,
44+ } = regexes ;
45+ const regex = new RegExp (
46+ `^(${ owner . source } )/(${ repository . source } )@((${ sha1Hash . source } )|${ majorSemanticVersion . source } |${ majorMinorSemanticVersion . source } |${ exactSemanticVersion . source } )$`
47+ ) ;
5048 const match = value . match ( regex ) ;
51- if ( match === null || match . length !== 4 ) {
52- return error ( [
53- "input.repo invalid -- expected {owner}/{repository}@{tag} format (example: EricCrosson/git-disjoint@v2)" ,
54- ] ) ;
49+ if ( match === null ) {
50+ // This error message is never used
51+ return error ( [ "not a valid target release" ] ) ;
5552 }
56-
5753 const target : TargetRelease = {
5854 slug : {
5955 owner : match [ 1 ] as string ,
6056 repository : match [ 2 ] as string ,
6157 } ,
62- // NOTE: we're not really parsing the content of this string,
63- // so this is an unlawful type assertion
64- tag : match [ 3 ] as SemanticVersion ,
58+ tag : match [ 3 ] as SemanticVersion | Sha1Hash ,
6559 } ;
6660 return ok ( target ) ;
6761}
6862
63+ function parseTargetRelease ( value : string ) : Either < TargetRelease > {
64+ const maybeTargetRelease = parseTargetReleaseVersion ( value ) ;
65+
66+ if ( isOk ( maybeTargetRelease ) ) {
67+ return ok ( maybeTargetRelease . value ) ;
68+ }
69+
70+ return error ( [
71+ `input.targetes invalid -- '${ value } ' does not match expected format '{owner}/{repository}@{tag}' (example: EricCrosson/git-disjoint@v2)` ,
72+ ] ) ;
73+ }
74+
6975export function parseTargetReleases ( value : string ) : Either < TargetRelease [ ] > {
7076 if ( value . length === 0 ) {
7177 return error ( [ "input.targets not defined" ] ) ;
0 commit comments