Skip to content

Commit

Permalink
Merge pull request #86 from weavejester/patch-add-cljfmt
Browse files Browse the repository at this point in the history
Add cljfmt support
  • Loading branch information
DeLaGuardo authored May 26, 2023
2 parents 8f7bae7 + 7f05c92 commit 3610d4a
Show file tree
Hide file tree
Showing 7 changed files with 293 additions and 0 deletions.
26 changes: 26 additions & 0 deletions .github/workflows/smoke-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,32 @@ jobs:
- name: Check clj-kondo version
run: clj-kondo --version

test-cljfmt:
strategy:
matrix:
os: [ubuntu-latest, macOS-latest, windows-latest]

runs-on: ${{ matrix.os }}

steps:
- name: Checkout
uses: actions/checkout@main

- name: Prepare java
uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: '8'

- name: Install cljfmt
uses: ./
with:
cljfmt: latest
github-token: ${{ secrets.GITHUB_TOKEN }}

- name: Check cljfmt version
run: cljfmt --version

test-cljstyle:
strategy:
matrix:
Expand Down
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ This action sets up Clojure tools environment for using in GitHub Actions.
* [boot-clj](https://boot-clj.github.io/)
* [babashka](https://babashka.org/)
* [clj-kondo](https://github.com/clj-kondo/clj-kondo)
* [cljfmt](https://github.com/weavejester/cljfmt)
* [cljstyle](https://github.com/greglook/cljstyle)
* [deps.clj](https://github.com/borkdude/deps.clj)
* [zprint](https://github.com/kkinnear/zprint)
Expand Down Expand Up @@ -55,6 +56,7 @@ jobs:
boot: 2.8.3 # Boot.clj
bb: 0.7.8 # Babashka
clj-kondo: 2022.05.31 # Clj-kondo
cljfmt: 0.10.2 # cljfmt
cljstyle: 0.15.0 # cljstyle
cmd-exe-workaround: 'latest' # Replaces `clojure` with `deps.clj` on Windows
zprint: 1.2.3 # zprint
Expand Down Expand Up @@ -89,6 +91,9 @@ jobs:
- name: Get clj-kondo version
run: clj-kondo --version

- name: Get cljfmt version
run: cljfmt --version

- name: Get cljstyle version
# cljstyle is not yet available for windows
if: ${{ matrix.os != 'windows-latest' }}
Expand Down
153 changes: 153 additions & 0 deletions __tests__/cljfmt.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
import _os from 'os'
import * as _core from '@actions/core'
import * as _tc from '@actions/tool-cache'
import * as cljfmt from '../src/cljfmt'

const getJson = jest.fn()
jest.mock('@actions/http-client', () => ({
HttpClient: function () {
return {getJson}
}
}))

jest.mock('os')
const os: jest.Mocked<typeof _os> = _os as never

jest.mock('@actions/tool-cache')
const tc: jest.Mocked<typeof _tc> = _tc as never

jest.mock('@actions/core')
const core: jest.Mocked<typeof _core> = _core as never

describe('cljfmt tests', () => {
beforeEach(() => {
jest.resetAllMocks()
})

describe('getLatestCljFmt', () => {
it('uses tag_name as latest version', async () => {
getJson.mockResolvedValueOnce({
result: {tag_name: '1.2.3'}
})
const res = await cljfmt.getLatestCljFmt()
expect(res).toBe('1.2.3')
expect(getJson).toHaveBeenCalledWith(
'https://api.github.com/repos/weavejester/cljfmt/releases/latest',
undefined
)
})

it('supports authorization', async () => {
getJson.mockResolvedValueOnce({
result: {tag_name: '1.2.3'}
})
const res = await cljfmt.getLatestCljFmt('token 123')
expect(res).toBe('1.2.3')
expect(getJson).toHaveBeenCalledWith(
'https://api.github.com/repos/weavejester/cljfmt/releases/latest',
{Authorization: 'token 123'}
)
})

it('throws on http client error', async () => {
getJson.mockRejectedValueOnce(new Error('some error'))
await expect(cljfmt.getLatestCljFmt()).rejects.toThrow('some error')
})

it('throws on wrong client answer', async () => {
getJson.mockResolvedValueOnce({result: {foo: 'bar'}})
await expect(cljfmt.getLatestCljFmt()).rejects.toThrow(
`Can't obtain latest cljfmt version`
)
})
})

describe('getArtifactName', () => {
test.each`
platform | artifact
${'win32'} | ${`cljfmt-1.2.3-win-amd64.zip`}
${'darwin'} | ${`cljfmt-1.2.3-darwin-amd64.tar.gz`}
${'linux'} | ${`cljfmt-1.2.3-linux-amd64.tar.gz`}
${'foobar'} | ${`cljfmt-1.2.3-linux-amd64.tar.gz`}
`('$platform -> $artifact', ({platform, artifact}) => {
os.platform.mockReturnValueOnce(platform as never)
expect(cljfmt.getArtifactName('1.2.3')).toBe(artifact)
})
})

describe('getArtifactUrl', () => {
test.each`
platform | artifact
${'win32'} | ${`cljfmt-1.2.3-win-amd64.zip`}
${'darwin'} | ${`cljfmt-1.2.3-darwin-amd64.tar.gz`}
${'linux'} | ${`cljfmt-1.2.3-linux-amd64.tar.gz`}
${'foobar'} | ${`cljfmt-1.2.3-linux-amd64.tar.gz`}
`('$platform -> $artifact', ({platform, artifact}) => {
os.platform.mockReturnValueOnce(platform as never)
expect(cljfmt.getArtifactUrl('1.2.3')).toBe(
`https://github.com/weavejester/cljfmt/releases/download/1.2.3/${artifact}`
)
})
})

describe('setup', () => {
it('uses cache', async () => {
tc.find.mockReturnValueOnce('/foo/bar')

await cljfmt.setup('1.2.3')

expect(tc.find).toHaveBeenCalledWith('cljfmt', '1.2.3')
expect(core.addPath).toHaveBeenCalledWith('/foo/bar')
})

it('uses cache', async () => {
tc.find.mockReturnValueOnce('/foo/bar')

await cljfmt.setup('1.2.3')

expect(tc.find).toHaveBeenCalledWith('cljfmt', '1.2.3')
expect(core.addPath).toHaveBeenCalledWith('/foo/bar')
})

it('fetches exact version', async () => {
tc.downloadTool.mockResolvedValueOnce('/foo/cljfmt.tar.gz')
tc.extractTar.mockResolvedValueOnce('/bar/baz')
tc.cacheDir.mockResolvedValueOnce('/qux')

await cljfmt.setup('1.2.3', 'token 123')

expect(tc.find).toHaveBeenCalledWith('cljfmt', '1.2.3')
expect(tc.downloadTool).toHaveBeenCalledWith(
'https://github.com/weavejester/cljfmt/releases/download/1.2.3/cljfmt-1.2.3-linux-amd64.tar.gz',
undefined,
'token 123'
)
expect(tc.cacheDir).toHaveBeenCalledWith('/bar/baz', 'cljfmt', '1.2.3')
expect(core.addPath).toHaveBeenCalledWith('/qux')
})

it('fetches latest version', async () => {
getJson.mockResolvedValueOnce({
result: {tag_name: '9.9.9'}
})
tc.downloadTool.mockResolvedValueOnce('/foo/cljfmt.tar.gz')
tc.extractTar.mockResolvedValueOnce('/bar/baz')
tc.cacheDir.mockResolvedValueOnce('/qux')

await cljfmt.setup('latest', 'token 123')

expect(getJson).toHaveBeenCalledWith(
'https://api.github.com/repos/weavejester/cljfmt/releases/latest',
{Authorization: 'token 123'}
)
expect(tc.find).toHaveBeenCalledWith('cljfmt', '9.9.9')
expect(tc.downloadTool).toHaveBeenCalledWith(
'https://github.com/weavejester/cljfmt/releases/download/9.9.9/cljfmt-9.9.9-linux-amd64.tar.gz',
undefined,
'token 123'
)
expect(tc.cacheDir).toHaveBeenCalledWith('/bar/baz', 'cljfmt', '9.9.9')
expect(core.addPath).toHaveBeenCalledWith('/qux')
})
})
})
13 changes: 13 additions & 0 deletions __tests__/entrypoint.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import * as _boot from '../src/boot'
import * as _cli from '../src/cli'
import * as _bb from '../src/babashka'
import * as _cljKondo from '../src/clj-kondo'
import * as _cljfmt from '../src/cljfmt'
import * as _cljstyle from '../src/cljstyle'
import * as _zprint from '../src/zprint'
import * as _utils from '../src/utils'
Expand All @@ -27,6 +28,9 @@ const bb: jest.Mocked<typeof _bb> = _bb as never
jest.mock('../src/clj-kondo')
const cljKondo: jest.Mocked<typeof _cljKondo> = _cljKondo as never

jest.mock('../src/cljfmt')
const cljfmt: jest.Mocked<typeof _cljfmt> = _cljfmt as never

jest.mock('../src/cljstyle')
const cljstyle: jest.Mocked<typeof _cljstyle> = _cljstyle as never

Expand Down Expand Up @@ -98,6 +102,15 @@ describe('setup-clojure', () => {
expect(cljKondo.setup).toHaveBeenCalledWith('1.2.3', 'token abc')
})

it('sets up cljfmt', async () => {
inputs['cljfmt'] = '1.2.3'
inputs['github-token'] = 'abc'

await main()

expect(cljfmt.setup).toHaveBeenCalledWith('1.2.3', 'token abc')
})

it('sets up cljstyle', async () => {
inputs['cljstyle'] = '1.2.3'
inputs['github-token'] = 'abc'
Expand Down
2 changes: 2 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ inputs:
description: 'Babashka version to install, `latest` can be used.'
clj-kondo:
description: 'Clj-kondo version to install, `latest` can be used.'
cljfmt:
description: 'cljfmt version to install, `latest` can be used.'
cljstyle:
description: 'cljstyle version to install, `latest` can be used.'
zprint:
Expand Down
75 changes: 75 additions & 0 deletions src/cljfmt.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import * as core from '@actions/core'
import * as http from '@actions/http-client'
import * as os from 'os'
import * as tc from '@actions/tool-cache'

export const identifier = 'cljfmt'

export async function getLatestCljFmt(githubAuth?: string): Promise<string> {
const client = new http.HttpClient('actions/setup-cljfmt', undefined, {
allowRetries: true,
maxRetries: 3
})

const res = await client.getJson<{tag_name: string}>(
`https://api.github.com/repos/weavejester/cljfmt/releases/latest`,
githubAuth ? {Authorization: githubAuth} : undefined
)

const result = res.result?.tag_name
if (result) {
return result
}

throw new Error(`Can't obtain latest cljfmt version`)
}

export function getArtifactName(version: string): string {
const platform = os.platform()
switch (platform) {
case 'win32':
return `cljfmt-${version}-win-amd64.zip`
case 'darwin':
return `cljfmt-${version}-darwin-amd64.tar.gz`
default:
return `cljfmt-${version}-linux-amd64.tar.gz`
}
}

export function getArtifactUrl(version: string): string {
const archiveName = getArtifactName(version)
return `https://github.com/weavejester/cljfmt/releases/download/${version}/${archiveName}`
}

export async function extract(source: string): Promise<string> {
return source.endsWith('.zip')
? await tc.extractZip(source)
: await tc.extractTar(source)
}

export async function setup(
version: string,
githubAuth?: string
): Promise<void> {
const ver = version === 'latest' ? await getLatestCljFmt(githubAuth) : version

let toolDir = tc.find(identifier, ver)
if (!toolDir) {
const archiveUrl = getArtifactUrl(ver)
core.info(`Downloading: ${archiveUrl}`)

const artifactFile = await tc.downloadTool(
archiveUrl,
undefined,
githubAuth
)

const extractedDir = await extract(artifactFile)
toolDir = await tc.cacheDir(extractedDir, identifier, ver)
core.info(`Caching directory: ${toolDir}`)
} else {
core.info(`Using cached directory: ${toolDir}`)
}

core.addPath(toolDir)
}
Loading

0 comments on commit 3610d4a

Please sign in to comment.