mirror of
https://github.com/renovatebot/renovate.git
synced 2025-01-13 15:36:25 +00:00
refactor(fs): Move chmod
to chmodLocalFile
(#16306)
* refactor(fs): Move `chmod` to `chmodLocalFile` * More refactoring and tests * Fix tests * Apply suggestions from code review Co-authored-by: Michael Kriese <michael.kriese@visualon.de> * Fix prettier Co-authored-by: Michael Kriese <michael.kriese@visualon.de>
This commit is contained in:
parent
0687799b28
commit
851d8f4f7a
6 changed files with 82 additions and 30 deletions
|
@ -1,4 +1,5 @@
|
||||||
import { readFile, stat } from 'fs-extra';
|
import type { Stats } from 'fs';
|
||||||
|
import { readFile } from 'fs-extra';
|
||||||
import { resolve } from 'upath';
|
import { resolve } from 'upath';
|
||||||
import { envMock, exec, mockExecAll } from '../../../../test/exec-util';
|
import { envMock, exec, mockExecAll } from '../../../../test/exec-util';
|
||||||
import * as httpMock from '../../../../test/http-mock';
|
import * as httpMock from '../../../../test/http-mock';
|
||||||
|
@ -54,7 +55,12 @@ describe('modules/manager/gradle-wrapper/artifacts', () => {
|
||||||
resetPrefetchedImages();
|
resetPrefetchedImages();
|
||||||
|
|
||||||
fs.readLocalFile.mockResolvedValue('test');
|
fs.readLocalFile.mockResolvedValue('test');
|
||||||
fs.stat.mockImplementation((p) => stat(p));
|
fs.statLocalFile.mockResolvedValue(
|
||||||
|
partial<Stats>({
|
||||||
|
isFile: () => true,
|
||||||
|
mode: 0o555,
|
||||||
|
})
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
|
@ -98,6 +104,12 @@ describe('modules/manager/gradle-wrapper/artifacts', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('gradlew not found', async () => {
|
it('gradlew not found', async () => {
|
||||||
|
fs.statLocalFile.mockResolvedValue(
|
||||||
|
partial<Stats>({
|
||||||
|
isFile: () => false,
|
||||||
|
mode: 0o555,
|
||||||
|
})
|
||||||
|
);
|
||||||
GlobalConfig.set({ ...adminConfig, localDir: 'some-dir' });
|
GlobalConfig.set({ ...adminConfig, localDir: 'some-dir' });
|
||||||
const res = await gradleWrapper.updateArtifacts({
|
const res = await gradleWrapper.updateArtifacts({
|
||||||
packageFileName: 'gradle-wrapper.properties',
|
packageFileName: 'gradle-wrapper.properties',
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
import is from '@sindresorhus/is';
|
import is from '@sindresorhus/is';
|
||||||
import { quote } from 'shlex';
|
import { quote } from 'shlex';
|
||||||
import upath from 'upath';
|
|
||||||
import { GlobalConfig } from '../../../config/global';
|
|
||||||
import { TEMPORARY_ERROR } from '../../../constants/error-messages';
|
import { TEMPORARY_ERROR } from '../../../constants/error-messages';
|
||||||
import { logger } from '../../../logger';
|
import { logger } from '../../../logger';
|
||||||
import { exec } from '../../../util/exec';
|
import { exec } from '../../../util/exec';
|
||||||
import type { ExecOptions } from '../../../util/exec/types';
|
import type { ExecOptions } from '../../../util/exec/types';
|
||||||
import { readLocalFile, stat, writeLocalFile } from '../../../util/fs';
|
import { readLocalFile, writeLocalFile } from '../../../util/fs';
|
||||||
import { getRepoStatus } from '../../../util/git';
|
import { getRepoStatus } from '../../../util/git';
|
||||||
import type { StatusResult } from '../../../util/git/types';
|
import type { StatusResult } from '../../../util/git/types';
|
||||||
import { Http } from '../../../util/http';
|
import { Http } from '../../../util/http';
|
||||||
|
@ -62,16 +60,9 @@ export async function updateArtifacts({
|
||||||
config,
|
config,
|
||||||
}: UpdateArtifact): Promise<UpdateArtifactsResult[] | null> {
|
}: UpdateArtifact): Promise<UpdateArtifactsResult[] | null> {
|
||||||
try {
|
try {
|
||||||
const projectDir = GlobalConfig.get('localDir');
|
|
||||||
logger.debug({ updatedDeps }, 'gradle-wrapper.updateArtifacts()');
|
logger.debug({ updatedDeps }, 'gradle-wrapper.updateArtifacts()');
|
||||||
const gradlew = gradleWrapperFileName();
|
const gradlewFile = gradleWrapperFileName();
|
||||||
const gradlewPath = upath.resolve(projectDir, `./${gradlew}`);
|
let cmd = await prepareGradleCommand(gradlewFile, `wrapper`);
|
||||||
let cmd = await prepareGradleCommand(
|
|
||||||
gradlew,
|
|
||||||
projectDir!,
|
|
||||||
await stat(gradlewPath).catch(() => null),
|
|
||||||
`wrapper`
|
|
||||||
);
|
|
||||||
if (!cmd) {
|
if (!cmd) {
|
||||||
logger.info('No gradlew found - skipping Artifacts update');
|
logger.info('No gradlew found - skipping Artifacts update');
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
import type { Stats } from 'fs';
|
|
||||||
import os from 'os';
|
import os from 'os';
|
||||||
import upath from 'upath';
|
|
||||||
import { GlobalConfig } from '../../../config/global';
|
import { GlobalConfig } from '../../../config/global';
|
||||||
import { logger } from '../../../logger';
|
import { logger } from '../../../logger';
|
||||||
import { chmod } from '../../../util/fs';
|
import { chmodLocalFile, statLocalFile } from '../../../util/fs';
|
||||||
import { newlineRegex, regEx } from '../../../util/regex';
|
import { newlineRegex, regEx } from '../../../util/regex';
|
||||||
import gradleVersioning from '../../versioning/gradle';
|
import gradleVersioning from '../../versioning/gradle';
|
||||||
import { id as npmVersioning } from '../../versioning/npm';
|
import { id as npmVersioning } from '../../versioning/npm';
|
||||||
|
@ -27,16 +25,16 @@ export function gradleWrapperFileName(): string {
|
||||||
|
|
||||||
export async function prepareGradleCommand(
|
export async function prepareGradleCommand(
|
||||||
gradlewName: string,
|
gradlewName: string,
|
||||||
cwd: string,
|
|
||||||
gradlew: Stats | null,
|
|
||||||
args: string | null
|
args: string | null
|
||||||
): Promise<string | null> {
|
): Promise<string | null> {
|
||||||
|
const gradlewFile = gradleWrapperFileName();
|
||||||
|
const gradlewStat = await statLocalFile(gradlewFile);
|
||||||
// istanbul ignore if
|
// istanbul ignore if
|
||||||
if (gradlew?.isFile() === true) {
|
if (gradlewStat?.isFile() === true) {
|
||||||
// if the file is not executable by others
|
// if the file is not executable by others
|
||||||
if ((gradlew.mode & 0o1) === 0) {
|
if ((gradlewStat.mode & 0o1) === 0) {
|
||||||
// add the execution permission to the owner, group and others
|
// add the execution permission to the owner, group and others
|
||||||
await chmod(upath.join(cwd, gradlewName), gradlew.mode | 0o111);
|
await chmodLocalFile(gradlewName, gradlewStat.mode | 0o111);
|
||||||
}
|
}
|
||||||
if (args === null) {
|
if (args === null) {
|
||||||
return gradlewName;
|
return gradlewName;
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { envMock } from '../../../test/exec-util';
|
||||||
import { env, mockedFunction } from '../../../test/util';
|
import { env, mockedFunction } from '../../../test/util';
|
||||||
import { GlobalConfig } from '../../config/global';
|
import { GlobalConfig } from '../../config/global';
|
||||||
import {
|
import {
|
||||||
|
chmodLocalFile,
|
||||||
ensureCacheDir,
|
ensureCacheDir,
|
||||||
ensureLocalDir,
|
ensureLocalDir,
|
||||||
findLocalSiblingOrParent,
|
findLocalSiblingOrParent,
|
||||||
|
@ -15,6 +16,7 @@ import {
|
||||||
localPathIsFile,
|
localPathIsFile,
|
||||||
readLocalDirectory,
|
readLocalDirectory,
|
||||||
readLocalFile,
|
readLocalFile,
|
||||||
|
statLocalFile,
|
||||||
writeLocalFile,
|
writeLocalFile,
|
||||||
} from '.';
|
} from '.';
|
||||||
|
|
||||||
|
@ -240,4 +242,40 @@ describe('util/fs/index', () => {
|
||||||
expect(res).toBeNull();
|
expect(res).toBeNull();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('chmodLocalFile', () => {
|
||||||
|
it('works', async () => {
|
||||||
|
await withDir(
|
||||||
|
async (tmpDir) => {
|
||||||
|
GlobalConfig.set({ localDir: tmpDir.path });
|
||||||
|
await writeLocalFile('foo', 'bar');
|
||||||
|
await chmodLocalFile('foo', 0o000);
|
||||||
|
expect(await readLocalFile('foo')).toBeNull();
|
||||||
|
await chmodLocalFile('foo', 0o444);
|
||||||
|
expect((await readLocalFile('foo'))!.toString()).toBe('bar');
|
||||||
|
},
|
||||||
|
{ unsafeCleanup: true }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('statLocalFile', () => {
|
||||||
|
it('works', async () => {
|
||||||
|
await withDir(
|
||||||
|
async (tmpDir) => {
|
||||||
|
GlobalConfig.set({ localDir: tmpDir.path });
|
||||||
|
|
||||||
|
expect(await statLocalFile('foo')).toBeNull();
|
||||||
|
|
||||||
|
await writeLocalFile('foo', 'bar');
|
||||||
|
await chmodLocalFile('foo', 0o123);
|
||||||
|
|
||||||
|
const res = await statLocalFile('foo');
|
||||||
|
expect(res!.isFile()).toBeTrue();
|
||||||
|
expect(res!.mode & 0o777).toBe(0o123);
|
||||||
|
},
|
||||||
|
{ unsafeCleanup: true }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -195,3 +195,24 @@ export async function findUpLocal(
|
||||||
// Return null if found file is outside of localDir
|
// Return null if found file is outside of localDir
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function chmodLocalFile(
|
||||||
|
fileName: string,
|
||||||
|
mode: string | number
|
||||||
|
): Promise<void> {
|
||||||
|
const localDir = GlobalConfig.get('localDir');
|
||||||
|
const fullFileName = upath.join(localDir, fileName);
|
||||||
|
return fs.chmod(fullFileName, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function statLocalFile(
|
||||||
|
fileName: string
|
||||||
|
): Promise<fs.Stats | null> {
|
||||||
|
const localDir = GlobalConfig.get('localDir');
|
||||||
|
const fullFileName = upath.join(localDir, fileName);
|
||||||
|
try {
|
||||||
|
return await fs.stat(fullFileName);
|
||||||
|
} catch (_) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -6,14 +6,6 @@ export function stat(path: string | Buffer): Promise<fs.Stats> {
|
||||||
return fs.stat(path);
|
return fs.stat(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
// istanbul ignore next
|
|
||||||
export function chmod(
|
|
||||||
path: string | Buffer,
|
|
||||||
mode: string | number
|
|
||||||
): Promise<void> {
|
|
||||||
return fs.chmod(path, mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function readFile(fileName: string): Promise<Buffer>;
|
export async function readFile(fileName: string): Promise<Buffer>;
|
||||||
export async function readFile(
|
export async function readFile(
|
||||||
fileName: string,
|
fileName: string,
|
||||||
|
|
Loading…
Reference in a new issue