Skip to content

Commit

Permalink
Merge pull request #1521 from konnov/igor/apalache-version
Browse files Browse the repository at this point in the history
Add the option `--apalache-version` to `quint verify`
  • Loading branch information
bugarela authored Oct 3, 2024
2 parents 15328f8 + 8d29fc5 commit 48ab15c
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 18 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## UNRELEASED

### Added

- `quint verify` has the option `--apalache-version` to pull a custom version (#1521)

### Changed
### Deprecated
### Removed
Expand Down
2 changes: 1 addition & 1 deletion quint/apalache-dist-tests.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ quint verify --verbosity=1 ../examples/language-features/booleans.qnt | \

<!-- !test out server not running -->
```
Downloading Apalache distribution... done.
Downloading Apalache distribution 0.46.1... done.
[ok] No violation found (duration).
[ok] No violation found (duration).
```
25 changes: 13 additions & 12 deletions quint/src/apalache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,16 +75,16 @@ export function serverEndpointToConnectionString(endpoint: ServerEndpoint): stri
return `${endpoint.hostname}:${endpoint.port}`
}

const APALACHE_VERSION_TAG = '0.46.1'
export const DEFAULT_APALACHE_VERSION_TAG = '0.46.1'
// TODO: used by GitHub api approach: https://github.com/informalsystems/quint/issues/1124
// const APALACHE_TGZ = 'apalache.tgz'

function quintConfigDir(): string {
return path.join(os.homedir(), '.quint')
}

