Skip to content
This repository was archived by the owner on Feb 26, 2025. It is now read-only.

Use backslashes in file paths for windows #1511

Merged
merged 1 commit into from
Feb 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/shared/organisms/DataPanel/DataPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ import {
} from '../../molecules/MyDataTable/MyDataTable';
import {
distributionMatchesTypes,
getPathSeparator,
getSizeOfResourcesToDownload,
pathForChildDistributions,
pathForTopLevelResources,
Expand Down Expand Up @@ -153,6 +154,7 @@ export async function downloadArchive({
const resourcesForDownload = resourcesPayload.filter(
item => item.localStorageType === 'resource'
);
const slash = getPathSeparator();

const resourcesNotFetched: Error[] = [];
const { results } = await PromisePool.withConcurrency(4)
Expand All @@ -174,7 +176,7 @@ export async function downloadArchive({
item,
existingPaths
);
const parentPath = `${path}/${filename}.${extension}`;
const parentPath = `${path}${slash}${filename}.${extension}`;
// For resources with distribution(s), we want to download both, the metadata as well as all its distribution(s).
// To do that, first prepare the metadata for download.
topLevelResources.push({
Expand Down Expand Up @@ -207,7 +209,7 @@ export async function downloadArchive({
...item,
// @ts-ignore
'@type': childResource['@type'] ?? 'File',
path: `${childPath.path}/${childPath.fileName}`,
path: `${childPath.path}${slash}${childPath.fileName}`,
_self: childResource._self ?? item._self,
resourceId: childResource['@id'],
});
Expand Down
28 changes: 28 additions & 0 deletions src/shared/utils/__tests__/datapanel.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,19 @@ import {
pathForTopLevelResources,
toLocalStorageResources,
} from '../datapanel';
import * as deviceMock from 'react-device-detect';

jest.mock('react-device-detect', () => ({
__esModule: true,
isWindows: false,
}));

describe('datapanel utilities', () => {
const orgName = 'orgA';
const projectName = 'projectA';

const getDeviceMock = () => (deviceMock as unknown) as { isWindows: boolean };

it('serializes resources with no distribution correctly to local storage object', () => {
const actualLSResources = toLocalStorageResources(
resourceWithoutDistrition,
Expand Down Expand Up @@ -404,4 +412,24 @@ describe('datapanel utilities', () => {

expect(actualPathProps).toEqual(expectPathProps);
});

it('uses backslashes as separator when user has windows device', () => {
getDeviceMock().isWindows = true;

const parentPath = `\\${orgName}\\${projectName}\\parentPath`;
const filename = 'awesome-file.asc';
const mockResource = getMockDistribution(filename);
const actualPathProps = pathForChildDistributions(
mockResource,
parentPath,
new Map()
);

const expectPathProps = {
path: `${parentPath}\\awesome-file`,
fileName: filename,
};

expect(actualPathProps).toEqual(expectPathProps);
});
});
12 changes: 10 additions & 2 deletions src/shared/utils/datapanel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import isValidUrl from '../../utils/validUrl';
import { ResourceObscured } from 'shared/organisms/DataPanel/DataPanel';
import { getResourceLabel, uuidv4 } from '.';
import { parseURL } from './nexusParse';
import { isWindows } from 'react-device-detect';

const baseLocalStorageObject = (
resource: Resource,
Expand Down Expand Up @@ -266,13 +267,20 @@ export function pathForTopLevelResources(
};
}

export const getPathSeparator = () => {
if (isWindows) {
return '\\';
}
return '/';
};

export function pathForChildDistributions(
distItem: any,
parentPath: string,
existingPaths: Map<string, number>
) {
const defaultUniqueName = uuidv4().substring(0, 10); // TODO use last part of child self or id

const slash = getPathSeparator();
const fullFileName = fileNameForDistributionItem(distItem, defaultUniqueName);
const fileNameWithoutExtension = fullFileName.slice(
0,
Expand All @@ -281,7 +289,7 @@ export function pathForChildDistributions(
const extension = fullFileName.slice(fullFileName.lastIndexOf('.') + 1);

const childDir = fileNameWithoutExtension; // Max Length 20
const pathToChildFile = `${parentPath}/${childDir}`; // Max Length 60 + 1 + 20 = 80
const pathToChildFile = `${parentPath}${slash}${childDir}`; // Max Length 60 + 1 + 20 = 80
let uniquePath: string; // TODO de-deuplicate
if (existingPaths.has(pathToChildFile)) {
const count = existingPaths.get(pathToChildFile)!;
Expand Down
Loading