Merge pull request #1856 from balena-io/default-convert-eol

v12 preparations: Add feature switch for default eol-converson
This commit is contained in:
bulldozer-balena[bot] 2020-06-05 19:25:04 +00:00 committed by GitHub
commit 523d563b4e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 159 additions and 85 deletions

View File

@ -60,7 +60,7 @@ const buildProject = function(docker, logger, composeOpts, opts) {
opts.buildEmulated,
opts.buildOpts,
composeOpts.inlineLogs,
opts.convertEol,
composeOpts.convertEol,
composeOpts.dockerfilePath,
composeOpts.nogitignore,
);
@ -152,9 +152,6 @@ Examples:
}
delete params.source;
options.convertEol = options['convert-eol'] || false;
delete options['convert-eol'];
const { application, arch, deviceType } = options;
return Promise.try(function() {
@ -203,7 +200,6 @@ Examples:
deviceType: resolvedDeviceType,
buildEmulated: !!options.emulated,
buildOpts,
convertEol: options.convertEol,
}),
);
});

View File

@ -97,7 +97,7 @@ const deployProject = function(docker, logger, composeOpts, opts) {
opts.buildEmulated,
opts.buildOpts,
composeOpts.inlineLogs,
opts.convertEol,
composeOpts.convertEol,
composeOpts.dockerfilePath,
composeOpts.nogitignore,
)
@ -263,16 +263,6 @@ Examples:
appName = appName_raw || appName || options.application;
delete options.application;
options.convertEol = options['convert-eol'] || false;
delete options['convert-eol'];
if (options.convertEol && !options.build) {
return Promise.reject(
new ExpectedError(
'The --eol-conversion flag is only valid with --build.',
),
);
}
return Promise.try(function() {
if (appName == null) {
throw new ExpectedError(
@ -320,7 +310,6 @@ Examples:
shouldUploadLogs: !options.nologupload,
buildEmulated: !!options.emulated,
buildOpts,
convertEol: options.convertEol,
}),
);
});

View File

