Skip to content

Commit

Permalink
Use lw.external.stat to check compilation output folder existence
Browse files Browse the repository at this point in the history
  • Loading branch information
James-Yu committed Sep 7, 2024
1 parent ba9b214 commit ee660c8
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 20 deletions.
10 changes: 8 additions & 2 deletions src/compile/recipe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,19 @@ function createOutputSubFolders(rootFile: string) {
outDir = path.resolve(rootDir, outDir)
}
logger.log(`outDir: ${outDir} .`)
lw.cache.getIncludedTeX(rootFile).forEach(file => {
lw.cache.getIncludedTeX(rootFile).forEach(async file => {
const relativePath = path.dirname(file.replace(rootDir, '.'))
const fullOutDir = path.resolve(outDir, relativePath)
// To avoid issues when fullOutDir is the root dir
// Using fs.mkdir() on the root directory even with recursion will result in an error
try {
if (! (lw.external.existsSync(fullOutDir) && lw.external.statSync(fullOutDir)?.isDirectory())) {
const fileStat = await lw.file.exists(fullOutDir)
if (
!fileStat ||
![vscode.FileType.Directory, vscode.FileType.Directory | vscode.FileType.SymbolicLink].includes(
fileStat.type
)
) {
lw.external.mkdirSync(fullOutDir, { recursive: true })
}
} catch (e) {
Expand Down
13 changes: 6 additions & 7 deletions src/core/file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -490,23 +490,22 @@ async function read(filePath: string, raise: boolean = false): Promise<string |
* the input is a string, it is converted to a file URI using
* `vscode.Uri.file()`. The function then attempts to retrieve the status of the
* file or directory at the given URI using `stat()` of VS Code workspace file
* system API. If the status retrieval is successful, the function returns
* `true`, indicating that the file or directory exists. If an error occurs
* (e.g., the file or directory does not exist), the function catches the error
* and returns `false`.
* system API. If the status retrieval is successful, the function returns the
* file stat, which can also be used to indicate that the file or directory
* exists. If an error occurs (e.g., the file or directory does not exist), the
* function catches the error and returns `false`.
*
* @param {vscode.Uri | string} uri - The URI or file path to check for
* existence.
* @returns {Promise<boolean>} - A promise that resolves to `true` if the file
* or directory exists, and `false` otherwise.
*/
async function exists(uri: vscode.Uri | string): Promise<boolean> {
async function exists(uri: vscode.Uri | string): Promise<vscode.FileStat | false> {
if (typeof(uri) === 'string') {
uri = vscode.Uri.file(uri)
}
try {
await lw.external.stat(uri)
return true
return await lw.external.stat(uri)
} catch {
return false
}
Expand Down
2 changes: 0 additions & 2 deletions src/lw.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,7 @@ export const lw = {
spawn: wrapper(cs.spawn),
sync: wrapper(cs.sync),
stat: wrapper(vscode.workspace.fs.stat),
existsSync: wrapper(fs.existsSync),
mkdirSync: wrapper(fs.mkdirSync),
statSync: wrapper(fs.statSync),
chmodSync: wrapper(fs.chmodSync)
},
onConfigChange,
Expand Down
13 changes: 4 additions & 9 deletions test/units/06_compile_recipe.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import * as vscode from 'vscode'
import * as path from 'path'
import * as fs from 'fs'
import Sinon, * as sinon from 'sinon'
import { assert, get, log, mock, set, sleep } from './utils'
import { lw } from '../../src/lw'
Expand Down Expand Up @@ -209,15 +208,13 @@ describe(path.basename(__filename).split('.')[0] + ':', () => {
const rootFile = set.root(fixture, 'main.tex')
const relativeOutDir = 'output'
const expectedOutDir = path.resolve(path.dirname(rootFile), relativeOutDir)
const existsStub = sinon.stub(lw.external, 'existsSync').returns(false)
const statStub = sinon.stub(lw.external, 'statSync').returns(fs.statSync(get.path(fixture)))
const mkdirStub = sinon.stub(lw.external, 'mkdirSync').returns(undefined)
const stub = sinon.stub(lw.file, 'exists').resolves(false)
getOutDirStub.returns(relativeOutDir)

await build(rootFile, 'latex', async () => {})
existsStub.restore()
statStub.restore()
mkdirStub.restore()
stub.restore()

assert.pathStrictEqual(mkdirStub.getCalls()[0].args[0].toString(), expectedOutDir)
assert.deepStrictEqual(mkdirStub.getCalls()[0].args[1], { recursive: true })
Expand All @@ -226,18 +223,16 @@ describe(path.basename(__filename).split('.')[0] + ':', () => {
it('should not create the output directory if it already exists', async () => {
const rootFile = set.root(fixture, 'main.tex')
const relativeOutDir = 'output'
const existsStub = sinon.stub(lw.external, 'existsSync').returns(true)
const statStub = sinon.stub(lw.external, 'statSync').returns(fs.statSync(get.path(fixture)))
const stub = sinon.stub(lw.file, 'exists').resolves({ type: vscode.FileType.Directory, ctime: 0, mtime: 0, size: 0 })
const mkdirStub = sinon.stub(lw.external, 'mkdirSync').returns(undefined)
getOutDirStub.returns(relativeOutDir)

await build(rootFile, 'latex', async () => {})
mkdirStub.resetHistory()

await build(rootFile, 'latex', async () => {})
existsStub.restore()
statStub.restore()
mkdirStub.restore()
stub.restore()

assert.ok(!mkdirStub.called)
})
Expand Down

0 comments on commit ee660c8

Please sign in to comment.