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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ packages/
#Other files
*.DotSettings
.vs/
.vscode/
*project.lock.json
jsconfig.json
package-lock.json
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"type": "prerelease",
"comment": "Improve inner loop and error reporting (local CLI)",
"packageName": "react-native-windows",
"email": "asklar@microsoft.com",
"dependentChangeType": "patch",
"date": "2020-04-09T02:30:11.182Z"
}
10 changes: 8 additions & 2 deletions vnext/local-cli/runWindows/runWindows.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const {newError, newInfo} = require('./utils/commandWithProgress');
const info = require('./utils/info');
const msbuildtools = require('./utils/msbuildtools');
const autolink = require('./utils/autolink');
const chalk = require('chalk');

async function runWindows(config, args, options) {
const verbose = options.logging;
Expand Down Expand Up @@ -71,8 +72,13 @@ async function runWindows(config, args, options) {
);
} catch (e) {
newError(
`Build failed with message ${e}. Check your build configuration.`,
`Build failed with message ${
e.message
}. Check your build configuration.`,
);
if (e.logfile) {
console.log('See', chalk.bold(e.logfile));
}
process.exit(1);
}
} else {
Expand All @@ -89,7 +95,7 @@ async function runWindows(config, args, options) {
await deploy.deployToDesktop(options, verbose);
}
} catch (e) {
newError(`Failed to deploy: ${e.message}`);
newError(`Failed to deploy${e ? `: ${e.message}` : ''}`);
process.exit(1);
}
} else {
Expand Down
2 changes: 1 addition & 1 deletion vnext/local-cli/runWindows/utils/WindowsStoreAppUtils.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ function EnableDevmode {
New-Item -Path $RegistryKeyPath -ItemType Directory -Force
}

Set-ItemProperty -Path $RegistryKeyPath -Name AllowDevelopmentWithoutDevLicense -Value 1
Set-ItemProperty -Path $RegistryKeyPath -Name AllowDevelopmentWithoutDevLicense -Value 1 -ErrorAction Stop
}

#
Expand Down
25 changes: 17 additions & 8 deletions vnext/local-cli/runWindows/utils/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ async function buildSolution(
}

