Skip to content

Commit b4f9753

Browse files
committed
refactor: sort exported functions alphabetically in releases modules
1 parent f0fd0ee commit b4f9753

2 files changed

Lines changed: 251 additions & 251 deletions

File tree

src/releases/github.ts

Lines changed: 179 additions & 179 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,185 @@ export interface RepoConfig {
5050
repo: string
5151
}
5252

53+
/**
54+
* Configuration for downloading a GitHub release.
55+
*/
56+
export interface DownloadGitHubReleaseConfig {
57+
/** GitHub repository owner/organization. */
58+
owner: string
59+
/** GitHub repository name. */
60+
repo: string
61+
/** Working directory (defaults to process.cwd()). */
62+
cwd?: string
63+
/** Download destination directory. @default 'build/downloaded' */
64+
downloadDir?: string
65+
/** Tool name for directory structure. */
66+
toolName: string
67+
/** Platform-arch identifier (e.g., 'linux-x64-musl'). */
68+
platformArch: string
69+
/** Binary filename (e.g., 'node', 'binject'). */
70+
binaryName: string
71+
/** Asset name on GitHub. */
72+
assetName: string
73+
/** Tool prefix for finding latest release. */
74+
toolPrefix?: string
75+
/** Specific release tag to download. */
76+
tag?: string
77+
/** Suppress log messages. @default false */
78+
quiet?: boolean
79+
/** Remove macOS quarantine attribute after download. @default true */
80+
removeMacOSQuarantine?: boolean
81+
}
82+
83+
/**
84+
* Download a binary from any GitHub repository with version caching.
85+
*
86+
* @param config - Download configuration
87+
* @returns Path to the downloaded binary
88+
*/
89+
export async function downloadGitHubRelease(
90+
config: DownloadGitHubReleaseConfig,
91+
): Promise<string> {
92+
const {
93+
assetName,
94+
binaryName,
95+
cwd = process.cwd(),
96+
downloadDir = 'build/downloaded',
97+
owner,
98+
platformArch,
99+
quiet = false,
100+
removeMacOSQuarantine = true,
101+
repo,
102+
tag: explicitTag,
103+
toolName,
104+
toolPrefix,
105+
} = config
106+
107+
// Get release tag (either explicit or latest).
108+
let tag: string
109+
if (explicitTag) {
110+
tag = explicitTag
111+
} else if (toolPrefix) {
112+
const latestTag = await getLatestRelease(
113+
toolPrefix,
114+
{ owner, repo },
115+
{ quiet },
116+
)
117+
if (!latestTag) {
118+
throw new Error(`No ${toolPrefix} release found in ${owner}/${repo}`)
119+
}
120+
tag = latestTag
121+
} else {
122+
throw new Error('Either toolPrefix or tag must be provided')
123+
}
124+
125+
// Resolve download directory (can be absolute or relative to cwd).
126+
const resolvedDownloadDir = path.isAbsolute(downloadDir)
127+
? downloadDir
128+
: path.join(cwd, downloadDir)
129+
130+
// Build download paths following socket-cli pattern.
131+
const binaryDir = path.join(resolvedDownloadDir, toolName, platformArch)
132+
const binaryPath = path.join(binaryDir, binaryName)
133+
const versionPath = path.join(binaryDir, '.version')
134+
135+
// Check if already downloaded.
136+
if (existsSync(versionPath) && existsSync(binaryPath)) {
137+
const cachedVersion = (await readFile(versionPath, 'utf8')).trim()
138+
if (cachedVersion === tag) {
139+
if (!quiet) {
140+
logger.info(`Using cached ${toolName} (${platformArch}): ${binaryPath}`)
141+
}
142+
return binaryPath
143+
}
144+
}
145+
146+
// Download the asset.
147+
if (!quiet) {
148+
logger.info(`Downloading ${toolName} for ${platformArch}...`)
149+
}
150+
await downloadReleaseAsset(
151+
tag,
152+
assetName,
153+
binaryPath,
154+
{ owner, repo },
155+
{ quiet },
156+
)
157+
158+
// Make executable on Unix-like systems.
159+
const isWindows = binaryName.endsWith('.exe')
160+
if (!isWindows) {
161+
chmodSync(binaryPath, 0o755)
162+
163+
// Remove macOS quarantine attribute if present (only on macOS host for macOS target).
164+
if (
165+
removeMacOSQuarantine &&
166+
process.platform === 'darwin' &&
167+
platformArch.startsWith('darwin')
168+
) {
169+
try {
170+
await spawn('xattr', ['-d', 'com.apple.quarantine', binaryPath], {
171+
stdio: 'ignore',
172+
})
173+
} catch {
174+
// Ignore errors - attribute might not exist or xattr might not be available.
175+
}
176+
}
177+
}
178+
179+
// Write version file.
180+
await writeFile(versionPath, tag, 'utf8')
181+
182+
if (!quiet) {
183+
logger.info(`Downloaded ${toolName} to ${binaryPath}`)
184+
}
185+
186+
return binaryPath
187+
}
188+
189+
/**
190+
* Download a specific release asset.
191+
*
192+
* @param tag - Release tag name
193+
* @param assetName - Asset name to download
194+
* @param outputPath - Path to write the downloaded file
195+
* @param repoConfig - Repository configuration (owner/repo)
196+
* @param options - Additional options
197+
*/
198+
export async function downloadReleaseAsset(
199+
tag: string,
200+
assetName: string,
201+
outputPath: string,
202+
repoConfig: RepoConfig,
203+
options: { quiet?: boolean } = {},
204+
): Promise<void> {
205+
const { owner, repo } = repoConfig
206+
const { quiet = false } = options
207+
208+
// Get the browser_download_url for the asset.
209+
const downloadUrl = await getReleaseAssetUrl(
210+
tag,
211+
assetName,
212+
{ owner, repo },
213+
{ quiet },
214+
)
215+
216+
if (!downloadUrl) {
217+
throw new Error(`Asset ${assetName} not found in release ${tag}`)
218+
}
219+
220+
// Create output directory.
221+
await safeMkdir(path.dirname(outputPath))
222+
223+
// Download using httpDownload which supports redirects and retries.
224+
await httpDownload(downloadUrl, outputPath, {
225+
logger: quiet ? undefined : logger,
226+
progressInterval: 10,
227+
retries: 2,
228+
retryDelay: 5000,
229+
})
230+
}
231+
53232
/**
54233
* Get GitHub authentication headers if token is available.
55234
* Checks GH_TOKEN or GITHUB_TOKEN environment variables.
@@ -198,182 +377,3 @@ export async function getReleaseAssetUrl(
198377
},
199378
)
200379
}
201-
202-
/**
203-
* Download a specific release asset.
204-
*
205-
* @param tag - Release tag name
206-
* @param assetName - Asset name to download
207-
* @param outputPath - Path to write the downloaded file
208-
* @param repoConfig - Repository configuration (owner/repo)
209-
* @param options - Additional options
210-
*/
211-
export async function downloadReleaseAsset(
212-
tag: string,
213-
assetName: string,
214-
outputPath: string,
215-
repoConfig: RepoConfig,
216-
options: { quiet?: boolean } = {},
217-
): Promise<void> {
218-
const { owner, repo } = repoConfig
219-
const { quiet = false } = options
220-
221-
// Get the browser_download_url for the asset.
222-
const downloadUrl = await getReleaseAssetUrl(
223-
tag,
224-
assetName,
225-
{ owner, repo },
226-
{ quiet },
227-
)
228-
229-
if (!downloadUrl) {
230-
throw new Error(`Asset ${assetName} not found in release ${tag}`)
231-
}
232-
233-
// Create output directory.
234-
await safeMkdir(path.dirname(outputPath))
235-
236-
// Download using httpDownload which supports redirects and retries.
237-
await httpDownload(downloadUrl, outputPath, {
238-
logger: quiet ? undefined : logger,
239-
progressInterval: 10,
240-
retries: 2,
241-
retryDelay: 5000,
242-
})
243-
}
244-
245-
/**
246-
* Configuration for downloading a GitHub release.
247-
*/
248-
export interface DownloadGitHubReleaseConfig {
249-
/** GitHub repository owner/organization. */
250-
owner: string
251-
/** GitHub repository name. */
252-
repo: string
253-
/** Working directory (defaults to process.cwd()). */
254-
cwd?: string
255-
/** Download destination directory. @default 'build/downloaded' */
256-
downloadDir?: string
257-
/** Tool name for directory structure. */
258-
toolName: string
259-
/** Platform-arch identifier (e.g., 'linux-x64-musl'). */
260-
platformArch: string
261-
/** Binary filename (e.g., 'node', 'binject'). */
262-
binaryName: string
263-
/** Asset name on GitHub. */
264-
assetName: string
265-
/** Tool prefix for finding latest release. */
266-
toolPrefix?: string
267-
/** Specific release tag to download. */
268-
tag?: string
269-
/** Suppress log messages. @default false */
270-
quiet?: boolean
271-
/** Remove macOS quarantine attribute after download. @default true */
272-
removeMacOSQuarantine?: boolean
273-
}
274-
275-
/**
276-
* Download a binary from any GitHub repository with version caching.
277-
*
278-
* @param config - Download configuration
279-
* @returns Path to the downloaded binary
280-
*/
281-
export async function downloadGitHubRelease(
282-
config: DownloadGitHubReleaseConfig,
283-
): Promise<string> {
284-
const {
285-
assetName,
286-
binaryName,
287-
cwd = process.cwd(),
288-
downloadDir = 'build/downloaded',
289-
owner,
290-
platformArch,
291-
quiet = false,
292-
removeMacOSQuarantine = true,
293-
repo,
294-
tag: explicitTag,
295-
toolName,
296-
toolPrefix,
297-
} = config
298-
299-
// Get release tag (either explicit or latest).
300-
let tag: string
301-
if (explicitTag) {
302-
tag = explicitTag
303-
} else if (toolPrefix) {
304-
const latestTag = await getLatestRelease(
305-
toolPrefix,
306-
{ owner, repo },
307-
{ quiet },
308-
)
309-
if (!latestTag) {
310-
throw new Error(`No ${toolPrefix} release found in ${owner}/${repo}`)
311-
}
312-
tag = latestTag
313-
} else {
314-
throw new Error('Either toolPrefix or tag must be provided')
315-
}
316-
317-
// Resolve download directory (can be absolute or relative to cwd).
318-
const resolvedDownloadDir = path.isAbsolute(downloadDir)
319-
? downloadDir
320-
: path.join(cwd, downloadDir)
321-
322-
// Build download paths following socket-cli pattern.
323-
const binaryDir = path.join(resolvedDownloadDir, toolName, platformArch)
324-
const binaryPath = path.join(binaryDir, binaryName)
325-
const versionPath = path.join(binaryDir, '.version')
326-
327-
// Check if already downloaded.
328-
if (existsSync(versionPath) && existsSync(binaryPath)) {
329-
const cachedVersion = (await readFile(versionPath, 'utf8')).trim()
330-
if (cachedVersion === tag) {
331-
if (!quiet) {
332-
logger.info(`Using cached ${toolName} (${platformArch}): ${binaryPath}`)
333-
}
334-
return binaryPath
335-
}
336-
}
337-
338-
// Download the asset.
339-
if (!quiet) {
340-
logger.info(`Downloading ${toolName} for ${platformArch}...`)
341-
}
342-
await downloadReleaseAsset(
343-
tag,
344-
assetName,
345-
binaryPath,
346-
{ owner, repo },
347-
{ quiet },
348-
)
349-
350-
// Make executable on Unix-like systems.
351-
const isWindows = binaryName.endsWith('.exe')
352-
if (!isWindows) {
353-
chmodSync(binaryPath, 0o755)
354-
355-
// Remove macOS quarantine attribute if present (only on macOS host for macOS target).
356-
if (
357-
removeMacOSQuarantine &&
358-
process.platform === 'darwin' &&
359-
platformArch.startsWith('darwin')
360-
) {
361-
try {
362-
await spawn('xattr', ['-d', 'com.apple.quarantine', binaryPath], {
363-
stdio: 'ignore',
364-
})
365-
} catch {
366-
// Ignore errors - attribute might not exist or xattr might not be available.
367-
}
368-
}
369-
}
370-
371-
// Write version file.
372-
await writeFile(versionPath, tag, 'utf8')
373-
374-
if (!quiet) {
375-
logger.info(`Downloaded ${toolName} to ${binaryPath}`)
376-
}
377-
378-
return binaryPath
379-
}

0 commit comments

Comments
 (0)