mirror of
https://github.com/balena-io/balena-cli.git
synced 2024-12-20 06:07:55 +00:00
Documentation update with debugging notes
Signed-off-by: Paul Jonathan <pj@balena.io>
This commit is contained in:
parent
972c2470c5
commit
9937b91606
@ -259,3 +259,12 @@ gotchas to bear in mind:
|
|||||||
`node_modules/balena-sdk/node_modules/balena-errors`
|
`node_modules/balena-sdk/node_modules/balena-errors`
|
||||||
In the case of subclasses of `TypedError`, a string comparison may be used instead:
|
In the case of subclasses of `TypedError`, a string comparison may be used instead:
|
||||||
`error.name === 'BalenaApplicationNotFound'`
|
`error.name === 'BalenaApplicationNotFound'`
|
||||||
|
|
||||||
|
## Further debugging notes
|
||||||
|
|
||||||
|
* If you need to selectively run specific tests, `it.only` will not work in cases when authorization is required as part of the test cycle. In order to target specific tests, control execution via `.mocharc.js` instead. Here is an example of targeting the `deploy` tests.
|
||||||
|
|
||||||
|
replace: `spec: 'tests/**/*.spec.ts',`
|
||||||
|
|
||||||
|
with: `spec: ['tests/auth/*.spec.ts', 'tests/**/deploy.spec.ts'],`
|
||||||
|
|
||||||
|
@ -45,6 +45,8 @@ import Logger = require('./logger');
|
|||||||
import { exists } from './which';
|
import { exists } from './which';
|
||||||
import jsyaml = require('js-yaml');
|
import jsyaml = require('js-yaml');
|
||||||
|
|
||||||
|
const allowedContractTypes = ['sw.application', 'sw.block'];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given an array representing the raw `--release-tag` flag of the deploy and
|
* Given an array representing the raw `--release-tag` flag of the deploy and
|
||||||
* push commands, parse it into separate arrays of release tag keys and values.
|
* push commands, parse it into separate arrays of release tag keys and values.
|
||||||
@ -1312,11 +1314,17 @@ export async function deployProject(
|
|||||||
const prefix = getChalk().cyan('[Info]') + ' ';
|
const prefix = getChalk().cyan('[Info]') + ' ';
|
||||||
const spinner = createSpinner();
|
const spinner = createSpinner();
|
||||||
|
|
||||||
const contract = await getContractContent(`${projectPath}/balena.yml`);
|
const contract = await getContractContent(
|
||||||
|
path.join(projectPath, 'balena.yml'),
|
||||||
|
);
|
||||||
if (contract?.version && !PLAIN_SEMVER_REGEX.test(contract?.version)) {
|
if (contract?.version && !PLAIN_SEMVER_REGEX.test(contract?.version)) {
|
||||||
throw new ExpectedError(
|
throw new ExpectedError(
|
||||||
stripIndent`Error: expected the version field in ${projectPath}/balena.yml to be a valid semver (e.g.: 1.0.0). Got '${contract.version}' instead`,
|
stripIndent`Error: expected the version field in ${path.join(
|
||||||
|
projectPath,
|
||||||
|
'balena.yml',
|
||||||
|
)} to be a basic semver in the format '1.2.3'. Got '${
|
||||||
|
contract.version
|
||||||
|
}' instead`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1423,26 +1431,29 @@ export function createRunLoop(tick: (...args: any[]) => void) {
|
|||||||
return runloop;
|
return runloop;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getContractContent(filePath: string): Promise<any | undefined> {
|
async function getContractContent(
|
||||||
|
filePath: string,
|
||||||
|
): Promise<Dictionary<any> | undefined> {
|
||||||
let fileContentAsString;
|
let fileContentAsString;
|
||||||
try {
|
try {
|
||||||
fileContentAsString = await fs.readFile(filePath, 'utf8');
|
fileContentAsString = await fs.readFile(filePath, 'utf8');
|
||||||
} catch {
|
} catch (e) {
|
||||||
// File does not exist. Return undefined
|
if (e.code === 'ENOENT') {
|
||||||
return;
|
return; // File does not exist
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
let asJson;
|
let asJson;
|
||||||
try {
|
try {
|
||||||
asJson = jsyaml.load(fileContentAsString) as any;
|
asJson = jsyaml.load(fileContentAsString);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
throw new ExpectedError(
|
throw new ExpectedError(
|
||||||
`Error parsing file "${filePath}":\n ${err.message}`,
|
`Error parsing file "${filePath}":\n ${err.message}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const allowedContractTypes = ['sw.application', 'sw.block'];
|
if (!isContract(asJson)) {
|
||||||
if (!asJson?.type || !allowedContractTypes.includes(asJson.type)) {
|
|
||||||
throw new ExpectedError(
|
throw new ExpectedError(
|
||||||
stripIndent`Error: application contract in '${filePath}' needs to
|
stripIndent`Error: application contract in '${filePath}' needs to
|
||||||
define a top level "type" field with an allowed application type.
|
define a top level "type" field with an allowed application type.
|
||||||
@ -1452,6 +1463,10 @@ async function getContractContent(filePath: string): Promise<any | undefined> {
|
|||||||
return asJson;
|
return asJson;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isContract(obj: any): obj is Dictionary<any> {
|
||||||
|
return obj?.type && allowedContractTypes.includes(obj.type);
|
||||||
|
}
|
||||||
|
|
||||||
function createLogStream(input: Readable) {
|
function createLogStream(input: Readable) {
|
||||||
const split = require('split') as typeof import('split');
|
const split = require('split') as typeof import('split');
|
||||||
const stripAnsi = require('strip-ansi-stream');
|
const stripAnsi = require('strip-ansi-stream');
|
||||||
|
Loading…
Reference in New Issue
Block a user