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
15 changes: 10 additions & 5 deletions lib/src/unix_single_instance_base.dart
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,13 @@ enum ErrorMode {
// kDebugMode makes the application noisy.
Future<bool> unixSingleInstance(
List<String> arguments, void Function(List<dynamic> args) cmdProcessor,
{bool kDebugMode = false, ErrorMode errorMode = ErrorMode.exit}) async {
// TODO make a named arg
{bool kDebugMode = false,
ErrorMode errorMode = ErrorMode.exit,
String? customConfigPath,
String socketFilename = 'socket'}) async {
// Kept short because of mac os x sandboxing makes the name too long for unix sockets.
var socketFilename = 'socket';
// TODO make configurable so it can be per X, per User, or for the whole machine based on optional named args
var configPath = await _applicationConfigDirectory();
var configPath = customConfigPath ?? await _applicationConfigDirectory();
await Directory(configPath).create(recursive: true);
var socketFilepath = p.join(configPath, socketFilename);
final InternetAddress host =
Expand All @@ -63,7 +64,11 @@ Future<bool> unixSingleInstance(
print("Message sent");
print("Quiting");
}
exit(0);
if (errorMode == ErrorMode.returnFalse) {
return false;
} else {
exit(0);
}
} else {
if (kDebugMode) {
print("Deleting dead socket");
Expand Down
1 change: 1 addition & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ dependencies:
path_provider: '>=2.1.5 <4.0.0'

dev_dependencies:
test: ^1.30.0
lints: '>=6.0.0 <8.0.0'

# This package supports only Linux and macOS.
Expand Down
69 changes: 69 additions & 0 deletions test/unix_single_instance_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import 'dart:io';

import 'package:test/test.dart';
import 'package:unix_single_instance/unix_single_instance.dart';
import 'package:path/path.dart' as p;

void main() {
group('unixSingleInstance', () {
late Directory tempDir;

setUp(() async {
tempDir =
await Directory.systemTemp.createTemp('unix_single_instance_test_');
});

tearDown(() async {
if (await tempDir.exists()) {
await tempDir.delete(recursive: true);
}
});

test('First instance returns true', () async {
var isFirst = await unixSingleInstance(
['arg1', 'arg2'],
(args) {},
customConfigPath: tempDir.path,
errorMode: ErrorMode.returnFalse,
);

expect(isFirst, isTrue);

// Verify socket file was created
var socketFile = File(p.join(tempDir.path, 'socket'));
expect(await socketFile.exists(), isTrue);
});

test('Second instance returns false and sends args to first instance',
() async {
var receivedArgs = <dynamic>[];

// Start the "first instance"
var isFirst = await unixSingleInstance(
['first'],
(args) {
receivedArgs.addAll(args);
},
customConfigPath: tempDir.path,
errorMode: ErrorMode.returnFalse,
);

expect(isFirst, isTrue);

// Start the "second instance"
var isSecondFirst = await unixSingleInstance(
['second1', 'second2'],
(args) {},
customConfigPath: tempDir.path,
errorMode: ErrorMode.returnFalse,
);

expect(isSecondFirst, isFalse);

// Give it a moment for the socket to process
await Future.delayed(Duration(milliseconds: 100));

expect(receivedArgs, equals(['second1', 'second2']));
});
});
}
Loading