Skip to content
This repository has been archived by the owner on Dec 8, 2020. It is now read-only.

Commit

Permalink
Make cargo use rustup (#276)
Browse files Browse the repository at this point in the history
  • Loading branch information
KalitaAlexey authored Jun 19, 2017
1 parent 9f30221 commit 767bdaf
Show file tree
Hide file tree
Showing 9 changed files with 85 additions and 19 deletions.
2 changes: 1 addition & 1 deletion doc/common_configuration_parameters.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ Users should adjust properties of this configuration parameter to customize rust
### toolchain

This configuration parameter specifies which toolchain the extension will invoke rustup with.
It is used for getting sysroot, installing components.
It is used for getting sysroot, installing components, invoking Cargo

However there are few exceptions. Currently RLS is available for nightly hence RLS and rust-analysis are installed for the nightly toolchain.
34 changes: 34 additions & 0 deletions src/CargoInvocationManager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { Configuration } from './components/configuration/Configuration';
import { Rustup } from './components/configuration/Rustup';

/**
* The class defines functions which can be used to get data required to invoke Cargo
*/
export class CargoInvocationManager {
private _configuration: Configuration;
private _rustup: Rustup | undefined;

public constructor(configuration: Configuration, rustup: Rustup | undefined) {
this._configuration = configuration;
this._rustup = rustup;
}

/**
* Cargo can be accessible from multiple places, but the only one is correct.
* This function determines the path to the executable which either Cargo itself or proxy to
* Cargo. If the executable is a proxy to Cargo, then the proxy may require some arguments to
* understand that Cargo is requested. An example is running Cargo using rustup.
*/
public getExecutableAndArgs(): { executable: string, args: string[] } {
const userCargoPath = this._configuration.getCargoPath();
if (userCargoPath) {
return { executable: userCargoPath, args: [] };
}
const userToolchain = this._rustup ? this._rustup.getUserToolchain() : undefined;
if (!userToolchain) {
return { executable: 'cargo', args: [] };
}
const args = ['run', userToolchain.toString(true, false), 'cargo'];
return { executable: Rustup.getRustupExecutable(), args };
}
}
3 changes: 3 additions & 0 deletions src/components/cargo/CargoManager.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as tmp from 'tmp';
import { Disposable, ExtensionContext, Uri, commands, window, workspace } from 'vscode';
import { CargoInvocationManager } from '../../CargoInvocationManager';
import { Configuration } from '../configuration/Configuration';
import { CurrentWorkingDirectoryManager }
from '../configuration/current_working_directory_manager';
Expand All @@ -17,13 +18,15 @@ export class CargoManager {
public constructor(
context: ExtensionContext,
configuration: Configuration,
cargoInvocationManager: CargoInvocationManager,
currentWorkingDirectoryManager: CurrentWorkingDirectoryManager,
logger: ChildLogger
) {
const stopCommandName = 'rust.cargo.terminate';
this._cargoTaskManager = new CargoTaskManager(
context,
configuration,
cargoInvocationManager,
currentWorkingDirectoryManager,
logger.createChildLogger('CargoTaskManager: '),
stopCommandName
Expand Down
19 changes: 16 additions & 3 deletions src/components/cargo/CargoTaskManager.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { join } from 'path';
import { ExtensionContext, window } from 'vscode';
import { CargoInvocationManager } from '../../CargoInvocationManager';
import { Configuration } from '../configuration/Configuration';
import { CurrentWorkingDirectoryManager }
from '../configuration/current_working_directory_manager';
Expand All @@ -13,6 +14,7 @@ import { UserDefinedArgs } from './UserDefinedArgs';

export class CargoTaskManager {
private _configuration: Configuration;
private _cargoInvocationManager: CargoInvocationManager;
private _currentWorkingDirectoryManager: CurrentWorkingDirectoryManager;
private _logger: ChildLogger;
private _outputChannelTaskManager: OutputChannelTaskManager;
Expand All @@ -21,11 +23,13 @@ export class CargoTaskManager {
public constructor(
context: ExtensionContext,
configuration: Configuration,
cargoInvocationManager: CargoInvocationManager,
currentWorkingDirectoryManager: CurrentWorkingDirectoryManager,
logger: ChildLogger,
stopCommandName: string
) {
this._configuration = configuration;
this._cargoInvocationManager = cargoInvocationManager;
this._currentWorkingDirectoryManager = currentWorkingDirectoryManager;
this._logger = logger;
this._outputChannelTaskManager = new OutputChannelTaskManager(
Expand Down Expand Up @@ -155,9 +159,10 @@ export class CargoTaskManager {
workingDirectory
));
}
const cargoPath = this._configuration.getCargoPath();
const { executable, args: preCommandArgs } = this._cargoInvocationManager.getExecutableAndArgs();
this.startTask(
cargoPath,
executable,
preCommandArgs,
command,
args,
workingDirectory,
Expand Down Expand Up @@ -241,6 +246,7 @@ export class CargoTaskManager {

private async startTask(
executable: string,
preCommandArgs: string[],
command: string,
args: string[],
cwd: string,
Expand All @@ -249,7 +255,13 @@ export class CargoTaskManager {
shouldParseOutput: boolean
): Promise<void> {
if (shouldExecuteCargoCommandInTerminal) {
await this._terminalTaskManager.startTask(executable, command, args, cwd);
await this._terminalTaskManager.startTask(
executable,
preCommandArgs,
command,
args,
cwd
);
} else {
// The output channel should be shown only if the user wants that.
// The only exception is checking invoked on saving the active document - in that case the output channel shouldn't be shown.
Expand All @@ -258,6 +270,7 @@ export class CargoTaskManager {
!(command === 'check' && reason === CommandInvocationReason.ActionOnSave);
await this._outputChannelTaskManager.startTask(
executable,
preCommandArgs,
command,
args,
cwd,
Expand Down
5 changes: 3 additions & 2 deletions src/components/cargo/output_channel_task_manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export class OutputChannelTaskManager {

public async startTask(
executable: string,
preCommandArgs: string[],
command: string,
args: string[],
cwd: string,
Expand All @@ -54,7 +55,7 @@ export class OutputChannelTaskManager {
}
}
prependArgsWithMessageFormatIfRequired();
args = [command].concat(args);
args = preCommandArgs.concat(command, ...args);
this.runningTask = new Task(
this.configuration,
this.logger.createChildLogger('Task: '),
Expand All @@ -65,7 +66,7 @@ export class OutputChannelTaskManager {
this.runningTask.setStarted(() => {
this.channel.clear();
this.channel.append(`Working directory: ${cwd}\n`);
this.channel.append(`Started cargo ${args.join(' ')}\n\n`);
this.channel.append(`Started ${executable} ${args.join(' ')}\n\n`);
this.diagnostics.clear();
});
this.runningTask.setLineReceivedInStdout(line => {
Expand Down
10 changes: 8 additions & 2 deletions src/components/cargo/terminal_task_manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,14 @@ export class TerminalTaskManager {
}
}

public async startTask(executable: string, command: string, args: string[], cwd: string): Promise<void> {
args = [command].concat(args);
public async startTask(
executable: string,
preCommandArgs: string[],
command: string,
args: string[],
cwd: string
): Promise<void> {
args = preCommandArgs.concat(command, ...args);
const terminal = window.createTerminal('Cargo Task');
this._runningTerminal = terminal;
const shell = parseShell(workspace.getConfiguration('terminal')['integrated']['shell']['windows']);
Expand Down
4 changes: 2 additions & 2 deletions src/components/configuration/Configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,8 @@ export class Configuration {
return Configuration.getPathConfigParameter('cargoCwd');
}

public getCargoPath(): string {
return Configuration.getPathConfigParameterOrDefault('cargoPath', 'cargo');
public getCargoPath(): string | undefined {
return Configuration.getPathConfigParameter('cargoPath');
}

public getCargoHomePath(): string | undefined {
Expand Down
15 changes: 8 additions & 7 deletions src/components/configuration/Rustup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@ export class Rustup {
*/
private _userToolchain: Toolchain | undefined;


/**
* Returns the executable of Rustup
*/
public static getRustupExecutable(): string {
return 'rustup';
}

/**
* Creates a new instance of the class.
* The method is asynchronous because it tries to find Rust's source code
Expand Down Expand Up @@ -373,13 +381,6 @@ export class Rustup {
return !componentInstalled;
}

/**
* Returns the executable of Rustup
*/
private static getRustupExecutable(): string {
return 'rustup';
}

/**
* Returns the name of the component rust-analysis
*/
Expand Down
12 changes: 10 additions & 2 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { Manager as LanguageClientManager } from './components/language_client/m
import { LoggingManager } from './components/logging/logging_manager';
import { ChildLogger } from './components/logging/child_logger';
import { RootLogger } from './components/logging/root_logger';
import { CargoInvocationManager } from './CargoInvocationManager';
import { LegacyModeManager } from './legacy_mode_manager';
import * as OutputChannelProcess from './OutputChannelProcess';
import { Toolchain } from './Toolchain';
Expand Down Expand Up @@ -85,19 +86,22 @@ class RlsMode {
private _configuration: Configuration;
private _rlsConfiguration: RlsConfiguration;
private _rustup: Rustup | undefined;
private _cargoInvocationManager: CargoInvocationManager;
private _logger: ChildLogger;
private _extensionContext: ExtensionContext;

public constructor(
configuration: Configuration,
rlsConfiguration: RlsConfiguration,
rustup: Rustup | undefined,
cargoInvocationManager: CargoInvocationManager,
logger: ChildLogger,
extensionContext: ExtensionContext
) {
this._configuration = configuration;
this._rlsConfiguration = rlsConfiguration;
this._rustup = rustup;
this._cargoInvocationManager = cargoInvocationManager;
this._logger = logger;
this._extensionContext = extensionContext;
}
Expand Down Expand Up @@ -240,9 +244,10 @@ class RlsMode {
switch (choice) {
case installRustfmtChoice:
logger.debug('User decided to install rustfmt');
const { executable, args } = this._cargoInvocationManager.getExecutableAndArgs();
const result = await OutputChannelProcess.create(
this._configuration.getCargoPath(),
['install', 'rustfmt'],
executable,
[...args, 'install', 'rustfmt'],
undefined,
'Installing rustfmt'
);
Expand Down Expand Up @@ -399,6 +404,7 @@ export async function activate(ctx: ExtensionContext): Promise<void> {
}
const rustSource = await RustSource.create(rustup);
const configuration = new Configuration(logger.createChildLogger('Configuration: '));
const cargoInvocationManager = new CargoInvocationManager(configuration, rustup);
const rlsConfiguration = await RlsConfiguration.create(rustup, rustSource);
if (configuration.mode() === undefined) {
// The current configuration does not contain any specified mode and hence we should try to
Expand All @@ -419,6 +425,7 @@ export async function activate(ctx: ExtensionContext): Promise<void> {
const cargoManager = new CargoManager(
ctx,
configuration,
cargoInvocationManager,
currentWorkingDirectoryManager,
logger.createChildLogger('Cargo Manager: ')
);
Expand All @@ -428,6 +435,7 @@ export async function activate(ctx: ExtensionContext): Promise<void> {
configuration,
rlsConfiguration,
rustup,
cargoInvocationManager,
logger.createChildLogger('RlsMode: '),
ctx
);
Expand Down

0 comments on commit 767bdaf

Please sign in to comment.