pax_global_header00006660000000000000000000000064143255742470014527gustar00rootroot0000000000000052 comment=893d726776bdec73648739627998c454ed63f886 raku-file-which-1.0.4/000077500000000000000000000000001432557424700145105ustar00rootroot00000000000000raku-file-which-1.0.4/.github/000077500000000000000000000000001432557424700160505ustar00rootroot00000000000000raku-file-which-1.0.4/.github/workflows/000077500000000000000000000000001432557424700201055ustar00rootroot00000000000000raku-file-which-1.0.4/.github/workflows/test.yml000066400000000000000000000012351432557424700216100ustar00rootroot00000000000000name: test on: push: branches: - '*' tags-ignore: - '*' pull_request: jobs: raku: strategy: matrix: os: - ubuntu-latest - macOS-latest - windows-latest raku-version: - 'latest' runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v3 - uses: Raku/setup-raku@v1 with: raku-version: ${{ matrix.raku-version }} - name: Install Dependencies run: zef install --/test --test-depends --deps-only . - name: Install App::Prove6 run: zef install --/test App::Prove6 - name: Run Tests run: prove6 -l t raku-file-which-1.0.4/.gitignore000066400000000000000000000000171432557424700164760ustar00rootroot00000000000000.precomp .idea raku-file-which-1.0.4/LICENSE000066400000000000000000000020771432557424700155230ustar00rootroot00000000000000The MIT License (MIT) Copyright (c) 2016-2017 Ahmad M. Zawawi Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. raku-file-which-1.0.4/META6.json000066400000000000000000000013241432557424700162170ustar00rootroot00000000000000{ "name" : "File::Which", "license" : "MIT", "version" : "1.0.4", "perl" : "6.c", "description" : "Cross platform Raku executable path finder (aka which on UNIX)", "depends" : [ { "name" : { "by-distro.name" : { "mswin32" : "Win32::Registry", "" : "" } } } ], "test-depends" : [ "Test" ], "provides" : { "File::Which" : "lib/File/Which.rakumod", "File::Which::MacOSX" : "lib/File/Which/MacOSX.rakumod", "File::Which::Unix" : "lib/File/Which/Unix.rakumod", "File::Which::Win32" : "lib/File/Which/Win32.rakumod" }, "source-url" : "git://github.com/azawawi/raku-file-which.git" } raku-file-which-1.0.4/README.md000066400000000000000000000033431432557424700157720ustar00rootroot00000000000000# File::Which [![Actions Status](https://github.com/azawawi/raku-file-which/workflows/test/badge.svg)](https://github.com/azawawi/raku-file-which/actions) This is a Raku Object-oriented port of [File::Which (CPAN)]( https://metacpan.org/pod/File::Which). File::Which finds the full or relative paths to an executable program on the system. This is normally the function of which utility which is typically implemented as either a program or a built in shell command. On some unfortunate platforms, such as Microsoft Windows it is not provided as part of the core operating system. This module provides a consistent API to this functionality regardless of the underlying platform. ```Raku use File::Which :whence; # All raku executables in PATH say which('raku', :all); # First executable in PATH say which('raku'); # Same as which('raku') say whence('raku'); ``` ## Installation To install it using zef (a module management tool bundled with Rakudo Star): ``` $ zef install File::Which ``` ## Testing - To run tests: ``` $ prove --ext .rakutest -ve "raku -I." ``` - To run all tests including author tests (Please make sure [Test::Meta](https://github.com/jonathanstowe/Test-META) is installed): ``` $ zef install Test::META $ AUTHOR_TESTING=1 prove --ext .rakutest -ve "raku -I." ``` ## Author Raku port: - Ahmad M. Zawawi, azawawi on #raku, https://github.com/azawawi/ - Nick Logan, ugexe on #raku, https://github.com/ugexe - Steve Dondley, sdondley on #raku, https://github.com/sdondley A bit of tests: - Altai-man, sena_kun on libera, https://github.com/Altai-man/ Perl 5 version: - Author: Per Einar Ellefsen - Maintainers: - Adam Kennedy - Graham Ollis ## License MIT License raku-file-which-1.0.4/examples/000077500000000000000000000000001432557424700163265ustar00rootroot00000000000000raku-file-which-1.0.4/examples/01-which.raku000077500000000000000000000002651432557424700205400ustar00rootroot00000000000000#!/usr/bin/env raku use v6; use File::Which; # All perl executables in PATH say which('raku', :all); say which('zzzaaa123', :all); # First executable in PATH say which('raku'); raku-file-which-1.0.4/examples/02-whence.raku000077500000000000000000000002401432557424700207010ustar00rootroot00000000000000#!/usr/bin/env raku use v6; use File::Which :whence; # All perl executables in PATH say whence('raku', :all); # First executable in PATH say whence('raku'); raku-file-which-1.0.4/lib/000077500000000000000000000000001432557424700152565ustar00rootroot00000000000000raku-file-which-1.0.4/lib/File/000077500000000000000000000000001432557424700161355ustar00rootroot00000000000000raku-file-which-1.0.4/lib/File/Which.rakumod000066400000000000000000000031021432557424700205570ustar00rootroot00000000000000 use v6; use File::Which::Unix; use File::Which::MacOSX; use File::Which::Win32; unit module File::Which; # Current which platform-specific implementation BEGIN my $platform = $*DISTRO.is-win ?? File::Which::Win32.new !! $*DISTRO.name.starts-with('macos') ?? File::Which::MacOSX.new !! File::Which::Unix.new; sub which(Str $exec, Bool :$all = False) is export { return $platform.which($exec, :$all); } sub whence(Str $exec, Bool :$all = False) is export(:all, :whence) { return which($exec, :$all); } =begin pod =head1 NAME File::Which - Cross platform Raku executable path finder (aka which on UNIX) =head1 SYNOPSIS use File::Which :whence; # All raku executables in PATH say which('raku', :all); # First executable in PATH say which('raku'); # Same as which('raku') say whence('raku'); =head1 DESCRIPTION This is a Raku Object-oriented port of L. File::Which finds the full or relative paths to an executable program on the system. This is normally the function of which utility which is typically implemented as either a program or a built in shell command. On some unfortunate platforms, such as Microsoft Windows it is not provided as part of the core operating system. This module provides a consistent API to this functionality regardless of the underlying platform. =head1 AUTHOR Ahmad M. Zawawi =head1 COPYRIGHT AND LICENSE Copyright 2016 Ahmad M. Zawawi This library is free software; you can redistribute it and/or modify it under the MIT License =end pod raku-file-which-1.0.4/lib/File/Which/000077500000000000000000000000001432557424700171775ustar00rootroot00000000000000raku-file-which-1.0.4/lib/File/Which/MacOSX.rakumod000066400000000000000000000031521432557424700216560ustar00rootroot00000000000000 use v6; unit class File::Which::MacOSX; method which(Str $exec, Bool :$all = False) { return Any unless $exec; fail("This only works on Mac OS X") unless $*DISTRO.name.starts-with('macos'); my @results; # check for aliases first my @aliases = %*ENV:exists ?? %*ENV.split( ',' ) !! (); for @aliases -> $alias { # This has not been tested!! # PPT which says MPW-Perl cannot resolve `Alias $alias`, # let's just hope it's fixed if $alias.lc eq $exec.lc { chomp(my $file = qx); last unless $file; # if it failed, just go on the normal way return $file unless $all; @results.push( $file ); last; } } my @path = flat( $*SPEC.path ); for @path.map({ $*SPEC.catfile($_, $exec) }) -> $file { # Ignore possibly -x directories next if $file.IO ~~ :d; if # Executable, normal case $file.IO ~~ :x # MacOS doesn't mark as executable so we check -e || $file.IO ~~ :e { if $all { @results.push( $file ); } else { return $file; } } } return @results.unique if $all; return Any; } =begin pod =head1 NAME File::Which::MacOSX - MacOSX which implementation =head1 SYNOPSIS use File::Which::MacOSX; my $o = File::Which::MacOSX.new; say $o.which('raku'); =head1 DESCRIPTION Implements the which method under the Mac OS X platform. =head1 AUTHOR Ahmad M. Zawawi =head1 COPYRIGHT AND LICENSE Copyright 2016 Ahmad M. Zawawi This library is free software; you can redistribute it and/or modify it under the MIT License =end pod raku-file-which-1.0.4/lib/File/Which/Unix.rakumod000066400000000000000000000020551432557424700215100ustar00rootroot00000000000000 use v6; unit class File::Which::Unix; method which(Str $exec, Bool :$all = False) { return Any unless $exec; my @results; return $exec if $exec ~~ /\// && $exec.IO ~~ :f && $exec.IO ~~ :x; my @path = flat( $*SPEC.path ); my @PATHEXT = ''; for @path.map({ $*SPEC.catfile($_, $exec) }) -> $file { # Ignore possibly -x directories next if $file.IO ~~ :d; # Executable, normal case if $file.IO ~~ :x { if $all { @results.push( $file ); } else { return $file; } } } return @results.unique if $all; return Any; } =begin pod =head1 NAME File::Which::Unix - Linux/Unix which implementation =head1 SYNOPSIS use File::Which::Unix; my $o = File::Which::Unix.new; say $o.which('raku'); =head1 DESCRIPTION Implements the which method under UNIX-based platforms =head1 AUTHOR Ahmad M. Zawawi =head1 COPYRIGHT AND LICENSE Copyright 2016 Ahmad M. Zawawi This library is free software; you can redistribute it and/or modify it under the MIT License =end pod raku-file-which-1.0.4/lib/File/Which/Win32.rakumod000066400000000000000000000104421432557424700214660ustar00rootroot00000000000000 use v6; unit class File::Which::Win32; use NativeCall; try require Win32::Registry qw<&RegGetValueW &key-exists &open-key &close-key &wstr>; method which(Str $exec, Bool :$all = False) { return Any unless $exec; fail("This only works on Windows") unless $*DISTRO.is-win; my @PATHEXT = ''; # WinNT. PATHEXT might be set on Cygwin, but not used. if ( %*ENV.defined ) { @PATHEXT = flat( %*ENV.split(';') ); } else { # Win9X or other: doesn't have PATHEXT, so needs hardcoded. @PATHEXT.push( <.com .exe .bat> ); } my @results; my @path = flat( $*SPEC.path ); for @path.map({ $*SPEC.catfile($_, $exec) }) -> $base { for @PATHEXT -> $ext { my $file = $base ~ $ext; # Ignore possibly -x directories next if $file.IO ~~ :d; # Windows systems don't pass -x on # non-exe/bat/com files. so we check -e. # However, we don't want to pass -e on files # that aren't in PATHEXT, like README. if @PATHEXT[1..@PATHEXT.elems - 1].grep({ $file.match(/ $_ $ /, :i) }) && $file.IO ~~ :e { if $all { @results.push( $file ); } else { return $file; } } } } return @results.unique if $all && @results; # Fallback to using win32 API to find executable location return self.which-win32-api($exec, @PATHEXT) || Any; } # # Searches for and retrieves a file or protocol association-related string from the registry. # # https://msdn.microsoft.com/en-us/library/windows/desktop/bb773471%28v=vs.85%29.aspx # https://source.winehq.org/WineAPI/AssocQueryStringA.html # sub AssocQueryStringA(uint32 $flags, uint32 $str, Str $assoc, uint32 $extra, CArray[uint8] $path, CArray[uint32] $out) returns uint32 is native('shlwapi') { * }; # This finds the executable path using the registry instead of the PATH # environment variable method which-win32-api(Str $exec, @paths) { constant ASSOCF_OPEN_BYEXENAME = 0x2; constant ASSOCSTR_EXECUTABLE = 0x2; constant MAX_PATH = 260; constant S_OK = 0; my $path = CArray[uint8].new; $path[$_] = 0 for 0..MAX_PATH - 1; my $size = CArray[uint32].new; $size[0] = MAX_PATH; my $hresult = &::("AssocQueryStringA")(ASSOCF_OPEN_BYEXENAME, ASSOCSTR_EXECUTABLE, $exec, 0, $path, $size); # Return nothing if it fails if $hresult == S_OK { # Compose path from CArray using the size DWORD (uint32) # Ignore null marker from null-terminated string my $exe-path = ''; for 0 .. $size[0] - 2 { $exe-path ~= chr($path[$_]); } # Return the executable path string if found return $exe-path if $exe-path; } # search registry for apps my $has-extension = @paths.first({ $exec.ends-with($_, :i)}).so; my @keys-to-check; @keys-to-check = $has-extension ?? $exec !! @paths.map: { $exec ~ $_ } ; my @hives-to-check = ; my $key = 'SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths'; for @keys-to-check -> $k { for @hives-to-check -> $h { my $full-key = $h ~ "\\$key\\$k"; if &::("key-exists")($full-key) { return get-path $full-key; } } } } sub get-path(Str:D $key) { my $k = &::("open-key")($key); my int32 $b = 600; my $value = CArray[uint16].new; $value[$_] = 0 for ^$b; my $blah = &::("RegGetValueW")($k, &::("wstr")(''), &::("wstr")(''), 0x0000ffff, 0, $value, $b); my $name = ''; $value[$b] = 0; if !$blah { for ^$b { last if !$value[$_].so; $name ~= chr($value[$_]); } } &::("close-key")($k); # Sometimes, the path is surrounded by quotes for some reason. Remove them. $name.=trans( '"' => ''); return $name; } =begin pod =head1 NAME File::Which::Win32 - Win32 which implementation =head1 SYNOPSIS use File::Which::Win32; my $o = File::Which::Win32.new; say $o.which('raku'); =head1 DESCRIPTION Implements the which method under win32-based platforms =head1 METHODS =head2 which Returns the full executable path string =head1 AUTHOR Ahmad M. Zawawi =head1 COPYRIGHT AND LICENSE Copyright 2016 Ahmad M. Zawawi This library is free software; you can redistribute it and/or modify it under the MIT License =end pod raku-file-which-1.0.4/t/000077500000000000000000000000001432557424700147535ustar00rootroot00000000000000raku-file-which-1.0.4/t/00-load.rakutest000066400000000000000000000002251432557424700176720ustar00rootroot00000000000000use Test; plan 4; use-ok("File::Which::MacOSX"); use-ok("File::Which::Unix"); use-ok("File::Which::Win32"); use-ok("File::Which"); done-testing(); raku-file-which-1.0.4/t/01-which.rakutest000066400000000000000000000005471432557424700200650ustar00rootroot00000000000000use v6; use Test; plan 4; use File::Which; ok 1, "'use File::Which' worked!"; my $raku = which('raku'); diag "Found raku at '$raku'"; ok $raku.defined, "raku is found"; ok $raku.IO ~~ :e, "raku file exists"; if $*DISTRO.is-win { skip("Windows does not set an executable file permission", 1); } else { ok $raku.IO ~~ :x, "raku and is an executable"; } raku-file-which-1.0.4/t/02-win32.rakutest000066400000000000000000000005671432557424700177300ustar00rootroot00000000000000use v6; use Test; use File::Which; my @execs = ('calc', 'cmd', 'explorer', 'notepad', 'wordpad'); plan @execs.elems * 2; unless $*DISTRO.is-win { skip-rest("Windows-only tests"); exit; } for @execs -> $exec { my Str $path = which($exec); ok $path.defined, sprintf("Found '%s' at '%s'", $exec, $path); ok $path.IO ~~ :e, sprintf("Path '%s' is found", $path); } raku-file-which-1.0.4/t/03-export.rakutest000066400000000000000000000006051432557424700203010ustar00rootroot00000000000000use v6; use Test; plan 4; use File::Which :whence; ok 1, "'use File::Which :whence' worked!"; my $raku = whence('raku'); diag "Found raku at '$raku' using whence"; ok $raku.defined, "raku is found"; ok $raku.IO ~~ :e, "raku file exists"; if $*DISTRO.is-win { skip("Windows does not set an executable file permission", 1); } else { ok $raku.IO ~~ :x, "raku and is an executable"; } raku-file-which-1.0.4/t/04-simple.rakutest000066400000000000000000000020251432557424700202500ustar00rootroot00000000000000use v6; use Test; use File::Which; plan *; is which(''), Any, 'Null-length false result'; is which('non_existent_very_unlinkely_thingy_executable'), Any, 'Positive length false result'; my $test-bin = $*SPEC.catdir('t', 'corpus', $*DISTRO.is-win ?? 'test-bin-win' !! 'test-bin-unix'); ok $test-bin.IO.e, 'Found test-bin'; if $*DISTRO.is-win { %*ENV ~= ";$test-bin"; } else { %*ENV ~= ":$test-bin"; } unless (File::Which::MacOSX || File::Which::Win32) { my $test3 = $*SPEC.catfile($test-bin, 'test3'); chmod 0o755, $test3; } if $*KERNEL ~~ 'linux' { is which('test3'), $*SPEC.catfile($test-bin, 'test3'), 'Check test3 for Unix'; } if $*DISTRO.is-win { is which('test1').lc, $*SPEC.catfile($test-bin, "test1.exe"), 'Looking for test1.exe'; is which('test2').lc, $*SPEC.catfile($test-bin, "test2.bat"), 'Looking for test2.bat'; is which('test3'), Any, 'test3 returns Any'; chdir($test-bin); is which('test1').lc, $*SPEC.catfile($*SPEC.curdir, 'test1.exe'), 'Looking for test1.exe in curdir'; } done-testing; raku-file-which-1.0.4/t/05-all.rakutest000066400000000000000000000014641432557424700175360ustar00rootroot00000000000000use v6; use Test; use File::Which; plan *; my $test-bin = $*SPEC.catdir('t', 'corpus', $*DISTRO.is-win ?? 'test-bin-win' !! 'test-bin-unix'); ok $test-bin.IO.e, 'Found test-bin'; if $*DISTRO.is-win { %*ENV ~= ";$test-bin"; } else { %*ENV ~= ":$test-bin"; } if $*KERNEL ~~ 'linux' { # On linux we need to have an execution bit. my $all = $*SPEC.catfile($test-bin, 'all'); chmod 0o755, $all; } my @result = which('all'); like @result[0], rx/all/, 'Found all'; ok @result.defined, 'Found at least one result'; if $*KERNEL ~~ 'linux' { # On linux we need to have an execution bit. my $zero = $*SPEC.catfile($test-bin, '0'); chmod 0o755, $zero; } my $zero = which '0'; ok $zero.defined, 'Zero is defined'; my $empty-string = which ''; is $empty-string, Any, 'Empty string'; done-testing; raku-file-which-1.0.4/t/99-author-meta.rakutest000066400000000000000000000002651432557424700212270ustar00rootroot00000000000000 use v6; use Test; plan 1; if ?%*ENV { require Test::META <&meta-ok>; meta-ok; done-testing; } else { skip-rest "Skipping author test"; exit; } raku-file-which-1.0.4/t/corpus/000077500000000000000000000000001432557424700162665ustar00rootroot00000000000000raku-file-which-1.0.4/t/corpus/test-bin-unix/000077500000000000000000000000001432557424700207745ustar00rootroot00000000000000raku-file-which-1.0.4/t/corpus/test-bin-unix/0000077500000000000000000000000001432557424700210470ustar00rootroot00000000000000raku-file-which-1.0.4/t/corpus/test-bin-unix/all000077500000000000000000000000001432557424700214600ustar00rootroot00000000000000raku-file-which-1.0.4/t/corpus/test-bin-unix/test3000077500000000000000000000001551432557424700217650ustar00rootroot00000000000000#!sh # ^ above shebang is needed for Cygwin echo "Just testing File::Which" echo "Nothing interesting here"raku-file-which-1.0.4/t/corpus/test-bin-win/000077500000000000000000000000001432557424700206065ustar00rootroot00000000000000raku-file-which-1.0.4/t/corpus/test-bin-win/0.exe000066400000000000000000000000001432557424700214360ustar00rootroot00000000000000raku-file-which-1.0.4/t/corpus/test-bin-win/all.bat000066400000000000000000000000001432557424700220340ustar00rootroot00000000000000raku-file-which-1.0.4/t/corpus/test-bin-win/all.exe000066400000000000000000000000001432557424700220470ustar00rootroot00000000000000raku-file-which-1.0.4/t/corpus/test-bin-win/test1.exe000066400000000000000000000000661432557424700223530ustar00rootroot00000000000000DO NOT RUN THIS PROGRAM IT IS ONLY TO TEST File::Whichraku-file-which-1.0.4/t/corpus/test-bin-win/test2.bat000066400000000000000000000001151432557424700223340ustar00rootroot00000000000000@echo off echo This is for testing File::Which echo Nothing interesting here!