Add cljstyle support

This commit is contained in:
Ilshat Sultanov 2022-06-16 16:57:17 +05:00
parent b23a7d0825
commit 3a55fb8d46
No known key found for this signature in database
GPG Key ID: 33B1D8EF26616886
7 changed files with 298 additions and 0 deletions

View File

@ -179,6 +179,34 @@ jobs:
- name: Check clj-kondo version - name: Check clj-kondo version
run: clj-kondo --version run: clj-kondo --version
test-cljstyle:
strategy:
matrix:
operating-system: [ubuntu-latest, macOS-latest]
runs-on: ${{ matrix.operating-system }}
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Prepare java
uses: actions/setup-java@v2
with:
distribution: 'zulu'
java-version: '8'
- name: Install cljstyle
# uses: DeLaGuardo/setup-clojure@master
uses: ./
with:
cljstyle: latest
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Check cljstyle version
run: cljstyle version
all-together: all-together:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -202,6 +230,7 @@ jobs:
boot: latest boot: latest
bb: latest bb: latest
clj-kondo: latest clj-kondo: latest
cljstyle: latest
github-token: ${{ secrets.GITHUB_TOKEN }} github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Check Clojure CLI - name: Check Clojure CLI
@ -218,3 +247,6 @@ jobs:
- name: Check clj-kondo version - name: Check clj-kondo version
run: clj-kondo --version run: clj-kondo --version
- name: Check cljstyle version
run: cljstyle version

View File

