Skip to content
This repository has been archived by the owner on Jan 24, 2022. It is now read-only.

Store relative paths in project file #1384

Merged
merged 3 commits into from
Jan 20, 2020
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: 1 addition & 5 deletions packages/cli/src/models/dependency/Dependency.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,7 @@ export default class Dependency {

public get projectFile(): ProjectFile | never {
if (!this._projectFile) {
const filePath = ProjectFile.getExistingFilePath(this.getDependencyFolder());
if (!filePath) {
throw new Error(`Could not find an .openzeppelin/project.json or zos.json file for '${this.name}'`);
}
this._projectFile = new ProjectFile(filePath);
this._projectFile = ProjectFile.getExistingProject(this.getDependencyFolder());
}
return this._projectFile;
}
Expand Down
46 changes: 31 additions & 15 deletions packages/cli/src/models/files/ProjectFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { Loggy } from '@openzeppelin/upgrades';
import Dependency from '../dependency/Dependency';
import { MANIFEST_VERSION, checkVersion } from './ManifestVersion';
import { OPEN_ZEPPELIN_FOLDER } from './constants';
import NetworkFile from './NetworkFile';
import { ProjectCompilerOptions } from '../compiler/ProjectCompilerOptions';

interface ConfigFileCompilerOptions {
Expand Down Expand Up @@ -42,12 +41,29 @@ interface ProjectFileData {
telemetryOptIn?: boolean;
}

function getProjectPath(file: string, dir: string): [string, string] {
if (!dir) dir = file ? getRootFromFilePath(file) : process.cwd();
if (!file) file = getFileFromRoot(dir);
return [file, dir];
}

function getRootFromFilePath(file: string): string {
const dir = path.dirname(file);
return path.basename(dir) === OPEN_ZEPPELIN_FOLDER ? path.dirname(dir) : dir;
}

function getFileFromRoot(dir: string): string {
// TODO-v3: remove legacy project file support, preferring the new format over the old one
return [PROJECT_FILE_PATH, LEGACY_PROJECT_FILE_NAME].map(p => path.join(dir, p)).find(fs.existsSync);
}

export const PROJECT_FILE_NAME = 'project.json';
export const PROJECT_FILE_PATH = path.join(OPEN_ZEPPELIN_FOLDER, PROJECT_FILE_NAME);
export const LEGACY_PROJECT_FILE_NAME = 'zos.json';

export default class ProjectFile {
public filePath: string;
public root: string;
public data: ProjectFileData;

public static getLinkedDependencies(filePath: string = null): string[] {
Expand All @@ -56,11 +72,21 @@ export default class ProjectFile {
return project.linkedDependencies;
}

public constructor(filePath: string = null) {
public static getExistingProject(folder: string): ProjectFile {
const projectFile = new ProjectFile(null, folder);
if (!projectFile.exists()) {
throw new Error(`Could not find an .openzeppelin/project.json or zos.json file in ${folder}`);
}
return projectFile;
}

public constructor(filePath: string = null, root: string = null) {
const defaultData = {
manifestVersion: MANIFEST_VERSION,
} as any;
this.filePath = filePath ?? ProjectFile.getExistingFilePath(process.cwd());

[this.filePath, this.root] = getProjectPath(filePath, root);

if (this.filePath) {
try {
this.data = fs.existsSync(this.filePath) ? fs.readJsonSync(this.filePath) : null;
Expand All @@ -83,10 +109,6 @@ export default class ProjectFile {
return fs.existsSync(this.filePath);
}

public get root(): string {
return path.dirname(this.filePath);
}

public set manifestVersion(version: string) {
if (this.data.manifestVersion) {
this.data.manifestVersion = version;
Expand Down Expand Up @@ -199,8 +221,8 @@ export default class ProjectFile {
const configOptions: ConfigFileCompilerOptions = {
manager,
solcVersion: version,
artifactsDir: outputDir,
contractsDir: inputDir,
artifactsDir: outputDir ? path.relative(this.root, outputDir) : undefined,
contractsDir: inputDir ? path.relative(this.root, inputDir) : undefined,
compilerSettings: {
evmVersion,
optimizer: {
Expand Down Expand Up @@ -270,12 +292,6 @@ export default class ProjectFile {
}
}

public static getExistingFilePath(dir: string = process.cwd(), ...paths: string[]): string {
// TODO-v3: remove legacy project file support
// Prefer the new format over the old one
return [...paths, `${dir}/${PROJECT_FILE_PATH}`, `${dir}/${LEGACY_PROJECT_FILE_NAME}`].find(fs.existsSync);
}

private hasChanged(): boolean {
const currentPackgeFile = fs.existsSync(this.filePath) ? fs.readJsonSync(this.filePath) : null;
return !isEqual(this.data, currentPackgeFile);
Expand Down
17 changes: 16 additions & 1 deletion packages/cli/test/models/ProjectFile.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
require('../setup');

import { expect } from 'chai';

import path from 'path';
import ProjectFile from '../../src/models/files/ProjectFile';
import { MANIFEST_VERSION } from '../../src/models/files/ManifestVersion';

Expand Down Expand Up @@ -38,6 +38,21 @@ describe('ProjectFile', function() {
});
});

describe('instance methods', function() {
describe('#setCompilerOptions', function() {
it('ensures relative paths to project file', function() {
const file = new ProjectFile('test/mocks/packages/new.zos.json');
file.setCompilerOptions({
inputDir: path.resolve('test/mocks/myContracts'), // path.resolve ensures absolute paths
outputDir: path.resolve('test/mocks/myBuild/contracts'),
});

file.compilerOptions.inputDir.should.eq('../myContracts');
file.compilerOptions.outputDir.should.eq('../myBuild/contracts');
});
});
});

it('supports deprecated manifest version', function() {
const file = new ProjectFile('test/mocks/packages/package-deprecated-manifest-version.zos.json');
file.data.zosversion.should.eq('2.2');
Expand Down