async function nugetRestore(nugetPath, slnFile, verbose, msbuildVersion) {
const text = 'Restoring NuGets';
const text = 'Restoring NuGet packages ';
const spinner = newSpinner(text);
console.log(nugetPath);
await commandWithProgress(
Expand Down Expand Up @@ -74,7 +74,7 @@ async function restoreNuGetPackages(options, slnFile, verbose) {
ensureNugetSpinner,
dlNugetText,
'powershell',
`Invoke-WebRequest https://dist.nuget.org/win-x86-commandline/v4.9.2/nuget.exe -outfile ${nugetPath}`.split(
`$progressPreference = [System.Management.Automation.ActionPreference]::SilentlyContinue; Invoke-WebRequest https://dist.nuget.org/win-x86-commandline/v4.9.2/nuget.exe -outfile ${nugetPath}`.split(
' ',
),
verbose,
Expand All @@ -83,12 +83,21 @@ async function restoreNuGetPackages(options, slnFile, verbose) {
ensureNugetSpinner.succeed('Found NuGet Binary');

const msbuildTools = MSBuildTools.findAvailableVersion('x86', verbose);
await nugetRestore(
nugetPath,
slnFile,
verbose,
msbuildTools.installationVersion,
);
try {
await nugetRestore(
nugetPath,
slnFile,
verbose,
msbuildTools.installationVersion,
);
} catch (e) {
if (!options.isRetryingNuget) {
const retryOptions = Object.assign({isRetryingNuget: true}, options);
fs.unlinkSync(nugetPath);
return restoreNuGetPackages(retryOptions, slnFile, verbose);
}
throw e;
}
}

function getSolutionFile(options) {
Expand Down
36 changes: 34 additions & 2 deletions vnext/local-cli/runWindows/utils/commandWithProgress.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,32 @@ function newSpinner(text) {
return ora(options).start();
}

async function runPowerShellScriptFunction(
taskDescription,
script,
funcName,
verbose,
) {
try {
await commandWithProgress(
newSpinner(taskDescription),
taskDescription,
'powershell',
[
'-NoProfile',
'-ExecutionPolicy',
'RemoteSigned',
`Import-Module "${script}"; ${funcName} -ErrorAction Stop; exit $LASTEXITCODE`,
],
verbose,
);
} catch {
// The error output from the process will be shown if verbose is set.
// We don't capture the process output if verbose is set, but at least we have the task name in text, so throw that.
throw new Error(taskDescription);
}
}

function commandWithProgress(spinner, taskDoingName, command, args, verbose) {
return new Promise(function(resolve, reject) {
const spawnOptions = verbose ? {stdio: 'inherit'} : {};
Expand All @@ -50,18 +76,23 @@ function commandWithProgress(spinner, taskDoingName, command, args, verbose) {
}

const cp = child_process.spawn(command, args, spawnOptions);

let firstErrorLine = null;
if (!verbose) {
cp.stdout.on('data', chunk => {
const text = chunk.toString();
setSpinnerText(spinner, taskDoingName + ': ', text);
});
cp.stderr.on('data', chunk => {
const text = chunk.toString();
if (!firstErrorLine) {
firstErrorLine = text;
}
if (verbose) {
console.error(chalk.red(text));
}
setSpinnerText(spinner, taskDoingName + ': ERROR: ', text);
if (text) {
setSpinnerText(spinner, taskDoingName + ': ERROR: ', firstErrorLine);
}
});
}
cp.on('error', e => {
Expand Down Expand Up @@ -105,4 +136,5 @@ module.exports = {
newSpinner,
newSuccess,
newWarn,
runPowerShellScriptFunction,
};
49 changes: 17 additions & 32 deletions vnext/local-cli/runWindows/utils/deploy.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const {
newWarn,
newSpinner,
commandWithProgress,
runPowerShellScriptFunction,
} = require('./commandWithProgress');

function pushd(pathArg) {
Expand Down Expand Up @@ -166,36 +167,24 @@ async function deployToDesktop(options, verbose) {

const popd = pushd(options.root);

const removingText = 'Removing old version of the app';
await commandWithProgress(
newSpinner(removingText),
removingText,
'powershell',
`-NoProfile -ExecutionPolicy RemoteSigned Import-Module "${windowsStoreAppUtils}" ; Uninstall-App ${appName}`.split(
' ',
),
await runPowerShellScriptFunction(
'Removing old version of the app',
windowsStoreAppUtils,
`Uninstall-App ${appName}`,
verbose,
);

const devmodeText = 'Enabling Developer Mode';
const devmodeEnable = `-NoProfile -ExecutionPolicy RemoteSigned Import-Module "${windowsStoreAppUtils}"; EnableDevmode "${script}"`;

await commandWithProgress(
newSpinner(devmodeText),
devmodeText,
'powershell',
devmodeEnable.split(' '),
await runPowerShellScriptFunction(
'Enabling Developer Mode',
windowsStoreAppUtils,
`EnableDevMode "${script}"`,
verbose,
);

const installingText = 'Installing new version of the app';
const installApp = `-NoProfile -ExecutionPolicy RemoteSigned Import-Module "${windowsStoreAppUtils}"; Install-App "${script}" -Force`;

await commandWithProgress(
newSpinner(installingText),
installingText,
'powershell',
installApp.split(' '),
await runPowerShellScriptFunction(
'Installing new version of the app',
windowsStoreAppUtils,
`Install-App "${script}" -Force`,
verbose,
);

Expand Down Expand Up @@ -223,14 +212,10 @@ async function deployToDesktop(options, verbose) {
);

if (shouldLaunchApp(options)) {
const startingText = 'Starting the app';
await commandWithProgress(
newSpinner(startingText),
startingText,
'powershell',
`-ExecutionPolicy RemoteSigned Import-Module "${windowsStoreAppUtils}"; Start-Locally ${appName} ${args}`.split(
' ',
),
await runPowerShellScriptFunction(
'Starting the app',
windowsStoreAppUtils,
`Start-Locally ${appName} ${args}`,
verbose,
);
} else {
Expand Down
44 changes: 31 additions & 13 deletions vnext/local-cli/runWindows/utils/msbuildtools.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,18 +51,18 @@ class MSBuildTools {
newInfo(`Build configuration: ${buildType}`);
newInfo(`Build platform: ${buildArch}`);

//const verbosityOption = verbose ? 'normal' : 'quiet';
const verbosityOption = 'normal';
const verbosityOption = verbose ? 'normal' : 'minimal';
const errorLog = path.join(process.env.temp, `msbuild_${process.pid}.err`);
const args = [
`/clp:NoSummary;NoItemAndPropertyList;Verbosity=${verbosityOption}`,
'/nologo',
`/p:Configuration=${buildType}`,
`/p:Platform=${buildArch}`,
'/p:AppxBundle=Never',
'/bl',
`/flp1:errorsonly;logfile=${errorLog}`,
];

args.push('/bl');

if (msBuildProps) {
Object.keys(msBuildProps).forEach(function(key) {
args.push(`/p:${key}=${msBuildProps[key]}`);
Expand All @@ -73,20 +73,38 @@ class MSBuildTools {
checkRequirements.isWinSdkPresent('10.0');
} catch (e) {
newError(e.message);
return;
throw e;
}

console.log(`Running MSBuild with args ${args.join(' ')}`);
if (verbose) {
console.log(`Running MSBuild with args ${args.join(' ')}`);
}

const progressName = 'Building Solution';
const spinner = newSpinner(progressName);
await commandWithProgress(
spinner,
progressName,
path.join(this.path, 'msbuild.exe'),
[slnFile].concat(args),
verbose,
);
try {
await commandWithProgress(
spinner,
progressName,
path.join(this.path, 'msbuild.exe'),
[slnFile].concat(args),
verbose,
);
} catch (e) {
let error = e;
if (!e) {
const firstMessage = (await fs.promises.readFile(errorLog))
.toString()
.split(EOL)[0];
error = new Error(firstMessage);
error.logfile = errorLog;
}
throw error;
}
// If we have no errors, delete the error log when we're done
if ((await fs.promises.stat(errorLog)).size === 0) {
await fs.promises.unlink(errorLog);
}
}
}

Expand Down