@ -7,6 +7,7 @@ This action sets up Clojure tools environment for using in GitHub Actions.
* boot-clj * boot-clj
* Babashka * Babashka
* Clj-kondo * Clj-kondo
* cljstyle
All three major tools available for MacOS and ubuntu based runners, Leiningen and Clojure CLI also available on Windows All three major tools available for MacOS and ubuntu based runners, Leiningen and Clojure CLI also available on Windows
@ -50,6 +51,7 @@ jobs:
boot: 2.8.3 # Boot.clj boot: 2.8.3 # Boot.clj
bb: 0.7.8 # Babashka bb: 0.7.8 # Babashka
clj-kondo: 2022.05.31 # Clj-kondo clj-kondo: 2022.05.31 # Clj-kondo
cljstyle: 0.15.0 # cljstyle
# (optional) To avoid rate limit errors please provide github token # (optional) To avoid rate limit errors please provide github token
github-token: ${{ secrets.GITHUB_TOKEN }} github-token: ${{ secrets.GITHUB_TOKEN }}
@ -71,6 +73,17 @@ jobs:
# Boot is not yet available for windows # Boot is not yet available for windows
if: ${{ matrix.os != 'windows-latest' }} if: ${{ matrix.os != 'windows-latest' }}
run: boot -V run: boot -V
- name: Get babashka version
run: bb --version
- name: Get clj-kondo version
run: clj-kondo --version
- name: Get cljstyle version
# cljstyle is not yet available for windows
if: ${{ matrix.os != 'windows-latest' }}
run: cljstyle version
``` ```
For more application cases please check [Smoke Test Workflow file](https://github.com/DeLaGuardo/setup-clojure/blob/master/.github/workflows/smoke-tests.yml) For more application cases please check [Smoke Test Workflow file](https://github.com/DeLaGuardo/setup-clojure/blob/master/.github/workflows/smoke-tests.yml)

151
__tests__/cljstyle.test.ts Normal file
View File

@ -0,0 +1,151 @@
import _os from 'os'
import * as _core from '@actions/core'
import * as _tc from '@actions/tool-cache'
import * as cljstyle from '../src/cljstyle'
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('cljstyle tests', () => {
beforeEach(() => {
jest.resetAllMocks()
})
describe('getLatestCljstyle', () => {
it('uses tag_name as latest version', async () => {
getJson.mockResolvedValueOnce({
result: {tag_name: '1.2.3'}
})
const res = await cljstyle.getLatestCljstyle()
expect(res).toBe('1.2.3')
expect(getJson).toHaveBeenCalledWith(
'https://api.github.com/repos/greglook/cljstyle/releases/latest',
undefined
)
})
it('supports authorization', async () => {
getJson.mockResolvedValueOnce({
result: {tag_name: '1.2.3'}
})
const res = await cljstyle.getLatestCljstyle('token 123')
expect(res).toBe('1.2.3')
expect(getJson).toHaveBeenCalledWith(
'https://api.github.com/repos/greglook/cljstyle/releases/latest',
{Authorization: 'token 123'}
)
})
it('throws on http client error', async () => {
getJson.mockRejectedValueOnce(new Error('some error'))
await expect(cljstyle.getLatestCljstyle()).rejects.toThrow('some error')
})
it('throws on wrong client answer', async () => {
getJson.mockResolvedValueOnce({result: {foo: 'bar'}})
await expect(cljstyle.getLatestCljstyle()).rejects.toThrow(
`Can't obtain latest cljstyle version`
)
})
})
describe('getArtifactName', () => {
test.each`
platform | artifact
${'darwin'} | ${`cljstyle_1.2.3_macos.zip`}
${'linux'} | ${`cljstyle_1.2.3_linux.zip`}
${'foobar'} | ${`cljstyle_1.2.3_linux.zip`}
`('$platform -> $artifact', ({platform, artifact}) => {
os.platform.mockReturnValueOnce(platform as never)
expect(cljstyle.getArtifactName('1.2.3')).toBe(artifact)
})
})
describe('getArtifactUrl', () => {
test.each`
platform | artifact
${'darwin'} | ${`cljstyle_1.2.3_macos.zip`}
${'linux'} | ${`cljstyle_1.2.3_linux.zip`}
${'foobar'} | ${`cljstyle_1.2.3_linux.zip`}
`('$platform -> $artifact', ({platform, artifact}) => {
os.platform.mockReturnValueOnce(platform as never)
expect(cljstyle.getArtifactUrl('1.2.3')).toBe(
`https://github.com/greglook/cljstyle/releases/download/1.2.3/${artifact}`
)
})
})
describe('setup', () => {
it('uses cache', async () => {
tc.find.mockReturnValueOnce('/foo/bar')
await cljstyle.setup('1.2.3')
expect(tc.find).toHaveBeenCalledWith('cljstyle', '1.2.3')
expect(core.addPath).toHaveBeenCalledWith('/foo/bar')
})
it('uses cache', async () => {
tc.find.mockReturnValueOnce('/foo/bar')
await cljstyle.setup('1.2.3')
expect(tc.find).toHaveBeenCalledWith('cljstyle', '1.2.3')
expect(core.addPath).toHaveBeenCalledWith('/foo/bar')
})
it('fetches exact version', async () => {
tc.downloadTool.mockResolvedValueOnce('/foo/cljstyle.tar.gz')
tc.extractZip.mockResolvedValueOnce('/bar/baz')
tc.cacheDir.mockResolvedValueOnce('/qux')
await cljstyle.setup('1.2.3', 'token 123')
expect(tc.find).toHaveBeenCalledWith('cljstyle', '1.2.3')
expect(tc.downloadTool).toHaveBeenCalledWith(
'https://github.com/greglook/cljstyle/releases/download/1.2.3/cljstyle_1.2.3_linux.zip',
undefined,
'token 123'
)
expect(tc.cacheDir).toHaveBeenCalledWith('/bar/baz', 'cljstyle', '1.2.3')
expect(core.addPath).toHaveBeenCalledWith('/qux')
})
it('fetches latest version', async () => {
getJson.mockResolvedValueOnce({
result: {tag_name: 'v9.9.9'}
})
tc.downloadTool.mockResolvedValueOnce('/foo/cljstyle.tar.gz')
tc.extractZip.mockResolvedValueOnce('/bar/baz')
tc.cacheDir.mockResolvedValueOnce('/qux')
await cljstyle.setup('latest', 'token 123')
expect(getJson).toHaveBeenCalledWith(
'https://api.github.com/repos/greglook/cljstyle/releases/latest',
{Authorization: 'token 123'}
)
expect(tc.find).toHaveBeenCalledWith('cljstyle', '9.9.9')
expect(tc.downloadTool).toHaveBeenCalledWith(
'https://github.com/greglook/cljstyle/releases/download/9.9.9/cljstyle_9.9.9_linux.zip',
undefined,
'token 123'
)
expect(tc.cacheDir).toHaveBeenCalledWith('/bar/baz', 'cljstyle', '9.9.9')
expect(core.addPath).toHaveBeenCalledWith('/qux')
})
})
})

View File

@ -4,6 +4,7 @@ import * as _boot from '../src/boot'
import * as _cli from '../src/cli' import * as _cli from '../src/cli'
import * as _bb from '../src/babashka' import * as _bb from '../src/babashka'
import * as _cljKondo from '../src/clj-kondo' import * as _cljKondo from '../src/clj-kondo'
import * as _cljstyle from '../src/cljstyle'
import * as _utils from '../src/utils' import * as _utils from '../src/utils'
import {run} from '../src/entrypoint' import {run} from '../src/entrypoint'
@ -25,6 +26,9 @@ const bb: jest.Mocked<typeof _bb> = _bb as never
jest.mock('../src/clj-kondo') jest.mock('../src/clj-kondo')
const cljKondo: jest.Mocked<typeof _cljKondo> = _cljKondo as never const cljKondo: jest.Mocked<typeof _cljKondo> = _cljKondo as never
jest.mock('../src/cljstyle')
const cljstyle: jest.Mocked<typeof _cljstyle> = _cljstyle as never
jest.mock('../src/utils') jest.mock('../src/utils')
const utils: jest.Mocked<typeof _utils> = _utils as never const utils: jest.Mocked<typeof _utils> = _utils as never
@ -119,6 +123,27 @@ describe('setup-clojure', () => {
expect(cljKondo.setup).toHaveBeenCalledWith('1.2.3', 'token abc') expect(cljKondo.setup).toHaveBeenCalledWith('1.2.3', 'token abc')
}) })
it('sets up cljstyle', async () => {
inputs['cljstyle'] = '1.2.3'
inputs['github-token'] = 'abc'
await run()
expect(cljstyle.setup).toHaveBeenCalledWith('1.2.3', 'token abc')
})
it('throws on cljstyle setup in Windows', async () => {
inputs['cljstyle'] = '1.2.3'
inputs['github-token'] = 'abc'
utils.isWindows.mockReturnValue(true)
await run()
expect(core.setFailed).toHaveBeenCalledWith(
'cljstyle on windows is not supported yet.'
)
})
it('throws if none of Clojure tools is specified', async () => { it('throws if none of Clojure tools is specified', async () => {
await run() await run()
expect(core.setFailed).toHaveBeenCalledWith( expect(core.setFailed).toHaveBeenCalledWith(

View File

@ -18,6 +18,8 @@ inputs:
description: 'Babashka version to install, `latest` can be used.' description: 'Babashka version to install, `latest` can be used.'
clj-kondo: clj-kondo:
description: 'Clj-kondo version to install, `latest` can be used.' description: 'Clj-kondo version to install, `latest` can be used.'
cljstyle:
description: 'cljstyle version to install, `latest` can be used.'
github-token: github-token:
description: >+ description: >+
To fix rate limit errors, provide `secrets.GITHUB_TOKEN` value to this field. To fix rate limit errors, provide `secrets.GITHUB_TOKEN` value to this field.

66
src/cljstyle.ts Normal file
View File

@ -0,0 +1,66 @@
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 async function getLatestCljstyle(githubAuth?: string): Promise<string> {
const client = new http.HttpClient('actions/setup-clojure', undefined, {
allowRetries: true,
maxRetries: 3
})
const res = await client.getJson<{tag_name: string}>(
`https://api.github.com/repos/greglook/cljstyle/releases/latest`,
githubAuth ? {Authorization: githubAuth} : undefined
)
const result = res.result?.tag_name?.replace(/^v/, '')
if (result) {
return result
}
throw new Error(`Can't obtain latest cljstyle version`)
}
export function getArtifactName(version: string): string {
const platform = os.platform()
switch (platform) {
case 'darwin':
return `cljstyle_${version}_macos.zip`
default:
return `cljstyle_${version}_linux.zip`
}
}
export function getArtifactUrl(version: string): string {
const archiveName = getArtifactName(version)
return `https://github.com/greglook/cljstyle/releases/download/${version}/${archiveName}`
}
export async function setup(
version: string,
githubAuth?: string
): Promise<void> {
const ver =
version === 'latest' ? await getLatestCljstyle(githubAuth) : version
let toolDir = tc.find('cljstyle', ver)
if (!toolDir) {
const archiveUrl = getArtifactUrl(ver)
core.info(`Downloading: ${archiveUrl}`)
const artifactFile = await tc.downloadTool(
archiveUrl,
undefined,
githubAuth
)
const extractedDir = await tc.extractZip(artifactFile)
toolDir = await tc.cacheDir(extractedDir, 'cljstyle', ver)
core.info(`Caching directory: ${toolDir}`)
} else {
core.info(`Using cached directory: ${toolDir}`)
}
core.addPath(toolDir)
}

View File

@ -4,6 +4,7 @@ import * as boot from './boot'
import * as cli from './cli' import * as cli from './cli'
import * as bb from './babashka' import * as bb from './babashka'
import * as cljKondo from './clj-kondo' import * as cljKondo from './clj-kondo'
import * as cljstyle from './cljstyle'
import * as utils from './utils' import * as utils from './utils'
export async function run(): Promise<void> { export async function run(): Promise<void> {
@ -14,6 +15,7 @@ export async function run(): Promise<void> {
const CLI_VERSION = core.getInput('cli') const CLI_VERSION = core.getInput('cli')
const BB_VERSION = core.getInput('bb') const BB_VERSION = core.getInput('bb')
const CLJ_KONDO_VERSION = core.getInput('clj-kondo') const CLJ_KONDO_VERSION = core.getInput('clj-kondo')
const CLJSTYLE_VERSION = core.getInput('cljstyle')
const githubToken = core.getInput('github-token') const githubToken = core.getInput('github-token')
const githubAuth = githubToken ? `token ${githubToken}` : undefined const githubAuth = githubToken ? `token ${githubToken}` : undefined
@ -56,6 +58,13 @@ export async function run(): Promise<void> {
tools.push(cljKondo.setup(CLJ_KONDO_VERSION, githubAuth)) tools.push(cljKondo.setup(CLJ_KONDO_VERSION, githubAuth))
} }
if (CLJSTYLE_VERSION) {
if (IS_WINDOWS) {
throw new Error('cljstyle on windows is not supported yet.')
}
tools.push(cljstyle.setup(CLJSTYLE_VERSION, githubAuth))
}
if (tools.length === 0) { if (tools.length === 0) {
throw new Error('You must specify at least one clojure tool.') throw new Error('You must specify at least one clojure tool.')
} }