Skip to content
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
3 changes: 3 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ jobs:
- name: Build cosmoscopes
run: sh ./e2e/exec-modelize.sh

- name: Lint
run: npm run lint

- name: Run unit tests
run: npm run test:unit -- --verbose

Expand Down
7 changes: 4 additions & 3 deletions controllers/autorecord.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,14 @@ function autorecord(title = '', type = 'undefined', tags = '', saveIdOnYmlFrontM
return;
}

let shouldSaveId;
if (config.opts['generate_id'] === 'never') {
saveIdOnYmlFrontMatter = false;
shouldSaveId = false;
} else {
saveIdOnYmlFrontMatter = config.opts['generate_id'] === 'always' || !!saveIdOnYmlFrontMatter;
shouldSaveId = config.opts['generate_id'] === 'always' || Boolean(saveIdOnYmlFrontMatter);
}

createRecord(title, type, tags, config, saveIdOnYmlFrontMatter);
createRecord(title, type, tags, config, shouldSaveId);
}

export default autorecord;
58 changes: 30 additions & 28 deletions controllers/batch.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,16 @@ async function batch(filePath, saveIdOnYmlFrontMatter) {
const config = Config.get(Config.configFilePath);
console.log(config.getConfigConsolMessage());

let shouldSaveId;
if (config.opts['generate_id'] === 'never') {
saveIdOnYmlFrontMatter = false;
shouldSaveId = false;
} else {
saveIdOnYmlFrontMatter = config.opts['generate_id'] === 'always' || !!saveIdOnYmlFrontMatter;
shouldSaveId = config.opts['generate_id'] === 'always' || Boolean(saveIdOnYmlFrontMatter);
}

if (fs.existsSync(filePath) === false) {
return console.error(['\x1b[31m', 'Err.', '\x1b[0m'].join(''), 'Data file does not exist.');
console.error(['\x1b[31m', 'Err.', '\x1b[0m'].join(''), 'Data file does not exist.');
return;
}

const files = await findMarkdownFilesRecursively(config.opts['files_origin']);
Expand All @@ -35,8 +37,8 @@ async function batch(filePath, saveIdOnYmlFrontMatter) {
const timestamps = [todayMaxTimestamp];

await Promise.all(
files.map(async (filePath) => {
const content = await fsPromises.readFile(filePath, 'utf8');
files.map(async (mdFile) => {
const content = await fsPromises.readFile(mdFile, 'utf8');
const record = Record.recordFromFile(content, config);
if (isTimestampIncrement(record.id)) {
timestamps.push(record.id);
Expand All @@ -51,62 +53,62 @@ async function batch(filePath, saveIdOnYmlFrontMatter) {
/** @type {Record[]} */
let records = [];

fs.readFile(filePath, 'utf-8', async (err, data) => {
fs.readFile(filePath, 'utf-8', async (err, rawData) => {
if (err) {
return console.error(['\x1b[31m', 'Err.', '\x1b[0m'].join(''), 'Cannot read data file.');
console.error(['\x1b[31m', 'Err.', '\x1b[0m'].join(''), 'Cannot read data file.');
return;
}

let parsedData;

switch (path.extname(filePath)) {
case '.json':
try {
data = JSON.parse(data);
} catch (error) {
return console.error(
['\x1b[31m', 'Err.', '\x1b[0m'].join(''),
'JSON data file is invalid.',
);
parsedData = JSON.parse(rawData);
} catch (_error) {
console.error(['\x1b[31m', 'Err.', '\x1b[0m'].join(''), 'JSON data file is invalid.');
return;
}
break;

case '.csv':
try {
data = parse(data, {
parsedData = parse(rawData, {
columns: true,
skip_empty_lines: true,
cast: (value) => (value === '' ? undefined : value),
});
} catch (error) {
return console.error(
['\x1b[31m', 'Err.', '\x1b[0m'].join(''),
'CSV data file is invalid.',
);
} catch (_error) {
console.error(['\x1b[31m', 'Err.', '\x1b[0m'].join(''), 'CSV data file is invalid.');
return;
}
break;

default:
return console.error(
console.error(
['\x1b[31m', 'Err.', '\x1b[0m'].join(''),
'Data file format unrecognized. Supported file extensions: .json, .csv.',
);
return;
}

if (!Array.isArray(data)) {
if (!Array.isArray(parsedData)) {
throw new Error('Batch data should be array');
}

records = data.map((e, i) => {
e = formatAsRecord(e, config);
return Record.recordWithIncrementedTimestamp(e, config, increment + i);
records = parsedData.map((entry, i) => {
const formatted = formatAsRecord(entry, config);
return Record.recordWithIncrementedTimestamp(formatted, config, increment + i);
});

await Promise.all(
records.map(async (record) => {
const filePath = path.join(config.opts['files_origin'], record.getFileName());
if (fs.existsSync(filePath)) {
throw new Error(`File ${filePath} already exist`);
const recordPath = path.join(config.opts['files_origin'], record.getFileName());
if (fs.existsSync(recordPath)) {
throw new Error(`File ${recordPath} already exist`);
}

await fsPromises.writeFile(filePath, record.getFileContent(saveIdOnYmlFrontMatter));
await fsPromises.writeFile(recordPath, record.getFileContent(shouldSaveId));
}),
);

Expand Down
20 changes: 11 additions & 9 deletions controllers/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,32 +12,34 @@ import slugify from '../core/utils/slugify.js';
*/

function makeConfigFile(title, { global: isGlobal }) {
isGlobal = !!isGlobal;
const globalFlag = Boolean(isGlobal);

// Early validations
if (isGlobal && fs.existsSync(Config.configDirPath) === false) {
return console.log(
if (globalFlag && fs.existsSync(Config.configDirPath) === false) {
console.log(
['\x1b[31m', 'Err.', '\x1b[0m'].join(''),
'To create global configuration files, first create a user data directory by running',
['\x1b[1m', 'cosma --create-user-data-dir', '\x1b[0m'].join(''),
'.',
);
return;
}
if (process.cwd() === Config.configDirPath && isGlobal === false) {
return console.log(
if (process.cwd() === Config.configDirPath && globalFlag === false) {
console.log(
['\x1b[31m', 'Err.', '\x1b[0m'].join(''),
'Cannot create a local config file in the global config directory.',
'To create a global config file, use "cosma config --global".',
);
return;
}

const defaultConfigExists = Config.defaultConfigExists();
const hasTitle = !!title;
const hasTitle = Boolean(title);

let opts;
let configSource;

if (isGlobal && !hasTitle) {
if (globalFlag && !hasTitle) {
opts = Config.base;
configSource = 'base';
} else if (defaultConfigExists) {
Expand All @@ -52,10 +54,10 @@ function makeConfigFile(title, { global: isGlobal }) {
let configFilePath;
let configScope;

if (isGlobal && hasTitle) {
if (globalFlag && hasTitle) {
configFilePath = path.join(Config.configDirPath, slugify(title) + '.yml');
configScope = 'global';
} else if (isGlobal && !hasTitle) {
} else if (globalFlag && !hasTitle) {
configFilePath = Config.defaultConfigPath;
configScope = 'global default';
} else {
Expand Down
22 changes: 15 additions & 7 deletions controllers/config.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ const mockConfigGet = jest.fn(() => ({ opts, getYaml: mockGetYaml }));
const mockDefaultConfigExists = jest.fn(() => false);

jest.mock('../core/models/config.js', () => ({
get: (path) => mockConfigGet(path),
getFrom: (opts) => mockConfigGet(opts),
get: (_path) => mockConfigGet(_path),
getFrom: (_opts) => mockConfigGet(_opts),
defaultConfigExists: () => mockDefaultConfigExists(),
configDirPath: 'configDirPath',
executionConfigPath: 'executionConfigPath.yml',
Expand Down Expand Up @@ -51,7 +51,9 @@ describe('makeConfigFile', () => {

it('should not make config file if global and config directory does not exist', () => {
mockFileExists.mockImplementation((path) => {
if (path === 'configDirPath') return false;
if (path === 'configDirPath') {
return false;
}
return true;
});

Expand All @@ -71,7 +73,9 @@ describe('makeConfigFile', () => {
beforeEach(() => {
mockDefaultConfigExists.mockReturnValue(false);
mockFileExists.mockImplementation((path) => {
if (path === 'configDirPath') return true;
if (path === 'configDirPath') {
return true;
}
return false;
});
});
Expand Down Expand Up @@ -145,8 +149,12 @@ describe('makeConfigFile', () => {
beforeEach(() => {
mockDefaultConfigExists.mockReturnValue(true);
mockFileExists.mockImplementation((path) => {
if (path === 'configDirPath') return true;
if (path === 'defaultConfigPath.yml') return true;
if (path === 'configDirPath') {
return true;
}
if (path === 'defaultConfigPath.yml') {
return true;
}
return false;
});
});
Expand Down Expand Up @@ -207,7 +215,7 @@ describe('makeConfigFile', () => {
describe('when config file already exists', () => {
beforeEach(() => {
mockDefaultConfigExists.mockReturnValue(false);
mockFileExists.mockImplementation((path) => {
mockFileExists.mockImplementation((_path) => {
return true;
});
});
Expand Down
18 changes: 9 additions & 9 deletions controllers/create-record.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,20 @@ function createRecord(
throw new Error('Need instance of Config to create record');
}

typeString = typeString.trim();
tagsString = tagsString.trim();
const trimmedType = typeString.trim();
const trimmedTags = tagsString.trim();

let types = [];
let tags = [];

if (typeString !== '') {
types = typeString
if (trimmedType !== '') {
types = trimmedType
.split(',')
.map((s) => s.trim())
.filter((s) => s !== '');
}
if (tagsString !== '') {
tags = tagsString
if (trimmedTags !== '') {
tags = trimmedTags
.split(',')
.map((s) => s.trim())
.filter((s) => s !== '');
Expand Down Expand Up @@ -75,7 +75,7 @@ function createRecord(
const filePath = path.join(config.opts['files_origin'], fileName);

const save = () =>
fs.writeFile(filePath, record.getFileContent(saveIdOnYmlFrontMatter), (err) => {
fs.writeFile(filePath, record.getFileContent(saveIdOnYmlFrontMatter), (_err) => {
logRecordIsSaved();
});

Expand All @@ -97,10 +97,10 @@ function createRecord(
save();

function logRecordIsSaved() {
const { dir: fileDir, base: fileName } = path.parse(filePath);
const { dir: fileDir, base: recordFileName } = path.parse(filePath);
console.log(
['\x1b[32m', 'Record created', '\x1b[0m'].join(''),
`: ${['\x1b[2m', fileDir, '/', '\x1b[0m', fileName].join('')}`,
`: ${['\x1b[2m', fileDir, '/', '\x1b[0m', recordFileName].join('')}`,
);
}
}
Expand Down
4 changes: 3 additions & 1 deletion controllers/history.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,16 @@ async function getHistorySavePath(projectName, projectScope) {
}
const pathFile = path.join(pathDir, `${getTimestampTuple().join('')}.html`);

return new Promise(async (resolve, reject) => {
return new Promise((resolve, reject) => {
if (fs.existsSync(pathDir) === false) {
fs.mkdir(pathDir, { recursive: true }, (err) => {
if (err) {
reject(err.message);
return;
}
resolve(pathFile);
});
return;
}
resolve(pathFile);
});
Expand Down
Loading