onepub-dev / dcli

An extensive library and tooling for building console/cli applications and scripts using the Dart programming language.
245 stars 28 forks source link

Enhanced Windows exe search #148

Closed bsutton closed 3 years ago

bsutton commented 3 years ago

One of the objectives of DCli is to make cross platform scripting easy.

One issues between linux and windows is that windows uses extension for exe name.

on linux ls is simple 'ls' on windows this would be 'ls.exe'

Windows also has a mechanism that allows the user to just type 'ls' it then finds 'ls.exe' and launches it.

Windows does this same process for both '.exe' and '.bat' file extensions.

These extension difference prove problematic when writing a single app to run on linux and windows.

Dart somewhat exacerbates this problem in that when you globally activate an app it has a .bat extension. For example 'pub global activate dcli' ends up with dcli.bat in the pub cache bin. If you then compile dcli with dcli you end up with a dcli.exe.

Ideally this whole extension things should be transparent as it is when running from a windows command shell.

This proposal is to enhance the dcli 'which' and 'run/start' etc commands to do an search for different extensions when run on windows. For example if you ran:

which('dcli') 

The which command on windows would search the path for dcli, dcli.exe and dcli.bat.

If you ran a command:

'dcli'.run;

Then the run command would search for dcli, dcli.exe and dcli.bat. Note: I discovered that on windows the docker command is just docker not docker.exe.

Of course this does raise the question about whether we should do similar on linux. e.g. when you run dcli we search for dcli and dcli.sh

I think the linux situation is different as there is no expectation on linux that running dcli would result in the os running dcli.sh.

If we were to do the above on windows then we should determine what mechanism windows uses to determine the list of extensions to match (i.e. does it match on .ps1 extensions).

The which command would have the following signature:

which(String exePath, {bool extensionSearch = true});

The extensionSearch would allow the user to control whether we check for alternate extensions. If the exePath had an extension then we would also suppress the search. On linux the extensionSearch option would have no affect.

When running an exe the user would need to use the start command to disable the search. So the start command function would be:

start(String commandAndArgs, {bool extensionSearch = true, ...})

With the same rules applied as per the which.

The above changes would then allow the following code to work on linux and windows:


   if (which('dcli').notfound)
  {
      DartSdk().globalActivate('dcli');
  }
  'dcli --help'.run;
}

We should probably look at python and ruby to see how this has been solved.
bsutton commented 3 years ago

This work has been completed and marked as experimental and is available in the current release.

I will close this out for now.