提交 400e1474 编写于 作者: T Tomas Vik

refactor: utility function for finding mr diffs

Multiple paces will need to search through all the MR changes and find
the correct diff. This commit extracts a method to do that.
上级 b6dc0785
import * as assert from 'assert';
import { DiffFilePath, findFileInDiffs } from '../utils/find_file_in_diffs';
// these helper functions are simplified version of the same lodash functions
const range = (start: number, end: number) => [...Array(end - start).keys()].map(n => n + start);
......@@ -37,8 +38,6 @@ type AddedLine = { type: typeof ADDED; newLine: number };
type UnchangedLine = { type: typeof UNCHANGED; oldLine: number; newLine: number };
type HunkLine = RemovedLine | AddedLine | UnchangedLine;
type FilePath = { oldPath?: string; newPath?: string };
/** Converts lines in the text hunk into data structures that represent type of the change and affected lines */
const parseHunk = (hunk: string): HunkLine[] => {
const [headerLine, ...remainingLines] = hunk.split('\n');
......@@ -81,14 +80,8 @@ const parseHunk = (hunk: string): HunkLine[] => {
return result.lines;
};
const getHunksForFile = (mrVersion: RestMrVersion, path: FilePath): HunkLine[][] => {
// VS Code Uri returns absolute path (leading slash) but GitLab uses relative paths (no leading slash)
const removeLeadingSlash = (filePath = ''): string => filePath.replace(/^\//, '');
const diff = mrVersion.diffs.find(
d =>
d.new_path === removeLeadingSlash(path.newPath) ||
d.old_path === removeLeadingSlash(path.oldPath),
);
const getHunksForFile = (mrVersion: RestMrVersion, path: DiffFilePath): HunkLine[][] => {
const diff = findFileInDiffs(mrVersion.diffs, path);
if (!diff) return [];
return getRawHunks(diff.diff).map(parseHunk);
};
......
......@@ -34,6 +34,7 @@ import {
GetProjectQueryResult,
queryGetProject,
} from './graphql/get_project';
import { removeLeadingSlash } from '../utils/remove_leading_slash';
interface CreateNoteResult {
createNote: {
......@@ -205,8 +206,7 @@ export class GitLabNewService {
}
async getFileContent(path: string, ref: string, projectId: number): Promise<string> {
const pathWithoutFirstSlash = path.replace(/^\//, '');
const encodedPath = encodeURIComponent(pathWithoutFirstSlash);
const encodedPath = encodeURIComponent(removeLeadingSlash(path));
const fileUrl = `${this.instanceUrl}/api/v4/projects/${projectId}/repository/files/${encodedPath}/raw?ref=${ref}`;
const fileResult = await crossFetch(fileUrl, this.fetchOptions);
if (!fileResult.ok) {
......
import { diffFile } from '../test_utils/entities';
import { findFileInDiffs } from './find_file_in_diffs';
describe('findFileInDiffs', () => {
const diff: RestDiffFile = {
...diffFile,
old_path: 'test/oldName.js',
new_path: 'test/newName.js',
};
it.each`
oldPath | newPath
${'/test/oldName.js'} | ${undefined}
${'test/oldName.js'} | ${undefined}
${undefined} | ${'/test/newName.js'}
${undefined} | ${'/test/newName.js'}
`('finds a file with oldPath: $oldPath and newPath: $newPath', ({ oldPath, newPath }) => {
expect(findFileInDiffs([diff], { oldPath, newPath })).toEqual(diff);
});
it('returns undefined when it does not find a file', () => {
expect(findFileInDiffs([diff], { oldPath: '/nonexistent' })).toEqual(undefined);
});
});
import { removeLeadingSlash } from './remove_leading_slash';
export type DiffFilePath = { oldPath?: string; newPath?: string };
export const findFileInDiffs = (
diffs: RestDiffFile[],
path: DiffFilePath,
): RestDiffFile | undefined =>
diffs.find(
d =>
d.new_path === removeLeadingSlash(path.newPath) ||
d.old_path === removeLeadingSlash(path.oldPath),
);
/** VS Code Uri returns absolute path (leading slash) but GitLab uses relative paths (no leading slash) */
export const removeLeadingSlash = (filePath = ''): string => filePath.replace(/^\//, '');
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册