Skip to content

Commit be2c077

Browse files
authored
refactor: split shell detection from install (#15)
1 parent 452d1dd commit be2c077

9 files changed

Lines changed: 195 additions & 265 deletions

lib/install.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/// Contains the functions related to the installation file
22
library install;
33

4-
export 'src/install/install_completion.dart';
5-
export 'src/install/shell_completion_installation.dart';
4+
export 'src/install/completion_installation.dart';
5+
export 'src/system_shell.dart';

lib/src/install/shell_completion_installation.dart renamed to lib/src/install/completion_installation.dart

Lines changed: 12 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,55 +2,38 @@ import 'dart:io';
22

33
import 'package:cli_completion/src/exceptions.dart';
44
import 'package:cli_completion/src/install/shell_completion_configuration.dart';
5+
import 'package:cli_completion/src/system_shell.dart';
56
import 'package:mason_logger/mason_logger.dart';
67
import 'package:meta/meta.dart';
78
import 'package:path/path.dart' as path;
89

910
/// {@template shell_completion_installation}
1011
/// A description of a completion installation process for a specific shell.
1112
///
12-
/// Creation should be done via [ShellCompletionInstallation.fromCurrentShell].
13+
/// Creation should be done via [CompletionInstallation.fromSystemShell].
1314
/// {@endtemplate}
14-
class ShellCompletionInstallation {
15+
class CompletionInstallation {
1516
/// {@macro shell_completion_installation}
1617
@visibleForTesting
17-
ShellCompletionInstallation({
18+
CompletionInstallation({
1819
required this.configuration,
1920
required this.logger,
2021
required this.isWindows,
2122
required this.environment,
2223
});
2324

24-
/// Identify the current shell and from there, create a
25-
/// [ShellCompletionInstallation] with the proper
26-
/// [ShellCompletionConfiguration].
27-
static ShellCompletionInstallation? fromCurrentShell({
25+
/// Creates a [CompletionInstallation] given the current [SystemShell].
26+
factory CompletionInstallation.fromSystemShell({
27+
required SystemShell systemShell,
2828
required Logger logger,
2929
bool? isWindowsOverride,
3030
Map<String, String>? environmentOverride,
3131
}) {
32-
final environment = environmentOverride ?? Platform.environment;
3332
final isWindows = isWindowsOverride ?? Platform.isWindows;
33+
final environment = environmentOverride ?? Platform.environment;
3434

35-
// TODO(renancaraujo): this detects the "login shell", which can be
36-
// different from the actual shell.
37-
final envShell = environment['SHELL'];
38-
if (envShell == null || envShell.isEmpty) return null;
39-
40-
final basename = path.basename(envShell);
41-
42-
final ShellCompletionConfiguration configuration;
43-
if (basename == 'zsh') {
44-
configuration = zshConfiguration;
45-
} else if (RegExp(r'bash(\.exe)?$').hasMatch(basename)) {
46-
// on windows basename can be bash.exe
47-
configuration = bashConfiguration;
48-
} else {
49-
return null;
50-
}
51-
52-
return ShellCompletionInstallation(
53-
configuration: configuration,
35+
return CompletionInstallation(
36+
configuration: ShellCompletionConfiguration.fromSystemShell(systemShell),
5437
logger: logger,
5538
isWindows: isWindows,
5639
environment: environment,
@@ -85,7 +68,8 @@ class ShellCompletionInstallation {
8568
}
8669
}
8770

88-
/// Perform the installation process.
71+
/// Install completion configuration hooks for a [rootCommand] in the
72+
/// current shell.
8973
void install(String rootCommand) {
9074
logger.detail(
9175
'Installing completion for the command $rootCommand '

lib/src/install/install_completion.dart

Lines changed: 0 additions & 36 deletions
This file was deleted.

lib/src/install/shell_completion_configuration.dart

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import 'package:cli_completion/src/system_shell.dart';
12
import 'package:meta/meta.dart';
23

34
/// A type definition for functions that creates the content of a
@@ -16,14 +17,25 @@ typedef SourceStringTemplate = String Function(String scriptPath);
1617
@immutable
1718
class ShellCompletionConfiguration {
1819
/// {@macro shell_completion_configuration}
19-
@visibleForTesting
20-
const ShellCompletionConfiguration({
20+
const ShellCompletionConfiguration._({
2121
required this.name,
2222
required this.shellRCFile,
2323
required this.sourceLineTemplate,
2424
required this.scriptTemplate,
2525
});
2626

27+
/// Creates a [ShellCompletionConfiguration] given the current [SystemShell].
28+
factory ShellCompletionConfiguration.fromSystemShell(
29+
SystemShell systemShell,
30+
) {
31+
switch (systemShell) {
32+
case SystemShell.zsh:
33+
return zshConfiguration;
34+
case SystemShell.bash:
35+
return bashConfiguration;
36+
}
37+
}
38+
2739
/// A descriptive string to identify the shell among others.
2840
final String name;
2941

@@ -42,7 +54,8 @@ class ShellCompletionConfiguration {
4254
}
4355

4456
/// A [ShellCompletionConfiguration] for zsh.
45-
final zshConfiguration = ShellCompletionConfiguration(
57+
@visibleForTesting
58+
final zshConfiguration = ShellCompletionConfiguration._(
4659
name: 'zsh',
4760
shellRCFile: '~/.zshrc',
4861
sourceLineTemplate: (String scriptPath) {
@@ -70,7 +83,8 @@ fi
7083
);
7184

7285
/// A [ShellCompletionConfiguration] for bash.
73-
final bashConfiguration = ShellCompletionConfiguration(
86+
@visibleForTesting
87+
final bashConfiguration = ShellCompletionConfiguration._(
7488
name: 'bash',
7589
shellRCFile: '~/.bash_profile',
7690
sourceLineTemplate: (String scriptPath) {

lib/src/system_shell.dart

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import 'dart:io';
2+
3+
import 'package:path/path.dart' as path;
4+
5+
/// The Supported shells
6+
enum SystemShell {
7+
/// The Zsh shell: https://www.zsh.org/
8+
zsh,
9+
10+
/// GNU Bash shell: https://www.gnu.org/software/bash/
11+
bash;
12+
13+
/// Identifies the current shell.
14+
static SystemShell? current({
15+
Map<String, String>? environmentOverride,
16+
}) {
17+
final environment = environmentOverride ?? Platform.environment;
18+
19+
// TODO(renancaraujo): this detects the "login shell", which can be
20+
// different from the actual shell.
21+
final envShell = environment['SHELL'];
22+
if (envShell == null || envShell.isEmpty) return null;
23+
24+
final basename = path.basename(envShell);
25+
26+
if (basename == 'zsh') {
27+
return SystemShell.zsh;
28+
} else if (RegExp(r'bash(\.exe)?$').hasMatch(basename)) {
29+
// on windows basename can be bash.exe
30+
return SystemShell.bash;
31+
}
32+
33+
return null;
34+
}
35+
}

0 commit comments

Comments
 (0)