Skip to content

Commit 70ca16c

Browse files
authored
feat: use .bashrc instead of .bash_profile (#113)
1 parent f51590e commit 70ca16c

File tree

4 files changed

+129
-12
lines changed

4 files changed

+129
-12
lines changed

lib/src/installer/completion_installation.dart

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -274,8 +274,24 @@ class CompletionInstallation {
274274
);
275275
}
276276

277-
String get _shellRCFilePath =>
278-
_resolveHome(configuration!.shellRCFile, environment);
277+
final _missingFiles = <String>[];
278+
String? __shellRCFilePath;
279+
String get _shellRCFilePath {
280+
String? firstPath;
281+
if (__shellRCFilePath == null) {
282+
for (final fileName in configuration!.shellRCFiles) {
283+
final filePath = _resolveHome(fileName, environment);
284+
firstPath ??= filePath;
285+
if (File(filePath).existsSync()) {
286+
__shellRCFilePath = filePath;
287+
return __shellRCFilePath!;
288+
}
289+
_missingFiles.add(filePath);
290+
}
291+
__shellRCFilePath = firstPath;
292+
}
293+
return __shellRCFilePath!;
294+
}
279295

280296
/// Write a source to the completion global script in the shell configuration
281297
/// file, which its location is described by the [configuration].
@@ -290,9 +306,17 @@ class CompletionInstallation {
290306

291307
final shellRCFile = File(_shellRCFilePath);
292308
if (!shellRCFile.existsSync()) {
309+
var message = '';
310+
if (_missingFiles.length > 1) {
311+
message =
312+
'No configuration files where found at '
313+
'\n ${_missingFiles.join('\n ')}';
314+
} else {
315+
message = 'No configuration file found at ${shellRCFile.path}';
316+
}
293317
throw CompletionInstallationException(
294318
rootCommand: rootCommand,
295-
message: 'No configuration file found at ${shellRCFile.path}',
319+
message: message,
296320
);
297321
}
298322

lib/src/installer/shell_completion_configuration.dart

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class ShellCompletionConfiguration {
2222
/// {@macro shell_completion_configuration}
2323
const ShellCompletionConfiguration._({
2424
required this.shell,
25-
required this.shellRCFile,
25+
required this.shellRCFiles,
2626
required this.sourceLineTemplate,
2727
required this.scriptTemplate,
2828
});
@@ -42,9 +42,12 @@ class ShellCompletionConfiguration {
4242
/// {@macro system_shell}
4343
final SystemShell shell;
4444

45-
/// The location of a config file that is run upon shell start.
45+
/// A preferential ordered list of locations of a config file that is run upon
46+
/// shell start. The list is to allow multiple options eg both .bash_profile
47+
/// and .bashrc. The first option will be tried first and and if the file
48+
/// doesn't exist the next one will be tried.
4649
/// Eg: .bash_profile or .zshrc
47-
final String shellRCFile;
50+
final List<String> shellRCFiles;
4851

4952
/// Generates a line to sources of a script file.
5053
final SourceStringTemplate sourceLineTemplate;
@@ -61,7 +64,7 @@ class ShellCompletionConfiguration {
6164
@visibleForTesting
6265
final zshConfiguration = ShellCompletionConfiguration._(
6366
shell: SystemShell.zsh,
64-
shellRCFile: '~/.zshrc',
67+
shellRCFiles: const ['~/.zshrc'],
6568
sourceLineTemplate: (String scriptPath) {
6669
return '[[ -f $scriptPath ]] && . $scriptPath || true';
6770
},
@@ -97,7 +100,7 @@ fi
97100
@visibleForTesting
98101
final bashConfiguration = ShellCompletionConfiguration._(
99102
shell: SystemShell.bash,
100-
shellRCFile: '~/.bash_profile',
103+
shellRCFiles: const ['~/.bashrc', '~/.bash_profile'],
101104
sourceLineTemplate: (String scriptPath) {
102105
return '[ -f $scriptPath ] && . $scriptPath || true';
103106
},

test/src/installer/completion_installation_test.dart

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,92 @@ void main() {
727727
);
728728
},
729729
);
730+
731+
test(
732+
'installing completion for .bashrc',
733+
() {
734+
final bashInstallation = CompletionInstallation(
735+
logger: logger,
736+
isWindows: false,
737+
environment: {
738+
'HOME': tempDir.path,
739+
},
740+
configuration: bashConfiguration,
741+
);
742+
743+
final configDir = bashInstallation.completionConfigDir;
744+
745+
final bashProfile = File(path.join(tempDir.path, '.bash_profile'))
746+
..createSync();
747+
748+
bashInstallation.install('very_good');
749+
750+
// Different format needed for matching cli output
751+
expect(bashProfile.readAsStringSync(), '''
752+
\n## [Completion]
753+
## Completion scripts setup. Remove the following line to uninstall
754+
[ -f ${configDir.path}/bash-config.bash ] && . ${configDir.path}/bash-config.bash || true
755+
## [/Completion]
756+
757+
''');
758+
},
759+
);
760+
761+
test(
762+
'installing completion for .bash_profile',
763+
() {
764+
final bashInstallation = CompletionInstallation(
765+
logger: logger,
766+
isWindows: false,
767+
environment: {
768+
'HOME': tempDir.path,
769+
},
770+
configuration: bashConfiguration,
771+
);
772+
773+
final configDir = bashInstallation.completionConfigDir;
774+
775+
final bashRc = File(path.join(tempDir.path, '.bashrc'))..createSync();
776+
777+
bashInstallation.install('very_good');
778+
779+
// Different format needed for matching cli output
780+
expect(bashRc.readAsStringSync(), '''
781+
\n## [Completion]
782+
## Completion scripts setup. Remove the following line to uninstall
783+
[ -f ${configDir.path}/bash-config.bash ] && . ${configDir.path}/bash-config.bash || true
784+
## [/Completion]
785+
786+
''');
787+
},
788+
);
789+
790+
test(
791+
'missing .bashrc and .bash_profile',
792+
() {
793+
final bashInstallation = CompletionInstallation(
794+
logger: logger,
795+
isWindows: false,
796+
environment: {
797+
'HOME': tempDir.path,
798+
},
799+
configuration: bashConfiguration,
800+
);
801+
802+
expect(
803+
() => bashInstallation.install('very_good'),
804+
throwsA(
805+
isA<CompletionInstallationException>().having(
806+
(e) => e.message,
807+
'message',
808+
'No configuration files where found at '
809+
'\n ${path.join(tempDir.path, '.bashrc')}'
810+
'\n ${path.join(tempDir.path, '.bash_profile')}',
811+
),
812+
),
813+
);
814+
},
815+
);
730816
});
731817

732818
group('uninstall', () {

test/src/installer/shell_completion_configuration_test.dart

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ void main() {
1616
expect(zshConfiguration.shell, SystemShell.zsh);
1717
});
1818

19-
test('shellRCFile', () {
20-
expect(zshConfiguration.shellRCFile, '~/.zshrc');
19+
test('shellRCFiles', () {
20+
expect(zshConfiguration.shellRCFiles.first, '~/.zshrc');
2121
});
2222

2323
test('sourceStringTemplate', () {
@@ -71,8 +71,12 @@ fi
7171
expect(bashConfiguration.shell, SystemShell.bash);
7272
});
7373

74-
test('shellRCFile', () {
75-
expect(bashConfiguration.shellRCFile, '~/.bash_profile');
74+
test('shellRCFiles first', () {
75+
expect(bashConfiguration.shellRCFiles.first, '~/.bashrc');
76+
});
77+
78+
test('shellRCFiles last', () {
79+
expect(bashConfiguration.shellRCFiles.last, '~/.bash_profile');
7680
});
7781

7882
test('sourceStringTemplate', () {

0 commit comments

Comments
 (0)