Merge pull request #1853 from balena-io/1770-devices-supported-et-al

v12 preparations: Add feature switches ('devices supported' and others)
This commit is contained in:
bulldozer-balena[bot] 2020-06-01 07:45:32 +00:00 committed by GitHub
commit 5c8d822aee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 66 additions and 33 deletions

View File

@ -21,6 +21,7 @@ import { stripIndent } from 'common-tags';
import Command from '../command'; import Command from '../command';
import * as cf from '../utils/common-flags'; import * as cf from '../utils/common-flags';
import { getBalenaSdk, getVisuals } from '../utils/lazy'; import { getBalenaSdk, getVisuals } from '../utils/lazy';
import { isV12 } from '../utils/version';
interface ExtendedApplication extends Application { interface ExtendedApplication extends Application {
device_count?: number; device_count?: number;
@ -49,7 +50,9 @@ export default class AppsCmd extends Command {
help: cf.help, help: cf.help,
verbose: flags.boolean({ verbose: flags.boolean({
char: 'v', char: 'v',
description: 'add extra columns in the tabular output (SLUG)', description: isV12()
? 'No-op since release v12.0.0'
: 'add extra columns in the tabular output (SLUG)',
}), }),
}; };
@ -83,7 +86,7 @@ export default class AppsCmd extends Command {
getVisuals().table.horizontal(applications, [ getVisuals().table.horizontal(applications, [
'id', 'id',
'app_name', 'app_name',
options.verbose ? 'slug' : '', options.verbose || isV12() ? 'slug' : '',
'device_type', 'device_type',
'online_devices', 'online_devices',
'device_count', 'device_count',

View File

@ -23,6 +23,7 @@ import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import { getBalenaSdk, getVisuals } from '../../utils/lazy'; import { getBalenaSdk, getVisuals } from '../../utils/lazy';
import { CommandHelp } from '../../utils/oclif-utils'; import { CommandHelp } from '../../utils/oclif-utils';
import { isV12 } from '../../utils/version';
interface FlagsDef { interface FlagsDef {
discontinued: boolean; discontinued: boolean;
@ -77,28 +78,30 @@ export default class DevicesSupportedCmd extends Command {
public async run() { public async run() {
const { flags: options } = this.parse<FlagsDef, {}>(DevicesSupportedCmd); const { flags: options } = this.parse<FlagsDef, {}>(DevicesSupportedCmd);
let deviceTypes: Array<Partial< let deviceTypes: Array<Partial<SDK.DeviceType>> = await getBalenaSdk()
SDK.DeviceType .models.config.getDeviceTypes()
>> = await getBalenaSdk().models.config.getDeviceTypes(); .map(d => {
if (!options.discontinued) {
deviceTypes = deviceTypes.filter(dt => dt.state !== 'DISCONTINUED');
}
const fields = ['slug', 'name'];
if (options.verbose) {
fields.splice(1, 0, 'aliases', 'arch', 'state');
deviceTypes = deviceTypes.map(d => {
if (d.aliases && d.aliases.length) { if (d.aliases && d.aliases.length) {
// remove aliases that are equal to the slug
d.aliases = d.aliases.filter((alias: string) => alias !== d.slug); d.aliases = d.aliases.filter((alias: string) => alias !== d.slug);
if (!options.json) { if (!options.json) {
// stringify the aliases array with commas and spaces // stringify the aliases array with commas and spaces
d.aliases = [d.aliases.join(', ')]; d.aliases = [d.aliases.join(', ')];
} }
} else { } else {
// ensure it is always an array (for the benefit of JSON output)
d.aliases = []; d.aliases = [];
} }
return d; return d;
}); });
if (!options.discontinued) {
deviceTypes = deviceTypes.filter(dt => dt.state !== 'DISCONTINUED');
} }
const fields = options.verbose
? ['slug', 'aliases', 'arch', 'state', 'name']
: isV12()
? ['slug', 'aliases', 'arch', 'name']
: ['slug', 'name'];
deviceTypes = _.sortBy( deviceTypes = _.sortBy(
deviceTypes.map(d => _.pick(d, fields) as Partial<SDK.DeviceType>), deviceTypes.map(d => _.pick(d, fields) as Partial<SDK.DeviceType>),
fields, fields,

View File

@ -562,10 +562,15 @@ export async function validateProjectDirectory(
checkCompose(path.join(opts.projectPath, '..')), checkCompose(path.join(opts.projectPath, '..')),
]); ]);
if (!hasCompose && hasParentCompose) { if (!hasCompose && hasParentCompose) {
Logger.getLogger().logWarn(stripIndent` const { isV12 } = await import('./version');
"docker-compose.y[a]ml" file found in parent directory: please check const msg = stripIndent`
that the correct folder was specified. (Suppress with '--noparent-check'.) "docker-compose.y[a]ml" file found in parent directory: please check that
`); the correct source folder was specified. (Suppress with '--noparent-check'.)`;
if (isV12()) {
throw new ExpectedError(`Error: ${msg}`);
} else {
Logger.getLogger().logWarn(msg);
}
} }
} }
} }

View File

@ -17,6 +17,7 @@
import { expect } from 'chai'; import { expect } from 'chai';
import { isV12 } from '../../../build/utils/version';
import { BalenaAPIMock } from '../../balena-api-mock'; import { BalenaAPIMock } from '../../balena-api-mock';
import { cleanOutput, runCommand } from '../../helpers'; import { cleanOutput, runCommand } from '../../helpers';
@ -52,7 +53,9 @@ describe('balena devices supported', function() {
const lines = cleanOutput(out); const lines = cleanOutput(out);
expect(lines[0].replace(/ +/g, ' ')).to.equal('SLUG NAME'); expect(lines[0].replace(/ +/g, ' ')).to.equal(
isV12() ? 'SLUG ALIASES ARCH NAME' : 'SLUG NAME',
);
expect(lines).to.have.lengthOf.at.least(2); expect(lines).to.have.lengthOf.at.least(2);
// Discontinued devices should be filtered out from results // Discontinued devices should be filtered out from results

View File

@ -22,6 +22,7 @@ import { expect } from 'chai';
import { fs } from 'mz'; import { fs } from 'mz';
import * as path from 'path'; import * as path from 'path';
import { isV12 } from '../../build/utils/version';
import { BalenaAPIMock } from '../balena-api-mock'; import { BalenaAPIMock } from '../balena-api-mock';
import { BuilderMock, builderResponsePath } from '../builder-mock'; import { BuilderMock, builderResponsePath } from '../builder-mock';
import { expectStreamNoCRLF, testPushBuildStream } from '../docker-build'; import { expectStreamNoCRLF, testPushBuildStream } from '../docker-build';
@ -230,14 +231,23 @@ describe('balena push', function() {
'.balena/balena.yml': { fileSize: 12, type: 'file' }, '.balena/balena.yml': { fileSize: 12, type: 'file' },
'.dockerignore': { fileSize: 438, type: 'file' }, '.dockerignore': { fileSize: 438, type: 'file' },
'.gitignore': { fileSize: 20, type: 'file' }, '.gitignore': { fileSize: 20, type: 'file' },
'.git/bar.txt': { fileSize: 4, type: 'file' },
'.git/foo.txt': { fileSize: 4, type: 'file' }, '.git/foo.txt': { fileSize: 4, type: 'file' },
'c.txt': { fileSize: 1, type: 'file' }, 'c.txt': { fileSize: 1, type: 'file' },
Dockerfile: { fileSize: 13, type: 'file' }, Dockerfile: { fileSize: 13, type: 'file' },
'src/.balena/balena.yml': { fileSize: 16, type: 'file' }, 'src/.balena/balena.yml': { fileSize: 16, type: 'file' },
'src/.gitignore': { fileSize: 10, type: 'file' }, 'src/.gitignore': { fileSize: 10, type: 'file' },
'vendor/.git/vendor-git-contents': { fileSize: 20, type: 'file' }, 'vendor/.git/vendor-git-contents': { fileSize: 20, type: 'file' },
...(isV12()
? {
'a.txt': { fileSize: 1, type: 'file' },
'src/src-a.txt': { fileSize: 5, type: 'file' },
'src/src-c.txt': { fileSize: 5, type: 'file' },
}
: {
'.git/bar.txt': { fileSize: 4, type: 'file' },
}),
}; };
const regSecretsPath = await addRegSecretsEntries(expectedFiles); const regSecretsPath = await addRegSecretsEntries(expectedFiles);
const responseFilename = 'build-POST-v3.json'; const responseFilename = 'build-POST-v3.json';
const responseBody = await fs.readFile( const responseBody = await fs.readFile(
@ -245,6 +255,8 @@ describe('balena push', function() {
'utf8', 'utf8',
); );
const expectedResponseLines = [ const expectedResponseLines = [
...(!isV12()
? [
'[Warn] Using file ignore patterns from:', '[Warn] Using file ignore patterns from:',
`[Warn] ${path.join(projectPath, '.dockerignore')}`, `[Warn] ${path.join(projectPath, '.dockerignore')}`,
`[Warn] ${path.join(projectPath, '.gitignore')}`, `[Warn] ${path.join(projectPath, '.gitignore')}`,
@ -253,6 +265,8 @@ describe('balena push', function() {
'[Warn] version release will disregard gitignore files and use a dockerignore file only.', '[Warn] version release will disregard gitignore files and use a dockerignore file only.',
'[Warn] Use the --nogitignore (-G) option to enable the new behavior already now and', '[Warn] Use the --nogitignore (-G) option to enable the new behavior already now and',
"[Warn] suppress this warning. For more information, see 'balena help push'.", "[Warn] suppress this warning. For more information, see 'balena help push'.",
]
: []),
...commonResponseLines[responseFilename], ...commonResponseLines[responseFilename],
]; ];
@ -486,12 +500,17 @@ describe('balena push: project validation', function() {
'basic', 'basic',
'service1', 'service1',
); );
const expectedErrorLines = [ const expectedErrorLines = isV12()
'The --nolive flag is only valid when pushing to a local mode device', ? [
]; 'Error: "docker-compose.y[a]ml" file found in parent directory: please check that',
const expectedOutputLines = [ "the correct source folder was specified. (Suppress with '--noparent-check'.)",
'[Warn] "docker-compose.y[a]ml" file found in parent directory: please check', ]
"[Warn] that the correct folder was specified. (Suppress with '--noparent-check'.)", : ['The --nolive flag is only valid when pushing to a local mode device'];
const expectedOutputLines = isV12()
? []
: [
'[Warn] "docker-compose.y[a]ml" file found in parent directory: please check that',
"[Warn] the correct source folder was specified. (Suppress with '--noparent-check'.)",
]; ];
const { out, err } = await runCommand( const { out, err } = await runCommand(