function apalacheDistDir(): string {
return path.join(quintConfigDir(), `apalache-dist-${APALACHE_VERSION_TAG}`)
function apalacheDistDir(apalacheVersion: string): string {
return path.join(quintConfigDir(), `apalache-dist-${apalacheVersion}`)
}

// The structure used to report errors
Expand Down Expand Up @@ -335,12 +335,12 @@ async function tryConnect(serverEndpoint: ServerEndpoint, retry: boolean = false
.map(apalache)
}

function downloadAndUnpackApalache(): Promise<ApalacheResult<null>> {
const url = `https://github.com/apalache-mc/apalache/releases/download/v${APALACHE_VERSION_TAG}/apalache.tgz`
function downloadAndUnpackApalache(apalacheVersion: string): Promise<ApalacheResult<null>> {
const url = `https://github.com/apalache-mc/apalache/releases/download/v${apalacheVersion}/apalache.tgz`
return fetch(url)
.then(
// unpack response body
res => pipeline(res.body!, tar.extract({ cwd: apalacheDistDir(), strict: true })),
res => pipeline(res.body!, tar.extract({ cwd: apalacheDistDir(apalacheVersion), strict: true })),
error => err(`Error fetching ${url}: ${error}`)
)
.then(
Expand All @@ -356,17 +356,17 @@ function downloadAndUnpackApalache(): Promise<ApalacheResult<null>> {
* - a `right<string>` equal to the path the Apalache dist was unpacked to,
* - a `left<ApalacheError>` indicating an error.
*/
async function fetchApalache(verbosityLevel: number): Promise<ApalacheResult<string>> {
async function fetchApalache(apalacheVersion: string, verbosityLevel: number): Promise<ApalacheResult<string>> {
const filename = process.platform === 'win32' ? 'apalache-mc.bat' : 'apalache-mc'
const apalacheBinary = path.join(apalacheDistDir(), 'apalache', 'bin', filename)
const apalacheBinary = path.join(apalacheDistDir(apalacheVersion), 'apalache', 'bin', filename)
if (fs.existsSync(apalacheBinary)) {
// Use existing download
debugLog(verbosityLevel, `Using existing Apalache distribution in ${apalacheBinary}`)
return right(apalacheBinary)
} else {
fs.mkdirSync(apalacheDistDir(), { recursive: true })
process.stdout.write('Downloading Apalache distribution...')
const res = await downloadAndUnpackApalache()
fs.mkdirSync(apalacheDistDir(apalacheVersion), { recursive: true })
process.stdout.write(`Downloading Apalache distribution ${apalacheVersion}...`)
const res = await downloadAndUnpackApalache(apalacheVersion)
process.stdout.write(' done.\n')
return res.map(_ => apalacheBinary)
}
Expand Down Expand Up @@ -430,6 +430,7 @@ async function fetchApalache(verbosityLevel: number): Promise<ApalacheResult<str
*/
export async function connect(
serverEndpoint: ServerEndpoint,
apalacheVersion: string,
verbosityLevel: number
): Promise<ApalacheResult<Apalache>> {
// Try to connect to Shai, and try to ping it
Expand All @@ -441,7 +442,7 @@ export async function connect(

// Connection or pinging failed, download Apalache
debugLog(verbosityLevel, 'No running Apalache server found, launching...')
const exeResult = await fetchApalache(verbosityLevel)
const exeResult = await fetchApalache(apalacheVersion, verbosityLevel)
// Launch Apalache from download
return exeResult
.asyncChain(
Expand Down
12 changes: 11 additions & 1 deletion quint/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import {
import { verbosity } from './verbosity'

import { version } from './version'
import { parseServerEndpoint } from './apalache'
import { DEFAULT_APALACHE_VERSION_TAG, parseServerEndpoint } from './apalache'

const defaultOpts = (yargs: any) =>
yargs.option('out', {
Expand Down Expand Up @@ -123,6 +123,11 @@ const compileCmd = {
type: 'number',
default: verbosity.defaultLevel,
})
.option('apalache-version', {
desc: 'The version of Apalache to use, if no running server is found (using this option may result in incompatibility)',
type: 'string',
default: DEFAULT_APALACHE_VERSION_TAG,
})
.option('server-endpoint', {
desc: 'Apalache server endpoint hostname:port',
type: 'string',
Expand Down Expand Up @@ -322,6 +327,11 @@ const verifyCmd = {
type: 'number',
default: verbosity.defaultLevel,
})
.option('apalache-version', {
desc: 'The version of Apalache to use, if no running server is found (using this option may result in incompatibility)',
type: 'string',
default: DEFAULT_APALACHE_VERSION_TAG,
})
.option('server-endpoint', {
desc: 'Apalache server endpoint hostname:port',
type: 'string',
Expand Down
9 changes: 7 additions & 2 deletions quint/src/cliCommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -710,7 +710,12 @@ export async function outputCompilationTarget(compiled: CompiledStage): Promise<
process.stdout.write(parsedSpecJson)
return right(compiled)
case 'tlaplus': {
const toTlaResult = await compileToTlaplus(args.serverEndpoint, parsedSpecJson, verbosityLevel)
const toTlaResult = await compileToTlaplus(
args.serverEndpoint,
args.apalacheVersion,
parsedSpecJson,
verbosityLevel
)
return toTlaResult
.mapRight(tla => {
process.stdout.write(tla) // Write out, since all went right
Expand Down Expand Up @@ -791,7 +796,7 @@ export async function verifySpec(prev: CompiledStage): Promise<CLIProcedure<Trac

const startMs = Date.now()

return verify(args.serverEndpoint, config, verbosityLevel).then(res => {
return verify(args.serverEndpoint, args.apalacheVersion, config, verbosityLevel).then(res => {
const elapsedMs = Date.now() - startMs
return res
.map(_ => {
Expand Down
6 changes: 5 additions & 1 deletion quint/src/compileToTlaplus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,16 @@ import { ApalacheResult, ServerEndpoint, connect } from './apalache'
* @param serverEndpoint
* a server endpoint
*
* @param apalacheVersion
* the version of Apalache to use if there is no active server connection
*
* @param parseDataJson the flattened, analyzed, parse data, in as a json string
*
* @returns right(tlaString) if parsing succeeds, or left(err) explaining the failure
*/
export async function compileToTlaplus(
serverEndpoint: ServerEndpoint,
apalacheVersion: string,
parseDataJson: string,
verbosityLevel: number
): Promise<ApalacheResult<string>> {
Expand All @@ -39,6 +43,6 @@ export async function compileToTlaplus(
},
},
}
const connectionResult = await connect(serverEndpoint, verbosityLevel)
const connectionResult = await connect(serverEndpoint, apalacheVersion, verbosityLevel)
return connectionResult.asyncChain(conn => conn.tla(config))
}
3 changes: 2 additions & 1 deletion quint/src/quintVerifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,10 @@ import { ApalacheResult, ServerEndpoint, connect } from './apalache'
*/
export async function verify(
serverEndpoint: ServerEndpoint,
apalacheVersion: string,
config: any,
verbosityLevel: number
): Promise<ApalacheResult<void>> {
const connectionResult = await connect(serverEndpoint, verbosityLevel)
const connectionResult = await connect(serverEndpoint, apalacheVersion, verbosityLevel)
return connectionResult.asyncChain(conn => conn.check(config))
}

0 comments on commit 48ab15c

Please sign in to comment.