@@ -5,6 +5,8 @@ import { info } from "ci-log"
55import { addEnv , addPath } from "envosman"
66import { pathExists } from "path-exists"
77import { addExeExt } from "patha"
8+ import semverCoerce from "semver/functions/coerce.js"
9+ import semverSatisfies from "semver/functions/satisfies.js"
810import { installAptPack } from "setup-apt"
911import { rcOptions } from "../cli-options.js"
1012import { loadAssetList , matchAsset } from "../utils/asset/load-assets.js"
@@ -102,13 +104,45 @@ export async function getMinGWPackageInfo(
102104 ia32 : "i386" ,
103105 } as Record < string , string | undefined >
104106
107+ // extract the base version by coercing the version
108+ const versionCoerce = semverCoerce ( version )
109+ if ( versionCoerce === null ) {
110+ throw new Error ( `Invalid MinGW version requested '${ version } '` )
111+ }
112+
113+ const runtime = extractMinGWRuntime ( version )
114+ const threadModel = extractMinGWThreadModel ( version )
115+ const exceptionModel = extractMingwExceptionModel ( version )
116+
105117 const asset = matchAsset (
106118 mingwAssets ,
107119 {
108120 version,
109121 keywords : [
110122 mingwArchMap [ arch ] ?? arch ,
111123 ] ,
124+ filterName : ( assetName ) => {
125+ const assetRuntime = extractMinGWRuntime ( assetName )
126+ const assetThreadModel = extractMinGWThreadModel ( assetName )
127+ const assetExceptionModel = extractMingwExceptionModel ( assetName )
128+
129+ return ( runtime === undefined || runtime === assetRuntime )
130+ && ( threadModel === undefined || threadModel === assetThreadModel )
131+ && ( assetExceptionModel === undefined || assetExceptionModel === exceptionModel )
132+ } ,
133+ versionSatisfies : ( assetVersion ) => {
134+ // extract the base version by coercing the version
135+ const assetCoerce = semverCoerce ( assetVersion )
136+ if ( assetCoerce === null ) {
137+ throw new Error ( `Invalid MinGW asset version: '${ assetVersion } '` )
138+ }
139+
140+ // if the asset version is satisfied by the version
141+ // and the runtime and thread model match or not specified
142+ return semverSatisfies ( assetCoerce , `^${ versionCoerce } ` )
143+ && ( runtime === undefined || runtime === extractMinGWRuntime ( assetVersion ) )
144+ && ( threadModel === undefined || threadModel === extractMinGWThreadModel ( assetVersion ) )
145+ } ,
112146 } ,
113147 )
114148
@@ -125,6 +159,50 @@ export async function getMinGWPackageInfo(
125159 }
126160}
127161
162+ /**
163+ * Extract the runtime used by the MinGW asset/version
164+ * @param input The input to extract the runtime from
165+ *
166+ * @example
167+ * extractMinGWRuntime("14.2.0posix-18.1.8-12.0.0-ucrt-r1") // "ucrt"
168+ * extractMinGWRuntime("10.5.0-11.0.1-msvcrt-r2") // "msvcrt"
169+ * extractMinGWRuntime("11.1.0-12.0.0-9.0.0-r1") // undefined
170+ */
171+ function extractMinGWRuntime ( input : string ) {
172+ const match = input . match ( / ( u c r t | m s v c r t ) / )
173+ return match !== null ? match [ 1 ] : undefined
174+ }
175+
176+ /**
177+ * Extract the thread model used by the MinGW asset/version
178+ * @param input The input to extract the thread model from
179+ *
180+ * @example
181+ * extractMinGWThreadModel("14.2.0posix-18.1.8-12.0.0-ucrt-r1") // "posix"
182+ * extractMinGWThreadModel("14.2.0mcf-12.0.0-ucrt-r1") // "mcf"
183+ * extractMinGWThreadModel("10.5.0-11.0.1-msvcrt-r2") // undefined
184+ * extractMinGWThreadModel("11.1.0-12.0.0-9.0.0-r1") // undefined
185+ */
186+ function extractMinGWThreadModel ( input : string ) {
187+ const match = input . match ( / ( p o s i x | m c f ) / )
188+ return match !== null ? match [ 1 ] : undefined
189+ }
190+
191+ /**
192+ * Extract the exception model used by the MinGW asset/version
193+ *
194+ * @param input The input to extract the exception model from
195+ *
196+ * @example
197+ * extractMingwExceptionModel("14.2.0posix-18.1.8-12.0.0-ucrt-r1") // "seh"
198+ * extractMingwExceptionModel("14.2.0mcf-12.0.0-ucrt-r1") // undefined
199+ * extractMingwExceptionModel("10.5.0-11.0.1-msvcrt-r2") // "dwarf"
200+ */
201+ function extractMingwExceptionModel ( input : string ) {
202+ const match = input . match ( / ( s e h | d w a r f ) / )
203+ return match !== null ? match [ 1 ] : undefined
204+ }
205+
128206async function activateMinGW ( binDir : string ) {
129207 const promises : Promise < void > [ ] = [ ]
130208
0 commit comments