Skip to content

Commit

Permalink
Use clj-msi to install ClojureCLI on Windows
Browse files Browse the repository at this point in the history
  • Loading branch information
DeLaGuardo committed Nov 14, 2024
1 parent 0747838 commit 08b2927
Show file tree
Hide file tree
Showing 9 changed files with 518 additions and 441 deletions.
575 changes: 294 additions & 281 deletions .github/workflows/smoke-tests.yml

Large diffs are not rendered by default.

11 changes: 8 additions & 3 deletions __tests__/tdeps.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import * as _io from '@actions/io'
import * as _tc from '@actions/tool-cache'
import * as _http from '@actions/http-client'
import * as _os from 'os'
import * as _crypto from 'crypto'
import * as _fs from '../src/fs'
import {join} from 'path'
import {VERSION} from '../src/version'
Expand Down Expand Up @@ -49,12 +50,16 @@ jest.mock('@actions/http-client', () => {
}
})

jest.mock('crypto')
const crypto: jest.Mocked<typeof _crypto> = _crypto as never

describe('tdeps tests', () => {
beforeAll(async () => {
process.env['RUNNER_TOOL_CACHE'] = toolPath
process.env['RUNNER_TEMP'] = tempPath
os.arch.mockReturnValue('x64')
os.platform.mockReturnValue('linux')
crypto.randomUUID.mockReturnValue('123-123-123-123-123')
jest.spyOn(global.Math, 'random').mockReturnValue(1)
})

Expand All @@ -79,7 +84,7 @@ describe('tdeps tests', () => {

expect(tc.downloadTool).toHaveBeenCalledWith(
'https://download.clojure.org/install/linux-install-1.10.1.469.sh',
undefined,
join(tempPath, '123-123-123-123-123', 'linux-install-1.10.1.469.sh'),
'auth token'
)
expect(io.mkdirP).toHaveBeenCalledWith('/tmp/usr/local/opt/ClojureTools')
Expand Down Expand Up @@ -110,7 +115,7 @@ describe('tdeps tests', () => {

expect(tc.downloadTool).toHaveBeenCalledWith(
'https://download.clojure.org/install/linux-install-1.2.3.sh',
undefined,
join(tempPath, '123-123-123-123-123', 'linux-install-1.2.3.sh'),
'auth token'
)
expect(io.mkdirP).toHaveBeenCalledWith('/tmp/usr/local/opt/ClojureTools')
Expand Down Expand Up @@ -146,7 +151,7 @@ describe('tdeps tests', () => {

expect(tc.downloadTool).toHaveBeenCalledWith(
'https://download.clojure.org/install/linux-install-1.2.3.sh',
undefined,
join(tempPath, '123-123-123-123-123', 'linux-install-1.2.3.sh'),
'foo'
)
expect(io.mkdirP).toHaveBeenCalledWith('/tmp/usr/local/opt/ClojureTools')
Expand Down
155 changes: 90 additions & 65 deletions dist/index.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/index.js.map

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions src/boot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ function getTempDirectory(): string {

if (!tempDirectory) {
let baseLocation
if (utils.isWindows()) {
if (core.platform.isWindows) {
baseLocation = process.env['USERPROFILE'] || 'C:\\'
} else {
if (process.platform === 'darwin') {
Expand All @@ -38,7 +38,7 @@ export async function setup(
os.arch()
)

if (utils.isWindows()) {
if (core.platform.isWindows) {
await setWindowsRegistry()
}

Expand All @@ -47,7 +47,7 @@ export async function setup(
} else {
const bootBootstrapFile = await tc.downloadTool(
`https://github.com/boot-clj/boot-bin/releases/download/latest/boot.${
utils.isWindows() ? 'exe' : 'sh'
core.platform.isWindows ? 'exe' : 'sh'
}`,
undefined,
githubAuth
Expand Down Expand Up @@ -88,10 +88,10 @@ async function installBoot(

await io.mv(
bin,
path.join(binDir, `boot${utils.isWindows() ? '.exe' : ''}`)
path.join(binDir, `boot${core.platform.isWindows ? '.exe' : ''}`)
)

if (!utils.isWindows()) {
if (!core.platform.isWindows) {
await fs.chmod(path.join(binDir, `boot`), '0755')
}

Expand All @@ -115,7 +115,7 @@ async function installBoot(
}

await exec.exec(
`./boot${utils.isWindows() ? '.exe' : ''} ${
`./boot${core.platform.isWindows ? '.exe' : ''} ${
version === 'latest' ? '-u' : '-V'
}`,
[],
Expand Down
164 changes: 108 additions & 56 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import * as path from 'path'
import * as os from 'os'
import * as fs from './fs'
import * as utils from './utils'
import * as crypto from 'crypto'

export const identifier = 'ClojureToolsDeps'

Expand Down Expand Up @@ -65,12 +66,12 @@ async function getUrls(
return {
posix: posix_install_url,
linux: `https://github.com/clojure/brew-install/releases/download/${tag}/linux-install.sh`,
windows: `github.com/clojure/brew-install/releases/download/${tag}/win-install.ps1`
windows: `https://github.com/casselc/clj-msi/releases/tag/v${tag}/clojure-${tag}.msi`
}
} else {
return {
linux: `https://download.clojure.org/install/linux-install-${tag}.sh`,
windows: `download.clojure.org/install/win-install-${tag}.ps1`
windows: `https://github.com/casselc/clj-msi/releases/tag/v${tag}/clojure-${tag}.msi`
}
}
}
Expand All @@ -81,8 +82,8 @@ export async function setup(
): Promise<void> {
core.debug('=== Run setup')
const version = await toolVersion(requestedVersion, githubAuth)
const installDir = utils.isWindows()
? 'C:\\Program Files\\WindowsPowerShell\\Modules'
const installDir = core.platform.isWindows
? 'C:\\tools'
: '/tmp/usr/local/opt'
const toolPath = tc.find(
identifier,
Expand All @@ -99,68 +100,76 @@ export async function setup(
} else {
const {linux, posix, windows} = await getUrls(version, githubAuth)

if (utils.isWindows()) {
await exec.exec(`powershell -c "iwr -useb ${windows} | iex"`, [], {
// Install to a modules location common to powershell/pwsh
env: {PSModulePath: installDir},
input: Buffer.from('1')
})

core.debug(
`clojure tools deps installed to ${path.join(
installDir,
'ClojureTools'
)}`
)
await tc.cacheDir(
path.join(installDir, 'ClojureTools'),
identifier,
utils.getCacheVersionString(version)
)
} else {
let clojureInstallScript

if (utils.isMacOS()) {
if (posix) {
clojureInstallScript = await tc.downloadTool(
posix,
undefined,
githubAuth
)
} else {
clojureInstallScript = await tc.downloadTool(
linux,
undefined,
githubAuth
)
await MacOSDeps(clojureInstallScript, githubAuth)
}
} else {
clojureInstallScript = await tc.downloadTool(
linux,
undefined,
githubAuth
)
}
const url = core.platform.isMacOS
? posix || linux
: core.platform.isWindows
? windows
: linux

const installerFileName = url.split(/\//).pop() || ''
const outputDir = path.join(utils.getTempDir(), crypto.randomUUID())
const outputFile = path.join(outputDir, installerFileName)

const clojureToolsDir = await runLinuxInstall(
clojureInstallScript,
path.join(installDir, 'ClojureTools')
let clojureInstallScript
if (core.platform.isWindows) {
await exec.exec(
'gh',
[
'release',
'-R',
'casselc/clj-msi',
'download',
`v${version}`,
'-D',
`${outputDir}`
],
{
env: {GH_TOKEN: core.getInput('github-token')}
}
)
core.debug(`clojure tools deps installed to ${clojureToolsDir}`)
await tc.cacheDir(
clojureToolsDir,
identifier,
utils.getCacheVersionString(version)
clojureInstallScript = path.join(outputDir, `clojure-${version}.msi`)
} else {
clojureInstallScript = await tc.downloadTool(
url,
outputFile,
githubAuth,
{accept: 'application/octet-stream'}
)
}

core.debug(
`Finish downloading of installation script to ${clojureInstallScript}`
)

if (core.platform.isMacOS && !posix) {
await MacOSDeps(clojureInstallScript, githubAuth)
}

const clojureToolsDir = core.platform.isWindows
? await runWindowsInstall(
clojureInstallScript,
path.join(installDir, 'ClojureTools')
)
: await runLinuxInstall(
clojureInstallScript,
path.join(installDir, 'ClojureTools')
)

core.debug(`clojure tools deps installed to ${clojureToolsDir}`)
await tc.cacheDir(
clojureToolsDir,
identifier,
utils.getCacheVersionString(version)
)
}

core.exportVariable(
'CLOJURE_INSTALL_DIR',
path.join(installDir, 'ClojureTools')
)
if (!utils.isWindows()) {
if (core.platform.isWindows) {
core.addPath(path.join(installDir, 'ClojureTools'))
} else {
core.addPath(path.join(installDir, 'ClojureTools', 'bin'))
}
}
Expand All @@ -178,6 +187,49 @@ async function runLinuxInstall(
return destinationFolder
}

async function runWindowsInstall(
installScript: string,
destinationFolder: string,
githubAuth?: string
): Promise<string> {
core.debug('=== Install on Windows')
await io.mkdirP(destinationFolder)

core.debug(`installing from ${installScript} to ${destinationFolder}`)
const output = await exec.getExecOutput(
'msiexec',
[
'/i',
`"${installScript}"`,
'/qn',
`APPLICATIONFOLDER="${destinationFolder}"`,
'/l*vx',
`"${path.join(utils.getTempDir(), 'install.log')}"`
],
{
env: githubAuth ? {GH_TOKEN: githubAuth} : {},
windowsVerbatimArguments: true,
ignoreReturnCode: true
}
)

const logs = await fs.readFile(path.join(utils.getTempDir(), 'install.log'), {
encoding: 'utf-8'
})

core.debug(`=== logs:`)
core.debug(logs)
core.debug(`===`)
core.debug(`exit code: ${output.exitCode}`)
core.debug(`===`)
core.debug(output.stderr)
core.debug(`===`)
core.debug(output.stdout)
core.debug(`===`)

return destinationFolder
}

async function MacOSDeps(file: string, githubAuth: string): Promise<void> {
core.debug('=== Install extra deps for MacOS')
const data = await fs.readFile(file, 'utf-8')
Expand Down
10 changes: 3 additions & 7 deletions src/entrypoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import * as cljKondo from './clj-kondo'
import * as cljfmt from './cljfmt'
import * as cljstyle from './cljstyle'
import * as zprint from './zprint'
import * as utils from './utils'
import * as cache from './cache'
import process from 'node:process'

Expand All @@ -29,7 +28,6 @@ export async function main(): Promise<void> {

const githubToken = core.getInput('github-token', {required: true})
const githubAuth = `Bearer ${githubToken}`
const IS_WINDOWS = utils.isWindows()

if (LEIN_VERSION) {
tools.push(lein.setup(LEIN_VERSION, githubAuth))
Expand Down Expand Up @@ -60,7 +58,7 @@ export async function main(): Promise<void> {
}

if (CLJSTYLE_VERSION) {
if (IS_WINDOWS) {
if (core.platform.isWindows) {
throw new Error('cljstyle on windows is not supported yet.')
}
tools.push(cljstyle.setup(CLJSTYLE_VERSION, githubAuth))
Expand Down Expand Up @@ -96,7 +94,6 @@ export async function pre(): Promise<void> {
ZPRINT_VERSION
} = getTools()

const IS_WINDOWS = utils.isWindows()
const tools = []

if (LEIN_VERSION) {
Expand Down Expand Up @@ -128,7 +125,7 @@ export async function pre(): Promise<void> {
}

if (CLJSTYLE_VERSION) {
if (!IS_WINDOWS) {
if (!core.platform.isWindows) {
tools.push(cache.restore(cljstyle.identifier, CLJSTYLE_VERSION))
}
}
Expand Down Expand Up @@ -159,7 +156,6 @@ export async function post(): Promise<void> {
ZPRINT_VERSION
} = getTools()

const IS_WINDOWS = utils.isWindows()
const tools = []

if (LEIN_VERSION) {
Expand Down Expand Up @@ -191,7 +187,7 @@ export async function post(): Promise<void> {
}

if (CLJSTYLE_VERSION) {
if (!IS_WINDOWS) {
if (!core.platform.isWindows) {
tools.push(cache.save(cljstyle.identifier, CLJSTYLE_VERSION))
}
}
Expand Down
Loading

0 comments on commit 08b2927

Please sign in to comment.