@ -117,6 +117,7 @@ export const push: CommandDefinition<
system?: boolean;
env?: string | string[];
'convert-eol'?: boolean;
'noconvert-eol'?: boolean;
}
> = {
signature: 'push <applicationOrDevice>',
@ -258,11 +259,23 @@ export const push: CommandDefinition<
{
signature: 'convert-eol',
alias: 'l',
description: stripIndent`
description: isV12()
? 'No-op and deprecated since balena CLI v12.0.0'
: stripIndent`
On Windows only, convert line endings from CRLF (Windows format) to LF (Unix format).
Source files are not modified.`,
boolean: true,
},
...(isV12()
? [
{
signature: 'noconvert-eol',
description:
"Don't convert line endings from CRLF (Windows format) to LF (Unix format).",
boolean: true,
},
]
: []),
{
signature: 'nogitignore',
alias: 'G',
@ -307,6 +320,9 @@ export const push: CommandDefinition<
);
const nogitignore = !!options.nogitignore || isV12();
const convertEol = isV12()
? !options['noconvert-eol']
: !!options['convert-eol'];
const buildTarget = getBuildTarget(appOrDevice);
switch (buildTarget) {
@ -346,7 +362,7 @@ export const push: CommandDefinition<
nocache: options.nocache || false,
registrySecrets,
headless: options.detached || false,
convertEol: options['convert-eol'] || false,
convertEol,
};
const args = {
app,
@ -388,7 +404,7 @@ export const push: CommandDefinition<
typeof options.env === 'string'
? [options.env]
: options.env || [],
convertEol: options['convert-eol'] || false,
convertEol,
}),
).catch(BuildError, e => {
throw new ExpectedError(e.toString());

View File

@ -47,6 +47,7 @@ export interface TaggedImage {
}
export interface ComposeOpts {
convertEol: boolean;
dockerfilePath?: string;
inlineLogs?: boolean;
noParentCheck: boolean;

View File

@ -92,12 +92,24 @@ export function appendOptions(opts) {
},
{
signature: 'convert-eol',
description: `\
description: isV12()
? 'No-op and deprecated since balena CLI v12.0.0'
: `\
On Windows only, convert line endings from CRLF (Windows format) to LF (Unix format). \
Source files are not modified.`,
boolean: true,
alias: 'l',
},
...(isV12()
? [
{
signature: 'noconvert-eol',
description:
"Don't convert line endings from CRLF (Windows format) to LF (Unix format).",
boolean: true,
},
]
: []),
]);
}
@ -111,6 +123,7 @@ export function generateOpts(options) {
projectName: options.projectName,
projectPath,
inlineLogs: !options.nologs && (!!options.logs || isV12()),
convertEol: isV12() ? !options['noconvert-eol'] : !!options['convert-eol'],
dockerfilePath: options.dockerfile,
nogitignore: !!options.nogitignore || isV12(),
noParentCheck: options['noparent-check'],

View File

@ -178,6 +178,7 @@ export async function deployToDevice(opts: DeviceDeployOptions): Promise<void> {
globalLogger.logInfo(`Starting build on device ${opts.deviceHost}`);
const project = await loadProject(globalLogger, {
convertEol: opts.convertEol,
dockerfilePath: opts.dockerfilePath,
noParentCheck: opts.noParentCheck,
projectName: 'local',

View File

@ -17,6 +17,7 @@
import { fs } from 'mz';
import Logger = require('./logger');
import { isV12 } from './version';
const globalLogger = Logger.getLogger();
@ -110,7 +111,9 @@ export async function readFileWithEolConversion(
);
// And summary warning later
globalLogger.deferredLog(
'Windows-format line endings were detected in some files. Consider using the `--convert-eol` option.',
isV12()
? 'Windows-format line endings were detected in some files, but were not converted due to `--noconvert-eol` option.'
: 'Windows-format line endings were detected in some files. Consider using the `--convert-eol` option.',
Logger.Level.WARN,
);

View File

@ -84,9 +84,14 @@ describe('balena build', function() {
it('should create the expected tar stream (single container)', async () => {
const projectPath = path.join(projectsPath, 'no-docker-compose', 'basic');
const isV12W = isWindows && isV12();
const expectedFiles: ExpectedTarStreamFiles = {
'src/start.sh': { fileSize: 89, type: 'file' },
'src/windows-crlf.sh': { fileSize: 70, type: 'file' },
'src/windows-crlf.sh': {
fileSize: isV12W ? 68 : 70,
testStream: isV12W ? expectStreamNoCRLF : undefined,
type: 'file',
},
Dockerfile: { fileSize: 88, type: 'file' },
'Dockerfile-alt': { fileSize: 30, type: 'file' },
};
@ -104,14 +109,17 @@ describe('balena build', function() {
: '[Build] main Image size: 1.14 MB',
];
if (isWindows) {
expectedResponseLines.push(
`[Warn] CRLF (Windows) line endings detected in file: ${path.join(
projectPath,
'src',
'windows-crlf.sh',
)}`,
'[Warn] Windows-format line endings were detected in some files. Consider using the `--convert-eol` option.',
);
const fname = path.join(projectPath, 'src', 'windows-crlf.sh');
if (isV12()) {
expectedResponseLines.push(
`[Info] Converting line endings CRLF -> LF for file: ${fname}`,
);
} else {
expectedResponseLines.push(
`[Warn] CRLF (Windows) line endings detected in file: ${fname}`,
'[Warn] Windows-format line endings were detected in some files. Consider using the `--convert-eol` option.',
);
}
}
docker.expectGetInfo({});
await testDockerBuildStream({
@ -129,6 +137,7 @@ describe('balena build', function() {
it('should create the expected tar stream (--emulated)', async () => {
const projectPath = path.join(projectsPath, 'no-docker-compose', 'basic');
const isV12W = isWindows && isV12();
const transposedDockerfile =
stripIndent`
FROM busybox
@ -138,7 +147,11 @@ describe('balena build', function() {
CMD ["/usr/src/start.sh"]` + '\n';
const expectedFiles: ExpectedTarStreamFiles = {
'src/start.sh': { fileSize: 89, type: 'file' },
'src/windows-crlf.sh': { fileSize: 70, type: 'file' },
'src/windows-crlf.sh': {
fileSize: isV12W ? 68 : 70,
testStream: isV12W ? expectStreamNoCRLF : undefined,
type: 'file',
},
Dockerfile: {
fileSize: transposedDockerfile.length,
type: 'file',
@ -162,14 +175,17 @@ describe('balena build', function() {
'[Success] Build succeeded!',
];
if (isWindows) {
expectedResponseLines.push(
`[Warn] CRLF (Windows) line endings detected in file: ${path.join(
projectPath,
'src',
'windows-crlf.sh',
)}`,
'[Warn] Windows-format line endings were detected in some files. Consider using the `--convert-eol` option.',
);
const fname = path.join(projectPath, 'src', 'windows-crlf.sh');
if (isV12()) {
expectedResponseLines.push(
`[Info] Converting line endings CRLF -> LF for file: ${fname}`,
);
} else {
expectedResponseLines.push(
`[Warn] CRLF (Windows) line endings detected in file: ${fname}`,
'[Warn] Windows-format line endings were detected in some files. Consider using the `--convert-eol` option.',
);
}
}
const arch = 'rpi';
const deviceType = 'raspberry-pi';
@ -207,13 +223,14 @@ describe('balena build', function() {
}
});
it('should create the expected tar stream (single container, --convert-eol)', async () => {
it('should create the expected tar stream (single container, --[no]convert-eol)', async () => {
const projectPath = path.join(projectsPath, 'no-docker-compose', 'basic');
const eol = isWindows && !isV12();
const expectedFiles: ExpectedTarStreamFiles = {
'src/start.sh': { fileSize: 89, type: 'file' },
'src/windows-crlf.sh': {
fileSize: isWindows ? 68 : 70,
testStream: isWindows ? expectStreamNoCRLF : undefined,
fileSize: eol ? 68 : 70,
testStream: eol ? expectStreamNoCRLF : undefined,
type: 'file',
},
Dockerfile: { fileSize: 88, type: 'file' },
@ -233,17 +250,23 @@ describe('balena build', function() {
: '[Build] main Image size: 1.14 MB',
];
if (isWindows) {
expectedResponseLines.push(
`[Info] Converting line endings CRLF -> LF for file: ${path.join(
projectPath,
'src',
'windows-crlf.sh',
)}`,
);
const fname = path.join(projectPath, 'src', 'windows-crlf.sh');
if (isV12()) {
expectedResponseLines.push(
`[Warn] CRLF (Windows) line endings detected in file: ${fname}`,
'[Warn] Windows-format line endings were detected in some files, but were not converted due to `--noconvert-eol` option.',
);
} else {
expectedResponseLines.push(
`[Info] Converting line endings CRLF -> LF for file: ${fname}`,
);
}
}
docker.expectGetInfo({});
await testDockerBuildStream({
commandLine: `build ${projectPath} --deviceType nuc --arch amd64 --convert-eol`,
commandLine: isV12()
? `build ${projectPath} --deviceType nuc --arch amd64 --noconvert-eol`
: `build ${projectPath} --deviceType nuc --arch amd64 --convert-eol`,
dockerMock: docker,
expectedFilesByService: { main: expectedFiles },
expectedQueryParamsByService: { main: commonQueryParams },

View File

@ -25,7 +25,7 @@ import * as sinon from 'sinon';
import { isV12 } from '../../build/utils/version';
import { BalenaAPIMock } from '../balena-api-mock';
import { testDockerBuildStream } from '../docker-build';
import { expectStreamNoCRLF, testDockerBuildStream } from '../docker-build';
import { DockerMock, dockerResponsePath } from '../docker-mock';
import { cleanOutput, runCommand, switchSentry } from '../helpers';
import { ExpectedTarStreamFiles } from '../projects';
@ -106,9 +106,14 @@ describe('balena deploy', function() {
it('should create the expected --build tar stream (single container)', async () => {
const projectPath = path.join(projectsPath, 'no-docker-compose', 'basic');
const isV12W = isWindows && isV12();
const expectedFiles: ExpectedTarStreamFiles = {
'src/start.sh': { fileSize: 89, type: 'file' },
'src/windows-crlf.sh': { fileSize: 70, type: 'file' },
'src/windows-crlf.sh': {
fileSize: isV12W ? 68 : 70,
testStream: isV12W ? expectStreamNoCRLF : undefined,
type: 'file',
},
Dockerfile: { fileSize: 88, type: 'file' },
'Dockerfile-alt': { fileSize: 30, type: 'file' },
};
@ -123,14 +128,17 @@ describe('balena deploy', function() {
`[Info] Creating default composition with source: "${projectPath}"`,
];
if (isWindows) {
expectedResponseLines.push(
`[Warn] CRLF (Windows) line endings detected in file: ${path.join(
projectPath,
'src',
'windows-crlf.sh',
)}`,
'[Warn] Windows-format line endings were detected in some files. Consider using the `--convert-eol` option.',
);
const fname = path.join(projectPath, 'src', 'windows-crlf.sh');
if (isV12()) {
expectedResponseLines.push(
`[Info] Converting line endings CRLF -> LF for file: ${fname}`,
);
} else {
expectedResponseLines.push(
`[Warn] CRLF (Windows) line endings detected in file: ${fname}`,
'[Warn] Windows-format line endings were detected in some files. Consider using the `--convert-eol` option.',
);
}
}
api.expectPatchImage({});
@ -189,7 +197,7 @@ describe('balena deploy', function() {
});
await testDockerBuildStream({
commandLine: `deploy testApp --build --source ${projectPath} -G`,
commandLine: `deploy testApp --build --source ${projectPath} --noconvert-eol -G`,
dockerMock: docker,
expectedFilesByService: { main: expectedFiles },
expectedQueryParamsByService: { main: commonQueryParams },

View File

@ -109,9 +109,14 @@ describe('balena push', function() {
it('should create the expected tar stream (single container)', async () => {
const projectPath = path.join(projectsPath, 'no-docker-compose', 'basic');
const isV12W = isWindows && isV12();
const expectedFiles: ExpectedTarStreamFiles = {
'src/start.sh': { fileSize: 89, type: 'file' },
'src/windows-crlf.sh': { fileSize: 70, type: 'file' },
'src/windows-crlf.sh': {
fileSize: isV12W ? 68 : 70,
testStream: isV12W ? expectStreamNoCRLF : undefined,
type: 'file',
},
Dockerfile: { fileSize: 88, type: 'file' },
'Dockerfile-alt': { fileSize: 30, type: 'file' },
};
@ -123,14 +128,17 @@ describe('balena push', function() {
);
const expectedResponseLines = [...commonResponseLines[responseFilename]];
if (isWindows) {
expectedResponseLines.push(
`[Warn] CRLF (Windows) line endings detected in file: ${path.join(
projectPath,
'src',
'windows-crlf.sh',
)}`,
'[Warn] Windows-format line endings were detected in some files. Consider using the `--convert-eol` option.',
);
const fname = path.join(projectPath, 'src', 'windows-crlf.sh');
if (isV12()) {
expectedResponseLines.push(
`[Info] Converting line endings CRLF -> LF for file: ${fname}`,
);
} else {
expectedResponseLines.push(
`[Warn] CRLF (Windows) line endings detected in file: ${fname}`,
'[Warn] Windows-format line endings were detected in some files. Consider using the `--convert-eol` option.',
);
}
}
await testPushBuildStream({
@ -165,7 +173,7 @@ describe('balena push', function() {
await testPushBuildStream({
builderMock: builder,
commandLine: `push testApp -s ${projectPath} -R ${regSecretsPath} --dockerfile Dockerfile-alt --nogitignore`,
commandLine: `push testApp -s ${projectPath} -R ${regSecretsPath} --dockerfile Dockerfile-alt --noconvert-eol --nogitignore`,
expectedFiles,
expectedQueryParams,
expectedResponseLines: commonResponseLines[responseFilename],
@ -175,14 +183,15 @@ describe('balena push', function() {
});
});
it('should create the expected tar stream (single container, --convert-eol)', async () => {
it('should create the expected tar stream (single container, --[no]convert-eol)', async () => {
const projectPath = path.join(projectsPath, 'no-docker-compose', 'basic');
const eol = isWindows && !isV12();
const expectedFiles: ExpectedTarStreamFiles = {
'src/start.sh': { fileSize: 89, type: 'file' },
'src/windows-crlf.sh': {
fileSize: isWindows ? 68 : 70,
fileSize: eol ? 68 : 70,
testStream: eol ? expectStreamNoCRLF : undefined,
type: 'file',
testStream: isWindows ? expectStreamNoCRLF : undefined,
},
Dockerfile: { fileSize: 88, type: 'file' },
'Dockerfile-alt': { fileSize: 30, type: 'file' },
@ -195,18 +204,24 @@ describe('balena push', function() {
);
const expectedResponseLines = [...commonResponseLines[responseFilename]];
if (isWindows) {
expectedResponseLines.push(
`[Info] Converting line endings CRLF -> LF for file: ${path.join(
projectPath,
'src',
'windows-crlf.sh',
)}`,
);
const fname = path.join(projectPath, 'src', 'windows-crlf.sh');
if (isV12()) {
expectedResponseLines.push(
`[Warn] CRLF (Windows) line endings detected in file: ${fname}`,
'[Warn] Windows-format line endings were detected in some files, but were not converted due to `--noconvert-eol` option.',
);
} else {
expectedResponseLines.push(
`[Info] Converting line endings CRLF -> LF for file: ${fname}`,
);
}
}
await testPushBuildStream({
builderMock: builder,
commandLine: `push testApp -s ${projectPath} -R ${regSecretsPath} -l`,
commandLine: isV12()
? `push testApp -s ${projectPath} -R ${regSecretsPath} --noconvert-eol`
: `push testApp -s ${projectPath} -R ${regSecretsPath} -l`,
expectedFiles,
expectedQueryParams: commonQueryParams,
expectedResponseLines,
@ -322,6 +337,10 @@ describe('balena push', function() {
});
});
// NOTE: if this test or other tests involving symbolic links fail on Windows
// (with a mismatched fileSize 13 vs 5 for 'symlink-a.txt'), ensure that the
// `core.symlinks` property is set to `true` in the `.git/config` file. Ref:
// https://git-scm.com/docs/git-config#Documentation/git-config.txt-coresymlinks
it('should create the expected tar stream (single container, symbolic links, --nogitignore)', async () => {
const projectPath = path.join(
projectsPath,
@ -367,7 +386,8 @@ describe('balena push', function() {
'src/src-b.txt': { fileSize: 5, type: 'file' },
'symlink-a.txt': { fileSize: 5, type: 'file' },
};
if (isWindows) {
const noV12W = isWindows && !isV12();
if (noV12W) {
// this test uses the old tarDirectory implementation, which uses
// the zeit/dockerignore library that has bugs on Windows
expectedFiles['src/src-a.txt'] = { fileSize: 5, type: 'file' };
@ -378,7 +398,7 @@ describe('balena push', function() {
path.join(builderResponsePath, responseFilename),
'utf8',
);
const expectedResponseLines = isWindows
const expectedResponseLines = noV12W
? [
'[Warn] Using file ignore patterns from:',
`[Warn] ${path.join(projectPath, '.dockerignore')}`,

View File

@ -57,6 +57,10 @@ describe('compare new and old tarDirectory implementations', function() {
await setupDockerignoreTestData({ cleanup: true });
});
// NOTE: if this test or other tests involving symbolic links fail on Windows
// (with a mismatched fileSize 13 vs 5 for 'symlink-a.txt'), ensure that the
// `core.symlinks` property is set to `true` in the `.git/config` file. Ref:
// https://git-scm.com/docs/git-config#Documentation/git-config.txt-coresymlinks
it('should produce the expected file list', async function() {
const dockerignoreProjDir = path.join(
projectsPath,