diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9c0e24a46..e22932771 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -254,7 +254,7 @@ jobs: cmd //c ir.cmd -e "puts RUBY_ENGINE" # irb loads reline, which on Windows looks up Win32 functions through Fiddle by # their names without the A suffix; 4.0.2 died there, at a pipe as at a console. - printf 'puts 6 * 7\n' | cmd //c irb.cmd | grep -x 42 + printf 'puts 6 * 7\n' | cmd //c iirb.cmd | grep -x 42 cmd //c ironruby.cmd Util/windows-desktop-check.rb rubyw="Src/Console/bin/Debug/$TFM/ironrubyw.exe" ruby subsystem.rb "$rubyw" @@ -263,7 +263,7 @@ jobs: ./ironruby smoke.rb ./ironruby names.rb ./ir.sh -e 'puts RUBY_ENGINE' - printf 'puts 6 * 7\n' | ./irb.sh | grep -x 42 + printf 'puts 6 * 7\n' | ./iirb.sh | grep -x 42 fi # IO#write_nonblock on a socket claims only what the kernel took (#14). On Linux the diff --git a/Docs/releases/v4.0.3.md b/Docs/releases/v4.0.3.md index c8c25c423..931c3b37a 100644 --- a/Docs/releases/v4.0.3.md +++ b/Docs/releases/v4.0.3.md @@ -1,7 +1,7 @@ ### Download -Self-contained: unpack one and run `./ironruby`, `./irb.sh` and `./igem.sh` - on Windows -`ironruby.cmd`, `irb.cmd` and `igem.cmd`. No .NET to install. Or, on Windows, run the +Self-contained: unpack one and run `./ironruby`, `./iirb.sh` and `./igem.sh` - on Windows +`ironruby.cmd`, `iirb.cmd` and `igem.cmd`. No .NET to install. Or, on Windows, run the installer. - **Windows x64 installer**: `ironruby-4.0.3-win-x64-setup.exe`, the zip below, installed @@ -23,7 +23,8 @@ gh attestation verify ironruby-4.0.3-win-x64-setup.exe --repo Largo/ironruby - **A Windows installer**, in the style of RubyInstaller. It installs the win-x64 zip's tree, unchanged, into `C:\IronRuby40-x64` by default, or a directory you choose, for you alone (no admin rights) or for all users, and puts that directory first on the PATH, so - `ironruby`, `ir`, `irb` and `igem` work from a new terminal. `igem install` writes into + `ironruby`, `ir`, `iirb` and `igem` work from a new terminal, while `irb` and `gem` stay + CRuby's. `igem install` writes into the install tree, which is why the default is a directory you can write to and has no space in its path: Bundler's `RUBYOPT`, the Rails templates and mspec break on one. Running `.rb` files with IronRuby is an option, off by default. The uninstaller removes @@ -37,6 +38,8 @@ gh attestation verify ironruby-4.0.3-win-x64-setup.exe --repo Largo/ironruby with no script and no `-e`, and stdin a terminal, `ironruby` is `iirb`. From a pipe or a file it still reads the program from stdin, as `ruby` does, and so do `ironruby -`, `-n`, `-p`, `-c` and `-x`. +- **No more `irb.cmd` and `irb.sh`; IronRuby's irb is `iirb`.** On a PATH, `irb` is CRuby's; + `ironruby -S irb` still runs IronRuby's. - **IronRuby no longer uses a CRuby's gems.** It used to offer the gem directory of a CRuby 4.0 found on the PATH for third-party gems. That loaded CRuby's code into IronRuby: with CRuby on the PATH, `igem install` loaded CRuby's rdoc plugin over the rdoc IronRuby ships diff --git a/README.md b/README.md index 650bac25a..1ae99db89 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ drives it in CI with nobody at the keyboard.* ## A first look ```console -$ ./irb.sh +$ ./iirb.sh irb(main):001> RUBY_DESCRIPTION => "IronRuby 4.0.2 (4.0.0) on .NET 8.0.31 [x86_64-linux]" irb(main):002> def fib(n) = n < 2 ? n : fib(n - 1) + fib(n - 2) @@ -102,8 +102,9 @@ RubyGems writes for an installed gem name the launcher by its path instead, `#!< so they only work where that path still does.) `ir.sh` and `ir.cmd` are its short name, the one IronRuby has used since 1.x, and run the same thing. `igem` / `iirb` / `irubyc` keep the i-prefix so they can sit on `PATH` beside CRuby's `gem` -and `irb`, as JRuby's `jgem`, `jirb` and `jrubyc` do. The unprefixed `gem`, `irb`, `bundle`, -`bundler` and `irubyc` live in `Src/StdLib/bin` and are what `ironruby -S ` finds. +and `irb`, as JRuby's `jgem`, `jirb` and `jrubyc` do; IronRuby has no launcher named `irb` or +`gem`, so those stay CRuby's. The unprefixed `gem`, `irb`, `bundle`, `bundler` and `irubyc` +live in `Src/StdLib/bin`, which is not on the PATH, and are what `ironruby -S ` finds. On Windows the build also has `ironrubyw.exe` next to `ir.exe`, as CRuby has `rubyw.exe` and JRuby `jrubyw.exe`: the same interpreter as a Windows GUI program, which gets no console window - for Windows Forms and WPF programs; `Samples\Notepad\notepad.cmd` starts it. @@ -509,7 +510,7 @@ which skips RubyGems); later runs of the activity take a few milliseconds. ## Platforms Linux is the primary target and the one the numbers above are measured on. **Windows works**: -`ir.cmd` and `irb.cmd` run, and `spec/language` (2920 examples) and `spec/security` pass with +`ir.cmd` and `iirb.cmd` run, and `spec/language` (2920 examples) and `spec/security` pass with **0 failures**. `spec/core` and `spec/library` are rougher there — symlinks/chmod/umask in `core/file`, fork and signals in `core/process`, and `IO.select`/`IO#wait` on pipes (which is `poll(2)`, so `core/io` and the socket suites hang rather than fail). Win32OLE and @@ -532,21 +533,21 @@ one and run the launchers in it: ```console $ tar xzf ironruby-4.0.2-linux-x64.tar.gz && cd ironruby-4.0.2-linux-x64 $ ./ironruby -e 'puts RUBY_DESCRIPTION' -$ ./irb.sh +$ ./iirb.sh $ ./igem.sh install rack ``` From 4.0.2 on, the archives have `ironruby` and `ironruby.cmd` (see above), and `ir.sh` / `ir.cmd` keep working; 4.0.1 and earlier have only those. -On Windows, unzip it and use `ironruby.cmd`, `irb.cmd` and `igem.cmd`, or double-click +On Windows, unzip it and use `ironruby.cmd`, `iirb.cmd` and `igem.cmd`, or double-click `Samples\Notepad\notepad.cmd`. From 4.0.3 on there is also an installer, `ironruby--win-x64-setup.exe`, in the style of RubyInstaller: it installs the same tree into `C:\IronRuby40-x64` (or a directory you choose), for you or for all users, puts -that directory first on your PATH so `ironruby`, `ir`, `irb` and `igem` work from a new +that directory first on your PATH so `ironruby`, `ir`, `iirb` and `igem` work from a new terminal, and its uninstaller removes it all again, installed gems included. It needs no admin rights for you alone, and keeps the default path free of spaces, which Bundler, the -Rails templates and mspec do not handle. IronRuby's `irb` then comes before CRuby's on the -PATH; CRuby's `ruby` and `gem` are not affected. `Util/installer/build-installer.sh` makes +Rails templates and mspec do not handle. Nothing in that directory is named like a CRuby +launcher, so CRuby's `ruby`, `irb` and `gem` are not affected. `Util/installer/build-installer.sh` makes it from the zip with [Inno Setup](https://jrsoftware.org/isinfo.php), from `Util/installer/ironruby.iss`. The archive has the same layout as a checkout, with the Release build in `Src/Console/bin/Release/net8.0`, so everything above applies to it @@ -634,7 +635,7 @@ Windows; `IronRuby.Prism.csproj` ships whichever shared libraries are there and $ dotnet build Src/Console/Ruby.Console.csproj -c Release -r win-x64 --self-contained false ``` -Copy `Src/Console/bin/Release/net8.0/win-x64/`, `Src/StdLib/`, `ir.cmd` and `irb.cmd` to the +Copy `Src/Console/bin/Release/net8.0/win-x64/`, `Src/StdLib/`, `ironruby.cmd`, `ir.cmd` and `iirb.cmd` to the Windows machine, keeping the same relative layout (`ir.cmd` finds the binaries under `Src\Console\bin\%IR_CONFIG%\net8.0\`, with or without a `win-x64` level). Then: @@ -642,7 +643,7 @@ Windows machine, keeping the same relative layout (`ir.cmd` finds the binaries u C:\ir> set IR_CONFIG=Release C:\ir> ir.cmd -e "puts RUBY_DESCRIPTION" IronRuby 4.0.2 (4.0.0) on .NET 8.0.31 [x64-mswin64] -C:\ir> irb.cmd +C:\ir> iirb.cmd C:\ir> set RUBY_EXE=C:\ir\ir.cmd C:\ir> ir.cmd -Imspec/lib mspec/bin/mspec-run spec/language ``` diff --git a/Util/installer/ironruby.iss b/Util/installer/ironruby.iss index fa8fa0819..dd0c91d65 100644 --- a/Util/installer/ironruby.iss +++ b/Util/installer/ironruby.iss @@ -12,9 +12,10 @@ ; the user can write to without admin rights, and a path with a space in it breaks ; Bundler's RUBYOPT, Rails' templates and mspec. Setup asks whether to install for the ; current user or for all users; either way it can add the install directory, where -; ironruby.cmd, ir.cmd, irb.cmd and igem.cmd are, to the front of that user's or the -; system's PATH. The uninstaller removes the files, whatever IronRuby wrote under Src -; since (installed gems included), and the PATH entry. +; ironruby.cmd, ir.cmd, iirb.cmd and igem.cmd are, to the front of that user's or the +; system's PATH. There is no irb.cmd or gem.cmd: those names stay CRuby's. The +; uninstaller removes the files, whatever IronRuby wrote under Src since (installed gems +; included), and the PATH entry. ; ; build-installer.sh passes these; to run ISCC by hand, pass them the same way: ; /DAppVersion=4.0.2 the version, as in the archive's name @@ -73,15 +74,20 @@ SetupLogging=yes Name: "english"; MessagesFile: "compiler:Default.isl" [Tasks] -Name: "modifypath"; Description: "Add IronRuby to the &PATH: ironruby, ir, irb, igem" +Name: "modifypath"; Description: "Add IronRuby to the &PATH: ironruby, ir, iirb, igem" Name: "assocfiles"; Description: "Run .&rb files with IronRuby when they are opened"; Flags: unchecked [Files] ; The archive's tree, unchanged. Source: "{#SourceDir}\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs +[InstallDelete] +; Earlier builds of this installer put an irb.cmd here, which on the PATH shadowed +; CRuby's irb; an upgrade removes it. +Type: files; Name: "{app}\irb.cmd" + [Icons] -Name: "{group}\Interactive IronRuby"; Filename: "{app}\irb.cmd"; WorkingDir: "{%USERPROFILE}" +Name: "{group}\Interactive IronRuby"; Filename: "{app}\iirb.cmd"; WorkingDir: "{%USERPROFILE}" Name: "{group}\Start Command Prompt with IronRuby"; Filename: "{cmd}"; Parameters: "/k ""set ""PATH={app};%PATH%"" & ironruby.cmd -v"""; WorkingDir: "{%USERPROFILE}" Name: "{group}\IronRuby Notepad"; Filename: "{app}\Samples\Notepad\notepad.cmd"; WorkingDir: "{app}\Samples\Notepad" @@ -172,7 +178,8 @@ begin Log('PATH is now: ' + Path); end; -{ First, as RubyInstaller puts Ruby first: irb is IronRuby's irb then. } +{ First, as RubyInstaller puts Ruby first. Every launcher here is i-prefixed or named + ironruby/ir, so being first shadows none of a CRuby's: irb and gem stay CRuby's. } procedure AddToPath(Dir: String); var Path: String; diff --git a/Util/installer/test-installer.ps1 b/Util/installer/test-installer.ps1 index 17e840a66..99ff16f6f 100644 --- a/Util/installer/test-installer.ps1 +++ b/Util/installer/test-installer.ps1 @@ -76,9 +76,13 @@ $setup = Start-Process -FilePath $installer -Wait -PassThru -ArgumentList @( '/VERYSILENT', '/SUPPRESSMSGBOXES', '/NORESTART', '/SP-', $mode, "/LOG=`"$log`"") if ($setup.ExitCode -ne 0) { Get-Content $log -Tail 30; Fail "setup exited with $($setup.ExitCode)" } -foreach ($launcher in 'ironruby.cmd', 'ir.cmd', 'irb.cmd', 'igem.cmd', 'unins000.exe') { +foreach ($launcher in 'ironruby.cmd', 'ir.cmd', 'iirb.cmd', 'igem.cmd', 'unins000.exe') { if (-not (Test-Path (Join-Path $Dir $launcher))) { Fail "no $launcher in $Dir" } } +# First on the PATH, these would shadow a CRuby's irb and gem. +foreach ($launcher in 'irb.cmd', 'gem.cmd') { + if (Test-Path (Join-Path $Dir $launcher)) { Fail "$launcher in $Dir would shadow CRuby's" } +} $first = ((Get-RawPath) -split ';')[0] if ($first -ne $Dir) { Fail "$Dir is not first on the $scope PATH, $first is" } @@ -88,8 +92,8 @@ $where = Invoke-Fresh 'where ironruby' if (($where -split "`r?`n")[0] -ne "$Dir\ironruby.cmd") { Fail "ironruby is not $Dir\ironruby.cmd" } $engine = Invoke-Fresh 'ir -e puts(RUBY_ENGINE)' if ($engine -ne 'ironruby') { Fail "ir: $engine" } -$irb = Invoke-Fresh 'irb' "puts 6 * 7`n" -if ($irb -notmatch '42') { Fail 'irb did not run the line it was given' } +$irb = Invoke-Fresh 'iirb' "puts 6 * 7`n" +if ($irb -notmatch '42') { Fail 'iirb did not run the line it was given' } Invoke-Fresh 'igem install rack --no-document' | Out-Null $gems = Join-Path $Dir 'Src\StdLib\ruby\gems\4.0.0\gems' if (-not (Get-ChildItem $gems -Filter 'rack-*' -Directory)) { Fail "rack is not in $gems" } diff --git a/Util/package-release.sh b/Util/package-release.sh index 7c9775b7c..22c18b1a3 100755 --- a/Util/package-release.sh +++ b/Util/package-release.sh @@ -7,8 +7,9 @@ # # The archive keeps the source tree's layout - the launchers at the top, the build in # Src/Console/bin/Release/, the standard library in Src/StdLib - so ir.sh/ir.cmd, -# igem, irb and irubyc work from the unpacked directory exactly as they do in a -# checkout (ir.sh picks the Release build when there is no Debug one). +# igem, iirb and irubyc work from the unpacked directory exactly as they do in a +# checkout (ir.sh picks the Release build when there is no Debug one). There is no irb +# or gem launcher: on a PATH those names are CRuby's. # # The build is self-contained, so it runs on a machine with no .NET installed, and # ReadyToRun, so IronRuby's own assemblies start as native code (see publish-r2r.sh). @@ -41,8 +42,8 @@ dotnet publish "$IR_ROOT/Src/Console/Ruby.Console.csproj" \ rm -f "$STAGE/Src/Console/bin/Release/$IR_TFM"/*.pdb case "$RID" in - win-*) launchers=(ironruby.cmd ir.cmd irb.cmd igem.cmd iirb.cmd irubyc.cmd) ;; - *) launchers=(ironruby ir.sh irb.sh igem.sh iirb.sh irubyc.sh) ;; + win-*) launchers=(ironruby.cmd ir.cmd igem.cmd iirb.cmd irubyc.cmd) ;; + *) launchers=(ironruby ir.sh igem.sh iirb.sh irubyc.sh) ;; esac for f in "${launchers[@]}" README.md; do cp "$IR_ROOT/$f" "$STAGE/" @@ -114,7 +115,7 @@ esac # A quick check that the unpacked tree starts, before it is archived - and on Windows # that Windows Forms and WPF load from it, which a missing framework reference breaks -# without breaking anything else. irb has to start too: it loads reline, which on Windows +# without breaking anything else. iirb has to start too: it loads reline, which on Windows # looks up Win32 functions through Fiddle, and 4.0.2's died there. # One command per line: set -e does not stop at a failure on the left of && - nor at a # case whose last && list failed that way - so a chain would let a broken tree through. @@ -124,13 +125,13 @@ case "$RID" in (cd "$STAGE" cmd //c ironruby.cmd -e 'puts RUBY_DESCRIPTION' cmd //c ir.cmd -e 'puts RUBY_ENGINE' - printf 'puts 6 * 7\n' | cmd //c irb.cmd | grep -x 42 + printf 'puts 6 * 7\n' | cmd //c iirb.cmd | grep -x 42 cmd //c ir.cmd "$(cygpath -w "$IR_ROOT/Util/windows-desktop-check.rb")") ;; *) "$STAGE/ironruby" -e 'puts RUBY_DESCRIPTION' "$STAGE/ir.sh" -e 'puts RUBY_ENGINE' - printf 'puts 6 * 7\n' | "$STAGE/irb.sh" | grep -x 42 + printf 'puts 6 * 7\n' | "$STAGE/iirb.sh" | grep -x 42 ;; esac diff --git a/iirb.cmd b/iirb.cmd index 55dc7c6c8..767da0160 100644 --- a/iirb.cmd +++ b/iirb.cmd @@ -1,3 +1,4 @@ @echo off -rem IronRuby's irb on Windows, i-prefixed. Same as irb.cmd / `ironruby.cmd -S irb`. +rem IronRuby's irb on Windows, the same as `ironruby.cmd -S irb`. i-prefixed, so that +rem `irb` on the PATH stays CRuby's even with IronRuby's directory in front of it. "%~dp0ironruby.cmd" -S irb %* diff --git a/iirb.sh b/iirb.sh index 464ad8844..4cb1bce3a 100755 --- a/iirb.sh +++ b/iirb.sh @@ -1,5 +1,5 @@ #!/bin/sh -# IronRuby's irb under the i-prefixed name (IronRuby 1.x shipped iirb.bat; JRuby -# ships jirb). irb.sh is the same thing under the plainer name. +# IronRuby's irb, the same as `./ironruby -S irb`, under the i-prefixed name +# (IronRuby 1.x shipped iirb.bat; JRuby ships jirb), so that `irb` stays CRuby's. IR_ROOT="$(dirname "$(readlink -f "$0")")" exec "$IR_ROOT/ironruby" -S irb "$@" diff --git a/irb.cmd b/irb.cmd deleted file mode 100644 index 06b6ac600..000000000 --- a/irb.cmd +++ /dev/null @@ -1,3 +0,0 @@ -@echo off -rem IronRuby's irb on Windows. The same thing as `ironruby.cmd -S irb`. -"%~dp0ironruby.cmd" -S irb %* diff --git a/irb.sh b/irb.sh deleted file mode 100755 index 763f35571..000000000 --- a/irb.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -# IronRuby's irb. The same thing as `./ironruby -S irb`, which also works; this is -# here so that starting a REPL does not need to know about -S. -IR_ROOT="$(dirname "$(readlink -f "$0")")" -exec "$IR_ROOT/ironruby" -S irb "$@"