diff --git a/META6.json b/META6.json index e370616..c3f0ccb 100644 --- a/META6.json +++ b/META6.json @@ -6,6 +6,9 @@ "authors": [ "Nathan McCarty " ], + "depends": [ + "paths" + ], "provides": { "IUtils": "lib/IUtils.rakumod", "IUtils::IDEMode": "lib/IUtils/IDEMode.rakumod", @@ -14,5 +17,5 @@ "bin": { "iutils": "bin/iutils" }, - "resources": [ ], + "resources": [ ] } diff --git a/bin/iutils b/bin/iutils index 85452e8..9f99a00 100755 --- a/bin/iutils +++ b/bin/iutils @@ -3,12 +3,22 @@ use v6.d; use IUtils; use IUtils::Comments; -my $contents = "/home/nathan/Projects/Idris/structures/test/src/Main.idr".IO.slurp; - -say "\nTesting full flagged-expression:"; -say $contents ~~ &flagged-expression; -when $contents ~~ &flagged-expression { - say $; - say $; - say $; +#| Execute the tests in an idris project +multi MAIN( + "test", + Str $project-path?, #= Base directory of the project, defaults to $*CWD +) { + # CD into the project path if needed + chdir($project-path.IO.resolve: :completely) if $project-path; + # Scan for our packages + my @packages = scan-packages; + # Collect tests + my @tests; + for @packages -> $package { + # FIXME + say 'Finding tests for ', $package.ipkg.relative; + for $package.sources -> $source { + say 'Scanning for tests in ', $source; + } + } } diff --git a/lib/IUtils.rakumod b/lib/IUtils.rakumod index 2064e2d..d41c8f8 100644 --- a/lib/IUtils.rakumod +++ b/lib/IUtils.rakumod @@ -3,6 +3,42 @@ unit module IUtils; need IUtils::IDEMode; +use paths; + +#| Structure representing the root of what idris considers a package directory, +#| with the associated ipkg and source files. These can and will overlap within +#| the same directory. +class PackageInfo { + has IO::Path:D $.ipkg is required; + has IO::Path:D $.root is required; + has IO::Path:D @.sources is required; +} + +#| Scan a particular ipkg for its associated sources +sub scan-ipkg(IO::Path:D $ipkg --> PackageInfo:D) { + my $contents = $ipkg.slurp; + my $src-dir = + ($contents ~~ + / 'sourcedir' \h* '=' \h* + '"' $=[<-["]>*] '"' /) + // "src"; + + my IO::Path:D @sources = + paths($ipkg.parent.add($src-dir), :file(*.ends-with(".idr"))).map(*.IO); + PackageInfo.new(ipkg => $ipkg, root => $ipkg.parent, sources => @sources) +} + +# TODO: Add some parsing of pack.toml to locate test packages and associate them +# with their source ipkg + +#| Scan $*CWD to locate ipkgs and their associated sources +sub scan-packages(--> Array[PackageInfo:D]) is export { + my PackageInfo:D @ipkgs = + paths(:file(*.ends-with(".ipkg"))).map(*.IO.&scan-ipkg); + return @ipkgs; +} + + # Utility functions for pack #| Invoke a pack command @@ -24,17 +60,34 @@ sub pack-run(*@cmd) is export { #| Build a package with pack sub pack-build($pkg) is export { - pack-run 'build', $pkg; + pack-run 'build', $pkg } #| Test a package with pack sub pack-test($pkg) is export { - pack-run 'build', $pkg; + pack-run 'build', $pkg } #| Clean a package with pack sub pack-clean($pkg) is export { - pack-run 'clean', $pkg; + pack-run 'clean', $pkg +} + +# Utility functions for idris + +#| An error coming from the idris compiler +class IdrisError is Exception { + has Str $.out; + has Str $.err; + has Int $.exit-code; + has Str $.command; + + method message { + qq:to/END/; + Error running idris command: $.command + Command exited with $.exit-code + END + } } #| Invoke an idris command @@ -43,7 +96,10 @@ sub idris-run(*@cmd) is export { my $out = $proc.out.slurp(:close); my $err = $proc.err.slurp(:close); unless $proc { - ($out, $err) + IdrisError.new( + out => $out, err => $err, + exit-code => $proc.exitcode, command => @cmd.Str) + .throw; } return $out; } diff --git a/lib/IUtils/Comments.rakumod b/lib/IUtils/Comments.rakumod index 9274e64..edd7e9d 100644 --- a/lib/IUtils/Comments.rakumod +++ b/lib/IUtils/Comments.rakumod @@ -10,5 +10,5 @@ my token name { <[\w \-]>+ } my regex flagged-expression is export { <&comment-start> \h* \h* \V* \v [<&comment-start> \V* \v]* - $= \h+ \: \V* \v + \h+ \: \V* \v }