diff options
author | Boris Fomitchev <bfomitchev@nvidia.com> | 2015-11-20 02:23:36 +0300 |
---|---|---|
committer | Boris Fomitchev <bfomitchev@nvidia.com> | 2015-11-20 02:23:36 +0300 |
commit | fbe7ffba6e8d6ec4375fb2fa85851ea595d2fb60 (patch) | |
tree | 4e6e247a8b0361cfc8678a005e5556e73704f033 | |
parent | 31690a82a01bf8a336699e6a278f85d5a420561f (diff) |
Squashed 'luarocks/' changes from b563ebd..8d8e364
8d8e364 Merge branch 'master' of https://github.com/keplerproject/luarocks
2b8301c Do not distribute appveyor files in release packages.
579cd75 Merge pull request #448 from zoresvit/patch-1
62017cc Use `command -v` for obtaining executable path.
ce3ea55 Merge pull request #413 from Tieske/unversion_LR
6f70ad5 Fix `find_program` function to be less fragile
cb3e2af explicit warn when enviornment variable given filename doesn't exist
9c99043 Merge pull request #440 from mpeterv/fix-patch-error
a65eb65 Merge pull request #439 from mpeterv/fix-patch-empty-lines
7886cff Fix patch error message when source is different
cfc253f Fix empty line handling in patch.lua
8fe1bbd Revert accidental commit.
bacd3da Use env for setting MACOSX_DEPLOYMENT_TARGET. See #422.
e3203ad add set_time function for tar module without lfs
c178fbb Merge pull request #426 from usstwxy/patch-1
b151ae8 Merge pull request #427 from tst2005/master
0797c93 missing to close file descriptor
5fa1201 We use lzlib, not lua-zlib
e869d7f Update tar.lua
0d2053e Fix documentation of --lua-version
daa4ef4 Update LuaCov
d305830 Merge pull request #418 from jasonwilliams200OK/master
bc186fc ci: updates appveyor config to use VS2015.
908756d update commandline help Windows installer
6a0de88 moved systree on top of Lua installation
a625fe2 fixed bad reference to main LuaRocks install path, should fix AppVeyor failures
838f1f9 added debug line
cc621bf Fixes appveyor build script for changed paths
b24f9b7 update windows installer help text
5159a50 Windows installer: no longer use the LR version in the target installation path. Fixes #151
8c182d5 Windows installer: backup configuration files before removing installation directory
c9d57bd minor textual fixes
2de1b0d Merge pull request #410 from mpeterv/fix-git-http-branch-command
8f65a7b Fix git cloning command when using git+http protocol
cc90426 Merge pull request #407 from Tieske/pref_versioned
ddefaeb added extra include files search paths, see https://github.com/keplerproject/luarocks/issues/403#issuecomment-119726674 updated bak files as per @ignacio see https://github.com/keplerproject/luarocks/pull/407#discussion-diff-33782733
e26e7a1 also version the `site_config` file
6ca144c Merge branch 'master' of github.com:keplerproject/luarocks into pref_versioned
642be5c update displayed data to match version
634ff0a Merge pull request #404 from ignacio/url_to_base_dir
d00c4e9 Merge pull request #405 from ignacio/pe_parser_04
d7aa0a0 Merge pull request #398 from Tieske/refactor_cfg
28a89ba Updates pe-parser to v0.4
c6e3556 Strip known extensions
02eff15 prefer versioned config files and directories over non-versioned ones
066e1c6 Make wording of help summaries consistent.
5861782 Merge pull request #400 from ignacio/400-config-help
1eccb03 Merge pull request #399 from mpeterv/write-rockspec-format
7e464b1 Changes wording as suggested
ed97ece Adds missing tests
f10113f Adds help to 'luarocks config' command
19ce8a6 Add a test for '--rockspec-format' option
4c7a5bc Add '--rockspec-format' option for write_rockspec command
5f7763b added error message in case of a bad platform value
253ed46 added correct order for platform overrides
e1badc4 Update appveyor test matrix to use Lua 5.3.1
d065a95 integrated cfg.platform and cfg.platforms
030dda2 Merge pull request #383 from ignacio/cmake_64
79ffabf Don't restrict the generator override to mingw
797b95f Use new key target_cpu
b3a4e88 CMake needs a hint to use 64 bit target with msvc.
f61e5a2 cmake backend: Generate 64 bits build when appropiate
30d869c Merge branch 'master' of https://github.com/keplerproject/luarocks into refactor_cfg
028b37f Merge pull request #397 from Tieske/fix_config
554836b refactored the loading of the config files in a more structural manner, removing duplicate code and error handling.
ec31f30 `detected` was only retained in `cfg` through multiple copies, removed by directly operating on `cfg.platform`
3b58640 do not reuse environments
1a85cb5 fix travis-ci error
e87c898 removed accidental reintroduced line
f6974b4 config.lua is not being integrated, bug introduced in #385
6cb37a1 Don't shadow filename variable: fixes error message.
9ed2084 Merge pull request #393 from Tieske/target_stuff
ca619eb Merge pull request #394 from ignacio/build_mandatory
8064e99 Update build matrix to use latest versions
8f7897c Make 'build' field in rockspecs mandatory.
26167e8 oops... remove debug stuff
8757d35 - site_config remains local, not exposed - added field 'target_cpu' to `cfg` and config file environments
9040c74 Merge branch 'master' of https://github.com/keplerproject/luarocks
85edc26 Remove `--extensions` flag. Fixes #391.
a0315b7 Merge pull request #392 from Alloyed/patch-1
d5fa171 fix typo
84f886f Merge pull request #385 from Tieske/master
fdcecd1 Allows luarocks.cfg to be used without being installed.
5b605a9 Merge pull request #389 from ignacio/check_others
c9b7f0b Factors the code to check for a tool. Changes 'not found' message wording.
998d012 fix: use same environment table for the system config file as well.
8d030a0 Checks if tool is installed (svn, cvs, hg)
7fb623c Merge pull request #387 from ignacio/check_git
83449f2 Checks if git is installed
f032ff7 Merge pull request #373 from keplerproject/makefile-fix
4792618 fixed typo
e1dd637 added 2 functions to the global environment of the config-file loader sandbox; `os_getenv()` and `__dump_env()`
0ecc743 Use LuaJIT 2.0.4 on AppVeyor's test matrix
9861f68 Merge pull request #376 from Tieske/master
baf7ffa remove excess line (windows installer)
58220b2 Merge branch 'master' of https://github.com/keplerproject/luarocks
b85baac Correct use of which_config. Fixes #374.
f0aa57e Add config_cmd.lua to Makefile.setup.inc.
5d8a165 Merge pull request #371 from ignacio/proxies
4462ca5 Add `luarocks config` command for querying LuaRocks settings.
b80244b Merge branch 'master' of https://github.com/keplerproject/luarocks
dd6f0e7 Update lmathx used for testing Lua 5.3
70c7577 Merge pull request #366 from Tieske/windows_exitcode
11b8b48 fixes #365
0d071fa Back to scm
7bff020 Mark release 2.2.2
2f9c115 Merge branch 'master' of https://github.com/keplerproject/luarocks
9736020 Install .md files as docs
97b98bf Clip string.gsub results to just one when redacting url.
2a0a9fa Merge pull request #359 from ignacio/redact_verbose
968e963 Redact api tokens when using --verbose flag
9aa5d05 Update upload URL as well.
cda43ce Merge branch 'master' of https://github.com/keplerproject/luarocks
022c87d MoonRocks → LuaRocks.org transition complete!
7b6efb9 Trust the user :)
2c536b4 Deal with 'no_proxy' env var
f022fe0 Drop use of config.proxy
b6b6754 Merge pull request #354 from Tieske/pe_parser
460e42d update to version 0.3
2ee6bd7 Merge pull request #349 from ignacio/build_only_deps
15ad97b Address issues spotted in the review
6b350de Adds --only-deps flag to install command
6dd402b Adds new file (fetch/git_https.lua) to Makefile.setup.inc
46f8ad6 Merge pull request #350 from jszakmeister/add-git-https-support
989347e Add git+https support.
0f67be5 Adds --only-deps flag to the 'build' command.
0fe8556 Update function documentation, as suggested by @ignacio in #347.
0679559 Decided to step back in turn this into a warning. `luarocks list` on an empty ~/.luarocks is a valid use case.
40f9173 Fail when given an invalid tree.
6d5dfcd Fix crash on `luarocks --tree=/path list`. Closes #347.
1fcf354 Add test that checks for error in default sysconfig. See #346.
3ce554c Restore comment about second return, but put it in the right function. https://github.com/keplerproject/luarocks/pull/346#discussion_r28008668
0e3a052 Merge pull request #346 from Tieske/bad_config
c66a88e bail out on bad config files, fixes #228
79addc7 Continuing slowly. Distracted by code golf. :)
58fb6b9 Merge branch 'master' of https://github.com/keplerproject/luarocks
ed1f916 Starting to port test suite from Unix shell to Lua.
6f87c47 Merge pull request #343 from xpol/master
cbde573 And also hide the startup logo for RC.
5cb4aa7 Merge branch 'master' of https://github.com/keplerproject/luarocks
303cca7 Add AppVeyor badge
ad8ba47 Merge pull request #335 from ignacio/appveyor
a52b5ca Merge branch 'master' of https://github.com/keplerproject/luarocks
6251735 Add Coveralls coverage badge
2fcc0cc Add options to hide the MSVC tools' startup logo.
ff68e97 Fallback for platform variable
e31c46b Improved the CI scripts
050d656 Fix summary detection in long paragraphs
4ad1f1a Remove failing test. Try this some other time.
db81c2e Force package to be in cache.
303628a Add more simple tests.
8d6a9e3 Merge branch 'master' of https://github.com/keplerproject/luarocks
5b45de2 More small tests.
066cda4 Merge pull request #341 from keplerproject/add-travis
2639401 Make localhost a known host.
a549c6d Try not to block checking server identification.
7c8e527 Let's see if Travis allow sftp'ing to localhost.
98e0979 Merge branch 'master' of https://github.com/keplerproject/luarocks
5f293dd Remove debugging print.
ed02691 Add trivial tests for `luarocks upload`
b4ea2a1 Merge pull request #340 from xpol/master
b9789f3 Revert incorrect remove of cmake_generator support. Only windows (msvc) default cmake_generator are removed.
a19af6d luacov-coveralls overwrites luacov.report.out!
1b5bbfc luacov-coveralls did not exit with 0?
df08baf Run luacov-coveralls from $testing_dir
f3aaee7 Avoid tests that mess with the testing environment.
836898f Let's try Coveralls
b5244be Merge branch 'master' of https://github.com/keplerproject/luarocks
30430cf Don't overwrite --detailed when given by the user.
19ca56c Actually direct users to the bug tracker
57c838e Merge branch 'master' of https://github.com/keplerproject/luarocks
5495f3c A missing CWD returns "" for lfs.current_dir() on Ubuntu
db90cb4 Really test for missing parameters.
d3d74bf A missing CWD returns "" for fs.current_dir on Ubuntu...
a027595 Let's try harder to fail if CWD does not exist.
876d9c8 Fix inconsistency in --homepage flag in `luarocks doc` and `luarocks write_rockspec`.
294e08f Fix --lib flag (and my last commit goof...)
62d4e05 Fix tests: new flag parser detected invalid flags in the testsuite.
7f7c006 Add support for space in long option assignments.
68aa7ae Merge branch 'master' of https://github.com/keplerproject/luarocks
e869c09 Fail nicely if CWD does not exist. Fixes #147.
ae51a3c Fix confusing error when unpack fails due to network error
93cdd54 Adds integration with AppVeyor
28ade76 Fixes #332.
51ea074 Expose platform and processor to home config files.
a02a53a Merge branch 'master' of https://github.com/keplerproject/luarocks
4c96972 Don't use user tree when running as root. Fixes #303.
f15e49d Merge pull request #330 from mpeterv/hg-support
9567ac5 Merge pull request #329 from mpeterv/persist-refactor
20eb947 Improve hg support
cf19178 Refactor persist.save_from_table
3c7c472 Refactor persist.load_into_table
603b0ea Merge branch 'master' of https://github.com/keplerproject/luarocks
be3c52d Add extra smartness to configure to check that the user-given flag seems correct. Closes #293.
d820069 Merge pull request #326 from mpeterv/fix-redact-api
8739847 Merge branch 'master' of https://github.com/keplerproject/luarocks
5db7c54 Merge branch 'xpol-master'
7d22ee5 Open file in 'rb
90586f6 Merge branch 'master' of https://github.com/keplerproject/luarocks
bdf218b Remove commented code after remove cfg.cmake_generator.
b5e2539 Better cmake support.
df332f6 Fix url redacting when Luasocket is used
88a903a Add logo :)
6e21673 Try the one we have as `lua` first!
4e9a0e3 This is for Makefile.luarocks only.
ccab32f Merge branch 'new-makefile'
855259b New set of Makefiles for self-upgrade.
ff6fdfc Ignore more files.
92d6363 Make sure suffix is produced when installing via rock (see #323) and copy over site_config.lua, in case we're installing to a different prefix (see https://sourceforge.net/p/luarocks/mailman/message/33608257/)
dc5f200 Make it a bit more robust.
4347dc7 Redact API URL to hide API key.
650c8ae Back to our regularly scheduled programming
8649a4e Release LuaRocks 2.2.1
c7a704a Add test files that were not committed before.
463ee89 Don't crash when modules table is missing.
d110857 Use the system-installed stat.
0f9d259 Test success of patching in `unpack`. Closes #316. Includes test cases for the test suite! Yay!
9a9caf8 We're always using the internal patch module. See #316.
c9cc478 All 5.x versions of Lua share the same license.
92c7acb Clarify that runtime support is optional.
5f3d390 Don't crash when asking for help on invalid cmd.
46f2d25 Code cleanups suggested by luacheck.
7fe62f1 Remove unused assignment.
53e0c65 Direct users to the bug tracker
2013547 Support both --lua-version and --with-lua-version. Error messages were even already using it by accident!
48847a4 Support more file extensions as source files.
23afae6 Merge branch 'master' of https://github.com/keplerproject/luarocks
c54cbfc Fix behavior of `luarocks pack` on Windows. It was failing when a path contained spaces due to lack of quoting. Closes #308.
7f6320c Merge pull request #309 from mpeterv/unused_variables
500741f Removed some unused and global variables
113ada0 Merge branch 'master' of https://github.com/keplerproject/luarocks
9204178 Discard excess characters when a tool gives out an octal mode string that's too long. Fixes #53.
aa4e0d3 Merge pull request #298 from seclorum/master
9702239 Use updated LuaFileSystem for Lua 5.3
0f1c937 Updates for Lua 5.3 compatibility
8d6845e Make conversion more robust for Lua 5.3
d98c3e0 Make it more robust. (I _think_ win32 needs something similar, but there's the complication of drive letters so I won't touch it now without proper testing.)
8d588f9 Catch error if filename is a directory
1885a7f Improve error checking
f74346e Do not pack scm versions
cd99315 Fix search of lua interpreter. Closes #301.
4c503eb Update stdlib for 5.3 (thought I had this in the previous commit!)
c5501d4 Merge branch 'master' of https://github.com/keplerproject/luarocks
de654b3 Updates for Lua 5.3 support
4636244 use cprint version compatible with Lua 5.3
fc6d30d Update stdlib for Lua 5.3 compatibility
76e5515 Add Lua 5.3 to the test matrix
9ab9988 Add test that catches #228.
0ebdcd4 Updates to testing infrastructure (use new luasec, luacov)
e7f9680 Error out on bad config files. Alternative implementation to the one given by @Tieske, following discussion in #260. Closes #260. Closes #228.
02e8bbd Safer guards for OSX Deployment target selection..
c4558a3 OSX 10.10 Yosemite sw_vers update
db46b22 Apply change suggested by @siffiejoe. Thanks @catwell for catching this! Closes #295.
1a1c407 Add test for #295.
8bbf02e Make test suite detect crashes on tests that should fail gracefully.
7a7c124 Add check for Fedora systems. Closes #289.
723bf99 Isolate the convenience hack, for readability.
a35dd43 Silence complaints from `luarocks upload`. Closes #292.
af679a9 Fix typo. Closes #294.
453179d Provide a fallback for when the version number is 'scm', to avoid breaking Windows default paths (which assume something like c:\luarocks\2.2\ ) Closes #288.
88ea74e Make code more resilient.
0467eba Merge branch 'master' of https://github.com/keplerproject/luarocks
8278ed2 Add flag to enable/disable SSL cert check. We disabled SSL certificate checks for wget and curl a while ago, when we first added https repositories. We'll keep the check disabled by default for now, but this adds a config option, `check_certificates=true` that can be used in your config.lua.
af19063 Don't report WIP versions as releases.
d15e99f Merge pull request #285 from mpeterv/fix-lint
86ba23c Fix `luarocks lint`.
e5cd7a9 Add --outdated as a flag to `luarocks list`. A variation of the feature suggested in #282.
f0d66ae Support per-field version checking. This will allow us to add fields and bump rockspec version numbers in a well-behaved manner.
0587afb Fix version number!
ffba286 Fix version number!!
git-subtree-dir: luarocks
git-subtree-split: 8d8e36451aae7f5832efe9ff64de4307e6e8b6a6
69 files changed, 2296 insertions, 717 deletions
diff --git a/.appveyor/build.bat b/.appveyor/build.bat new file mode 100644 index 0000000..a4ff637 --- /dev/null +++ b/.appveyor/build.bat @@ -0,0 +1,111 @@ +@echo off +Setlocal EnableDelayedExpansion EnableExtensions + +cd %APPVEYOR_BUILD_FOLDER% + +:: ========================================================= +:: Make sure some environment variables are set +if not defined LUA_VER call :die LUA_VER is not defined +if not defined LUA call :die LUA is not defined +if not defined LUA_SHORTV call :die LUA_SHORTV is not defined +if not defined LUA_DIR call :die LUA_DIR is not defined + +:: ========================================================= +:: Set some defaults. Infer some variables. +:: +if not defined LUAROCKS_VER set LUAROCKS_VER=2.2.1 + +set LUAROCKS_SHORTV=%LUAROCKS_VER:~0,3% + +if not defined LR_EXTERNAL set LR_EXTERNAL=c:\external +if not defined LR_ROOT set LR_ROOT=%LUA_DIR%\LuaRocks +if not defined LR_SYSTREE set LR_SYSTREE=%LR_ROOT%\systree + +:: +:: ========================================================= + + +if not exist %LUA_DIR%\bin\%LUA%.exe call :die "Missing Lua interpreter at %LUA_DIR%\bin\%LUA%.exe" + + + +:: ========================================================= +:: LuaRocks +:: ========================================================= + +cd %APPVEYOR_BUILD_FOLDER% +call install.bat /LUA %LUA_DIR% /Q /LV %LUA_SHORTV% /P "%LR_ROOT%" /TREE "%LR_SYSTREE%" + +if not exist "%LR_ROOT%" call :die "LuaRocks not found at %LR_ROOT%" + +set PATH=%LR_ROOT%;%LR_SYSTREE%\bin;%PATH% + +:: Lua will use just the system rocks +set LUA_PATH=%LR_ROOT%\lua\?.lua;%LR_ROOT%\lua\?\init.lua +set LUA_PATH=%LUA_PATH%;%LR_SYSTREE%\share\lua\%LUA_SHORTV%\?.lua +set LUA_PATH=%LUA_PATH%;%LR_SYSTREE%\share\lua\%LUA_SHORTV%\?\init.lua +set LUA_CPATH=%LR_SYSTREE%\lib\lua\%LUA_SHORTV%\?.dll + +call luarocks --version || call :die "Error with LuaRocks installation" +call luarocks list + + +if not exist "%LR_EXTERNAL%" ( + mkdir "%LR_EXTERNAL%" + mkdir "%LR_EXTERNAL%\lib" + mkdir "%LR_EXTERNAL%\include" +) + +set PATH=%LR_EXTERNAL%;%PATH% + +:: Exports the following variables: +:: (beware of whitespace between & and ^ below) +endlocal & set PATH=%PATH%&^ +set LR_SYSTREE=%LR_SYSTREE%&^ +set LUA_PATH=%LUA_PATH%&^ +set LUA_CPATH=%LUA_CPATH%&^ +set LR_EXTERNAL=%LR_EXTERNAL% + +echo. +echo ====================================================== +echo Installation of LuaRocks %LUAROCKS_VER% done. +echo . +echo LUA_PATH - %LUA_PATH% +echo LUA_CPATH - %LUA_CPATH% +echo. +echo LR_EXTERNAL - %LR_EXTERNAL% +echo ====================================================== +echo. + +goto :eof + + + + + + + + + + + + + + + + + + +:: This blank space is intentional. If you see errors like "The system cannot find the batch label specified 'foo'" +:: then try adding or removing blank lines lines above. +:: Yes, really. +:: http://stackoverflow.com/questions/232651/why-the-system-cannot-find-the-batch-label-specified-is-thrown-even-if-label-e + +:: helper functions: + +:: for bailing out when an error occurred +:die %1 +echo %1 +exit /B 1 +goto :eof + diff --git a/.appveyor/install.bat b/.appveyor/install.bat new file mode 100644 index 0000000..a2aefdd --- /dev/null +++ b/.appveyor/install.bat @@ -0,0 +1,154 @@ +@echo off + +cd %APPVEYOR_BUILD_FOLDER% + +:: ========================================================= +:: Set some defaults. Infer some variables. +:: +:: These are set globally +if "%LUA_VER%" NEQ "" ( + set LUA=lua + set LUA_SHORTV=%LUA_VER:~0,3% +) else ( + set LUA=luajit + set LJ_SHORTV=%LJ_VER:~0,3% + set LUA_SHORTV=5.1 +) + +:: unless we specify a platform on appveyor.yaml, we won't get this variable +if not defined platform set platform=x86 + +:: defines LUA_DIR so Cmake can find this Lua install +if "%LUA%"=="luajit" ( + set LUA_DIR=c:\lua\%platform%\lj%LJ_SHORTV% +) else ( + set LUA_DIR=c:\lua\%platform%\%LUA_VER% +) + +:: Now we declare a scope +Setlocal EnableDelayedExpansion EnableExtensions + +if not defined LUA_URL set LUA_URL=http://www.lua.org/ftp +if not defined LUAJIT_GIT_REPO set LUAJIT_GIT_REPO=http://luajit.org/git/luajit-2.0.git +if not defined LUAJIT_URL set LUAJIT_URL=http://luajit.org/download + +if not defined SEVENZIP set SEVENZIP=7z +:: +:: ========================================================= + +:: first create some necessary directories: +mkdir downloads 2>NUL + +:: Download and compile Lua (or LuaJIT) +if "%LUA%"=="luajit" ( + if not exist %LUA_DIR% ( + if "%LJ_SHORTV%"=="2.1" ( + :: Clone repository and checkout 2.1 branch + set lj_source_folder=%APPVEYOR_BUILD_FOLDER%\downloads\luajit-%LJ_VER% + if not exist !lj_source_folder! ( + echo Cloning git repo %LUAJIT_GIT_REPO% !lj_source_folder! + git clone %LUAJIT_GIT_REPO% !lj_source_folder! || call :die "Failed to clone repository" + ) + cd !lj_source_folder!\src + git checkout v2.1 || call :die + ) else ( + set lj_source_folder=%APPVEYOR_BUILD_FOLDER%\downloads\luajit-%LJ_VER% + if not exist !lj_source_folder! ( + echo Downloading... %LUAJIT_URL%/LuaJIT-%LJ_VER%.tar.gz + curl --silent --fail --max-time 120 --connect-timeout 30 %LUAJIT_URL%/LuaJIT-%LJ_VER%.tar.gz | %SEVENZIP% x -si -so -tgzip | %SEVENZIP% x -si -ttar -aoa -odownloads + ) + cd !lj_source_folder!\src + ) + :: Compiles LuaJIT + call msvcbuild.bat + + mkdir %LUA_DIR% 2> NUL + for %%a in (bin include lib) do ( mkdir "%LUA_DIR%\%%a" ) + + for %%a in (luajit.exe lua51.dll) do ( move "!lj_source_folder!\src\%%a" "%LUA_DIR%\bin" ) + + move "!lj_source_folder!\src\lua51.lib" "%LUA_DIR%\lib" + for %%a in (lauxlib.h lua.h lua.hpp luaconf.h lualib.h luajit.h) do ( + copy "!lj_source_folder!\src\%%a" "%LUA_DIR%\include" + ) + + ) else ( + echo LuaJIT %LJ_VER% already installed at %LUA_DIR% + ) +) else ( + if not exist %LUA_DIR% ( + :: Download and compile Lua + if not exist downloads\lua-%LUA_VER% ( + curl --silent --fail --max-time 120 --connect-timeout 30 %LUA_URL%/lua-%LUA_VER%.tar.gz | %SEVENZIP% x -si -so -tgzip | %SEVENZIP% x -si -ttar -aoa -odownloads + ) + + mkdir downloads\lua-%LUA_VER%\etc 2> NUL + if not exist downloads\lua-%LUA_VER%\etc\winmake.bat ( + curl --silent --location --insecure --fail --max-time 120 --connect-timeout 30 https://github.com/Tieske/luawinmake/archive/master.tar.gz | %SEVENZIP% x -si -so -tgzip | %SEVENZIP% e -si -ttar -aoa -odownloads\lua-%LUA_VER%\etc luawinmake-master\etc\winmake.bat + ) + + cd downloads\lua-%LUA_VER% + call etc\winmake + call etc\winmake install %LUA_DIR% + ) else ( + echo Lua %LUA_VER% already installed at %LUA_DIR% + ) +) + +if not exist %LUA_DIR%\bin\%LUA%.exe call :die "Missing Lua interpreter at %LUA_DIR%\bin\%LUA%.exe" + +set PATH=%LUA_DIR%\bin;%PATH% +call %LUA% -v + + + +:: Exports the following variables: +endlocal & set PATH=%PATH% + +echo. +echo ====================================================== +if "%LUA%"=="luajit" ( + echo Installation of LuaJIT %LJ_VER% done. +) else ( + echo Installation of Lua %LUA_VER% done. +) +echo Platform - %platform% +echo LUA - %LUA% +echo LUA_SHORTV - %LUA_SHORTV% +echo LJ_SHORTV - %LJ_SHORTV% +echo. +echo ====================================================== +echo. + +goto :eof + + + + + + + + + + + + + + + + + + +:: This blank space is intentional. If you see errors like "The system cannot find the batch label specified 'foo'" +:: then try adding or removing blank lines lines above. +:: Yes, really. +:: http://stackoverflow.com/questions/232651/why-the-system-cannot-find-the-batch-label-specified-is-thrown-even-if-label-e + +:: helper functions: + +:: for bailing out when an error occurred +:die %1 +echo %1 +exit /B 1 +goto :eof + @@ -1,2 +1,4 @@ /config.* /src/luarocks/site_config.lua +/test/testing_* +/test/luacov.* diff --git a/.travis.yml b/.travis.yml index cf2b1e6..69ec28f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,9 +2,12 @@ language: c compiler: gcc +sudo: false + env: matrix: - LUA_VER=5.1.5 - - LUA_VER=5.2.3 + - LUA_VER=5.2.4 + - LUA_VER=5.3.1 script: cd test && ./testing.sh --travis --lua $LUA_VER @@ -2,31 +2,13 @@ include config.unix .PHONY: all build dev build_bins luadoc check_makefile cleanup_bins clean \ - install_bins install_luas install_site_config write_sysconfig \ - install bootstrap install_rock + install_site_config write_sysconfig install bootstrap install_rock -DESTDIR = -PREFIX ?= /usr/local ROCKS_TREE ?= $(PREFIX) SYSCONFDIR ?= $(PREFIX)/etc/luarocks -BINDIR ?= $(PREFIX)/bin -LUADIR ?= $(PREFIX)/share/lua/$(LUA_VERSION)/ LUA_DIR ?= /usr/local LUA_BINDIR ?= $(LUA_DIR)/bin -BIN_FILES = luarocks luarocks-admin -LUAROCKS_FILES = fs/unix/tools.lua fs/unix.lua fs/win32/tools.lua fs/win32.lua \ -fs/lua.lua persist.lua list.lua require.lua repos.lua dir.lua make_manifest.lua \ -command_line.lua install.lua build/command.lua build/cmake.lua build/make.lua \ -build/builtin.lua fetch/cvs.lua fetch/git.lua fetch/sscm.lua tools/patch.lua \ -fetch/svn.lua tools/zip.lua tools/tar.lua pack.lua type_check.lua make.lua \ -remove.lua fs.lua manif.lua add.lua deps.lua build.lua search.lua show.lua \ -manif_core.lua fetch.lua unpack.lua validate.lua cfg.lua download.lua \ -help.lua util.lua index.lua cache.lua refresh_cache.lua loader.lua \ -admin_remove.lua fetch/hg.lua fetch/git_file.lua new_version.lua lint.lua \ -purge.lua path.lua path_cmd.lua write_rockspec.lua doc.lua upload.lua \ -upload/api.lua upload/multipart.lua fetch/git_http.lua - CONFIG_FILE = $(SYSCONFDIR)/config-$(LUA_VERSION).lua SAFEPWD=`echo "$$PWD" | sed -e 's/\([][]\)\1/]]..'\''\1\1'\''..[[/g'` @@ -38,6 +20,9 @@ all: @echo " to install LuaRocks in $(PREFIX) as a rock." @echo +include Makefile.setup.inc +include Makefile.install.inc + build: src/luarocks/site_config.lua build_bins @echo @echo "Done. Type 'make install' to install into $(PREFIX)." @@ -139,23 +124,6 @@ cleanup_bins: clean: cleanup_bins rm -f src/luarocks/site_config.lua -install_bins: - mkdir -p "$(DESTDIR)$(BINDIR)" - cd src/bin && for f in $(BIN_FILES); \ - do \ - cp "$$f" "$(DESTDIR)$(BINDIR)/$$f-$(LUA_VERSION)"; \ - ln -nfs "$$f-$(LUA_VERSION)" "$(DESTDIR)$(BINDIR)/$$f"; \ - done - -install_luas: - mkdir -p "$(DESTDIR)$(LUADIR)/luarocks" - cd src/luarocks && for f in $(LUAROCKS_FILES); \ - do \ - d="$(DESTDIR)$(LUADIR)/luarocks"/`dirname "$$f"` && \ - mkdir -p "$$d" && \ - cp "$$f" "$$d" || exit 1; \ - done - install_site_config: src/luarocks/site_config.lua mkdir -p "$(DESTDIR)$(LUADIR)/luarocks" cp src/luarocks/site_config.lua "$(DESTDIR)$(LUADIR)/luarocks" @@ -180,3 +148,4 @@ bootstrap: src/luarocks/site_config.lua install_site_config write_sysconfig clea '$(LUA_BINDIR)/lua$(LUA_SUFFIX)' -e "package.path=[[$(SAFEPWD)/src/?.lua;]]..package.path" src/bin/luarocks make rockspec --tree="$(PREFIX)" install_rock: install_bins install_luas + diff --git a/Makefile.install.inc b/Makefile.install.inc new file mode 100644 index 0000000..20d96a1 --- /dev/null +++ b/Makefile.install.inc @@ -0,0 +1,22 @@ + +.PHONY: install_bins install_luas + +install_bins: + mkdir -p "$(DESTDIR)$(BINDIR)" + cd src/bin && \ + luaver="$(LUA_VERSION)" && [ -n "$$luaver" ] || luaver=`$(LUA) -e 'print(_VERSION:sub(5))'`; \ + for f in $(BIN_FILES); \ + do \ + cp "$$f" "$(DESTDIR)$(BINDIR)/$$f-$$luaver"; \ + ln -nfs "$$f-$$luaver" "$(DESTDIR)$(BINDIR)/$$f"; \ + done + +install_luas: + mkdir -p "$(DESTDIR)$(LUADIR)/luarocks" + cd src/luarocks && for f in $(LUAROCKS_FILES); \ + do \ + d="$(DESTDIR)$(LUADIR)/luarocks"/`dirname "$$f"` && \ + mkdir -p "$$d" && \ + cp "$$f" "$$d" || exit 1; \ + done + diff --git a/Makefile.luarocks b/Makefile.luarocks new file mode 100644 index 0000000..1eecfea --- /dev/null +++ b/Makefile.luarocks @@ -0,0 +1,15 @@ + +include Makefile.setup.inc +include Makefile.install.inc + +.PHONY: all install copy_site_config + +all: + @echo This Makefile is used by the LuaRocks rockspec for upgrading itself. + +install: install_bins install_luas copy_site_config + +copy_site_config: + luaver="$(LUA_VERSION)" && [ -n "$$luaver" ] || luaver=`$(LUA) -e 'print(_VERSION:sub(5))'`; \ + mkdir -p "$(DESTDIR)$(LUADIR)/luarocks"; \ + cp $(LUAROCKS_PREFIX)/share/lua/$$luaver/luarocks/site_config.lua "$(DESTDIR)$(LUADIR)/luarocks" diff --git a/Makefile.setup.inc b/Makefile.setup.inc new file mode 100644 index 0000000..c228e78 --- /dev/null +++ b/Makefile.setup.inc @@ -0,0 +1,20 @@ + +DESTDIR = +PREFIX ?= /usr/local +BINDIR ?= $(PREFIX)/bin +LUADIR ?= $(PREFIX)/share/lua/$(LUA_VERSION)/ + +BIN_FILES = luarocks luarocks-admin +LUAROCKS_FILES = fs/unix/tools.lua fs/unix.lua fs/win32/tools.lua fs/win32.lua \ +fs/lua.lua persist.lua list.lua require.lua repos.lua dir.lua make_manifest.lua \ +command_line.lua config_cmd.lua install.lua build/command.lua build/cmake.lua \ +build/make.lua build/builtin.lua fetch/cvs.lua fetch/git.lua fetch/sscm.lua \ +tools/patch.lua fetch/svn.lua tools/zip.lua tools/tar.lua pack.lua type_check.lua \ +make.lua remove.lua fs.lua manif.lua add.lua deps.lua build.lua search.lua \ +show.lua manif_core.lua fetch.lua unpack.lua validate.lua cfg.lua download.lua \ +help.lua util.lua index.lua cache.lua refresh_cache.lua loader.lua \ +admin_remove.lua fetch/hg.lua fetch/git_file.lua new_version.lua lint.lua \ +purge.lua path.lua path_cmd.lua write_rockspec.lua doc.lua upload.lua \ +upload/api.lua upload/multipart.lua fetch/git_http.lua fetch/hg_http.lua \ +fetch/hg_https.lua fetch/hg_ssh.lua fetch/git_https.lua + @@ -1,22 +1,23 @@ -LuaRocks -======== +<p align="center"><a href="http://luarocks.org"><img border="0" src="http://keplerproject.github.io/luarocks/luarocks.png" alt="LuaRocks" width="500px"></a></p> A package manager for Lua modules. [![Build Status](https://travis-ci.org/keplerproject/luarocks.png?branch=master)](https://travis-ci.org/keplerproject/luarocks) +[![Build status](https://ci.appveyor.com/api/projects/status/4x4630tcf64da48i/branch/master?svg=true)](https://ci.appveyor.com/project/hishamhm/luarocks/branch/master) +[![Coverage Status](https://coveralls.io/repos/keplerproject/luarocks/badge.svg?branch=master)](https://coveralls.io/r/keplerproject/luarocks?branch=master) Main website: [luarocks.org](http://www.luarocks.org) It allows you to install Lua modules as self-contained packages called [*rocks*][1], which also contain version [dependency][2] information. This -information is used both during installation, so that when one rock is -requested all rocks it depends on are installed as well, and at run time, so -that when a module is required, the correct version is loaded. LuaRocks -supports both local and [remote][3] repositories, and multiple local rocks -trees. You can [download][4] and install LuaRocks on [Unix][5] and +information can be used both during installation, so that when one rock is +requested all rocks it depends on are installed as well, and also optionally +at run time, so that when a module is required, the correct version is loaded. +LuaRocks supports both local and [remote][3] repositories, and multiple local +rocks trees. You can [download][4] and install LuaRocks on [Unix][5] and [Windows][6]. -LuaRocks is free software and uses the same [license][7] as Lua 5.1. +LuaRocks is free software and uses the same [license][7] as Lua 5.x. [1]: http://luarocks.org/en/Types_of_rocks [2]: http://luarocks.org/en/Dependencies diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 0000000..d7fc7cc --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,30 @@ +version: 2.2.1.{build}-test + +shallow_clone: true + +environment: + LUAROCKS_VER: 2.2.1 + + matrix: + - LUA_VER: 5.1.5 + - LUA_VER: 5.2.4 + - LUA_VER: 5.3.1 + - LJ_VER: 2.0.4 + - LJ_VER: 2.1 + +init: +# Setup Lua development/build environment +# Make VS 2015 command line tools available +- call "%ProgramFiles(x86)%\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" %platform% + +install: +# Setup Lua development/build environment +- call .appveyor\install.bat + +build_script: +- call .appveyor\build.bat + +test_script: +- echo "Testing..." +- cd test +- call testing.bat @@ -40,7 +40,7 @@ system's package manager. Default is \$PREFIX --lua-version=VERSION Use specific Lua version: 5.1, 5.2, or 5.3 - Default is "$LUA_VERSION" + Default is auto-detected. --lua-suffix=SUFFIX Versioning suffix to use in Lua filenames. Default is "$LUA_SUFFIX" (lua$LUA_SUFFIX...) --with-lua=PREFIX Use Lua from given prefix. @@ -71,26 +71,7 @@ EOF # Helper functions find_program() { - path="$PATH" - item="`echo "$path" | sed 's/\([^:]*\):.*/\1/'`" - path="`echo "$path" | sed -n 's/[^:]*::*\(.*\)/\1/p'`" - found="no" - while [ -n "$item" ] - do - if [ -f "$item/$1" ] - then - found="yes" - break - fi - item="`echo "$path" | sed 's/\([^:]*\):.*/\1/'`" - path="`echo "$path" | sed -n 's/[^:]*::*\(.*\)/\1/p'`" - done - if [ "$found" = "yes" ] - then - echo "$item" - else - echo "" - fi + command -v "$1" 2>/dev/null } die() { @@ -177,7 +158,7 @@ do LUA_SUFFIX="$value" LUA_SUFFIX_SET=yes ;; - --lua-version) + --lua-version|--with-lua-version) [ -n "$value" ] || die "Missing value in flag $key." LUA_VERSION="$value" [ "$LUA_VERSION" = "5.1" -o "$LUA_VERSION" = "5.2" -o "$LUA_VERSION" = "5.3" ] || die "Invalid Lua version in flag $key." @@ -250,13 +231,13 @@ detect_lua_version() { LUA_VERSION=$detected_lua elif [ "$LUA_VERSION" != "$detected_lua" ] then - die "This clashes with the value of --with-lua-version. Please check your configuration." + die "This clashes with the value of --lua-version. Please check your configuration." fi fi } search_interpreter() { - LUA_SUFFIX="$1" + suffix="$1" if [ "$LUA_BINDIR_SET" = "yes" ] then find_lua="$LUA_BINDIR" @@ -269,10 +250,11 @@ search_interpreter() { else find_lua=`find_program lua$suffix` fi - if [ -n "$find_lua" ] + if [ -n "$find_lua" -a -x "$find_lua/lua$suffix" ] then - echo "Lua interpreter: $find_lua/lua$suffix..." - detect_lua_version "$find_lua/lua$suffix" + echo "Lua interpreter found: $find_lua/lua$suffix..." + LUA_SUFFIX=$suffix + detect_lua_version "$find_lua/lua$LUA_SUFFIX" return 0 fi return 1 @@ -292,9 +274,13 @@ then else suffixes="5.3 53 -5.3 -53 5.2 52 -5.2 -52 5.1 51 -5.1 -51" fi - for suffix in `echo $suffixes` "" + lua_interp_found=no + for suffix in "" `echo $suffixes` do - search_interpreter "$suffix" && break + search_interpreter "$suffix" && { + lua_interp_found=yes + break + } done fi @@ -313,7 +299,7 @@ then echo "lua$LUA_SUFFIX found in \$PATH: $find_lua" else echo "lua$LUA_SUFFIX not found in \$PATH." - die "You may want to use the flags --with-lua and/or --lua-suffix. See --help." + die "You may want to use the flags --with-lua, --with-lua-bin and/or --lua-suffix. See --help." fi fi @@ -332,6 +318,18 @@ then LUA_BINDIR="$LUA_DIR/bin" fi +if [ "$lua_interp_found" != "yes" ] +then + echo_n "Checking Lua interpreter... " + if [ -x "$LUA_BINDIR/lua$LUA_SUFFIX" ] + then + echo "lua$LUA_SUFFIX found in $LUA_BINDIR" + else + echo "lua$LUA_SUFFIX not found (looked in $LUA_BINDIR)" + die "You may want to use the flag --with-lua or --with-lua-bin. See --help." + fi +fi + echo_n "Checking Lua includes... " lua_h="$LUA_INCDIR/lua.h" if [ -f "$lua_h" ] @@ -419,6 +417,10 @@ then if [ -n "$GCC_ARCH" -a -d "/usr/lib/$GCC_ARCH" ] then MULTIARCH_SUBDIR="lib/$GCC_ARCH" + elif [ -d "/usr/lib64" ] + then + # Useful for Fedora systems + MULTIARCH_SUBDIR="lib64" fi fi diff --git a/install.bat b/install.bat index 52d2135..42b01c4 100644 --- a/install.bat +++ b/install.bat @@ -8,6 +8,9 @@ local vars = {} vars.PREFIX = nil
vars.VERSION = "2.2"
vars.SYSCONFDIR = nil
+vars.CONFBACKUPDIR = nil
+vars.SYSCONFFILENAME = nil
+vars.CONFIG_FILE = nil
vars.TREE_ROOT = nil
vars.TREE_BIN = nil
vars.TREE_LMODULE = nil
@@ -77,7 +80,7 @@ end local function exec(cmd)
--print(cmd)
- local status = os.execute(cmd)
+ local status = os.execute("type NUL && "..cmd)
return (status == 0 or status == true) -- compat 5.1/5.2
end
@@ -90,12 +93,12 @@ local function mkdir (dir) return exec([[.\win32\tools\mkdir -p "]]..dir..[[" >NUL]])
end
--- does the current user have admin priviledges ( = elevated)
+-- does the current user have admin privileges ( = elevated)
local function permission()
return exec("net session >NUL 2>&1") -- fails if not admin
end
--- rename file (full path) to backup (name only), appending number if required
+-- rename filename (full path) to backupname (name only), appending number if required
-- returns the new name (name only)
local function backup(filename, backupname)
local path = filename:match("(.+)%\\.-$").."\\"
@@ -119,14 +122,12 @@ local function print_help() Installs LuaRocks.
/P [dir] Where to install LuaRocks.
- Note that version; $VERSION, will be appended to this
- path, so "/P c:\luarocks\" will install in
- "c:\luarocks\$VERSION\"
Default is %PROGRAMFILES%\LuaRocks
Configuring the destinations:
-/TREE [dir] Root of the local tree of installed rocks.
- Default is %PROGRAMFILES%\LuaRocks\systree
+/TREE [dir] Root of the local system tree of installed rocks.
+ Default is {BIN}\..\ if {BIN} ends with '\bin'
+ otherwise it is {BIN}\systree.
/SCRIPTS [dir] Where to install commandline scripts installed by
rocks. Default is {TREE}\bin.
/LUAMOD [dir] Where to install Lua modules installed by rocks.
@@ -175,7 +176,7 @@ Other options: /F Remove installation directory if it already exists.
/NOREG Do not load registry info to register '.rockspec'
extension with LuaRocks commands (right-click).
-/NOADMIN The installer requires admin priviledges. If not
+/NOADMIN The installer requires admin privileges. If not
available it will elevate a new process. Use this
switch to prevent elevation, but make sure the
destination paths are all accessible for the current
@@ -253,7 +254,7 @@ local function check_flags() die("Cannot combine option /L with any of /LUA /BIN /LIB /INC")
end
if vars.LUA_VERSION ~= "5.1" then
- die("Bundled Lua version is 5.1, cannot install 5.2")
+ die("Bundled Lua version is 5.1, cannot install "..vars.LUA_VERSION)
end
end
if vars.LUA_VERSION ~= "5.1" then
@@ -319,7 +320,7 @@ local function look_for_interpreter (directory) return true
end
end
- print(" No Lua interpreter found")
+ --print(" No Lua interpreter found")
return false
end
@@ -360,7 +361,14 @@ local function look_for_headers (directory) die(S"lua.h not found in $LUA_INCDIR")
end
- for _, e in ipairs{ [[\]], [[\include\]]} do
+ for _, e in ipairs{
+ S([[\include\lua\$LUA_VERSION]]),
+ S([[\include\lua$LUA_SHORTV]]),
+ S([[\include\lua$LUA_VERSION]]),
+ S([[\include\$LUA_VERSION]]),
+ [[\include\]],
+ [[\]],
+ } do
print(" checking for "..directory..e.."\\lua.h")
if exists(directory..e.."\\lua.h") then
vars.LUA_INCDIR = directory..e
@@ -470,6 +478,28 @@ local function look_for_lua_install () return false
end
+-- backup config[x.x].lua[.bak] and site_config[_x_x].lua
+local function backup_config_files()
+ local temppath
+ while not temppath do
+ temppath = os.getenv("temp").."\\LR-config-backup-"..tostring(math.random(10000))
+ if exists(temppath) then temppath = nil end
+ end
+ vars.CONFBACKUPDIR = temppath
+ mkdir(vars.CONFBACKUPDIR)
+ exec(S[[COPY "$PREFIX\config*.*" "$CONFBACKUPDIR" >NUL]])
+ exec(S[[COPY "$PREFIX\lua\luarocks\site_config*.*" "$CONFBACKUPDIR" >NUL]])
+end
+
+-- restore previously backed up config files
+local function restore_config_files()
+ if not vars.CONFBACKUPDIR then return end -- there is no backup to restore
+ exec(S[[COPY "$CONFBACKUPDIR\config*.*" "$PREFIX" >NUL]])
+ exec(S[[COPY "$CONFBACKUPDIR\site_config*.*" "$PREFIX\lua\luarocks" >NUL]])
+ -- cleanup
+ exec(S[[RD /S /Q "$CONFBACKUPDIR"]])
+ vars.CONFBACKUPDIR = nil
+end
-- ***********************************************************
-- Installer script start
@@ -550,12 +580,12 @@ check_flags() if not permission() then
if not NOADMIN then
- -- must elevate the process with admin priviledges
+ -- must elevate the process with admin privileges
if not exec("PowerShell /? >NUL 2>&1") then
-- powershell is not available, so error out
- die("No administrative priviledges detected and cannot auto-elevate. Please run with admin priviledges or use the /NOADMIN switch")
+ die("No administrative privileges detected and cannot auto-elevate. Please run with admin privileges or use the /NOADMIN switch")
end
- print("Need admin priviledges, now elevating a new process to continue installing...")
+ print("Need admin privileges, now elevating a new process to continue installing...")
local runner = os.getenv("TEMP").."\\".."LuaRocks_Installer.bat"
local f = io.open(runner, "w")
f:write("@echo off\n")
@@ -567,21 +597,20 @@ if not permission() then f:close()
-- run the created temp batch file in elevated mode
exec("PowerShell -Command (New-Object -com 'Shell.Application').ShellExecute('"..runner.."', '', '', 'runas')\n")
- print("Now exiting unpriviledged installer")
+ print("Now exiting unprivileged installer")
os.exit() -- exit here, the newly created elevated process will do the installing
else
- print("Attempting to install without admin priviledges...")
+ print("Attempting to install without admin privileges...")
end
else
- print("Admin priviledges available for installing")
+ print("Admin privileges available for installing")
end
vars.PREFIX = vars.PREFIX or os.getenv("PROGRAMFILES")..[[\LuaRocks]]
-vars.FULL_PREFIX = S"$PREFIX\\$VERSION"
-vars.BINDIR = vars.FULL_PREFIX
-vars.LIBDIR = vars.FULL_PREFIX
-vars.LUADIR = S"$FULL_PREFIX\\lua"
-vars.INCDIR = S"$FULL_PREFIX\\include"
+vars.BINDIR = vars.PREFIX
+vars.LIBDIR = vars.PREFIX
+vars.LUADIR = S"$PREFIX\\lua"
+vars.INCDIR = S"$PREFIX\\include"
vars.LUA_SHORTV = vars.LUA_VERSION:gsub("%.", "")
if INSTALL_LUA then
@@ -602,15 +631,23 @@ else vars.UNAME_M = get_architecture() -- can only do when installation was found
end
-local datapath
-if vars.UNAME_M == "x86" then
- datapath = os.getenv("PROGRAMFILES") .. [[\LuaRocks]]
-else
- -- our target interpreter is 64bit, so the tree (with binaries) should go into 64bit program files
- datapath = os.getenv("ProgramW6432") .. [[\LuaRocks]]
+-- check location of system tree
+if not vars.TREE_ROOT then
+ -- no system tree location given, so we need to construct a default value
+ if vars.LUA_BINDIR:lower():match([[([\/]+bin[\/]*)$]]) then
+ -- lua binary is located in a 'bin' subdirectory, so assume
+ -- default Lua layout and match rocktree on top
+ vars.TREE_ROOT = vars.LUA_BINDIR:lower():gsub([[[\/]+bin[\/]*$]], [[\]])
+ else
+ -- no 'bin', so use a named tree next to the Lua executable
+ vars.TREE_ROOT = vars.LUA_BINDIR .. [[\systree]]
+ end
end
+
+local datapath
vars.SYSCONFDIR = vars.SYSCONFDIR or vars.PREFIX
-vars.TREE_ROOT = vars.TREE_ROOT or datapath..[[\systree]]
+vars.SYSCONFFILENAME = S"config-$LUA_VERSION.lua"
+vars.CONFIG_FILE = vars.SYSCONFDIR.."\\"..vars.SYSCONFFILENAME
if SELFCONTAINED then
vars.SYSCONFDIR = vars.PREFIX
vars.TREE_ROOT = vars.PREFIX..[[\systree]]
@@ -624,8 +661,8 @@ print(S[[ ==========================
Will configure LuaRocks with the following paths:
-LuaRocks : $FULL_PREFIX
-Config file : $SYSCONFDIR\config.lua
+LuaRocks : $PREFIX
+Config file : $CONFIG_FILE
Rocktree : $TREE_ROOT
Lua interpreter : $LUA_BINDIR\$LUA_INTERPRETER
@@ -653,17 +690,19 @@ print([[ -- ***********************************************************
-- Install LuaRocks files
-- ***********************************************************
-if FORCE then
- print(S"Removing $FULL_PREFIX...")
- exec(S[[RD /S /Q "$FULL_PREFIX"]])
- print()
-end
-if exists(vars.FULL_PREFIX) then
- die(S"$FULL_PREFIX exists. Use /F to force removal and reinstallation.")
+if exists(vars.PREFIX) then
+ if not FORCE then
+ die(S"$PREFIX exists. Use /F to force removal and reinstallation.")
+ else
+ backup_config_files()
+ print(S"Removing $PREFIX...")
+ exec(S[[RD /S /Q "$PREFIX"]])
+ print()
+ end
end
-print(S"Installing LuaRocks in $FULL_PREFIX...")
+print(S"Installing LuaRocks in $PREFIX...")
if not exists(vars.BINDIR) then
if not mkdir(vars.BINDIR) then
die()
@@ -729,7 +768,8 @@ IF NOT "%LUA_PATH_5_3%"=="" ( )
SET "PATH=$BINDIR;%PATH%"
"$LUA_BINDIR\$LUA_INTERPRETER" "$BINDIR\]]..c..[[.lua" %*
-IF NOT "%ERRORLEVEL%"=="2" GOTO EXITLR
+SET EXITCODE=%ERRORLEVEL%
+IF NOT "%EXITCODE%"=="2" GOTO EXITLR
REM Permission denied error, try and auto elevate...
REM already an admin? (checking to prevent loops)
@@ -754,48 +794,33 @@ ECHO ECHO Press any key to close this window... >> "%TMPFILE%" ECHO PAUSE ^> NUL >> "%TMPFILE%"
ECHO DEL "%TMPFILE%" >> "%TMPFILE%"
-ECHO Now retrying as a priviledged user...
+ECHO Now retrying as a privileged user...
PowerShell -Command (New-Object -com 'Shell.Application').ShellExecute('%TMPFILE%', '', '', 'runas')
:EXITLR
-ENDLOCAL
+exit /b %EXITCODE%
]])
f:close()
print(S"Created LuaRocks command: $BINDIR\\"..c..".bat")
end
--- part below was commented out as its purpose was unclear
--- see https://github.com/keplerproject/luarocks/pull/197#issuecomment-30176548
-
--- configure 'scripts' directory
--- if vars.TREE_BIN then
--- mkdir(vars.TREE_BIN)
--- if not USE_MINGW then
--- -- definitly not for MinGW because of conflicting runtimes
--- -- but is it ok to do it for others???
--- exec(S[[COPY lua5.1\bin\*.dll "$TREE_BIN" >NUL]])
--- end
--- else
--- if not USE_MINGW then
--- mkdir(S[[$TREE_ROOT\bin]])
--- -- definitly not for MinGW because of conflicting runtimes
--- -- but is it ok to do it for others???
--- exec(S[[COPY lua5.1\bin\*.dll "$TREE_ROOT"\bin >NUL]])
--- end
--- end
-
-- ***********************************************************
-- Configure LuaRocks
-- ***********************************************************
+restore_config_files()
print()
print("Configuring LuaRocks...")
-- Create a site-config file
-if exists(S[[$LUADIR\luarocks\site_config.lua]]) then
- exec(S[[RENAME "$LUADIR\luarocks\site_config.lua" site_config.lua.bak]])
+local site_config = S("site_config_$LUA_VERSION"):gsub("%.","_")
+if exists(S([[$LUADIR\luarocks\]]..site_config..[[.lua]])) then
+ local nname = backup(S([[$LUADIR\luarocks\]]..site_config..[[.lua]]), site_config..".lua.bak")
+ print("***************")
+ print("*** WARNING *** LuaRocks site_config file already exists: '"..site_config..".lua'. The old file has been renamed to '"..nname.."'")
+ print("***************")
end
-local f = io.open(vars.LUADIR.."\\luarocks\\site_config.lua", "w")
+local f = io.open(vars.LUADIR.."\\luarocks\\"..site_config..".lua", "w")
f:write(S[=[
local site_config = {}
site_config.LUA_INCDIR=[[$LUA_INCDIR]]
@@ -810,7 +835,7 @@ else end
f:write(S[=[
site_config.LUAROCKS_UNAME_M=[[$UNAME_M]]
-site_config.LUAROCKS_SYSCONFIG=[[$SYSCONFDIR\config.lua]]
+site_config.LUAROCKS_SYSCONFIG=[[$CONFIG_FILE]]
site_config.LUAROCKS_ROCKS_TREE=[[$TREE_ROOT]]
site_config.LUAROCKS_PREFIX=[[$PREFIX]]
site_config.LUAROCKS_DOWNLOADER=[[wget]]
@@ -819,24 +844,16 @@ site_config.LUAROCKS_MD5CHECKER=[[md5sum]] if FORCE_CONFIG then
f:write("site_config.LUAROCKS_FORCE_CONFIG=true\n")
end
-if exists(vars.LUADIR.."\\luarocks\\site_config.lua.bak") then
- for line in io.lines(vars.LUADIR.."\\luarocks\\site_config.lua.bak", "r") do
- f:write(line)
- f:write("\n")
- end
- exec(S[[DEL /F /Q "$LUADIR\luarocks\site_config.lua.bak"]])
-end
f:write("return site_config\n")
f:close()
-print(S[[Created LuaRocks site-config file: $LUADIR\luarocks\site_config.lua]])
+print(S([[Created LuaRocks site-config file: $LUADIR\luarocks\]]..site_config..[[.lua]]))
-- create config file
-vars.CONFIG_FILE = vars.SYSCONFDIR.."\\config.lua"
if not exists(vars.SYSCONFDIR) then
mkdir(vars.SYSCONFDIR)
end
if exists(vars.CONFIG_FILE) then
- local nname = backup(vars.CONFIG_FILE, "config.bak")
+ local nname = backup(vars.CONFIG_FILE, vars.SYSCONFFILENAME..".bak")
print("***************")
print(S"*** WARNING *** LuaRocks config file already exists: '$CONFIG_FILE'. The old file has been renamed to '"..nname.."'")
print("***************")
@@ -901,17 +918,17 @@ if REGISTRY then -- expand template with correct path information
print()
print([[Loading registry information for ".rockspec" files]])
- exec( S[[win32\lua5.1\bin\lua5.1.exe "$FULL_PREFIX\LuaRocks.reg.lua" "$FULL_PREFIX\LuaRocks.reg.template"]] )
- exec( S[[regedit /S "$FULL_PREFIX\\LuaRocks.reg"]] )
+ exec( S[[win32\lua5.1\bin\lua5.1.exe "$PREFIX\LuaRocks.reg.lua" "$PREFIX\LuaRocks.reg.template"]] )
+ exec( S[[regedit /S "$PREFIX\\LuaRocks.reg"]] )
end
-- ***********************************************************
-- Cleanup
-- ***********************************************************
-- remove regsitry related files, no longer needed
-exec( S[[del "$FULL_PREFIX\LuaRocks.reg.*" >NUL]] )
+exec( S[[del "$PREFIX\LuaRocks.reg.*" >NUL]] )
-- remove pe-parser module
-exec( S[[del "$FULL_PREFIX\pe-parser.lua" >NUL]] )
+exec( S[[del "$PREFIX\pe-parser.lua" >NUL]] )
-- ***********************************************************
-- Exit handlers
@@ -931,8 +948,8 @@ Lua interpreter; PATH : $LUA_BINDIR
PATHEXT : .LUA
LuaRocks;
- PATH : $FULL_PREFIX
- LUA_PATH : $FULL_PREFIX\lua\?.lua;$FULL_PREFIX\lua\?\init.lua
+ PATH : $PREFIX
+ LUA_PATH : $PREFIX\lua\?.lua;$PREFIX\lua\?\init.lua
Local user rocktree (Note: %APPDATA% is user dependent);
PATH : %APPDATA%\LuaRocks\bin
LUA_PATH : %APPDATA%\LuaRocks\share\lua\$LUA_VERSION\?.lua;%APPDATA%\LuaRocks\share\lua\$LUA_VERSION\?\init.lua
@@ -39,8 +39,8 @@ do cp "$i" "$out/$dir" if echo "$i" | grep -v "/bin/" | grep -q "^src/" then - grep -qw `basename "$i"` Makefile || { - echo "Missing ref in makefile: $i" + grep -qw `basename "$i"` Makefile.setup.inc || { + echo "Missing ref in Makefile.setup.inc: $i" touch "missing_ref" exit 1 } @@ -61,14 +61,14 @@ mkdir "release-windows" mv "$out" "release-windows/$out-win32" cd "release-unix/$out" -rm -rf makedist install.bat COPYING_lua COPYING_7z COPYING_win win32 lfw .travis.yml .gitignore +rm -rf makedist install.bat COPYING_lua COPYING_7z COPYING_win win32 lfw .travis.yml .gitignore appveyor* .appveyor cd .. tar czvpf ../"$out.tar.gz" "$out" cd .. rm -rf "release-unix" cd "release-windows/$out-win32" -rm -rf makedist Makefile configure lfw .travis.yml .gitignore +rm -rf makedist Makefile* configure lfw .travis.yml .gitignore test appveyor* .appveyor cd .. zip -r ../"$out-win32.zip" "$out-win32" cd .. @@ -1,7 +1,10 @@ package = "LuaRocks" -local VER = "2.2.0beta1" -local REV = "1" -version = VER.."-"..REV +local VER = "scm" +version = VER .. "-1" + +source = { + url = "--this rockspec is used by `make bootstrap` only--", +} description = { summary = "A deployment and management system for Lua modules.", @@ -23,16 +26,13 @@ dependencies = { "lua >= 5.1" } -source = { - url = "http://luarocks.org/releases/luarocks-"..VER..".tar.gz", -} - build = { type = "make", install_target = "install_rock", build_pass=false, install_variables = { BINDIR="$(BINDIR)", - LUADIR="$(LUADIR)" + LUADIR="$(LUADIR)", + LUA="$(LUA)", } } diff --git a/src/bin/luarocks b/src/bin/luarocks index d2f3c22..be6c2b8 100755 --- a/src/bin/luarocks +++ b/src/bin/luarocks @@ -27,6 +27,7 @@ commands = { purge = "luarocks.purge", doc = "luarocks.doc", upload = "luarocks.upload", + config = "luarocks.config_cmd", } command_line.run_command(...) diff --git a/src/luarocks/add.lua b/src/luarocks/add.lua index fc913c9..81adff9 100644 --- a/src/luarocks/add.lua +++ b/src/luarocks/add.lua @@ -50,7 +50,7 @@ local function add_files_to_server(refresh, rockfiles, server, upload_server) if not ok then return nil, err end local files = {} - for i, rockfile in ipairs(rockfiles) do + for _, rockfile in ipairs(rockfiles) do if fs.exists(rockfile) then util.printout("Copying file "..rockfile.." to "..local_cache.."...") local absolute = fs.absolute_name(rockfile) diff --git a/src/luarocks/admin_remove.lua b/src/luarocks/admin_remove.lua index 839121d..5a1cf20 100644 --- a/src/luarocks/admin_remove.lua +++ b/src/luarocks/admin_remove.lua @@ -46,7 +46,7 @@ local function remove_files_from_server(refresh, rockfiles, server, upload_serve if not ok then return nil, err end local nr_files = 0 - for i, rockfile in ipairs(rockfiles) do + for _, rockfile in ipairs(rockfiles) do local basename = dir.base_name(rockfile) local file = dir.path(local_cache, basename) util.printout("Removing file "..file.."...") diff --git a/src/luarocks/build.lua b/src/luarocks/build.lua index 01bfa9d..68f2026 100644 --- a/src/luarocks/build.lua +++ b/src/luarocks/build.lua @@ -37,6 +37,8 @@ or the name of a rock to be fetched from a repository. rockspec. Allows to specify a different branch to fetch. Particularly for SCM rocks. +--only-deps Installs only the dependencies of the rock. + ]]..util.deps_mode_help() --- Install files to a given location. @@ -130,17 +132,17 @@ function build.apply_patches(rockspec) end local function install_default_docs(name, version) - local patterns = { "readme", "license", "copying" } + local patterns = { "readme", "license", "copying", ".*%.md" } local dest = dir.path(path.install_dir(name, version), "doc") local has_dir = false - for name in fs.dir() do + for file in fs.dir() do for _, pattern in ipairs(patterns) do - if name:lower():match("^"..pattern) then + if file:lower():match("^"..pattern) then if not has_dir then fs.make_dir(dest) has_dir = true end - fs.copy(name, dest) + fs.copy(file, dest) break end end @@ -157,9 +159,10 @@ end -- @param deps_mode string: Dependency mode: "one" for the current default tree, -- "all" for all trees, "order" for all trees with priority >= the current default, -- "none" for no trees. +-- @param build_only_deps boolean: true to build the listed dependencies only. -- @return (string, string) or (nil, string, [string]): Name and version of -- installed rock if succeeded or nil and an error message followed by an error code. -function build.build_rockspec(rockspec_file, need_to_fetch, minimal_mode, deps_mode) +function build.build_rockspec(rockspec_file, need_to_fetch, minimal_mode, deps_mode, build_only_deps) assert(type(rockspec_file) == "string") assert(type(need_to_fetch) == "boolean") @@ -181,12 +184,19 @@ function build.build_rockspec(rockspec_file, need_to_fetch, minimal_mode, deps_m end end - local ok, err, errcode = deps.check_external_deps(rockspec, "build") + local name, version = rockspec.name, rockspec.version + if build_only_deps then + util.printout("Stopping after installing dependencies for " ..name.." "..version) + util.printout() + return name, version + end + + local ok + ok, err, errcode = deps.check_external_deps(rockspec, "build") if err then return nil, err, errcode end - local name, version = rockspec.name, rockspec.version if repos.is_installed(name, version) then repos.delete_version(name, version) end @@ -340,37 +350,41 @@ end -- @param deps_mode: string: Which trees to check dependencies for: -- "one" for the current default tree, "all" for all trees, -- "order" for all trees with priority >= the current default, "none" for no trees. +-- @param build_only_deps boolean: true to build the listed dependencies only. -- @return boolean or (nil, string, [string]): True if build was successful, -- or false and an error message and an optional error code. -function build.build_rock(rock_file, need_to_fetch, deps_mode) +function build.build_rock(rock_file, need_to_fetch, deps_mode, build_only_deps) assert(type(rock_file) == "string") assert(type(need_to_fetch) == "boolean") - - local unpack_dir, err, errcode = fetch.fetch_and_unpack_rock(rock_file) + + local ok, err, errcode + local unpack_dir + unpack_dir, err, errcode = fetch.fetch_and_unpack_rock(rock_file) if not unpack_dir then return nil, err, errcode end local rockspec_file = path.rockspec_name_from_rock(rock_file) - local ok, err = fs.change_dir(unpack_dir) + ok, err = fs.change_dir(unpack_dir) if not ok then return nil, err end - local ok, err, errcode = build.build_rockspec(rockspec_file, need_to_fetch, false, deps_mode) + ok, err, errcode = build.build_rockspec(rockspec_file, need_to_fetch, false, deps_mode, build_only_deps) fs.pop_dir() return ok, err, errcode end -local function do_build(name, version, deps_mode) +local function do_build(name, version, deps_mode, build_only_deps) if name:match("%.rockspec$") then - return build.build_rockspec(name, true, false, deps_mode) + return build.build_rockspec(name, true, false, deps_mode, build_only_deps) elseif name:match("%.src%.rock$") then - return build.build_rock(name, false, deps_mode) + return build.build_rock(name, false, deps_mode, build_only_deps) elseif name:match("%.all%.rock$") then local install = require("luarocks.install") - return install.install_binary_rock(name, deps_mode) + local install_fun = build_only_deps and install.install_binary_rock_deps or install.install_binary_rock + return install_fun(name, deps_mode) elseif name:match("%.rock$") then - return build.build_rock(name, true, deps_mode) + return build.build_rock(name, true, deps_mode, build_only_deps) elseif not name:match(dir.separator) then local search = require("luarocks.search") - return search.act_on_src_or_rockspec(build.run, name:lower(), version, deps.deps_mode_to_flag(deps_mode)) + return search.act_on_src_or_rockspec(build.run, name:lower(), version, deps.deps_mode_to_flag(deps_mode), build_only_deps and "--only-deps") end return nil, "Don't know what to do with "..name end @@ -395,9 +409,12 @@ function build.run(...) else local ok, err = fs.check_command_permissions(flags) if not ok then return nil, err, cfg.errorcodes.PERMISSIONDENIED end - ok, err = do_build(name, version, deps.get_deps_mode(flags)) + ok, err = do_build(name, version, deps.get_deps_mode(flags), flags["only-deps"]) if not ok then return nil, err end local name, version = ok, err + if flags["only-deps"] then + return name, version + end if (not flags["keep"]) and not cfg.keep_other_versions then local ok, err = remove.remove_other_versions(name, version, flags["force"]) if not ok then util.printerr(err) end diff --git a/src/luarocks/build/builtin.lua b/src/luarocks/build/builtin.lua index 47aa71f..00fd09e 100644 --- a/src/luarocks/build/builtin.lua +++ b/src/luarocks/build/builtin.lua @@ -74,7 +74,7 @@ function builtin.run(rockspec) add_flags(extras, "-I%s", incdirs) return execute(variables.CC.." "..variables.CFLAGS, "-c", "-o", object, "-I"..variables.LUA_INCDIR, source, unpack(extras)) end - compile_library = function(library, objects, libraries, libdirs, name) + compile_library = function(library, objects, libraries, libdirs) local extras = { unpack(objects) } add_flags(extras, "-L%s", libdirs) add_flags(extras, "-l%s", libraries) @@ -138,7 +138,7 @@ function builtin.run(rockspec) local resname = basename..".res" local wrapname = basename..".exe" make_rc(fullname, fullbasename..".rc") - local ok = execute(variables.RC, "-r", "-fo"..resname, rcname) + local ok = execute(variables.RC, "-nologo", "-r", "-fo"..resname, rcname) if not ok then return ok end ok = execute(variables.CC.." "..variables.CFLAGS, "-c", "-Fo"..object, "-I"..variables.LUA_INCDIR, variables.WRAPPER) @@ -170,7 +170,7 @@ function builtin.run(rockspec) end return execute(variables.LD.." "..variables.LIBFLAG, "-o", library, "-L"..variables.LUA_LIBDIR, unpack(extras)) end - compile_wrapper_binary = function(fullname, name) return true, name end + compile_wrapper_binary = function(_, name) return true, name end --TODO EXEWRAPPER end @@ -196,7 +196,9 @@ function builtin.run(rockspec) end end - + if not build.modules then + return nil, "Missing build.modules table" + end for name, info in pairs(build.modules) do local moddir = path.module_to_path(name) if type(info) == "string" then diff --git a/src/luarocks/build/cmake.lua b/src/luarocks/build/cmake.lua index ed2af3f..7b16fa5 100644 --- a/src/luarocks/build/cmake.lua +++ b/src/luarocks/build/cmake.lua @@ -15,7 +15,7 @@ function cmake.run(rockspec) assert(type(rockspec) == "table") local build = rockspec.build local variables = build.variables or {} - + -- Pass Env variables variables.CMAKE_MODULE_PATH=os.getenv("CMAKE_MODULE_PATH") variables.CMAKE_LIBRARY_PATH=os.getenv("CMAKE_LIBRARY_PATH") @@ -23,10 +23,11 @@ function cmake.run(rockspec) util.variable_substitutions(variables, rockspec.variables) - if not fs.execute_quiet(rockspec.variables.CMAKE, "--help") then - return nil, "'"..rockspec.variables.CMAKE.."' program not found. Is cmake installed? You may want to edit variables.CMAKE" + local ok, err_msg = fs.is_tool_available(rockspec.variables.CMAKE, "CMake") + if not ok then + return nil, err_msg end - + -- If inline cmake is present create CMakeLists.txt from it. if type(build.cmake) == "string" then local cmake_handler = assert(io.open(fs.current_dir().."/CMakeLists.txt", "w")) @@ -34,25 +35,29 @@ function cmake.run(rockspec) cmake_handler:close() end - -- Execute cmake with variables. local args = "" + + -- Try to pick the best generator. With msvc and x64, CMake does not select it by default so we need to be explicit. if cfg.cmake_generator then args = args .. ' -G"'..cfg.cmake_generator.. '"' + elseif cfg.is_platform("windows") and cfg.target_cpu:match("x86_64$") then + args = args .. " -DCMAKE_GENERATOR_PLATFORM=x64" end + for k,v in pairs(variables) do - args = args .. ' -D' ..k.. '="' ..v.. '"' + args = args .. ' -D' ..k.. '="' ..tostring(v).. '"' end - if not fs.execute_string(rockspec.variables.CMAKE.." . " ..args) then + if not fs.execute_string(rockspec.variables.CMAKE.." -H. -Bbuild.luarocks "..args) then return nil, "Failed cmake." end - - if not fs.execute_string(rockspec.variables.MAKE.." -fMakefile") then + + if not fs.execute_string(rockspec.variables.CMAKE.." --build build.luarocks --config Release") then return nil, "Failed building." end - if not fs.execute_string(rockspec.variables.MAKE.." -fMakefile install") then + if not fs.execute_string(rockspec.variables.CMAKE.." --build build.luarocks --target install --config Release") then return nil, "Failed installing." end return true diff --git a/src/luarocks/cfg.lua b/src/luarocks/cfg.lua index b2acfcc..e3d6e74 100644 --- a/src/luarocks/cfg.lua +++ b/src/luarocks/cfg.lua @@ -32,10 +32,12 @@ if not ok then site_config = {} end -cfg.site_config = site_config - -cfg.program_version = "2.2.0beta1" -cfg.major_version = cfg.program_version:match("([^.]%.[^.])") +cfg.program_version = "scm" +cfg.program_series = "2.2" +cfg.major_version = (cfg.program_version:match("([^.]%.[^.])")) or cfg.program_series +cfg.variables = {} +cfg.rocks_trees = {} +cfg.platforms = {} local persist = require("luarocks.persist") @@ -43,6 +45,8 @@ cfg.errorcodes = setmetatable({ OK = 0, UNSPECIFIED = 1, PERMISSIONDENIED = 2, + CONFIGFILE = 3, + CRASH = 99 },{ __index = function(t, key) local val = rawget(t, key) @@ -67,67 +71,86 @@ end -- System detection: -local detected = {} -local system,proc - -- A proper installation of LuaRocks will hardcode the system -- and proc values with site_config.LUAROCKS_UNAME_S and site_config.LUAROCKS_UNAME_M, -- so that this detection does not run every time. When it is -- performed, we use the Unix way to identify the system, -- even on Windows (assuming UnxUtils or Cygwin). -system = site_config.LUAROCKS_UNAME_S or io.popen("uname -s"):read("*l") -proc = site_config.LUAROCKS_UNAME_M or io.popen("uname -m"):read("*l") +local system = site_config.LUAROCKS_UNAME_S or io.popen("uname -s"):read("*l") +local proc = site_config.LUAROCKS_UNAME_M or io.popen("uname -m"):read("*l") if proc:match("i[%d]86") then - proc = "x86" + cfg.target_cpu = "x86" elseif proc:match("amd64") or proc:match("x86_64") then - proc = "x86_64" + cfg.target_cpu = "x86_64" elseif proc:match("Power Macintosh") then - proc = "powerpc" + cfg.target_cpu = "powerpc" + else + cfg.target_cpu = proc end if system == "FreeBSD" then - detected.unix = true - detected.freebsd = true - detected.bsd = true + cfg.platforms.unix = true + cfg.platforms.freebsd = true + cfg.platforms.bsd = true elseif system == "OpenBSD" then - detected.unix = true - detected.openbsd = true - detected.bsd = true + cfg.platforms.unix = true + cfg.platforms.openbsd = true + cfg.platforms.bsd = true elseif system == "NetBSD" then - detected.unix = true - detected.netbsd = true - detected.bsd = true + cfg.platforms.unix = true + cfg.platforms.netbsd = true + cfg.platforms.bsd = true elseif system == "Darwin" then - detected.unix = true - detected.macosx = true - detected.bsd = true + cfg.platforms.unix = true + cfg.platforms.macosx = true + cfg.platforms.bsd = true elseif system == "Linux" then - detected.unix = true - detected.linux = true + cfg.platforms.unix = true + cfg.platforms.linux = true elseif system == "SunOS" then - detected.unix = true - detected.solaris = true + cfg.platforms.unix = true + cfg.platforms.solaris = true elseif system and system:match("^CYGWIN") then - detected.unix = true - detected.cygwin = true + cfg.platforms.unix = true + cfg.platforms.cygwin = true elseif system and system:match("^Windows") then - detected.windows = true + cfg.platforms.windows = true + cfg.platforms.win32 = true elseif system and system:match("^MINGW") then - detected.windows = true - detected.mingw32 = true + cfg.platforms.windows = true + cfg.platforms.mingw32 = true + cfg.platforms.win32 = true else - detected.unix = true + cfg.platforms.unix = true -- Fall back to Unix in unknown systems. end --- Path configuration: +-- Set order for platform overrides +local platform_order = { + -- Unixes + unix = 1, + bsd = 2, + solaris = 3, + netbsd = 4, + openbsd = 5, + freebsd = 6, + linux = 7, + macosx = 8, + cygwin = 9, + -- Windows + win32 = 10, + mingw32 = 11, + windows = 12 } + +-- Path configuration: local sys_config_file, home_config_file +local sys_config_file_default, home_config_file_default local sys_config_dir, home_config_dir local sys_config_ok, home_config_ok = false, false local extra_luarocks_module_dir sys_config_dir = site_config.LUAROCKS_SYSCONFDIR -if detected.windows then +if cfg.platforms.windows then cfg.home = os.getenv("APPDATA") or "c:" sys_config_dir = sys_config_dir or "c:/luarocks" home_config_dir = cfg.home.."/luarocks" @@ -136,54 +159,105 @@ else cfg.home = os.getenv("HOME") or "" sys_config_dir = sys_config_dir or "/etc/luarocks" home_config_dir = cfg.home.."/.luarocks" - cfg.home_tree = cfg.home.."/.luarocks/" + cfg.home_tree = (os.getenv("USER") ~= "root") and cfg.home.."/.luarocks/" end -cfg.variables = {} -cfg.rocks_trees = {} +-- Create global environment for the config files; +local env_for_config_file = function() + local e + e = { + home = cfg.home, + lua_version = cfg.lua_version, + platforms = util.make_shallow_copy(cfg.platforms), + processor = cfg.target_cpu, -- remains for compat reasons + target_cpu = cfg.target_cpu, -- replaces `processor` + os_getenv = os.getenv, + dump_env = function() + -- debug function, calling it from a config file will show all + -- available globals to that config file + print(util.show_table(e, "global environment")) + end, + } + return e +end -sys_config_file = site_config.LUAROCKS_SYSCONFIG or sys_config_dir.."/config-"..cfg.lua_version..".lua" -local err -sys_config_ok, err = persist.load_into_table(sys_config_file, cfg) +-- Merge values from config files read into the `cfg` table +local merge_overrides = function(overrides) + -- remove some stuff we do not want to integrate + overrides.os_getenv = nil + overrides.dump_env = nil + -- remove tables to be copied verbatim instead of deeply merged + if overrides.rocks_trees then cfg.rocks_trees = nil end + if overrides.rocks_servers then cfg.rocks_servers = nil end + -- perform actual merge + util.deep_merge(cfg, overrides) +end -if not sys_config_ok then - sys_config_file = sys_config_dir.."/config.lua" - sys_config_ok, err = persist.load_into_table(sys_config_file, cfg) +-- load config file from a list until first succesful one. Info is +-- added to `cfg` module table, returns filepath of succesfully loaded +-- file or nil if it failed +local load_config_file = function(list) + for _, filepath in ipairs(list) do + local result, err, errcode = persist.load_into_table(filepath, env_for_config_file()) + if (not result) and errcode ~= "open" then + -- errcode is either "load" or "run"; bad config file, so error out + io.stderr:write(err.."\n") + os.exit(cfg.errorcodes.CONFIGFILE) + end + if result then + -- succes in loading and running, merge contents and exit + merge_overrides(result) + return filepath + end + end + return nil -- nothing was loaded end -if err and sys_config_ok == nil then - io.stderr:write(err.."\n") + + +-- Load system configuration file +do + sys_config_file_default = sys_config_dir.."/config-"..cfg.lua_version..".lua" + sys_config_file = load_config_file({ + site_config.LUAROCKS_SYSCONFIG or sys_config_file_default, + sys_config_dir.."/config.lua", + }) + sys_config_ok = (sys_config_file ~= nil) end +-- Load user configuration file (if allowed) if not site_config.LUAROCKS_FORCE_CONFIG then - local home_overrides, err - home_config_file = os.getenv("LUAROCKS_CONFIG_" .. version_suffix) or os.getenv("LUAROCKS_CONFIG") - if home_config_file then - home_overrides, err = persist.load_into_table(home_config_file, { home = cfg.home, lua_version = cfg.lua_version }) - else - home_config_file = home_config_dir.."/config-"..cfg.lua_version..".lua" - home_overrides, err = persist.load_into_table(home_config_file, { home = cfg.home, lua_version = cfg.lua_version }) - if not home_overrides then - home_config_file = home_config_dir.."/config.lua" - home_overrides, err = persist.load_into_table(home_config_file, { home = cfg.home, lua_version = cfg.lua_version }) - end + + home_config_file_default = home_config_dir.."/config-"..cfg.lua_version..".lua" + + local config_env_var = "LUAROCKS_CONFIG_" .. version_suffix + local config_env_value = os.getenv(config_env_var) + if not config_env_value then + config_env_var = "LUAROCKS_CONFIG" + config_env_value = os.getenv(config_env_var) end - if home_overrides then - home_config_ok = true - if home_overrides.rocks_trees then - cfg.rocks_trees = nil - end - if home_overrides.rocks_servers then - cfg.rocks_servers = nil - end - util.deep_merge(cfg, home_overrides) - else -- nil or false - home_config_ok = home_overrides - if err and home_config_ok == nil then - io.stderr:write(err.."\n") + + -- first try environment provided file, so we can explicitly warn when it is missing + if config_env_value then + local list = { config_env_value } + home_config_file = load_config_file(list) + home_config_ok = (home_config_file ~= nil) + if not home_config_ok then + io.stderr:write("Warning: could not load configuration file `"..config_env_value.."` given in environment variable "..config_env_var.."\n") end end + + -- try the alternative defaults if there was no environment specified file or it didn't work + if not home_config_ok then + local list = { + home_config_file_default, + home_config_dir.."/config.lua", + } + home_config_file = load_config_file(list) + home_config_ok = (home_config_file ~= nil) + end end + if not next(cfg.rocks_trees) then if cfg.home_tree then table.insert(cfg.rocks_trees, { name = "user", root = cfg.home_tree } ) @@ -193,17 +267,37 @@ if not next(cfg.rocks_trees) then end end --- Configure defaults: -local root = cfg.rocks_trees[#cfg.rocks_trees] +-- update platforms list; keyed -> array +do + local lst = {} -- use temp array to not confuse `pairs` in loop + for plat in pairs(cfg.platforms) do + if cfg.platforms[plat] then -- entries set to 'false' skipped + if not platform_order[plat] then + local pl = "" + for k,_ in pairs(platform_order) do pl = pl .. ", " .. k end + io.stderr:write("Bad platform given; "..tostring(plat)..". Valid entries are: "..pl:sub(3,-1) ..".\n") + os.exit(cfg.errorcodes.CONFIGFILE) + end + table.insert(lst, plat) + else + cfg.platforms[plat] = nil + end + end + -- platform overrides depent on the order, so set priorities + table.sort(lst, function(key1, key2) return platform_order[key1] < platform_order[key2] end) + util.deep_merge(cfg.platforms, lst) +end + +-- Configure defaults: local defaults = { local_by_default = false, - use_extensions = false, accept_unknown_fields = false, fs_use_modules = true, hooks_enabled = true, deps_mode = "one", + check_certificates = false, lua_modules_path = "/share/lua/"..cfg.lua_version, lib_modules_path = "/lib/lua/"..cfg.lua_version, @@ -215,17 +309,17 @@ local defaults = { rocks_servers = { { - "https://rocks.moonscript.org", + "https://luarocks.org", "https://raw.githubusercontent.com/rocks-moonscript-org/moonrocks-mirror/master/", "http://luafr.org/moonrocks/", "http://luarocks.logiceditor.com/rocks", } }, disabled_servers = {}, - + upload = { - server = "https://rocks.moonscript.org", - tool_version = "0.0.1", + server = "https://luarocks.org", + tool_version = "1.0.0", api_version = "1", }, @@ -260,7 +354,6 @@ local defaults = { FIND = "find", TEST = "test", CHMOD = "chmod", - PATCH = "patch", ZIP = "zip", UNZIP = "unzip -n", @@ -272,12 +365,15 @@ local defaults = { OPENSSL = "openssl", MD5 = "md5", STAT = "stat", + TOUCH = "touch", CMAKE = "cmake", SEVENZ = "7z", RSYNCFLAGS = "--exclude=.git -Oavz", STATFLAG = "-c '%a'", + CURLNOCERTFLAG = "", + WGETNOCERTFLAG = "", }, external_deps_subdirs = site_config.LUAROCKS_EXTERNAL_DEPS_SUBDIRS or { @@ -294,14 +390,13 @@ local defaults = { rocks_provided = {} } -if detected.windows then - local full_prefix = site_config.LUAROCKS_PREFIX.."\\"..cfg.major_version +if cfg.platforms.windows then + local full_prefix = (site_config.LUAROCKS_PREFIX or (os.getenv("PROGRAMFILES")..[[\LuaRocks]])) extra_luarocks_module_dir = full_prefix.."\\lua\\?.lua" home_config_file = home_config_file and home_config_file:gsub("\\","/") defaults.fs_use_modules = false - defaults.arch = "win32-"..proc - defaults.platforms = {"win32", "windows" } + defaults.arch = "win32-"..cfg.target_cpu defaults.lib_extension = "dll" defaults.external_lib_extension = "dll" defaults.obj_extension = "obj" @@ -309,7 +404,7 @@ if detected.windows then defaults.variables.LUA_BINDIR = site_config.LUA_BINDIR and site_config.LUA_BINDIR:gsub("\\", "/") or "c:/lua"..cfg.lua_version.."/bin" defaults.variables.LUA_INCDIR = site_config.LUA_INCDIR and site_config.LUA_INCDIR:gsub("\\", "/") or "c:/lua"..cfg.lua_version.."/include" defaults.variables.LUA_LIBDIR = site_config.LUA_LIBDIR and site_config.LUA_LIBDIR:gsub("\\", "/") or "c:/lua"..cfg.lua_version.."/lib" - defaults.cmake_generator = "MinGW Makefiles" + defaults.makefile = "Makefile.win" defaults.variables.MAKE = "nmake" defaults.variables.CC = "cl" @@ -318,8 +413,8 @@ if detected.windows then defaults.variables.LD = "link" defaults.variables.MT = "mt" defaults.variables.LUALIB = "lua"..cfg.lua_version..".lib" - defaults.variables.CFLAGS = "/MD /O2" - defaults.variables.LIBFLAG = "/dll" + defaults.variables.CFLAGS = "/nologo /MD /O2" + defaults.variables.LIBFLAG = "/nologo /dll" local bins = { "SEVENZ", "CP", "FIND", "LS", "MD5SUM", "MKDIR", "MV", "PWD", "RMDIR", "TEST", "UNAME", "WGET" } @@ -354,8 +449,7 @@ if detected.windows then defaults.web_browser = "start" end -if detected.mingw32 then - defaults.platforms = { "win32", "mingw32", "windows" } +if cfg.platforms.mingw32 then defaults.obj_extension = "o" defaults.cmake_generator = "MinGW Makefiles" defaults.variables.MAKE = "mingw32-make" @@ -379,7 +473,7 @@ if detected.mingw32 then end -if detected.unix then +if cfg.platforms.unix then defaults.lib_extension = "so" defaults.external_lib_extension = "so" defaults.obj_extension = "o" @@ -389,7 +483,6 @@ if detected.unix then defaults.variables.LUA_LIBDIR = site_config.LUA_LIBDIR or "/usr/local/lib" defaults.variables.CFLAGS = "-O2" defaults.cmake_generator = "Unix Makefiles" - defaults.platforms = { "unix" } defaults.variables.CC = "gcc" defaults.variables.LD = "gcc" defaults.gcc_rpath = true @@ -416,66 +509,63 @@ if detected.unix then defaults.web_browser = "xdg-open" end -if detected.cygwin then +if cfg.platforms.cygwin then defaults.lib_extension = "so" -- can be overridden in the config file for mingw builds - defaults.arch = "cygwin-"..proc - defaults.platforms = {"unix", "cygwin"} + defaults.arch = "cygwin-"..cfg.target_cpu defaults.cmake_generator = "Unix Makefiles" defaults.variables.CC = "echo -llua | xargs gcc" defaults.variables.LD = "echo -llua | xargs gcc" defaults.variables.LIBFLAG = "-shared" end -if detected.bsd then +if cfg.platforms.bsd then defaults.variables.MAKE = "gmake" defaults.variables.STATFLAG = "-f '%OLp'" end -if detected.macosx then +if cfg.platforms.macosx then defaults.variables.MAKE = "make" defaults.external_lib_extension = "dylib" - defaults.arch = "macosx-"..proc - defaults.platforms = {"unix", "bsd", "macosx"} + defaults.arch = "macosx-"..cfg.target_cpu defaults.variables.LIBFLAG = "-bundle -undefined dynamic_lookup -all_load" + defaults.variables.STAT = "/usr/bin/stat" defaults.variables.STATFLAG = "-f '%A'" local version = io.popen("sw_vers -productVersion"):read("*l") version = tonumber(version and version:match("^[^.]+%.([^.]+)")) or 3 - if version >= 5 then + if version >= 10 then + version = 8 + elseif version >= 5 then version = 5 else defaults.gcc_rpath = false end - defaults.variables.CC = "export MACOSX_DEPLOYMENT_TARGET=10."..version.."; gcc" - defaults.variables.LD = "export MACOSX_DEPLOYMENT_TARGET=10."..version.."; gcc" + defaults.variables.CC = "env MACOSX_DEPLOYMENT_TARGET=10."..version.." gcc" + defaults.variables.LD = "env MACOSX_DEPLOYMENT_TARGET=10."..version.." gcc" defaults.web_browser = "open" end -if detected.linux then - defaults.arch = "linux-"..proc - defaults.platforms = {"unix", "linux"} +if cfg.platforms.linux then + defaults.arch = "linux-"..cfg.target_cpu end -if detected.freebsd then - defaults.arch = "freebsd-"..proc - defaults.platforms = {"unix", "bsd", "freebsd"} +if cfg.platforms.freebsd then + defaults.arch = "freebsd-"..cfg.target_cpu defaults.gcc_rpath = false defaults.variables.CC = "cc" defaults.variables.LD = "cc" end -if detected.openbsd then - defaults.arch = "openbsd-"..proc - defaults.platforms = {"unix", "bsd", "openbsd"} +if cfg.platforms.openbsd then + defaults.arch = "openbsd-"..cfg.target_cpu end -if detected.netbsd then - defaults.arch = "netbsd-"..proc - defaults.platforms = {"unix", "bsd", "netbsd"} +if cfg.platforms.netbsd then + defaults.arch = "netbsd-"..cfg.target_cpu end -if detected.solaris then - defaults.arch = "solaris-"..proc - defaults.platforms = {"unix", "solaris"} +if cfg.platforms.solaris then + defaults.arch = "solaris-"..cfg.target_cpu + --defaults.platforms = {"unix", "solaris"} defaults.variables.MAKE = "gmake" end @@ -532,6 +622,11 @@ local cfg_mt = { } setmetatable(cfg, cfg_mt) +if not cfg.check_certificates then + cfg.variables.CURLNOCERTFLAG = "-k" + cfg.variables.WGETNOCERTFLAG = "--no-check-certificate" +end + function cfg.make_paths_from_tree(tree) local lua_path, lib_path, bin_path if type(tree) == "string" then @@ -555,7 +650,7 @@ function cfg.package_paths() table.insert(new_cpath, lib_path.."/?."..cfg.lib_extension) table.insert(new_bin, bin_path) end - if extra_luarocks_module_dir then + if extra_luarocks_module_dir then table.insert(new_path, extra_luarocks_module_dir) end return table.concat(new_path, ";"), table.concat(new_cpath, ";"), table.concat(new_bin, cfg.export_path_separator) @@ -568,11 +663,24 @@ function cfg.init_package_paths() end function cfg.which_config() - return sys_config_file, sys_config_ok, home_config_file, home_config_ok + return { + system = { + file = sys_config_file or sys_config_file_default, + ok = sys_config_ok, + }, + user = { + file = home_config_file or home_config_file_default, + ok = home_config_ok, + } + } end cfg.user_agent = "LuaRocks/"..cfg.program_version.." "..cfg.arch +cfg.http_proxy = os.getenv("http_proxy") +cfg.https_proxy = os.getenv("https_proxy") +cfg.no_proxy = os.getenv("no_proxy") + --- Check if platform was detected -- @param query string: The platform name to check. -- @return boolean: true if LuaRocks is currently running on queried platform. diff --git a/src/luarocks/command_line.lua b/src/luarocks/command_line.lua index cc2e168..dbf64b9 100644 --- a/src/luarocks/command_line.lua +++ b/src/luarocks/command_line.lua @@ -10,6 +10,7 @@ local cfg = require("luarocks.cfg") local path = require("luarocks.path") local dir = require("luarocks.dir") local deps = require("luarocks.deps") +local fs = require("luarocks.fs") local program = util.this_program("luarocks") @@ -21,7 +22,7 @@ local function die(message, exitcode) local ok, err = pcall(util.run_scheduled_functions) if not ok then - util.printerr("\nLuaRocks "..cfg.program_version.." internal bug (please report at luarocks-developers@lists.sourceforge.net):\n"..err) + util.printerr("\nLuaRocks "..cfg.program_version.." internal bug (please report at https://github.com/keplerproject/luarocks/issues):\n"..err) end util.printerr("\nError: "..message) os.exit(exitcode or cfg.errorcodes.UNSPECIFIED) @@ -63,6 +64,9 @@ function command_line.run_command(...) end local nonflags = { util.parse_flags(unpack(args)) } local flags = table.remove(nonflags, 1) + if flags.ERROR then + die(flags.ERROR.." See --help.") + end if flags["from"] then flags["server"] = flags["from"] end if flags["only-from"] then flags["only-server"] = flags["only-from"] end @@ -79,7 +83,6 @@ function command_line.run_command(...) if flags["verbose"] then -- setting it in the config file will kick-in earlier in the process cfg.verbose = true - local fs = require("luarocks.fs") fs.verbose() end @@ -110,12 +113,6 @@ function command_line.run_command(...) end end command = command:gsub("-", "_") - - if flags["extensions"] then - cfg.use_extensions = true - local type_check = require("luarocks.type_check") - type_check.load_extensions() - end if cfg.local_by_default then flags["local"] = true @@ -126,16 +123,10 @@ function command_line.run_command(...) end if flags["branch"] then - if flags["branch"] == true or flags["branch"] == "" then - die("Argument error: use --branch=<branch-name>") - end cfg.branch = flags["branch"] end if flags["tree"] then - if flags["tree"] == true or flags["tree"] == "" then - die("Argument error: use --tree=<path>") - end local named = false for _, tree in ipairs(cfg.rocks_trees) do if type(tree) == "table" and flags["tree"] == tree.name then @@ -153,6 +144,11 @@ function command_line.run_command(...) replace_tree(flags, args, root_dir) end elseif flags["local"] then + if not cfg.home_tree then + die("The --local flag is meant for operating in a user's home directory.\n".. + "You are running as a superuser, which is intended for system-wide operation.\n".. + "To force using the superuser's home, use --tree explicitly.") + end replace_tree(flags, args, cfg.home_tree) else local trees = cfg.rocks_trees @@ -173,17 +169,11 @@ function command_line.run_command(...) cfg.variables.SCRIPTS_DIR = cfg.deploy_bin_dir if flags["server"] then - if flags["server"] == true then - die("Argument error: use --server=<url>") - end local protocol, path = dir.split_url(flags["server"]) table.insert(cfg.rocks_servers, 1, protocol.."://"..path) end if flags["only-server"] then - if flags["only-server"] == true then - die("Argument error: use --only-server=<url>") - end cfg.rocks_servers = { flags["only-server"] } end @@ -196,6 +186,10 @@ function command_line.run_command(...) cfg.variables[k] = v end end + + if not fs.current_dir() or fs.current_dir() == "" then + die("Current directory does not exist. Please run LuaRocks from an existing directory.") + end if commands[command] then -- TODO the interface of run should be modified, to receive the @@ -207,8 +201,8 @@ function command_line.run_command(...) local cmd = require(commands[command]) local xp, ok, err, exitcode = xpcall(function() return cmd.run(unpack(args)) end, function(err) die(debug.traceback("LuaRocks "..cfg.program_version - .." bug (please report at luarocks-developers@lists.sourceforge.net).\n" - ..err, 2)) + .." bug (please report at https://github.com/keplerproject/luarocks/issues).\n" + ..err, 2), cfg.errorcodes.CRASH) end) if xp and (not ok) then die(err, exitcode) diff --git a/src/luarocks/config_cmd.lua b/src/luarocks/config_cmd.lua new file mode 100644 index 0000000..bf282a7 --- /dev/null +++ b/src/luarocks/config_cmd.lua @@ -0,0 +1,73 @@ +--- Module implementing the LuaRocks "config" command. +-- Queries information about the LuaRocks configuration. +local config_cmd = {} + +local cfg = require("luarocks.cfg") +local util = require("luarocks.util") +local dir = require("luarocks.dir") + +config_cmd.help_summary = "Query information about the LuaRocks configuration." +config_cmd.help_arguments = "<flag>" +config_cmd.help = [[ +--lua-incdir Path to Lua header files. + +--lua-libdir Path to Lua library files. + +--lua-ver Lua version (in major.minor format). e.g. 5.1 + +--system-config Location of the system config file. + +--user-config Location of the user config file. + +--rock-trees Rocks trees in use. First the user tree, then the system tree. +]] + +local function config_file(conf) + print(dir.normalize(conf.file)) + if conf.ok then + return true + else + return nil, "file not found" + end +end + +--- Driver function for "config" command. +-- @return boolean: True if succeeded, nil on errors. +function config_cmd.run(...) + local flags = util.parse_flags(...) + + if flags["lua-incdir"] then + print(cfg.variables.LUA_INCDIR) + return true + end + if flags["lua-libdir"] then + print(cfg.variables.LUA_LIBDIR) + return true + end + if flags["lua-ver"] then + print(cfg.lua_version) + return true + end + local conf = cfg.which_config() + if flags["system-config"] then + return config_file(conf.system) + end + if flags["user-config"] then + return config_file(conf.user) + end + if flags["rock-trees"] then + for _, tree in ipairs(cfg.rocks_trees) do + if type(tree) == "string" then + util.printout(dir.normalize(tree)) + else + local name = tree.name and "\t"..tree.name or "" + util.printout(dir.normalize(tree.root)..name) + end + end + return true + end + + return nil, "Please provide a flag for querying configuration values. "..util.see_help("config") +end + +return config_cmd diff --git a/src/luarocks/deps.lua b/src/luarocks/deps.lua index 3f75f9b..0e3265b 100644 --- a/src/luarocks/deps.lua +++ b/src/luarocks/deps.lua @@ -608,10 +608,12 @@ function deps.check_external_deps(rockspec, mode) local found = false failed_file = nil for _, f in pairs(files) do + -- small convenience hack if f:match("%.so$") or f:match("%.dylib$") or f:match("%.dll$") then f = f:gsub("%.[^.]+$", "."..cfg.external_lib_extension) end + for _, d in ipairs(paths) do if f:match("%*") then local replaced = f:gsub("%.", "%%."):gsub("%*", ".*") diff --git a/src/luarocks/doc.lua b/src/luarocks/doc.lua index 6dee106..53ed011 100644 --- a/src/luarocks/doc.lua +++ b/src/luarocks/doc.lua @@ -13,7 +13,7 @@ local fetch = require("luarocks.fetch") local fs = require("luarocks.fs") local download = require("luarocks.download") -doc.help_summary = "Shows documentation for an installed rock." +doc.help_summary = "Show documentation for an installed rock." doc.help = [[ <argument> is an existing package name. @@ -21,7 +21,7 @@ Without any flags, tries to load the documentation using a series of heuristics. With these flags, return only the desired information: ---homepage Open the home page of project. +--home Open the home page of project. --list List documentation files only. For more information about a rock, see the 'show' command. @@ -75,7 +75,7 @@ function doc.run(...) if not rockspec then return nil,err end local descript = rockspec.description or {} - if flags["homepage"] then + if flags["home"] then return show_homepage(descript.homepage, name, version) end diff --git a/src/luarocks/fetch.lua b/src/luarocks/fetch.lua index 980c8fe..e92aedd 100644 --- a/src/luarocks/fetch.lua +++ b/src/luarocks/fetch.lua @@ -37,11 +37,11 @@ function fetch.fetch_url(url, filename, cache) if protocol == "file" then return fs.absolute_name(pathname) elseif fetch.is_basic_protocol(protocol, true) then - local ok, filename = fs.download(url, filename, cache) + local ok, name = fs.download(url, filename, cache) if not ok then return nil, "Failed downloading "..url..(filename and " - "..filename or ""), "network" end - return filename + return name else return nil, "Unsupported protocol "..protocol end @@ -170,8 +170,13 @@ function fetch.fetch_and_unpack_rock(rock_file, dest) end function fetch.url_to_base_dir(url) + -- for extensions like foo.tar.gz, "gz" is stripped first + local known_exts = {} + for _, ext in ipairs{"zip", "git", "tgz", "tar", "gz", "bz2"} do + known_exts[ext] = "" + end local base = dir.base_name(url) - return base:gsub("%.[^.]*$", ""):gsub("%.tar$", "") + return (base:gsub("%.([^.]*)$", known_exts):gsub("%.tar", "")) end --- Back-end function that actually loads the local rockspec. @@ -193,9 +198,8 @@ function fetch.load_local_rockspec(filename, quick) end local globals = err - local ok, err = true, nil if not quick then - ok, err = type_check.type_check_rockspec(rockspec, globals) + local ok, err = type_check.type_check_rockspec(rockspec, globals) if not ok then return nil, filename..": "..err end @@ -319,9 +323,10 @@ function fetch.get_sources(rockspec, extract, dest_dir) local url = rockspec.source.url local name = rockspec.name.."-"..rockspec.version local filename = rockspec.source.file - local source_file, store_dir, err, errcode + local source_file, store_dir + local ok, err, errcode if dest_dir then - local ok, err = fs.change_dir(dest_dir) + ok, err = fs.change_dir(dest_dir) if not ok then return nil, err, "dest_dir" end source_file, err, errcode = fetch.fetch_url(url, filename) fs.pop_dir() diff --git a/src/luarocks/fetch/cvs.lua b/src/luarocks/fetch/cvs.lua index cc9fd65..ccf928c 100644 --- a/src/luarocks/fetch/cvs.lua +++ b/src/luarocks/fetch/cvs.lua @@ -20,9 +20,15 @@ function cvs.get_sources(rockspec, extract, dest_dir) assert(type(rockspec) == "table") assert(type(dest_dir) == "string" or not dest_dir) + local cvs_cmd = rockspec.variables.CVS + local ok, err_msg = fs.is_tool_available(cvs_cmd, "CVS") + if not ok then + return nil, err_msg + end + local name_version = rockspec.name .. "-" .. rockspec.version local module = rockspec.source.module or dir.base_name(rockspec.source.url) - local command = {rockspec.variables.CVS, "-d"..rockspec.source.pathname, "export", module} + local command = {cvs_cmd, "-d"..rockspec.source.pathname, "export", module} if rockspec.source.tag then table.insert(command, 4, "-r") table.insert(command, 5, rockspec.source.tag) diff --git a/src/luarocks/fetch/git.lua b/src/luarocks/fetch/git.lua index 53fd444..a635f19 100644 --- a/src/luarocks/fetch/git.lua +++ b/src/luarocks/fetch/git.lua @@ -40,6 +40,11 @@ function git.get_sources(rockspec, extract, dest_dir, depth) -- Strip off .git from base name if present module = module:gsub("%.git$", "") + local ok, err_msg = fs.is_tool_available(git_cmd, "Git") + if not ok then + return nil, err_msg + end + local store_dir if not dest_dir then store_dir = fs.make_temp_dir(name_version) @@ -63,7 +68,7 @@ function git.get_sources(rockspec, extract, dest_dir, depth) if git_can_clone_by_tag(git_cmd) then -- The argument to `--branch` can actually be a branch or a tag as of -- Git 1.7.10. - table.insert(command, 4, "--branch=" .. tag_or_branch) + table.insert(command, 3, "--branch=" .. tag_or_branch) end end if not fs.execute(unpack(command)) then diff --git a/src/luarocks/fetch/git_https.lua b/src/luarocks/fetch/git_https.lua new file mode 100644 index 0000000..67f8ad6 --- /dev/null +++ b/src/luarocks/fetch/git_https.lua @@ -0,0 +1,7 @@ +--- Fetch back-end for retrieving sources from Git repositories +-- that use https:// transport. For example, for fetching a repository +-- that requires the following command line: +-- `git clone https://example.com/foo.git` +-- you can use this in the rockspec: +-- source = { url = "git+https://example.com/foo.git" } +return require "luarocks.fetch.git_http" diff --git a/src/luarocks/fetch/hg.lua b/src/luarocks/fetch/hg.lua index b2ba56e..518130b 100644 --- a/src/luarocks/fetch/hg.lua +++ b/src/luarocks/fetch/hg.lua @@ -21,16 +21,21 @@ function hg.get_sources(rockspec, extract, dest_dir) assert(type(dest_dir) == "string" or not dest_dir) local hg_cmd = rockspec.variables.HG + local ok, err_msg = fs.is_tool_available(hg_cmd, "Mercurial") + if not ok then + return nil, err_msg + end + local name_version = rockspec.name .. "-" .. rockspec.version -- Strip off special hg:// protocol type - local url = rockspec.source.url:gsub("^hg://", "") + local url = rockspec.source.url:gsub("^hg://", "") local module = dir.base_name(url) local command = {hg_cmd, "clone", url, module} local tag_or_branch = rockspec.source.tag or rockspec.source.branch if tag_or_branch then - command = {hg_cmd, "clone", "--rev", url, module} + command = {hg_cmd, "clone", "--rev", tag_or_branch, url, module} end local store_dir if not dest_dir then diff --git a/src/luarocks/fetch/hg_http.lua b/src/luarocks/fetch/hg_http.lua new file mode 100644 index 0000000..8f506da --- /dev/null +++ b/src/luarocks/fetch/hg_http.lua @@ -0,0 +1,24 @@ + +--- Fetch back-end for retrieving sources from hg repositories +-- that use http:// transport. For example, for fetching a repository +-- that requires the following command line: +-- `hg clone http://example.com/foo` +-- you can use this in the rockspec: +-- source = { url = "hg+http://example.com/foo" } +local hg_http = {} + +local hg = require("luarocks.fetch.hg") + +--- Download sources for building a rock, using hg over http. +-- @param rockspec table: The rockspec table +-- @param extract boolean: Unused in this module (required for API purposes.) +-- @param dest_dir string or nil: If set, will extract to the given directory. +-- @return (string, string) or (nil, string): The absolute pathname of +-- the fetched source tarball and the temporary directory created to +-- store it; or nil and an error message. +function hg_http.get_sources(rockspec, extract, dest_dir) + rockspec.source.url = rockspec.source.url:gsub("^hg.", "") + return hg.get_sources(rockspec, extract, dest_dir) +end + +return hg_http diff --git a/src/luarocks/fetch/hg_https.lua b/src/luarocks/fetch/hg_https.lua new file mode 100644 index 0000000..e67417f --- /dev/null +++ b/src/luarocks/fetch/hg_https.lua @@ -0,0 +1,8 @@ + +--- Fetch back-end for retrieving sources from hg repositories +-- that use https:// transport. For example, for fetching a repository +-- that requires the following command line: +-- `hg clone https://example.com/foo` +-- you can use this in the rockspec: +-- source = { url = "hg+https://example.com/foo" } +return require "luarocks.fetch.hg_http" diff --git a/src/luarocks/fetch/hg_ssh.lua b/src/luarocks/fetch/hg_ssh.lua new file mode 100644 index 0000000..0c365fa --- /dev/null +++ b/src/luarocks/fetch/hg_ssh.lua @@ -0,0 +1,8 @@ + +--- Fetch back-end for retrieving sources from hg repositories +-- that use ssh:// transport. For example, for fetching a repository +-- that requires the following command line: +-- `hg clone ssh://example.com/foo` +-- you can use this in the rockspec: +-- source = { url = "hg+ssh://example.com/foo" } +return require "luarocks.fetch.hg_http" diff --git a/src/luarocks/fetch/svn.lua b/src/luarocks/fetch/svn.lua index abeacf9..755e5e3 100644 --- a/src/luarocks/fetch/svn.lua +++ b/src/luarocks/fetch/svn.lua @@ -21,6 +21,11 @@ function svn.get_sources(rockspec, extract, dest_dir) assert(type(dest_dir) == "string" or not dest_dir) local svn_cmd = rockspec.variables.SVN + local ok, err_msg = fs.is_tool_available(svn_cmd, "--version", "Subversion") + if not ok then + return nil, err_msg + end + local name_version = rockspec.name .. "-" .. rockspec.version local module = rockspec.source.module or dir.base_name(rockspec.source.url) local url = rockspec.source.url:gsub("^svn://", "") diff --git a/src/luarocks/fs.lua b/src/luarocks/fs.lua index 72e11c0..57302c7 100644 --- a/src/luarocks/fs.lua +++ b/src/luarocks/fs.lua @@ -31,7 +31,8 @@ fs.verbose = function() -- patch io.popen and os.execute to display commands old_exec = os.execute os.execute = function(cmd) - print("\nos.execute: ", cmd) + -- redact api keys if present + print("\nos.execute: ", (cmd:gsub("(/api/[^/]+/)([^/]+)/", function(cap, key) return cap.."<redacted>/" end)) ) local code = pack(old_exec(cmd)) print("Results: "..tostring(code.n)) for i = 1,code.n do diff --git a/src/luarocks/fs/lua.lua b/src/luarocks/fs/lua.lua index b261905..73ae269 100644 --- a/src/luarocks/fs/lua.lua +++ b/src/luarocks/fs/lua.lua @@ -122,6 +122,27 @@ function fs_lua.execute_quiet(command, ...) end end +--- Checks if the given tool is available. +-- The tool is executed using a flag, usually just to ask its version. +-- @param tool_cmd string: The command to be used to check the tool's presence (e.g. hg in case of Mercurial) +-- @param tool_name string: The actual name of the tool (e.g. Mercurial) +-- @param arg string: The flag to pass to the tool. '--version' by default. +function fs_lua.is_tool_available(tool_cmd, tool_name, arg) + assert(type(tool_cmd) == "string") + assert(type(tool_name) == "string") + + arg = arg or "--version" + assert(type(arg) == "string") + + if not fs.execute_quiet(tool_cmd, arg) then + local msg = "'%s' program not found. Make sure %s is installed and is available in your PATH " .. + "(or you may want to edit the 'variables.%s' value in file 'config.lua')" + return nil, msg:format(tool_cmd, tool_name, tool_cmd:upper()) + else + return true + end +end + --- Check the MD5 checksum for a file. -- @param file string: The file to be checked. -- @param md5sum string: The string with the expected MD5 checksum. @@ -207,8 +228,13 @@ end -- Allows leaving a directory (e.g. for deleting it) in -- a crossplatform way. function fs_lua.change_dir_to_root() - table.insert(dir_stack, lfs.currentdir()) + local current = lfs.currentdir() + if not current or current == "" then + return false + end + table.insert(dir_stack, current) lfs.chdir("/") -- works on Windows too + return true end --- Change working directory to the previous in the dir stack. @@ -540,7 +566,7 @@ local redirect_protocols = { local function request(url, method, http, loop_control) local result = {} - local proxy = cfg.proxy + local proxy = cfg.http_proxy if type(proxy) ~= "string" then proxy = nil end -- LuaSocket's http.request crashes when given URLs missing the scheme part. if proxy and not proxy:find("://") then @@ -648,6 +674,11 @@ function fs_lua.download(url, filename, cache) assert(type(filename) == "string" or not filename) filename = fs.absolute_name(filename or dir.base_name(url)) + + -- delegate to the configured downloader so we don't have to deal with whitelists + if cfg.no_proxy then + return fs.use_downloader(url, filename, cache) + end local content, err, https_err if util.starts_with(url, "http:") then @@ -655,7 +686,8 @@ function fs_lua.download(url, filename, cache) elseif util.starts_with(url, "ftp:") then content, err = ftp.get(url) elseif util.starts_with(url, "https:") then - if luasec_ok then + -- skip LuaSec when proxy is enabled since it is not supported + if luasec_ok and not cfg.https_proxy then content, err = http_request(url, https, cache and filename) else https_err = true @@ -732,7 +764,7 @@ function fs_lua.chmod(file, mode) -- LuaPosix (as of 5.1.15) does not support octal notation... if mode:sub(1,1) == "0" then local new_mode = {} - for c in mode:sub(2):gmatch(".") do + for c in mode:sub(-3):gmatch(".") do table.insert(new_mode, octal_to_rwx[c]) end mode = table.concat(new_mode) diff --git a/src/luarocks/fs/unix/tools.lua b/src/luarocks/fs/unix/tools.lua index f36e815..442004c 100644 --- a/src/luarocks/fs/unix/tools.lua +++ b/src/luarocks/fs/unix/tools.lua @@ -12,7 +12,7 @@ local dir_stack = {} local vars = cfg.variables local function command_at(directory, cmd) - return "cd " .. fs.Q(directory) .. " && " .. cmd + return "cd " .. fs.Q(fs.absolute_name(directory)) .. " && " .. cmd end --- Obtain current directory. @@ -21,7 +21,7 @@ end function tools.current_dir() local current = cfg.cache_pwd if not current then - local pipe = io.popen(fs.Q(vars.PWD)) + local pipe = io.popen(fs.Q(vars.PWD).." 2> /dev/null") current = pipe:read("*l") pipe:close() cfg.cache_pwd = current @@ -38,7 +38,9 @@ end -- @return boolean: true if command succeeds (status code 0), false -- otherwise. function tools.execute_string(cmd) - local code, err = os.execute(command_at(fs.current_dir(), cmd)) + local current = fs.current_dir() + if not current then return false end + local code, err = os.execute(command_at(current, cmd)) if code == 0 or code == true then return true else @@ -246,7 +248,7 @@ function tools.use_downloader(url, filename, cache) local ok if cfg.downloader == "wget" then - local wget_cmd = fs.Q(vars.WGET).." --no-check-certificate --no-cache --user-agent='"..cfg.user_agent.." via wget' --quiet " + local wget_cmd = fs.Q(vars.WGET).." "..vars.WGETNOCERTFLAG.." --no-cache --user-agent='"..cfg.user_agent.." via wget' --quiet " if cfg.connection_timeout and cfg.connection_timeout > 0 then wget_cmd = wget_cmd .. "--timeout="..tonumber(cfg.connection_timeout).." --tries=1 " end @@ -262,7 +264,7 @@ function tools.use_downloader(url, filename, cache) ok = fs.execute_quiet(wget_cmd, url) end elseif cfg.downloader == "curl" then - local curl_cmd = fs.Q(vars.CURL).." -f -k -L --user-agent '"..cfg.user_agent.." via curl' " + local curl_cmd = fs.Q(vars.CURL).." "..vars.CURLNOCERTFLAG.." -f -L --user-agent '"..cfg.user_agent.." via curl' " if cfg.connection_timeout and cfg.connection_timeout > 0 then curl_cmd = curl_cmd .. "--connect-timeout "..tonumber(cfg.connection_timeout).." " end @@ -283,12 +285,6 @@ function tools.chmod(pathname, mode) end end ---- Apply a patch. --- @param patchname string: The filename of the patch. -function tools.apply_patch(patchname) - return fs.execute(vars.PATCH.." -p1 -f -i ", patchname) -end - --- Unpack an archive. -- Extract the contents of an archive, detecting its format by -- filename extension. @@ -350,4 +346,9 @@ function tools.browser(url) return fs.execute(cfg.web_browser, url) end +function tools.set_time(file, time) + file = dir.normalize(file) + return fs.execute(vars.TOUCH, "-d", "@"..tostring(time), file) +end + return tools diff --git a/src/luarocks/fs/win32.lua b/src/luarocks/fs/win32.lua index 12d86d1..32766e5 100644 --- a/src/luarocks/fs/win32.lua +++ b/src/luarocks/fs/win32.lua @@ -125,6 +125,7 @@ function win32.wrap_script(file, dest, name, version) local ppaths = "package.path="..util.LQ(lpath..";").."..package.path; package.cpath="..util.LQ(lcpath..";").."..package.cpath" local addctx = "local k,l,_=pcall(require,"..util.LQ("luarocks.loader")..") _=k and l.add_context("..util.LQ(name)..","..util.LQ(version)..")" wrapper:write(fs.Qb(lua)..' -e '..fs.Qb(ppaths)..' -e '..fs.Qb(addctx)..' '..fs.Qb(file)..' %*\n') + wrapper:write("exit /b %ERRORLEVEL%\n") wrapper:close() return true end diff --git a/src/luarocks/fs/win32/tools.lua b/src/luarocks/fs/win32/tools.lua index f970f36..b9dce85 100644 --- a/src/luarocks/fs/win32/tools.lua +++ b/src/luarocks/fs/win32/tools.lua @@ -39,7 +39,7 @@ end function tools.current_dir() local current = cfg.cache_pwd if not current then - local pipe = io.popen(fs.Q(vars.PWD)) + local pipe = io.popen(fs.Q(vars.PWD).. " 2> NUL") current = pipe:read("*l") pipe:close() cfg.cache_pwd = current @@ -56,7 +56,9 @@ end -- @return boolean: true if command succeeds (status code 0), false -- otherwise. function tools.execute_string(cmd) - cmd = command_at(fs.current_dir(), cmd) + local current = fs.current_dir() + if not current then return false end + cmd = command_at(current, cmd) local code = os.execute(cmd) if code == 0 or code == true then return true @@ -149,7 +151,7 @@ end -- plus an error message. function tools.copy_contents(src, dest) assert(src and dest) - if fs.execute_quiet(fs.Q(vars.CP).." -dR "..src.."\\*.* "..fs.Q(dest)) then + if fs.execute_quiet(fs.Q(vars.CP), "-dR", src.."\\*.*", dest) then return true else return false, "Failed copying "..src.." to "..dest @@ -256,7 +258,7 @@ function tools.use_downloader(url, filename, cache) local ok if cfg.downloader == "wget" then - local wget_cmd = fs.Q(vars.WGET).." --no-check-certificate --no-cache --user-agent=\""..cfg.user_agent.." via wget\" --quiet " + local wget_cmd = fs.Q(vars.WGET).." "..vars.WGETNOCERTFLAG.." --no-cache --user-agent=\""..cfg.user_agent.." via wget\" --quiet " if cfg.connection_timeout and cfg.connection_timeout > 0 then wget_cmd = wget_cmd .. "--timeout="..tonumber(cfg.connection_timeout).." --tries=1 " end @@ -272,7 +274,7 @@ function tools.use_downloader(url, filename, cache) ok = fs.execute_quiet(wget_cmd, url) end elseif cfg.downloader == "curl" then - local curl_cmd = vars.CURL.." -f -k -L --user-agent \""..cfg.user_agent.." via curl\" " + local curl_cmd = fs.Q(vars.CURL).." "..vars.CURLNOCERTFLAG.." -f -L --user-agent \""..cfg.user_agent.." via curl\" " if cfg.connection_timeout and cfg.connection_timeout > 0 then curl_cmd = curl_cmd .. "--connect-timeout "..tonumber(cfg.connection_timeout).." " end diff --git a/src/luarocks/help.lua b/src/luarocks/help.lua index 0a15550..92458b2 100644 --- a/src/luarocks/help.lua +++ b/src/luarocks/help.lua @@ -31,10 +31,8 @@ end local function get_status(status) if status then return "ok" - elseif status == false then - return "not found" else - return "failed" + return "not found" end end @@ -47,7 +45,7 @@ function help.run(...) local flags, command = util.parse_flags(...) if not command then - local sys_file, sys_ok, home_file, home_ok = cfg.which_config() + local conf = cfg.which_config() print_banner() print_section("NAME") util.printout("\t"..program..[[ - ]]..program_description) @@ -83,9 +81,9 @@ function help.run(...) print_section("CONFIGURATION") util.printout("\tLua version: " .. cfg.lua_version) util.printout("\tConfiguration files:") - util.printout("\t\tSystem: ".. dir.normalize(sys_file) .. " (" .. get_status(sys_ok) ..")") - if home_file then - util.printout("\t\tUser : ".. dir.normalize(home_file) .. " (" .. get_status(home_ok) ..")\n") + util.printout("\t\tSystem: ".. dir.normalize(conf.system.file) .. " (" .. get_status(conf.system.ok) ..")") + if conf.user.file then + util.printout("\t\tUser : ".. dir.normalize(conf.user.file) .. " (" .. get_status(conf.user.ok) ..")\n") else util.printout("\t\tUser : disabled in this LuaRocks installation.\n") end @@ -100,7 +98,7 @@ function help.run(...) end else command = command:gsub("-", "_") - local cmd = require(commands[command]) + local cmd = commands[command] and require(commands[command]) if cmd then local arguments = cmd.help_arguments or "<argument>" print_banner() diff --git a/src/luarocks/install.lua b/src/luarocks/install.lua index 7678c0c..6d457fc 100644 --- a/src/luarocks/install.lua +++ b/src/luarocks/install.lua @@ -26,6 +26,8 @@ or a filename of a locally available rock. rock after installing a new one. This behavior can be made permanent by setting keep_other_versions=true in the configuration file. + +--only-deps Installs only the dependencies of the rock. ]]..util.deps_mode_help() @@ -109,6 +111,43 @@ function install.install_binary_rock(rock_file, deps_mode) return name, version end +--- Installs the dependencies of a binary rock. +-- @param rock_file string: local or remote filename of a rock. +-- @param deps_mode: string: Which trees to check dependencies for: +-- "one" for the current default tree, "all" for all trees, +-- "order" for all trees with priority >= the current default, "none" for no trees. +-- @return (string, string) or (nil, string, [string]): Name and version of +-- the rock whose dependencies were installed if succeeded or nil and an error message +-- followed by an error code. +function install.install_binary_rock_deps(rock_file, deps_mode) + assert(type(rock_file) == "string") + + local name, version, arch = path.parse_name(rock_file) + if not name then + return nil, "Filename "..rock_file.." does not match format 'name-version-revision.arch.rock'." + end + + if arch ~= "all" and arch ~= cfg.arch then + return nil, "Incompatible architecture "..arch, "arch" + end + + local ok, err, errcode = fetch.fetch_and_unpack_rock(rock_file, path.install_dir(name, version)) + if not ok then return nil, err, errcode end + + local rockspec, err, errcode = fetch.load_rockspec(path.rockspec_file(name, version)) + if err then + return nil, "Failed loading rockspec for installed package: "..err, errcode + end + + ok, err, errcode = deps.fulfill_dependencies(rockspec, deps_mode) + if err then return nil, err, errcode end + + util.printout() + util.printout("Succesfully installed dependencies for " ..name.." "..version) + + return name, version +end + --- Driver function for the "install" command. -- @param name string: name of a binary rock. If an URL or pathname -- to a binary rock is given, fetches and installs it. If a rockspec or a @@ -131,12 +170,16 @@ function install.run(...) if name:match("%.rockspec$") or name:match("%.src%.rock$") then util.printout("Using "..name.."... switching to 'build' mode") local build = require("luarocks.build") - return build.run(name, util.forward_flags(flags, "local", "keep", "deps-mode")) + return build.run(name, util.forward_flags(flags, "local", "keep", "deps-mode", "only-deps")) elseif name:match("%.rock$") then - ok, err = install.install_binary_rock(name, deps.get_deps_mode(flags)) + if flags["only-deps"] then + ok, err = install.install_binary_rock_deps(name, deps.get_deps_mode(flags)) + else + ok, err = install.install_binary_rock(name, deps.get_deps_mode(flags)) + end if not ok then return nil, err end local name, version = ok, err - if (not flags["keep"]) and not cfg.keep_other_versions then + if (not flags["only-deps"]) and (not flags["keep"]) and not cfg.keep_other_versions then local ok, err = remove.remove_other_versions(name, version, flags["force"]) if not ok then util.printerr(err) end end diff --git a/src/luarocks/list.lua b/src/luarocks/list.lua index 319909d..fddded0 100644 --- a/src/luarocks/list.lua +++ b/src/luarocks/list.lua @@ -6,33 +6,97 @@ local list = {} package.loaded["luarocks.list"] = list local search = require("luarocks.search") +local deps = require("luarocks.deps") local cfg = require("luarocks.cfg") local util = require("luarocks.util") local path = require("luarocks.path") -list.help_summary = "Lists currently installed rocks." +list.help_summary = "List currently installed rocks." list.help_arguments = "[--porcelain] <filter>" list.help = [[ <filter> is a substring of a rock name to filter by. +--outdated List only rocks for which there is a + higher version available in the rocks server. + --porcelain Produce machine-friendly output. ]] +local function check_outdated(trees, query) + local results_installed = {} + for _, tree in ipairs(trees) do + search.manifest_search(results_installed, path.rocks_dir(tree), query) + end + local outdated = {} + for name, versions in util.sortedpairs(results_installed) do + local latest_installed + local latest_available, latest_available_repo + + for version, _ in util.sortedpairs(versions) do + latest_installed = version + break + end + + local query_available = search.make_query(name:lower()) + query.exact_name = true + local results_available, err = search.search_repos(query_available) + + if results_available[name] then + for version, repos in util.sortedpairs(results_available[name], deps.compare_versions) do + latest_available = version + for _, repo in ipairs(repos) do + latest_available_repo = repo.repo + break + end + break + end + + if deps.compare_versions(latest_available, latest_installed) then + table.insert(outdated, { name = name, installed = latest_installed, available = latest_available, repo = latest_available_repo }) + end + end + end + return outdated +end + +local function list_outdated(trees, query, porcelain) + util.title("Outdated rocks:", porcelain) + local outdated = check_outdated(trees, query) + for _, item in ipairs(outdated) do + if porcelain then + util.printout(item.name, item.installed, item.available, item.repo) + else + util.printout(item.name) + util.printout(" "..item.installed.." < "..item.available.." at "..item.repo) + util.printout() + end + end + return true +end + --- Driver function for "list" command. -- @param filter string or nil: A substring of a rock name to filter by. -- @param version string or nil: a version may also be passed. -- @return boolean: True if succeeded, nil on errors. function list.run(...) local flags, filter, version = util.parse_flags(...) - local results = {} local query = search.make_query(filter and filter:lower() or "", version) query.exact_name = false local trees = cfg.rocks_trees if flags["tree"] then trees = { flags["tree"] } end + + if flags["outdated"] then + return list_outdated(trees, query, flags["porcelain"]) + end + + local results = {} for _, tree in ipairs(trees) do - search.manifest_search(results, path.rocks_dir(tree), query) + local ok, err = search.manifest_search(results, path.rocks_dir(tree), query) + if not ok then + util.warning(err) + end end util.title("Installed rocks:", flags["porcelain"]) search.print_results(results, flags["porcelain"]) diff --git a/src/luarocks/manif_core.lua b/src/luarocks/manif_core.lua index 1a2c111..d719caa 100644 --- a/src/luarocks/manif_core.lua +++ b/src/luarocks/manif_core.lua @@ -9,7 +9,6 @@ local persist = require("luarocks.persist") local type_check = require("luarocks.type_check") local dir = require("luarocks.dir") local util = require("luarocks.util") -local cfg = require("luarocks.cfg") local path = require("luarocks.path") manif_core.manifest_cache = {} diff --git a/src/luarocks/path.lua b/src/luarocks/path.lua index 598e51d..fb5eec7 100644 --- a/src/luarocks/path.lua +++ b/src/luarocks/path.lua @@ -339,6 +339,8 @@ function path.map_trees(deps_mode, fn, ...) return result end +local is_src_extension = { [".lua"] = true, [".tl"] = true, [".tld"] = true, [".moon"] = true } + --- Return the pathname of the file that would be loaded for a module, indexed. -- @param module_name string: module name (eg. "socket.core") -- @param name string: name of the package (eg. "luasocket") @@ -349,7 +351,8 @@ end -- @return string: filename of the module (eg. "/usr/local/lib/lua/5.1/socket/core.so") function path.which_i(module_name, name, version, tree, i) local deploy_dir - if module_name:match("%.lua$") then + local extension = module_name:match("%.[a-z]+$") + if is_src_extension[extension] then deploy_dir = path.deploy_lua_dir(tree) module_name = dir.path(deploy_dir, module_name) else diff --git a/src/luarocks/path_cmd.lua b/src/luarocks/path_cmd.lua index 95532f9..2bee4cb 100644 --- a/src/luarocks/path_cmd.lua +++ b/src/luarocks/path_cmd.lua @@ -6,7 +6,6 @@ local path_cmd = {} local util = require("luarocks.util") local deps = require("luarocks.deps") local cfg = require("luarocks.cfg") -local path = require("luarocks.path") path_cmd.help_summary = "Return the currently configured package path." path_cmd.help_arguments = "" diff --git a/src/luarocks/persist.lua b/src/luarocks/persist.lua index 9d601a4..354b17c 100644 --- a/src/luarocks/persist.lua +++ b/src/luarocks/persist.lua @@ -9,60 +9,85 @@ package.loaded["luarocks.persist"] = persist local util = require("luarocks.util") +--- Load and run a Lua file in an environment. +-- @param filename string: the name of the file. +-- @param env table: the environment table. +-- @return (true, any) or (nil, string, string): true and the return value +-- of the file, or nil, an error message and an error code ("open", "load" +-- or "run") in case of errors. +local function run_file(filename, env) + local fd, err = io.open(filename) + if not fd then + return nil, err, "open" + end + local str, err = fd:read("*a") + fd:close() + if not str then + return nil, err, "open" + end + str = str:gsub("^#![^\n]*\n", "") + local chunk, ran + if _VERSION == "Lua 5.1" then -- Lua 5.1 + chunk, err = loadstring(str, filename) + if chunk then + setfenv(chunk, env) + ran, err = pcall(chunk) + end + else -- Lua 5.2 + chunk, err = load(str, filename, "t", env) + if chunk then + ran, err = pcall(chunk) + end + end + if not chunk then + return nil, "Error loading file: "..err, "load" + end + if not ran then + return nil, "Error running file: "..err, "run" + end + return true, err +end + --- Load a Lua file containing assignments, storing them in a table. -- The global environment is not propagated to the loaded file. -- @param filename string: the name of the file. -- @param tbl table or nil: if given, this table is used to store -- loaded values. --- @return table or (nil, string): a table with the file's assignments --- as fields, or nil and a message in case of errors. +-- @return (table, table) or (nil, string, string): a table with the file's assignments +-- as fields and set of undefined globals accessed in file, +-- or nil, an error message and an error code ("open"; couldn't open the file, +-- "load"; compile-time error, or "run"; run-time error) +-- in case of errors. function persist.load_into_table(filename, tbl) assert(type(filename) == "string") assert(type(tbl) == "table" or not tbl) - local result, chunk, ran, err - result = tbl or {} + local result = tbl or {} local globals = {} local globals_mt = { - __index = function(t, n) - globals[n] = true - return rawget(t, n) + __index = function(t, k) + globals[k] = true end } local save_mt = getmetatable(result) setmetatable(result, globals_mt) - if _VERSION == "Lua 5.1" then -- Lua 5.1 - chunk, err = loadfile(filename) - if chunk then - setfenv(chunk, result) - ran, err = pcall(chunk) - end - else -- Lua 5.2 - chunk, err = loadfile(filename, "t", result) - if chunk then - ran, err = pcall(chunk) - end - end - setmetatable(result, save_mt) - if not chunk then - if err:sub(1,5) ~= filename:sub(1,5) then - return false, err - end - return nil, "Error loading file: "..err - end - if not ran then - return nil, "Error running file: "..err + local ok, err, errcode = run_file(filename, result) + + setmetatable(result, save_mt) + + if not ok then + return nil, err, errcode end return result, globals end local write_table ---- Write a value as Lua code, invoking write_table. --- This function handles only numbers, strings and tables --- are keys (tables are handled recursively). --- @param out userdata: a file object, open for writing. +--- Write a value as Lua code. +-- This function handles only numbers and strings, invoking write_table +-- to write tables. +-- @param out table or userdata: a writer object supporting :write() method. -- @param v: the value to be written. -- @param level number: the indentation level -- @param sub_order table: optional prioritization table @@ -71,28 +96,27 @@ local function write_value(out, v, level, sub_order) if type(v) == "table" then write_table(out, v, level + 1, sub_order) elseif type(v) == "string" then - if v:match("\n") then + if v:match("[\r\n]") then local open, close = "[[", "]]" local equals = 0 - while v:find(open,1,true) or v:find(close,1,true) do + while v:find(close, 1, true) do equals = equals + 1 local eqs = ("="):rep(equals) open, close = "["..eqs.."[", "]"..eqs.."]" end out:write(open.."\n"..v..close) else - out:write("\""..v:gsub("\"", "\\\"").."\"") + out:write("\""..v:gsub("\\", "\\\\"):gsub("\"", "\\\"").."\"") end else out:write(tostring(v)) end end ---- Write a table as Lua code representing a table to disk --- (that is, in curly brackets notation). --- This function handles only numbers, strings and tables --- are keys (tables are handled recursively). --- @param out userdata: a file object, open for writing. +--- Write a table as Lua code in curly brackets notation to a writer object. +-- Only numbers, strings and tables (containing numbers, strings +-- or other recursively processed tables) are supported. +-- @param out table or userdata: a writer object supporting :write() method. -- @param tbl table: the table to be written. -- @param level number: the indentation level -- @param field_order table: optional prioritization table @@ -107,28 +131,29 @@ write_table = function(out, tbl, level, field_order) if indent then for n = 1,level do out:write(indentation) end end - sep = ",\n" - indent = true - if type(k) == "number" then - if k ~= i then - out:write("["..tostring(k).."]=") - else - i = i + 1 - end - indent = false - sep = ", " - elseif type(k) == "table" then - out:write("[") - write_table(out, k, level + 1) - out:write("] = ") + + if k == i then + i = i + 1 else - if k:match("^[a-zA-Z_][a-zA-Z0-9_]*$") then - out:write(k.." = ") + if type(k) == "string" and k:match("^[a-zA-Z_][a-zA-Z0-9_]*$") then + out:write(k) else - out:write("['"..k:gsub("'", "\\'").."'] = ") + out:write("[") + write_value(out, k, level) + out:write("]") end + + out:write(" = ") end + write_value(out, v, level, sub_order) + if type(k) == "number" then + sep = ", " + indent = false + else + sep = ",\n" + indent = true + end end if sep ~= "\n" then out:write("\n") @@ -137,18 +162,16 @@ write_table = function(out, tbl, level, field_order) out:write("}") end ---- Writes a table to an io-like object. --- @param out userdata: a file object, open for writing. +--- Write a table as series of assignments to a writer object. +-- @param out table or userdata: a writer object supporting :write() method. -- @param tbl table: the table to be written. -- @param field_order table: optional prioritization table --- @return userdata The file object originally passed in as the `out` parameter. -local function write_table(out, tbl, field_order) +local function write_table_as_assignments(out, tbl, field_order) for k, v, sub_order in util.sortedpairs(tbl, field_order) do out:write(k.." = ") write_value(out, v, 0, sub_order) out:write("\n") end - return out end --- Save the contents of a table to a string. @@ -161,7 +184,7 @@ end function persist.save_from_table_to_string(tbl, field_order) local out = {buffer = {}} function out:write(data) table.insert(self.buffer, data) end - write_table(out, tbl, field_order) + write_table_as_assignments(out, tbl, field_order) return table.concat(out.buffer) end @@ -179,7 +202,7 @@ function persist.save_from_table(filename, tbl, field_order) if not out then return nil, "Cannot create file at "..filename end - write_table(out, tbl, field_order) + write_table_as_assignments(out, tbl, field_order) out:close() return true end diff --git a/src/luarocks/remove.lua b/src/luarocks/remove.lua index e1cd44f..5d41981 100644 --- a/src/luarocks/remove.lua +++ b/src/luarocks/remove.lua @@ -159,7 +159,7 @@ function remove.run(...) local results = {} search.manifest_search(results, cfg.rocks_dir, search.make_query(name, version)) if not results[name] then - return nil, "Could not find rock '"..name..(version and " "..version or "").."' in "..cfg.root_dir + return nil, "Could not find rock '"..name..(version and " "..version or "").."' in "..path.rocks_tree_to_string(cfg.root_dir) end return remove.remove_search_results(results, name, deps_mode, flags["force"]) diff --git a/src/luarocks/search.lua b/src/luarocks/search.lua index 5343938..f1a82d5 100644 --- a/src/luarocks/search.lua +++ b/src/luarocks/search.lua @@ -155,10 +155,11 @@ function search.disk_search(repo, query, results) return results end ---- Perform search on a rocks server. +--- Perform search on a rocks server or tree. -- @param results table: The results table, where keys are package names and -- versions are tables matching version strings to an array of servers. --- @param repo string: The URL of the rocks server. +-- @param repo string: The URL of a rocks server or +-- the pathname of a rocks tree (as returned by path.rocks_dir()). -- @param query table: A table describing the query in dependency -- format (for example, {name = "filesystem", exact_name = false, -- constraints = {op = "~>", version = {1,0}}}, arch = "rockspec"). diff --git a/src/luarocks/show.lua b/src/luarocks/show.lua index 3243c0c..08b2673 100644 --- a/src/luarocks/show.lua +++ b/src/luarocks/show.lua @@ -11,7 +11,7 @@ local path = require("luarocks.path") local deps = require("luarocks.deps") local fetch = require("luarocks.fetch") local manif = require("luarocks.manif") -show.help_summary = "Shows information about an installed rock." +show.help_summary = "Show information about an installed rock." show.help = [[ <argument> is an existing package name. diff --git a/src/luarocks/tools/patch.lua b/src/luarocks/tools/patch.lua index 8df3093..debaf63 100644 --- a/src/luarocks/tools/patch.lua +++ b/src/luarocks/tools/patch.lua @@ -22,8 +22,8 @@ local format = string.format -- logging local debugmode = false -local function debug(s) end -local function info(s) end +local function debug(_) end +local function info(_) end local function warning(s) io.stderr:write(s .. '\n') end -- Returns boolean whether string s2 starts with string s. @@ -57,27 +57,30 @@ end local function isfile() return true end --FIX? local function read_file(filename) - local fh, err, oserr = io.open(filename, 'rb') + local fh, data, err, oserr + fh, err, oserr = io.open(filename, 'rb') if not fh then return fh, err, oserr end - local data, err, oserr = fh:read'*a' + data, err, oserr = fh:read'*a' fh:close() if not data then return nil, err, oserr end return data end local function write_file(filename, data) - local fh, err, oserr = io.open(filename 'wb') + local fh, status, err, oserr + fh, err, oserr = io.open(filename 'wb') if not fh then return fh, err, oserr end - local status, err, oserr = fh:write(data) + status, err, oserr = fh:write(data) fh:close() if not status then return nil, err, oserr end return true end local function file_copy(src, dest) - local data, err, oserr = read_file(src) + local data, status, err, oserr + data, err, oserr = read_file(src) if not data then return data, err, oserr end - local status, err, oserr = write_file(dest) + status, err, oserr = write_file(dest) if not status then return status, err, oserr end return true end @@ -197,8 +200,13 @@ function patch.read_patch(filename, data) if state == 'hunkbody' then -- skip hunkskip and hunkbody code until definition of hunkhead read + if line:match"^[\r\n]*$" then + -- prepend space to empty lines to interpret them as context properly + line = " " .. line + end + -- process line first - if line:match"^[- +\\]" or line:match"^[\r\n]*$" then + if line:match"^[- +\\]" then -- gather stats about line endings local he = files.hunkends[nextfileno] if endswith(line, "\r\n") then @@ -420,7 +428,7 @@ local function find_hunk(file, h, hno) end h.startsrc = location h.starttgt = h.starttgt + offset - for i=1,fuzz do + for _=1,fuzz do table.remove(h.text, 1) table.remove(h.text, #h.text) end @@ -452,16 +460,15 @@ local function find_hunks(file, hunks) end local function check_patched(file, hunks) - local matched = true local lineno = 1 local ok, err = pcall(function() if #file == 0 then - error 'nomatch' + error('nomatch', 0) end for hno, h in ipairs(hunks) do -- skip to line just before hunk starts if #file < h.starttgt then - error 'nomatch' + error('nomatch', 0) end lineno = h.starttgt for _, hline in ipairs(h.text) do @@ -470,22 +477,18 @@ local function check_patched(file, hunks) local line = file[lineno] lineno = lineno + 1 if #line == 0 then - error 'nomatch' + error('nomatch', 0) end if endlstrip(line) ~= endlstrip(hline:sub(2)) then warning(format("file is not patched - failed hunk: %d", hno)) - error 'nomatch' + error('nomatch', 0) end end end end end) - if err == 'nomatch' then - matched = false - end - -- todo: display failed hunk, i.e. expected/found - - return matched + -- todo: display failed hunk, i.e. expected/found + return err ~= 'nomatch' end local function patch_hunks(srcname, tgtname, hunks) @@ -532,7 +535,7 @@ local function patch_hunks(srcname, tgtname, hunks) local line2write = hline:sub(2) -- detect if line ends are consistent in source file local sum = 0 - for k,v in pairs(lineends) do if v > 0 then sum=sum+1 end end + for _,v in pairs(lineends) do if v > 0 then sum=sum+1 end end if sum == 1 then local newline for k,v in pairs(lineends) do if v ~= 0 then newline = k end end @@ -553,7 +556,7 @@ end local function strip_dirs(filename, strip) if strip == nil then return filename end - for i=1,strip do + for _=1,strip do filename=filename:gsub("^[^/]*/", "") end return filename @@ -593,7 +596,6 @@ function patch.apply_patch(the_patch, strip) local hunkno = 1 local hunk = hunks[hunkno] local hunkfind = {} - local hunkreplace = {} local validhunks = 0 local canpatch = false local hunklineno @@ -610,15 +612,10 @@ function patch.apply_patch(the_patch, strip) elseif lineno == hunk.startsrc then hunkfind = {} for _,x in ipairs(hunk.text) do - if x:sub(1,1) == ' ' or x:sub(1,1) == '-' then - hunkfind[#hunkfind+1] = endlstrip(x:sub(2)) - end end - hunkreplace = {} - for _,x in ipairs(hunk.text) do - if x:sub(1,1) == ' ' or x:sub(1,1) == '+' then - hunkreplace[#hunkreplace+1] = endlstrip(x:sub(2)) - end end - --pprint(hunkreplace) + if x:sub(1,1) == ' ' or x:sub(1,1) == '-' then + hunkfind[#hunkfind+1] = endlstrip(x:sub(2)) + end + end hunklineno = 1 -- todo \ No newline at end of file diff --git a/src/luarocks/tools/tar.lua b/src/luarocks/tools/tar.lua index 03f7de3..b2bd930 100644 --- a/src/luarocks/tools/tar.lua +++ b/src/luarocks/tools/tar.lua @@ -31,9 +31,10 @@ local function octal_to_number(octal) local number = 0 for i = #octal,1,-1 do local digit = tonumber(octal:sub(i,i)) - if not digit then break end - number = number + (digit * 8^exp) - exp = exp + 1 + if digit then + number = number + (digit * 8^exp) + exp = exp + 1 + end end return number end @@ -143,6 +144,7 @@ function tar.untar(filename, destdir) util.printout() --]] end + tar_handle:close() return true end diff --git a/src/luarocks/tools/zip.lua b/src/luarocks/tools/zip.lua index 40cc089..101cae8 100644 --- a/src/luarocks/tools/zip.lua +++ b/src/luarocks/tools/zip.lua @@ -1,6 +1,6 @@ --- A Lua implementation of .zip file archiving (used for creating .rock files), --- using only lua-zlib. +-- using only lzlib. --module("luarocks.tools.zip", package.seeall) local zip = {} @@ -10,7 +10,7 @@ local dir = require("luarocks.dir") local function number_to_bytestring(number, nbytes) local out = {} - for i = 1, nbytes do + for _ = 1, nbytes do local byte = number % 256 table.insert(out, string.char(byte)) number = (number - byte) / 256 @@ -237,7 +237,7 @@ function zip.zip(zipfile, ...) end end - local ok = zw:close() + ok = zw:close() if not ok then return false, "error closing "..zipfile end diff --git a/src/luarocks/type_check.lua b/src/luarocks/type_check.lua index a78c484..65b4fc1 100644 --- a/src/luarocks/type_check.lua +++ b/src/luarocks/type_check.lua @@ -6,72 +6,97 @@ local type_check = {} package.loaded["luarocks.type_check"] = type_check local cfg = require("luarocks.cfg") +local deps = require("luarocks.deps") -type_check.rockspec_format = "1.0" +type_check.rockspec_format = "1.1" + +local string_1 = { _type = "string" } +local number_1 = { _type = "number" } +local mandatory_string_1 = { _type = "string", _mandatory = true } + +-- Syntax for type-checking tables: +-- +-- A type-checking table describes typing data for a value. +-- Any key starting with an underscore has a special meaning: +-- _type (string) is the Lua type of the value. Default is "table". +-- _version (string) is the minimum rockspec_version that supports this value. Default is "1.0". +-- _mandatory (boolean) indicates if the value is a mandatory key in its container table. Default is false. +-- For "string" types only: +-- _pattern (string) is the string-matching pattern, valid for string types only. Default is ".*". +-- For "table" types only: +-- _any (table) is the type-checking table for unspecified keys, recursively checked. +-- _more (boolean) indicates that the table accepts unspecified keys and does not type-check them. +-- Any other string keys that don't start with an underscore represent known keys and are type-checking tables, recursively checked. local rockspec_types = { - rockspec_format = "string", - MUST_package = "string", - MUST_version = "[%w.]+-[%d]+", + rockspec_format = string_1, + package = mandatory_string_1, + version = { _type = "string", _pattern = "[%w.]+-[%d]+", _mandatory = true }, description = { - summary = "string", - detailed = "string", - homepage = "string", - license = "string", - maintainer = "string" + summary = string_1, + detailed = string_1, + homepage = string_1, + license = string_1, + maintainer = string_1, }, dependencies = { - platforms = {}, - ANY = "string" + platforms = {}, -- recursively defined below + _any = string_1, }, supported_platforms = { - ANY = "string" + _any = string_1, }, external_dependencies = { - platforms = {}, - ANY = { - program = "string", - header = "string", - library = "string" + platforms = {}, -- recursively defined below + _any = { + program = string_1, + header = string_1, + library = string_1, } }, - MUST_source = { - platforms = {}, - MUST_url = "string", - md5 = "string", - file = "string", - dir = "string", - tag = "string", - branch = "string", - module = "string", - cvs_tag = "string", - cvs_module = "string" + source = { + _mandatory = true, + platforms = {}, -- recursively defined below + url = mandatory_string_1, + md5 = string_1, + file = string_1, + dir = string_1, + tag = string_1, + branch = string_1, + module = string_1, + cvs_tag = string_1, + cvs_module = string_1, }, build = { - platforms = {}, - type = "string", + platforms = {}, -- recursively defined below + type = string_1, install = { lua = { - MORE = true + _more = true }, lib = { - MORE = true + _more = true }, conf = { - MORE = true + _more = true }, bin = { - MORE = true + _more = true } }, copy_directories = { - ANY = "string" + _any = string_1, }, - MORE = true + _more = true, + _mandatory = true }, hooks = { - platforms = {}, - post_install = "string" + platforms = {}, -- recursively defined below + post_install = string_1, + }, + deploy = { + _version = "1.1", + wrap_bin_scripts = { _type = "boolean", _version = "1.1" }, } } @@ -82,69 +107,61 @@ type_check.rockspec_order = {"rockspec_format", "package", "version", { "build", {"type", "modules", "copy_directories", "platforms"} }, "hooks"} -function type_check.load_extensions() - type_check.rockspec_format = "1.1" - rockspec_types.deploy = { - wrap_bin_scripts = true, - } -end - -if cfg.use_extensions then - type_check.load_extensions() -end - -rockspec_types.build.platforms.ANY = rockspec_types.build -rockspec_types.dependencies.platforms.ANY = rockspec_types.dependencies -rockspec_types.external_dependencies.platforms.ANY = rockspec_types.external_dependencies -rockspec_types.MUST_source.platforms.ANY = rockspec_types.MUST_source -rockspec_types.hooks.platforms.ANY = rockspec_types.hooks +rockspec_types.build.platforms._any = rockspec_types.build +rockspec_types.dependencies.platforms._any = rockspec_types.dependencies +rockspec_types.external_dependencies.platforms._any = rockspec_types.external_dependencies +rockspec_types.source.platforms._any = rockspec_types.source +rockspec_types.hooks.platforms._any = rockspec_types.hooks local manifest_types = { - MUST_repository = { + repository = { + _mandatory = true, -- packages - ANY = { + _any = { -- versions - ANY = { + _any = { -- items - ANY = { - MUST_arch = "string", - modules = { ANY = "string" }, - commands = { ANY = "string" }, - dependencies = { ANY = "string" }, + _any = { + arch = mandatory_string_1, + modules = { _any = string_1 }, + commands = { _any = string_1 }, + dependencies = { _any = string_1 }, -- TODO: to be extended with more metadata. } } } }, - MUST_modules = { + modules = { + _mandatory = true, -- modules - ANY = { + _any = { -- providers - ANY = "string" + _any = string_1 } }, - MUST_commands = { + commands = { + _mandatory = true, -- modules - ANY = { + _any = { -- commands - ANY = "string" + _any = string_1 } }, dependencies = { -- each module - ANY = { + _any = { -- each version - ANY = { + _any = { -- each dependency - ANY = { - name = "string", + _any = { + name = string_1, constraints = { - ANY = { - no_upgrade = "boolean", - op = "string", + _any = { + no_upgrade = { _type = "boolean" }, + op = string_1, version = { - string = "string", - ANY = 0, + string = string_1, + _any = number_1, } } } @@ -154,54 +171,75 @@ local manifest_types = { } } +local function check_version(version, typetbl, context) + local typetbl_version = typetbl._version or "1.0" + if deps.compare_versions(typetbl_version, version) then + if context == "" then + return nil, "Invalid rockspec_format version number in rockspec? Please fix rockspec accordingly." + else + return nil, context.." is not supported in rockspec format "..version.." (requires version "..typetbl_version.."), please fix the rockspec_format field accordingly." + end + end + return true +end + local type_check_table --- Type check an object. -- The object is compared against an archetypical value -- matching the expected type -- the actual values don't matter, -- only their types. Tables are type checked recursively. --- @param name any: The object name (for error messages). +-- @param version string: The version of the item. -- @param item any: The object being checked. --- @param expected any: The reference object. In case of a table, --- its is structured as a type reference table. +-- @param typetbl any: The type-checking table for the object. -- @param context string: A string indicating the "context" where the --- error occurred (such as the name of the table the item is a part of), --- to be used by error messages. +-- error occurred (the full table path), for error messages. -- @return boolean or (nil, string): true if type checking -- succeeded, or nil and an error message if it failed. -- @see type_check_table -local function type_check_item(name, item, expected, context) - name = tostring(name) - - local item_type = type(item) - local expected_type = type(expected) +local function type_check_item(version, item, typetbl, context) + assert(type(version) == "string") + + local ok, err = check_version(version, typetbl, context) + if not ok then + return nil, err + end + + local item_type = type(item) or "nil" + local expected_type = typetbl._type or "table" + if expected_type == "number" then if not tonumber(item) then - return nil, "Type mismatch on field "..context..name..": expected a number" + return nil, "Type mismatch on field "..context..": expected a number" end elseif expected_type == "string" then - if type(item) ~= "string" then - return nil, "Type mismatch on field "..context..name..": expected a string" + if item_type ~= "string" then + return nil, "Type mismatch on field "..context..": expected a string, got "..item_type end - if expected ~= "string" then - if item_type ~= "string" then - return nil, "Type mismatch on field "..context..name..": expected a string, got a "..type(item) - elseif not item:match("^"..expected.."$") then - return nil, "Type mismatch on field "..context..name..": invalid value "..item.." does not match '"..expected.."'" + if typetbl._pattern then + if not item:match("^"..typetbl._pattern.."$") then + return nil, "Type mismatch on field "..context..": invalid value "..item.." does not match '"..typetbl._pattern.."'" end end elseif expected_type == "table" then if item_type ~= expected_type then - return nil, "Type mismatch on field "..context..name..": expected a table" + return nil, "Type mismatch on field "..context..": expected a table" else - return type_check_table(item, expected, context..name..".") + return type_check_table(version, item, typetbl, context) end elseif item_type ~= expected_type then - return nil, "Type mismatch on field "..context..name..": expected a "..expected_type + return nil, "Type mismatch on field "..context..": expected "..expected_type end return true end +local function mkfield(context, field) + if context == "" then + return field + end + return context.."."..field +end + --- Type check the contents of a table. -- The table's contents are compared against a reference table, -- which contains the recognized fields, with archetypical values @@ -215,23 +253,31 @@ end -- with MUST_, it is mandatory; its absence from the table is -- a type error. -- Tables are type checked recursively. +-- @param version string: The version of tbl. -- @param tbl table: The table to be type checked. --- @param types table: The reference table, containing +-- @param typetbl table: The type-checking table, containing -- values for recognized fields in the checked table. -- @param context string: A string indicating the "context" where the -- error occurred (such as the name of the table the item is a part of), -- to be used by error messages. -- @return boolean or (nil, string): true if type checking -- succeeded, or nil and an error message if it failed. -type_check_table = function(tbl, types, context) +type_check_table = function(version, tbl, typetbl, context) + assert(type(version) == "string") assert(type(tbl) == "table") - assert(type(types) == "table") + assert(type(typetbl) == "table") + + local ok, err = check_version(version, typetbl, context) + if not ok then + return nil, err + end + for k, v in pairs(tbl) do - local t = types[k] or (type(k) == "string" and types["MUST_"..k]) or types.ANY + local t = typetbl[k] or typetbl._any if t then - local ok, err = type_check_item(k, v, t, context) + local ok, err = type_check_item(version, v, t, mkfield(context, k)) if not ok then return nil, err end - elseif types.MORE then + elseif typetbl._more then -- Accept unknown field else if not cfg.accept_unknown_fields then @@ -239,21 +285,20 @@ type_check_table = function(tbl, types, context) end end end - for k, v in pairs(types) do - local mandatory_key = k:match("^MUST_(.+)") - if mandatory_key then - if not tbl[mandatory_key] then - return nil, "Mandatory field "..context..mandatory_key.." is missing." + for k, v in pairs(typetbl) do + if k:sub(1,1) ~= "_" and v._mandatory then + if not tbl[k] then + return nil, "Mandatory field "..mkfield(context, k).." is missing." end end end return true end -local function check_undeclared_globals(globals, types) +local function check_undeclared_globals(globals, typetbl) local undeclared = {} for glob, _ in pairs(globals) do - if not (types[glob] or types["MUST_"..glob]) then + if not (typetbl[glob] or typetbl["MUST_"..glob]) then table.insert(undeclared, glob) end end @@ -273,13 +318,12 @@ end -- succeeded, or nil and an error message if it failed. function type_check.type_check_rockspec(rockspec, globals) assert(type(rockspec) == "table") - if rockspec.rockspec_format then - -- relies on global state - type_check.load_extensions() + if not rockspec.rockspec_format then + rockspec.rockspec_format = "1.0" end local ok, err = check_undeclared_globals(globals, rockspec_types) if not ok then return nil, err end - return type_check_table(rockspec, rockspec_types, "") + return type_check_table(rockspec.rockspec_format, rockspec, rockspec_types, "") end --- Type check a manifest table. @@ -292,7 +336,7 @@ function type_check.type_check_manifest(manifest, globals) assert(type(manifest) == "table") local ok, err = check_undeclared_globals(globals, manifest_types) if not ok then return nil, err end - return type_check_table(manifest, manifest_types, "") + return type_check_table("1.0", manifest, manifest_types, "") end return type_check diff --git a/src/luarocks/unpack.lua b/src/luarocks/unpack.lua index 9204e26..a889bac 100644 --- a/src/luarocks/unpack.lua +++ b/src/luarocks/unpack.lua @@ -43,9 +43,10 @@ local function unpack_rockspec(rockspec_file, dir_name) end ok, err = fs.change_dir(sources_dir) if not ok then return nil, err end - build.apply_patches(rockspec) + ok, err = build.apply_patches(rockspec) fs.pop_dir() fs.pop_dir() + if not ok then return nil, err end return rockspec end @@ -79,8 +80,9 @@ local function unpack_rock(rock_file, dir_name, kind) end ok, err = fs.change_dir(rockspec.source.dir) if not ok then return nil, err end - build.apply_patches(rockspec) + ok, err = build.apply_patches(rockspec) fs.pop_dir() + if not ok then return nil, err end end end return rockspec diff --git a/src/luarocks/upload.lua b/src/luarocks/upload.lua index d87313a..19ddee8 100644 --- a/src/luarocks/upload.lua +++ b/src/luarocks/upload.lua @@ -54,7 +54,7 @@ function upload.run(...) end local rock_fname - if not flags["skip-pack"] then + if not flags["skip-pack"] and not rockspec.version:match("^scm") then util.printout("Packing " .. tostring(rockspec.package)) rock_fname, err = pack.pack_source_rock(fname) if not rock_fname then @@ -77,7 +77,7 @@ function upload.run(...) if rock_fname then util.printout(("Sending " .. tostring(rock_fname) .. " ...")) - res, err = api:method("upload_rock/" .. tostring(res.version.id), nil, { + res, err = api:method("upload_rock/" .. ("%d"):format(res.version.id), nil, { rock_file = multipart.new_file(rock_fname) }) if not res then return nil, err end diff --git a/src/luarocks/upload/api.lua b/src/luarocks/upload/api.lua index c588335..2cf462f 100644 --- a/src/luarocks/upload/api.lua +++ b/src/luarocks/upload/api.lua @@ -10,16 +10,15 @@ local multipart = require("luarocks.upload.multipart") local Api = {} local function upload_config_file() - local _, _, home_conf, home_ok = cfg.which_config() - if not home_conf then + local conf = cfg.which_config() + if not conf.user.file then return nil end - return (home_conf:gsub("/[^/]+$", "/upload_config.lua")) + return (conf.user.file:gsub("/[^/]+$", "/upload_config.lua")) end function Api:load_config() local upload_conf = upload_config_file() - print(upload_conf) if not upload_conf then return nil end local cfg, err = persist.load_into_table(upload_conf) return cfg @@ -116,6 +115,11 @@ local function require_json() return nil end +local function redact_api_url(url) + url = tostring(url) + return (url:gsub(".*/api/[^/]+/[^/]+", "")) or "" +end + local ltn12_ok, ltn12 = pcall(require, "ltn12") if not ltn12_ok then -- If not using LuaSocket and/or LuaSec... @@ -155,25 +159,28 @@ function Api:request(url, params, post_params) if cfg.connection_timeout and cfg.connection_timeout > 0 then curl_cmd = curl_cmd .. "--connect-timeout "..tonumber(cfg.connection_timeout).." " end - ok = fs.execute_string(curl_cmd..fs.Q(url).." -o "..fs.Q(tmpfile)) + local ok = fs.execute_string(curl_cmd..fs.Q(url).." -o "..fs.Q(tmpfile)) + if not ok then + return nil, "API failure: " .. redact_api_url(url) + end else local ok, err = fs.download(url, tmpfile) if not ok then - return nil, "API failure: " .. tostring(err) .. " - " .. tostring(url) + return nil, "API failure: " .. tostring(err) .. " - " .. redact_api_url(url) end end local tmpfd = io.open(tmpfile) if not tmpfd then os.remove(tmpfile) - return nil, "API failure reading temporary file - " .. tostring(url) + return nil, "API failure reading temporary file - " .. redact_api_url(url) end out = tmpfd:read("*a") tmpfd:close() os.remove(tmpfile) if self.debug then - util.printout("[" .. tostring(method) .. " via curl] " .. tostring(url) .. " ... ") + util.printout("[" .. tostring(method) .. " via curl] " .. redact_api_url(url) .. " ... ") end return json.decode(out) @@ -226,7 +233,7 @@ function Api:request(url, params, post_params) end local method = post_params and "POST" or "GET" if self.debug then - util.printout("[" .. tostring(method) .. " via "..via.."] " .. tostring(url) .. " ... ") + util.printout("[" .. tostring(method) .. " via "..via.."] " .. redact_api_url(url) .. " ... ") end local out = {} local _, status = http.request({ @@ -240,14 +247,14 @@ function Api:request(url, params, post_params) util.printout(tostring(status)) end if status ~= 200 then - return nil, "API returned " .. tostring(status) .. " - " .. tostring(url) + return nil, "API returned " .. tostring(status) .. " - " .. redact_api_url(url) end return json.decode(table.concat(out)) end end -function api.new(flags, name) +function api.new(flags) local self = {} setmetatable(self, { __index = Api }) self.config = self:load_config() or {} diff --git a/src/luarocks/upload/multipart.lua b/src/luarocks/upload/multipart.lua index 5677657..aad2e43 100644 --- a/src/luarocks/upload/multipart.lua +++ b/src/luarocks/upload/multipart.lua @@ -19,15 +19,14 @@ function File:mime() local mimetypes_ok, mimetypes = pcall(require, "mimetypes") if mimetypes_ok then self.mimetype = mimetypes.guess(self.fname) - else - self.mimetype = "application/octet-stream" end + self.mimetype = self.mimetype or "application/octet-stream" end return self.mimetype end function File:content() - local fd = io.open(self.fname) + local fd = io.open(self.fname, "rb") if not fd then return nil, "Failed to open file: "..self.fname end diff --git a/src/luarocks/util.lua b/src/luarocks/util.lua index 8772883..c06c835 100644 --- a/src/luarocks/util.lua +++ b/src/luarocks/util.lua @@ -63,6 +63,76 @@ function util.matchquote(s) return (s:gsub("[?%-+*%[%].%%()$^]","%%%1")) end +--- List of supported arguments. +-- Arguments that take no parameters are marked with the boolean true. +-- Arguments that take a parameter are marked with a descriptive string. +-- Arguments that may take an empty string are described in quotes, +-- (as in the value for --detailed="<text>"). +-- For all other string values, it means the parameter is mandatory. +local supported_flags = { + ["all"] = true, + ["api-key"] = "<key>", + ["append"] = true, + ["arch"] = "<arch>", + ["bin"] = true, + ["binary"] = true, + ["branch"] = "<branch-name>", + ["debug"] = true, + ["deps"] = true, + ["deps-mode"] = "<mode>", + ["detailed"] = "\"<text>\"", + ["force"] = true, + ["from"] = "<server>", + ["help"] = true, + ["home"] = true, + ["homepage"] = "\"<url>\"", + ["keep"] = true, + ["lib"] = "<library>", + ["license"] = "\"<text>\"", + ["list"] = true, + ["local"] = true, + ["local-tree"] = true, + ["lr-bin"] = true, + ["lr-cpath"] = true, + ["lr-path"] = true, + ["lua-version"] = "<vers>", + ["lua-ver"] = true, + ["lua-incdir"] = true, + ["lua-libdir"] = true, + ["modules"] = true, + ["mversion"] = true, + ["no-refresh"] = true, + ["nodeps"] = true, + ["old-versions"] = true, + ["only-deps"] = true, + ["only-from"] = "<server>", + ["only-server"] = "<server>", + ["only-sources"] = "<url>", + ["only-sources-from"] = "<url>", + ["outdated"] = true, + ["output"] = "<file>", + ["pack-binary-rock"] = true, + ["porcelain"] = true, + ["quick"] = true, + ["rock-dir"] = true, + ["rock-tree"] = true, + ["rock-trees"] = true, + ["rockspec"] = true, + ["rockspec-format"] = "<ver>", + ["server"] = "<server>", + ["skip-pack"] = true, + ["source"] = true, + ["summary"] = "\"<text>\"", + ["system-config"] = true, + ["tag"] = "<tag>", + ["timeout"] = "<seconds>", + ["to"] = "<path>", + ["tree"] = "<path>", + ["user-config"] = true, + ["verbose"] = true, + ["version"] = true, +} + --- Extract flags from an arguments list. -- Given string arguments, extract flag arguments into a flags set. -- For example, given "foo", "--tux=beep", "--bla", "bar", "--baz", @@ -71,19 +141,59 @@ end function util.parse_flags(...) local args = {...} local flags = {} - for i = #args, 1, -1 do + local i = 1 + local out = {} + local ignore_flags = false + while i <= #args do local flag = args[i]:match("^%-%-(.*)") - if flag then + if flag == "--" then + ignore_flags = true + end + if flag and not ignore_flags then local var,val = flag:match("([a-z_%-]*)=(.*)") if val then - flags[var] = val + local vartype = supported_flags[var] + if type(vartype) == "string" then + if val == "" and vartype:sub(1,1) ~= '"' then + return { ERROR = "Invalid argument: parameter to flag --"..var.."="..vartype.." cannot be empty." } + end + flags[var] = val + else + if vartype then + return { ERROR = "Invalid argument: flag --"..var.." does not take an parameter." } + else + return { ERROR = "Invalid argument: unknown flag --"..var.."." } + end + end else - flags[flag] = true + local var = flag + local vartype = supported_flags[var] + if type(vartype) == "string" then + i = i + 1 + local val = args[i] + if not val then + return { ERROR = "Invalid argument: flag --"..var.."="..vartype.." expects a parameter." } + end + if val:match("^%-%-.*") then + return { ERROR = "Invalid argument: flag --"..var.."="..vartype.." expects a parameter (if you really want to pass "..val.." as an argument to --"..var..", use --"..var.."="..val..")." } + else + if val == "" and vartype:sub(1,1) ~= '"' then + return { ERROR = "Invalid argument: parameter to flag --"..var.."="..vartype.." cannot be empty." } + end + flags[var] = val + end + elseif vartype == true then + flags[var] = true + else + return { ERROR = "Invalid argument: unknown flag --"..var.."." } + end end - table.remove(args, i) + else + table.insert(out, args[i]) end + i = i + 1 end - return flags, unpack(args) + return flags, unpack(out) end --- Build a sequence of flags for forwarding from one command to @@ -177,7 +287,7 @@ local var_format_pattern = "%$%((%a[%a%d_]+)%)" -- the original table (ie, does not copy recursively). -- @param tbl table: the input table -- @return table: a new table with the same contents. -local function make_shallow_copy(tbl) +function util.make_shallow_copy(tbl) local copy = {} for k,v in pairs(tbl) do copy[k] = v @@ -196,7 +306,7 @@ end -- needed variables. -- @param msg string: the warning message to display. function util.warn_if_not_used(var_defs, needed_set, msg) - needed_set = make_shallow_copy(needed_set) + needed_set = util.make_shallow_copy(needed_set) for _, val in pairs(var_defs) do for used in val:gmatch(var_format_pattern) do needed_set[used] = nil diff --git a/src/luarocks/write_rockspec.lua b/src/luarocks/write_rockspec.lua index 403cbc8..972562c 100644 --- a/src/luarocks/write_rockspec.lua +++ b/src/luarocks/write_rockspec.lua @@ -24,18 +24,19 @@ If a repository URL is given with no version, it creates an 'scm' rock. Note that the generated file is a _starting point_ for writing a rockspec, and is not guaranteed to be complete or correct. ---output=<file> Write the rockspec with the given filename. - If not given, a file is written in the current - directory with a filename based on given name and version. ---license="<string>" A license string, such as "MIT/X11" or "GNU GPL v3". ---summary="<txt>" A short one-line description summary. ---detailed="<txt>" A longer description string. ---homepage=<url> Project homepage. ---lua-version=<ver> Supported Lua versions. Accepted values are "5.1", "5.2", - "5.3", "5.1,5.2", "5.2,5.3", or "5.1,5.2,5.3". ---tag=<tag> Tag to use. Will attempt to extract version number from it. ---lib=<lib>[,<lib>] A comma-separated list of libraries that C files need to - link to. +--output=<file> Write the rockspec with the given filename. + If not given, a file is written in the current + directory with a filename based on given name and version. +--license="<string>" A license string, such as "MIT/X11" or "GNU GPL v3". +--summary="<txt>" A short one-line description summary. +--detailed="<txt>" A longer description string. +--homepage=<url> Project homepage. +--lua-version=<ver> Supported Lua versions. Accepted values are "5.1", "5.2", + "5.3", "5.1,5.2", "5.2,5.3", or "5.1,5.2,5.3". +--rockspec-format=<ver> Rockspec format version, such as "1.0" or "1.1". +--tag=<tag> Tag to use. Will attempt to extract version number from it. +--lib=<lib>[,<lib>] A comma-separated list of libraries that C files need to + link to. ]] local function open_file(name) @@ -76,25 +77,24 @@ local function configure_lua_version(rockspec, luaver) end end -local function detect_description(rockspec) +local function detect_description() local fd = open_file("README.md") or open_file("README") if not fd then return end local data = fd:read("*a") fd:close() local paragraph = data:match("\n\n([^%[].-)\n\n") if not paragraph then paragraph = data:match("\n\n(.*)") end + local summary, detailed if paragraph then + detailed = paragraph + if #paragraph < 80 then - rockspec.description.summary = paragraph:gsub("\n", "") - rockspec.description.detailed = paragraph + summary = paragraph:gsub("\n", "") else - local summary = paragraph:gsub("\n", " "):match("([^.]*%.) ") - if summary then - rockspec.description.summary = summary:gsub("\n", "") - end - rockspec.description.detailed = paragraph + summary = paragraph:gsub("\n", " "):match("([^.]*%.) ") end end + return summary, detailed end local function detect_mit_license(data) @@ -209,17 +209,13 @@ function write_rockspec.run(...) elseif not url_or_dir then url_or_dir = version end - - if flags["tag"] == true then - return nil, "Incorrect usage: --tag requires an argument. "..util.see_help("write_rockspec") - end if flags["tag"] then if not version then version = flags["tag"]:gsub("^v", "") end end - + local protocol, pathname = dir.split_url(url_or_dir) if not fetch.is_basic_protocol(protocol) then if not name then @@ -251,6 +247,7 @@ function write_rockspec.run(...) end local rockspec = { + rockspec_format = flags["rockspec-format"], package = name, name = name:lower(), version = version.."-1", @@ -316,7 +313,11 @@ function write_rockspec.run(...) local ok, err = fs.change_dir(local_dir) if not ok then return nil, "Failed reaching files from project - error entering directory "..local_dir end - detect_description(rockspec) + if (not flags["summary"]) or (not flags["detailed"]) then + local summary, detailed = detect_description() + rockspec.description.summary = flags["summary"] or summary + rockspec.description.detailed = flags["detailed"] or detailed + end local is_mit = show_license(rockspec) diff --git a/test/testfiles/invalid_patch-0.1-1.rockspec b/test/testfiles/invalid_patch-0.1-1.rockspec new file mode 100644 index 0000000..c2ecd16 --- /dev/null +++ b/test/testfiles/invalid_patch-0.1-1.rockspec @@ -0,0 +1,29 @@ +package = "invalid_patch" +version = "0.1-1" +source = { + -- any valid URL + url = "https://raw.github.com/keplerproject/luarocks/master/src/luarocks/build.lua" +} +description = { + summary = "A rockspec with an invalid patch", +} +dependencies = { + "lua >= 5.1" +} +build = { + type = "builtin", + modules = { + build = "build.lua" + }, + patches = { + ["I_am_an_invalid_patch.patch"] = +[[ +diff -Naur luadoc-3.0.1/src/luadoc/doclet/html.lua luadoc-3.0.1-new/src/luadoc/doclet/html.lua +--- luadoc-3.0.1/src/luadoc/doclet/html.lua2007-12-21 15:50:48.000000000 -0200 ++++ luadoc-3.0.1-new/src/luadoc/doclet/html.lua2008-02-28 01:59:53.000000000 -0300 +@@ -18,6 +18,7 @@ +- gabba gabba gabba ++ gobo gobo gobo +]] + } +} diff --git a/test/testfiles/no_build_table-0.1-1.rockspec b/test/testfiles/no_build_table-0.1-1.rockspec new file mode 100644 index 0000000..5d79e9a --- /dev/null +++ b/test/testfiles/no_build_table-0.1-1.rockspec @@ -0,0 +1,12 @@ +package = "no_build_table" +version = "0.1-1" +source = { + -- any valid URL + url = "https://raw.github.com/keplerproject/luarocks/master/src/luarocks/build.lua" +} +description = { + summary = "A rockspec with no build field", +} +dependencies = { + "lua >= 5.1" +} diff --git a/test/testfiles/not_a_zipfile-1.0-1.src.rock b/test/testfiles/not_a_zipfile-1.0-1.src.rock new file mode 100644 index 0000000..e36f8bb --- /dev/null +++ b/test/testfiles/not_a_zipfile-1.0-1.src.rock @@ -0,0 +1 @@ +I am not a .zip file! diff --git a/test/testfiles/type_mismatch_string-1.0-1.rockspec b/test/testfiles/type_mismatch_string-1.0-1.rockspec new file mode 100644 index 0000000..7a607cf --- /dev/null +++ b/test/testfiles/type_mismatch_string-1.0-1.rockspec @@ -0,0 +1,4 @@ + +package="type_mismatch_version" +version=1.0 + diff --git a/test/testfiles/type_mismatch_table-1.0-1.rockspec b/test/testfiles/type_mismatch_table-1.0-1.rockspec new file mode 100644 index 0000000..f348b79 --- /dev/null +++ b/test/testfiles/type_mismatch_table-1.0-1.rockspec @@ -0,0 +1,5 @@ + +package="type_mismatch_table" +version="1.0-1" + +source = "not a table" diff --git a/test/testfiles/type_mismatch_version-1.0-1.rockspec b/test/testfiles/type_mismatch_version-1.0-1.rockspec new file mode 100644 index 0000000..5e30dae --- /dev/null +++ b/test/testfiles/type_mismatch_version-1.0-1.rockspec @@ -0,0 +1,4 @@ + +package="type_mismatch_version" +version="1.0" + diff --git a/test/testing.bat b/test/testing.bat new file mode 100644 index 0000000..319e12c --- /dev/null +++ b/test/testing.bat @@ -0,0 +1,9 @@ +@echo off +Setlocal EnableDelayedExpansion EnableExtensions + +if not defined LUAROCKS_REPO set LUAROCKS_REPO=http://rocks.moonscript.org + +appveyor DownloadFile %LUAROCKS_REPO%/stdlib-41.0.0-1.src.rock +luarocks build stdlib + +endlocal diff --git a/test/testing.lua b/test/testing.lua new file mode 100644 index 0000000..63dead2 --- /dev/null +++ b/test/testing.lua @@ -0,0 +1,457 @@ + +local variables = {} + +-- Expand variables in the format $foo or ${foo} according +-- to the variables table. +local function expand_variables(str) + return str:gsub("%$({?)([A-Za-z0-9_]+)(}?)", function(o, v, c) + return #o <= #c and (variables[v] or "") .. (#o < #c and c or "") + end) +end + +-- @param cmd command to run +-- @param envtable optional table of temporary environment variables +local function run(cmd, envtable) + cmd = expand_variables(cmd) + local env = {} + for var, val in pairs(envtable) do + table.insert(env, var.."='"..expand_variables(val).."' ") + end + local code = os.execute(table.concat(env)..cmd) + return (code == 0 or code == true) +end + +local function cd_run(dir, cmd, envtable) + return run("cd "..dir.." && "..cmd, envtable) +end + +local function run_get_contents(cmd) +end + +local function mkdir(dirname) + cmd = expand_variables(dirname) + -- TODO +end + +local function rm_rf(...) + -- TODO +end + +local function mv(src, dst) + -- TODO +end + +local function exists(filename) + filename = expand_variables(filename) + -- TODO +end + +local function glob(patt) + -- TODO +end + +local function touch(filename) + -- TODO +end + +local function rm(...) + for _, filename in ipairs {...} do + filename = expand_variables(filename) + -- TODO + end + return true +end + +local function file_set_contents(filename, contents) + filename = expand_variables(filename) + + local fd, err = io.open(filename, "w") + if not fd then return nil, err end + fd:write(contents) + fd:close() + return true +end + +local function need_luasocket() + -- TODO +end + +local tests = { + + test_version = function() return run "$luarocks --version" end, + fail_unknown_command = function() return run "$luarocks unknown_command" end, + fail_arg_boolean_parameter = function() return run "$luarocks --porcelain=invalid" end, + fail_arg_boolean_unknown = function() return run "$luarocks --invalid-flag" end, + fail_arg_string_no_parameter = function() return run "$luarocks --server" end, + fail_arg_string_followed_by_flag = function() return run "$luarocks --server --porcelain" end, + fail_arg_string_unknown = function() return run "$luarocks --invalid-flag=abc" end, + test_empty_list = function() return run "$luarocks list" end, + fail_sysconfig_err = function() + mkdir "$testing_lrprefix/etc/luarocks" + file_set_contents("$testing_lrprefix/etc/luarocks/config.lua", "aoeui") + return run "$luarocks list" + and rm "$testing_lrprefix/etc/luarocks/config.lua" + end, + fail_sysconfig_default_err = function() + mkdir "$testing_lrprefix/etc/luarocks" + file_set_contents("$testing_lrprefix/etc/luarocks/config-$luashortversion.lua", "aoeui") + return run "$luarocks list" + and rm "$testing_lrprefix/etc/luarocks/config-$luashortversion.lua" + end, + fail_build_noarg = function() return run "$luarocks build" end, + fail_download_noarg = function() return run "$luarocks download" end, + fail_install_noarg = function() return run "$luarocks install" end, + fail_lint_noarg = function() return run "$luarocks lint" end, + fail_search_noarg = function() return run "$luarocks search" end, + fail_show_noarg = function() return run "$luarocks show" end, + fail_unpack_noarg = function() return run "$luarocks unpack" end, + fail_upload_noarg = function() return run "$luarocks upload" end, + fail_remove_noarg = function() return run "$luarocks remove" end, + fail_doc_noarg = function() return run "$luarocks doc" end, + fail_new_version_noarg = function() return run "$luarocks new_version" end, + fail_write_rockspec_noarg = function() return run "$luarocks write_rockspec" end, + fail_build_invalid = function() return run "$luarocks build invalid" end, + fail_download_invalid = function() return run "$luarocks download invalid" end, + fail_install_invalid = function() return run "$luarocks install invalid" end, + fail_lint_invalid = function() return run "$luarocks lint invalid" end, + fail_show_invalid = function() return run "$luarocks show invalid" end, + fail_new_version_invalid = function() return run "$luarocks new_version invalid" end, + test_list_invalidtree = function() return run "$luarocks --tree=/some/invalid/tree list" end, + fail_inexistent_dir = function() + -- Unix only? + return run "mkdir idontexist; cd idontexist; rmdir ../idontexist; $luarocks; err=$?; cd ..; return $err" + end, + fail_make_norockspec = function() return run "$luarocks make" end, + fail_build_permissions = function() return run "$luarocks build --tree=/usr lpeg" end, + fail_build_permissions_parent = function() return run "$luarocks build --tree=/usr/invalid lpeg" end, + test_build_verbose = function() return run "$luarocks build --verbose lpeg" end, + fail_build_blank_arg = function() return run "$luarocks build --tree="" lpeg" end, + test_build_withpatch = function() need_luasocket(); return run "$luarocks build luadoc" end, + test_build_diffversion = function() return run "$luarocks build luacov ${version_luacov}" end, + test_build_command = function() return run "$luarocks build stdlib" end, + test_build_install_bin = function() return run "$luarocks build luarepl" end, + test_build_nohttps = function() + need_luasocket() + return run "$luarocks download --rockspec validate-args ${verrev_validate_args}" + and run "$luarocks build ./validate-args-${version_validate_args}-1.rockspec" + and rm "./validate-args-${version_validate_args}-1.rockspec" + end, + test_build_https = function() + need_luasocket() + return run "$luarocks download --rockspec validate-args ${verrev_validate_args}" + and run "$luarocks install luasec" + and run "$luarocks build ./validate-args-${verrev_validate_args}.rockspec" + and rm "./validate-args-${verrev_validate_args}.rockspec" + end, + test_build_supported_platforms = function() return run "$luarocks build lpty" end, + test_build_only_deps_rockspec = function() + return run "$luarocks download --rockspec lxsh ${verrev_lxsh}" + and run "$luarocks build ./lxsh-${verrev_lxsh}.rockspec --only-deps" + and (not run "$luarocks show lxsh") + end, + test_build_only_deps_src_rock = function() + return run "$luarocks download --source lxsh ${verrev_lxsh}" + and run "$luarocks build ./lxsh-${verrev_lxsh}.src.rock --only-deps" + and (not run "$luarocks show lxsh") + end, + test_build_only_deps = function() return run "$luarocks build luasec --only-deps" and (not run "$luarocks show luasec") end, + test_install_only_deps = function() return run "$luarocks install lxsh ${verrev_lxsh} --only-deps" and (not run "$luarocks show lxsh") end, + fail_build_missing_external = function() return run '$luarocks build "$testing_dir/testfiles/missing_external-0.1-1.rockspec" INEXISTENT_INCDIR="/invalid/dir"' end, + fail_build_invalidpatch = function() + need_luasocket() + return run '$luarocks build "$testing_dir/testfiles/invalid_patch-0.1-1.rockspec"' + end, + test_build_deps_partial_match = function() return run "$luarocks build lmathx" end, + test_build_show_downloads = function() + return run("$luarocks build alien", { LUAROCKS_CONFIG="$testing_dir/testing_config_show_downloads.lua" }) + end, + test_download_all = function() + return run "$luarocks download --all validate-args" + and rm(glob("validate-args-*")) + end, + test_download_rockspecversion = function() + return run "$luarocks download --rockspec validate-args ${verrev_validate_args}" + and rm(glob("validate-args-*")) + end, + test_help = function() return run "$luarocks help" end, + fail_help_invalid = function() return run "$luarocks help invalid" end, + test_install_binaryrock = function() + return run "$luarocks build --pack-binary-rock cprint" + and run "$luarocks install ./cprint-${verrev_cprint}.${platform}.rock" + and rm "./cprint-${verrev_cprint}.${platform}.rock" + end, + test_install_with_bin = function() return run "$luarocks install wsapi" end, + fail_install_notazipfile = function() return run '$luarocks install "$testing_dir/testfiles/not_a_zipfile-1.0-1.src.rock"' end, + fail_install_invalidpatch = function() + need_luasocket() + return run '$luarocks install "$testing_dir/testfiles/invalid_patch-0.1-1.rockspec"' + end, + fail_install_invalid_filename = function() return run '$luarocks install "invalid.rock"' end, + fail_install_invalid_arch = function() return run '$luarocks install "foo-1.0-1.impossible-x86.rock"' end, + test_install_reinstall = function() + return run '$luarocks install "$testing_cache/luasocket-$verrev_luasocket.$platform.rock"' + and run '$luarocks install --deps-mode=none "$testing_cache/luasocket-$verrev_luasocket.$platform.rock"' + end, + fail_local_root = function() return run("$luarocks install --local luasocket", { USER="root" }) end, + test_site_config = function() + mv("../src/luarocks/site_config.lua", "../src/luarocks/site_config.lua.tmp") + local ok = run "$luarocks" + mv("../src/luarocks/site_config.lua.tmp", "../src/luarocks/site_config.lua") + return ok + end, + test_lint_ok = function() + return run "$luarocks download --rockspec validate-args ${verrev_validate_args}" + and run "$luarocks lint ./validate-args-${verrev_validate_args}.rockspec" + and rm "./validate-args-${verrev_validate_args}.rockspec" + end, + fail_lint_type_mismatch_string = function() return run '$luarocks lint "$testing_dir/testfiles/type_mismatch_string-1.0-1.rockspec"' end, + fail_lint_type_mismatch_version = function() return run '$luarocks lint "$testing_dir/testfiles/type_mismatch_version-1.0-1.rockspec"' end, + fail_lint_type_mismatch_table = function() return run '$luarocks lint "$testing_dir/testfiles/type_mismatch_table-1.0-1.rockspec"' end, + fail_lint_no_build_table = function() return run '$luarocks lint "$testing_dir/testfiles/no_build_table-0.1-1.rockspec"' end, + test_list = function() return run "$luarocks list" end, + test_list_porcelain = function() return run "$luarocks list --porcelain" end, + test_make_with_rockspec = function() + return rm_rf "./luasocket-${verrev_luasocket}" + and run "$luarocks download --source luasocket" + and run "$luarocks unpack ./luasocket-${verrev_luasocket}.src.rock" + and cd_run("luasocket-${verrev_luasocket}/${srcdir_luasocket}", "$luarocks make luasocket-${verrev_luasocket}.rockspec") + and rm_rf "./luasocket-${verrev_luasocket}" + end, + test_make_default_rockspec = function() + return rm_rf "./lxsh-${verrev_lxsh}" + and run "$luarocks download --source lxsh ${verrev_lxsh}" + and run "$luarocks unpack ./lxsh-${verrev_lxsh}.src.rock" + and cd_run("lxsh-${verrev_lxsh}/lxsh-${version_lxsh}-1", "$luarocks make") + and rm_rf "./lxsh-${verrev_lxsh}" + end, + test_make_pack_binary_rock = function() + return rm_rf "./lxsh-${verrev_lxsh}" + and run "$luarocks download --source lxsh ${verrev_lxsh}" + and run "$luarocks unpack ./lxsh-${verrev_lxsh}.src.rock" + and cd_run("lxsh-${verrev_lxsh}/lxsh-${version_lxsh}-1", "$luarocks make --deps-mode=none --pack-binary-rock") + and exists "lxsh-${verrev_lxsh}/lxsh-${version_lxsh}-1/lxsh-${verrev_lxsh}.all.rock" + and rm_rf "./lxsh-${verrev_lxsh}" + end, + fail_make_which_rockspec = function() + rm_rf "./luasocket-${verrev_luasocket}" + run "$luarocks download --source luasocket" + run "$luarocks unpack ./luasocket-${verrev_luasocket}.src.rock" + local ok = cd_run("luasocket-${verrev_luasocket}/${srcdir_luasocket}", "$luarocks make") + rm_rf "./luasocket-${verrev_luasocket}" + return ok + end, + test_new_version = function() + return run "$luarocks download --rockspec luacov ${version_luacov}" + and run "$luarocks new_version ./luacov-${version_luacov}-1.rockspec 0.2" + and rm(glob("./luacov-0.*")) + end, + test_new_version_url = function() + return run "$luarocks download --rockspec abelhas 1.0" + and run "$luarocks new_version ./abelhas-1.0-1.rockspec 1.1 https://github.com/downloads/ittner/abelhas/abelhas-1.1.tar.gz" + and rm(glob("./abelhas-*")) + end, + test_pack = function() + return run "$luarocks list" + and run "$luarocks pack luacov" + and rm(glob("./luacov-*.rock")) + end, + test_pack_src = function() + return run "$luarocks install luasec" + and run "$luarocks download --rockspec luasocket" + and run "$luarocks pack ./luasocket-${verrev_luasocket}.rockspec" + and rm(glob("./luasocket-${version_luasocket}-*.rock")) + end, + test_path = function() return run "$luarocks path --bin" end, + test_path_lr_path = function() return run "$luarocks path --lr-path" end, + test_path_lr_cpath = function() return run "$luarocks path --lr-cpath" end, + test_path_lr_bin = function() return run "$luarocks path --lr-bin" end, + fail_purge_missing_tree = function() return run '$luarocks purge --tree="$testing_tree"' end, + test_purge = function() return run '$luarocks purge --tree="$testing_sys_tree"' end, + test_remove = function() + return run "$luarocks build abelhas ${version_abelhas}" + and run "$luarocks remove abelhas ${version_abelhas}" + end, + test_remove_force = function() + need_luasocket() + return run "$luarocks build lualogging" + and run "$luarocks remove --force luasocket" + end, + fail_remove_deps = function() + need_luasocket() + return run "$luarocks build lualogging" + and run "$luarocks remove luasocket" + end, + fail_remove_missing = function() return run "$luarocks remove missing_rock" end, + fail_remove_invalid_name = function() return run "$luarocks remove invalid.rock" end, + test_search_found = function() return run "$luarocks search zlib" end, + test_search_missing = function() return run "$luarocks search missing_rock" end, + test_show = function() return run "$luarocks show luacov" end, + test_show_modules = function() return run "$luarocks show --modules luacov" end, + test_show_home = function() return run "$luarocks show --home luacov" end, + test_show_depends = function() + need_luasocket() + return run "$luarocks install luasec" + and run "$luarocks show luasec" + end, + test_show_oldversion = function() + return run "$luarocks install luacov ${version_luacov}" + and run "$luarocks show luacov ${version_luacov}" + end, + test_unpack_download = function() + return rm_rf "./cprint-${verrev_cprint}" + and run "$luarocks unpack cprint" + and rm_rf "./cprint-${verrev_cprint}" + end, + test_unpack_src = function() + return rm_rf "./cprint-${verrev_cprint}" + and run "$luarocks download --source cprint" + and run "$luarocks unpack ./cprint-${verrev_cprint}.src.rock" + and rm_rf "./cprint-${verrev_cprint}" + end, + test_unpack_rockspec = function() + return rm_rf "./cprint-${verrev_cprint}" + and run "$luarocks download --rockspec cprint" + and run "$luarocks unpack ./cprint-${verrev_cprint}.rockspec" + and rm_rf "./cprint-${verrev_cprint}" + end, + test_unpack_binary = function() + return rm_rf "./cprint-${verrev_cprint}" + and run "$luarocks build cprint" + and run "$luarocks pack cprint" + and run "$luarocks unpack ./cprint-${verrev_cprint}.${platform}.rock" + and rm_rf "./cprint-${verrev_cprint}" + end, + fail_unpack_invalidpatch = function() + need_luasocket() + return run '$luarocks unpack "$testing_dir/testfiles/invalid_patch-0.1-1.rockspec"' + end, + fail_unpack_invalidrockspec = function() + need_luasocket() + return run '$luarocks unpack "invalid.rockspec"' + end, + fail_upload_invalidrockspec = function() return run '$luarocks upload "invalid.rockspec"' end, + fail_upload_invalidkey = function() return run '$luarocks upload --api-key="invalid" "invalid.rockspec"' end, + test_admin_help = function() return run "$luarocks_admin help" end, + test_admin_make_manifest = function() return run "$luarocks_admin make_manifest" end, + test_admin_add_rsync = function() return run '$luarocks_admin --server=testing add "$testing_server/luasocket-${verrev_luasocket}.src.rock"' end, + test_admin_add_sftp = function() + return run("$luarocks_admin --server=testing add ./luasocket-${verrev_luasocket}.src.rock", { LUAROCKS_CONFIG="$testing_dir/testing_config_sftp.lua" }) + end, + fail_admin_add_missing = function() return run "$luarocks_admin --server=testing add" end, + fail_admin_invalidserver = function() return run '$luarocks_admin --server=invalid add "$testing_server/luasocket-${verrev_luasocket}.src.rock"' end, + fail_admin_invalidrock = function() return run "$luarocks_admin --server=testing add invalid" end, + test_admin_refresh_cache = function() return run "$luarocks_admin --server=testing refresh_cache" end, + test_admin_remove = function() return run "$luarocks_admin --server=testing remove luasocket-${verrev_luasocket}.src.rock" end, + fail_admin_remove_missing = function() return run "$luarocks_admin --server=testing remove" end, + fail_deps_mode_invalid_arg = function() return run "$luarocks remove luacov --deps-mode" end, + + test_deps_mode_one = function() + return run '$luarocks build --tree="system" lpeg' + and run '$luarocks list' + and run '$luarocks build --deps-mode=one --tree="$testing_tree" lxsh' + and run_get_contents '$luarocks_noecho list --tree="$testing_tree" --porcelain lpeg' ~= "" + end, + test_deps_mode_order = function() + return run '$luarocks build --tree="system" lpeg' + and run '$luarocks build --deps-mode=order --tree="$testing_tree" lxsh' + and run '$luarocks_noecho list --tree="$testing_tree" --porcelain lpeg' + and run_get_contents '$luarocks_noecho list --tree="$testing_tree" --porcelain lpeg' == "" + end, + test_deps_mode_order_sys = function() + return run '$luarocks build --tree="$testing_tree" lpeg' + and run '$luarocks build --deps-mode=order --tree="$testing_sys_tree" lxsh' + and run_get_contents '$luarocks_noecho list --tree="$testing_sys_tree" --porcelain lpeg' ~= "" + end, + test_deps_mode_all_sys = function() + return run '$luarocks build --tree="$testing_tree" lpeg' + and run '$luarocks build --deps-mode=all --tree="$testing_sys_tree" lxsh' + and run_get_contents '$luarocks_noecho list --tree="$testing_sys_tree" --porcelain lpeg' == "" + end, + + test_deps_mode_none = function() + return run '$luarocks build --tree="$testing_tree" --deps-mode=none lxsh' + and run_get_contents '$luarocks_noecho list --tree="$testing_tree" --porcelain lpeg' == "" + end, + test_deps_mode_nodeps_alias = function() + return run '$luarocks build --tree="$testing_tree" --nodeps lxsh' + and run_get_contents '$luarocks_noecho list --tree="$testing_tree" --porcelain lpeg' == "" + end, + test_deps_mode_make_order = function() + local ok = run '$luarocks build --tree="$testing_sys_tree" lpeg' + and rm_rf "./lxsh-${verrev_lxsh}" + and run "$luarocks download --source lxsh ${verrev_lxsh}" + and run "$luarocks unpack ./lxsh-${verrev_lxsh}.src.rock" + and cd_run("lxsh-${verrev_lxsh}/lxsh-${version_lxsh}-1", '$luarocks make --tree="$testing_tree" --deps-mode=order') + if not ok then + return false + end + local found = run_get_contents '$luarocks_noecho list --tree="$testing_tree" --porcelain lpeg' + rm_rf "./lxsh-${verrev_lxsh}" + return found == "" + end, + test_deps_mode_make_order_sys = function() + local ok = run '$luarocks build --tree="$testing_tree" lpeg' + and rm_rf "./lxsh-${verrev_lxsh}" + and run "$luarocks download --source lxsh ${verrev_lxsh}" + and run "$luarocks unpack ./lxsh-${verrev_lxsh}.src.rock" + and cd_run("lxsh-${verrev_lxsh}/lxsh-${version_lxsh}-1", '$luarocks make --tree="$testing_sys_tree" --deps-mode=order') + if not ok then + return false + end + local found = run_get_contents '$luarocks_noecho list --tree="$testing_sys_tree" --porcelain lpeg' + rm_rf "./lxsh-${verrev_lxsh}" + return found ~= "" + end, + test_write_rockspec = function() return run "$luarocks write_rockspec git://github.com/keplerproject/luarocks" end, + test_write_rockspec_lib = function() return run '$luarocks write_rockspec git://github.com/mbalmer/luafcgi --lib=fcgi --license="3-clause BSD" --lua-version=5.1,5.2' end, + test_write_rockspec_format = function() return run '$luarocks write_rockspec git://github.com/keplerproject/luarocks --rockspec-format=1.1 --lua-version=5.1,5.2' end, + test_write_rockspec_fullargs = function() return run '$luarocks write_rockspec git://github.com/keplerproject/luarocks --lua-version=5.1,5.2 --license="MIT/X11" --homepage="http://www.luarocks.org" --summary="A package manager for Lua modules"' end, + fail_write_rockspec_args = function() return run "$luarocks write_rockspec invalid" end, + fail_write_rockspec_args_url = function() return run "$luarocks write_rockspec http://example.com/invalid.zip" end, + test_write_rockspec_http = function() return run "$luarocks write_rockspec http://luarocks.org/releases/luarocks-2.1.0.tar.gz --lua-version=5.1" end, + test_write_rockspec_basedir = function() return run "$luarocks write_rockspec https://github.com/downloads/Olivine-Labs/luassert/luassert-1.2.tar.gz --lua-version=5.1" end, + + fail_config_noflags = function() return run "$luarocks config; " end, + test_config_lua_incdir = function() return run "$luarocks config --lua-incdir; " end, + test_config_lua_libdir = function() return run "$luarocks config --lua-libdir; " end, + test_config_lua_ver = function() return run "$luarocks config --lua-ver; " end, + fail_config_system_config = function() + return rm "$testing_lrprefix/etc/luarocks/config.lua" + and run "$luarocks config --system-config; " + end, + test_config_system_config = function() + local ok = mkdir "$testing_lrprefix/etc/luarocks" + and touch "$testing_lrprefix/etc/luarocks/config.lua" + and run "$luarocks config --system-config; " + rm "$testing_lrprefix/etc/luarocks/config.lua" + return ok + end, + fail_config_system_config_invalid = function() + local ok = mkdir "$testing_lrprefix/etc/luarocks" + and run "echo 'if if if' > '$testing_lrprefix/etc/luarocks/config.lua' ;" + and run "$luarocks config --system-config" + rm "$testing_lrprefix/etc/luarocks/config.lua" + return ok + end, + test_config_user_config = function() return run "$luarocks config --user-config; " end, + fail_config_user_config = function() return run "LUAROCKS_CONFIG='/missing_file.lua' $luarocks config --user-config; " end, + test_config_rock_trees = function() return run "$luarocks config --rock-trees;" end, + test_config_help = function() return run "$luarocks help config;" end, + test_doc = function() + return run "$luarocks install luarepl" + and run "$luarocks doc luarepl" + end, + + -- Tests for https://github.com/keplerproject/luarocks/issues/375 + test_fetch_base_dir = function() + local fetch = require "luarocks.fetch" + + return assert("v0.3" == fetch.url_to_base_dir("https://github.com/hishamhm/lua-compat-5.2/archive/v0.3.zip")) + and assert("lua-compat-5.2" == fetch.url_to_base_dir("https://github.com/hishamhm/lua-compat-5.2.zip")) + and assert("lua-compat-5.2" == fetch.url_to_base_dir("https://github.com/hishamhm/lua-compat-5.2.tar.gz")) + and assert("lua-compat-5.2" == fetch.url_to_base_dir("https://github.com/hishamhm/lua-compat-5.2.tar.bz2")) + and assert("parser.moon" == fetch.url_to_base_dir("git://github.com/Cirru/parser.moon")) + and assert("v0.3" == fetch.url_to_base_dir("https://github.com/hishamhm/lua-compat-5.2/archive/v0.3")) + end + +} diff --git a/test/testing.sh b/test/testing.sh index b0d95c3..26bdde5 100755 --- a/test/testing.sh +++ b/test/testing.sh @@ -30,8 +30,11 @@ then shift fi +luashortversion=`echo $luaversion | cut -d. -f 1-2` + testing_dir="$PWD" +testing_lrprefix="$testing_dir/testing_lrprefix-$luaversion" testing_tree="$testing_dir/testing-$luaversion" testing_sys_tree="$testing_dir/testing_sys-$luaversion" testing_tree_copy="$testing_dir/testing_copy-$luaversion" @@ -39,7 +42,6 @@ testing_sys_tree_copy="$testing_dir/testing_sys_copy-$luaversion" testing_cache="$testing_dir/testing_cache-$luaversion" testing_server="$testing_dir/testing_server-$luaversion" - if [ "$1" == "--clean" ] then shift @@ -51,6 +53,7 @@ fi rm -f luacov.report.out rm -rf /tmp/luarocks_testing mkdir /tmp/luarocks_testing +rm -rf "$testing_lrprefix" rm -rf "$testing_tree" rm -rf "$testing_sys_tree" rm -rf "$testing_tree_copy" @@ -77,7 +80,7 @@ rocks_servers = { } local_cache = "$testing_cache" upload_server = "testing" -upload_user = "hisham" +upload_user = "$USER" upload_servers = { testing = { rsync = "localhost/tmp/luarocks_testing", @@ -107,7 +110,7 @@ rocks_trees = { } local_cache = "$testing_cache" upload_server = "testing" -upload_user = "hisham" +upload_user = "$USER" upload_servers = { testing = { sftp = "localhost/tmp/luarocks_testing", @@ -153,8 +156,16 @@ then make install INSTALL_TOP="$luadir" &> /dev/null fi popd + [ -e ~/.ssh/id_rsa.pub ] || ssh-keygen -t rsa -P "" -f ~/.ssh/id_rsa + cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys + chmod og-wx ~/.ssh/authorized_keys + ssh-keyscan localhost >> ~/.ssh/known_hosts else luadir="/Programs/Lua/Current" + if [ ! -e "$luadir" ] + then + luadir="/usr/local" + fi fi if [ `uname -m` = i686 ] @@ -171,19 +182,21 @@ verrev_luasocket=${version_luasocket}-1 srcdir_luasocket=luasocket-3.0-rc1 version_cprint=0.1 -verrev_cprint=0.1-1 +verrev_cprint=0.1-2 -version_luacov=0.5 -verrev_luacov=0.5-1 +version_luacov=0.8 +verrev_luacov=${version_luacov}-1 version_lxsh=0.8.6 version_validate_args=1.5.4 verrev_validate_args=1.5.4-1 verrev_lxsh=${version_lxsh}-2 +version_abelhas=1.0 +verrev_abelhas=${version_abelhas}-1 luasec=luasec cd .. -./configure --with-lua="$luadir" +./configure --with-lua="$luadir" --prefix="$testing_lrprefix" make clean make src/luarocks/site_config.lua make dev @@ -217,8 +230,7 @@ luarocks_admin_nocov="run_lua --nocov luarocks-admin" mkdir -p "$testing_server" ( cd "$testing_server" - luarocks_repo="http://luarocks.org/repositories/rocks" - luarocks_scm_repo="http://luarocks.org/repositories/rocks-scm" + luarocks_repo="http://rocks.moonscript.org" get() { [ -e `basename "$1"` ] || wget -c "$1"; } get "$luarocks_repo/luacov-${verrev_luacov}.src.rock" get "$luarocks_repo/luacov-${verrev_luacov}.rockspec" @@ -226,26 +238,32 @@ mkdir -p "$testing_server" get "$luarocks_repo/lualogging-1.3.0-1.src.rock" get "$luarocks_repo/luasocket-${verrev_luasocket}.src.rock" get "$luarocks_repo/luasocket-${verrev_luasocket}.rockspec" - get "$luarocks_repo/luafilesystem-1.6.2-1.src.rock" - get "$luarocks_repo/stdlib-35-1.src.rock" + get "$luarocks_repo/luafilesystem-1.6.3-1.src.rock" + get "$luarocks_repo/stdlib-41.0.0-1.src.rock" get "$luarocks_repo/luarepl-0.4-1.src.rock" get "$luarocks_repo/validate-args-1.5.4-1.rockspec" - get "$luarocks_scm_repo/luasec-scm-1.rockspec" + get "$luarocks_repo/luasec-0.5-2.rockspec" get "$luarocks_repo/luabitop-1.0.2-1.rockspec" get "$luarocks_repo/lpty-1.0.1-1.src.rock" get "$luarocks_repo/cprint-${verrev_cprint}.src.rock" get "$luarocks_repo/cprint-${verrev_cprint}.rockspec" get "$luarocks_repo/wsapi-1.6-1.src.rock" get "$luarocks_repo/lxsh-${verrev_lxsh}.src.rock" - get "$luarocks_repo/abelhas-1.0-1.rockspec" - get "$luarocks_repo/lzlib-0.4.work3-1.src.rock" + get "$luarocks_repo/lxsh-${verrev_lxsh}.rockspec" + get "$luarocks_repo/abelhas-${verrev_abelhas}.rockspec" + get "$luarocks_repo/lzlib-0.4.1.53-1.src.rock" get "$luarocks_repo/lpeg-0.12-1.src.rock" - get "$luarocks_repo/luaposix-31-1.src.rock" + get "$luarocks_repo/luaposix-33.2.1-1.src.rock" get "$luarocks_repo/md5-1.2-1.src.rock" - get "$luarocks_repo/lrandom-20120430.51-1.src.rock" - get "$luarocks_repo/lrandom-20120430.52-1.src.rock" - get "$luarocks_repo/lrandom-20120430.51-1.rockspec" - get "$luarocks_repo/lrandom-20120430.52-1.rockspec" + get "$luarocks_repo/lmathx-20120430.51-1.src.rock" + get "$luarocks_repo/lmathx-20120430.51-1.rockspec" + get "$luarocks_repo/lmathx-20120430.52-1.src.rock" + get "$luarocks_repo/lmathx-20120430.52-1.rockspec" + get "$luarocks_repo/lmathx-20150505-1.src.rock" + get "$luarocks_repo/lmathx-20150505-1.rockspec" + get "$luarocks_repo/lua-path-0.2.3-1.src.rock" + get "$luarocks_repo/lua-cjson-2.1.0-1.src.rock" + get "$luarocks_repo/luacov-coveralls-0.1.1-1.src.rock" ) $luarocks_admin_nocov make_manifest "$testing_server" @@ -270,6 +288,8 @@ build_environment() { $luarocks_nocov pack --tree="$testing_sys_tree" $package; mv $package-*.rock "$testing_cache" } done + export LUA_PATH= + export LUA_CPATH= eval `$luarocks_noecho_nocov path --bin` cp -a "$testing_tree" "$testing_tree_copy" cp -a "$testing_sys_tree" "$testing_sys_tree_copy" @@ -316,12 +336,19 @@ need_luasocket() { need luasocket $verrev_luasocket; } test_version() { $luarocks --version; } -fail_arg_server() { $luarocks --server; } -fail_arg_only_server() { $luarocks --only-server; } fail_unknown_command() { $luarocks unknown_command; } +fail_arg_boolean_parameter() { $luarocks --porcelain=invalid; } +fail_arg_boolean_unknown() { $luarocks --invalid-flag; } +fail_arg_string_no_parameter() { $luarocks --server; } +fail_arg_string_followed_by_flag() { $luarocks --server --porcelain; } +fail_arg_string_unknown() { $luarocks --invalid-flag=abc; } + test_empty_list() { $luarocks list; } +fail_sysconfig_err() { local err=0; local scdir="$testing_lrprefix/etc/luarocks/"; mkdir -p "$scdir"; local sysconfig="$scdir/config.lua"; echo "aoeui" > "$sysconfig"; echo $sysconfig; $luarocks list; err=$?; rm "$sysconfig"; return "$err"; } +fail_sysconfig_default_err() { local err=0; local scdir="$testing_lrprefix/etc/luarocks/"; mkdir -p "$scdir"; local sysconfig="$scdir/config-$luashortversion.lua"; echo "aoeui" > "$sysconfig"; echo $sysconfig; $luarocks list; err=$?; rm "$sysconfig"; return "$err"; } + fail_build_noarg() { $luarocks build; } fail_download_noarg() { $luarocks download; } fail_install_noarg() { $luarocks install; } @@ -329,6 +356,7 @@ fail_lint_noarg() { $luarocks lint; } fail_search_noarg() { $luarocks search; } fail_show_noarg() { $luarocks show; } fail_unpack_noarg() { $luarocks unpack; } +fail_upload_noarg() { $luarocks upload; } fail_remove_noarg() { $luarocks remove; } fail_doc_noarg() { $luarocks doc; } fail_new_version_noarg() { $luarocks new_version; } @@ -341,8 +369,16 @@ fail_lint_invalid() { $luarocks lint invalid; } fail_show_invalid() { $luarocks show invalid; } fail_new_version_invalid() { $luarocks new_version invalid; } +test_list_invalidtree() { $luarocks --tree=/some/invalid/tree list; } + +fail_inexistent_dir() { mkdir idontexist; cd idontexist; rmdir ../idontexist; $luarocks; err=$?; cd ..; return $err; } + fail_make_norockspec() { $luarocks make; } +fail_build_permissions() { $luarocks build --tree=/usr lpeg; } +fail_build_permissions_parent() { $luarocks build --tree=/usr/invalid lpeg; } + +test_build_verbose() { $luarocks build --verbose lpeg; } fail_build_blank_arg() { $luarocks build --tree="" lpeg; } test_build_withpatch() { need_luasocket; $luarocks build luadoc; } test_build_diffversion() { $luarocks build luacov ${version_luacov}; } @@ -351,32 +387,47 @@ test_build_install_bin() { $luarocks build luarepl; } test_build_nohttps() { need_luasocket; $luarocks download --rockspec validate-args ${verrev_validate_args} && $luarocks build ./validate-args-${version_validate_args}-1.rockspec && rm ./validate-args-${version_validate_args}-1.rockspec; } test_build_https() { need_luasocket; $luarocks download --rockspec validate-args ${verrev_validate_args} && $luarocks install $luasec && $luarocks build ./validate-args-${verrev_validate_args}.rockspec && rm ./validate-args-${verrev_validate_args}.rockspec; } test_build_supported_platforms() { $luarocks build lpty; } +test_build_only_deps_rockspec() { $luarocks download --rockspec lxsh ${verrev_lxsh} && $luarocks build ./lxsh-${verrev_lxsh}.rockspec --only-deps && { $luarocks show lxsh; [ $? -ne 0 ]; }; } +test_build_only_deps_src_rock() { $luarocks download --source lxsh ${verrev_lxsh} && $luarocks build ./lxsh-${verrev_lxsh}.src.rock --only-deps && { $luarocks show lxsh; [ $? -ne 0 ]; }; } +test_build_only_deps() { $luarocks build luasec --only-deps && { $luarocks show luasec; [ $? -ne 0 ]; }; } +test_install_only_deps() { $luarocks install lxsh ${verrev_lxsh} --only-deps && { $luarocks show lxsh; [ $? -ne 0 ]; }; } fail_build_missing_external() { $luarocks build "$testing_dir/testfiles/missing_external-0.1-1.rockspec" INEXISTENT_INCDIR="/invalid/dir"; } +fail_build_invalidpatch() { need_luasocket; $luarocks build "$testing_dir/testfiles/invalid_patch-0.1-1.rockspec"; } -test_build_deps_partial_match() { $luarocks build lrandom; } +test_build_deps_partial_match() { $luarocks build lmathx; } test_build_show_downloads() { export LUAROCKS_CONFIG="$testing_dir/testing_config_show_downloads.lua" && $luarocks build alien; export LUAROCKS_CONFIG="$testing_dir/testing_config.lua"; } test_download_all() { $luarocks download --all validate-args && rm validate-args-*; } test_download_rockspecversion() { $luarocks download --rockspec validate-args ${verrev_validate_args} && rm validate-args-*; } test_help() { $luarocks help; } +fail_help_invalid() { $luarocks help invalid; } test_install_binaryrock() { $luarocks build --pack-binary-rock cprint && $luarocks install ./cprint-${verrev_cprint}.${platform}.rock && rm ./cprint-${verrev_cprint}.${platform}.rock; } test_install_with_bin() { $luarocks install wsapi; } fail_install_notazipfile() { $luarocks install "$testing_dir/testfiles/not_a_zipfile-1.0-1.src.rock"; } +fail_install_invalidpatch() { need_luasocket; $luarocks install "$testing_dir/testfiles/invalid_patch-0.1-1.rockspec"; } +fail_install_invalid_filename() { $luarocks install "invalid.rock"; } +fail_install_invalid_arch() { $luarocks install "foo-1.0-1.impossible-x86.rock"; } +test_install_reinstall() { $luarocks install "$testing_cache/luasocket-$verrev_luasocket.$platform.rock"; $luarocks install --deps-mode=none "$testing_cache/luasocket-$verrev_luasocket.$platform.rock"; } + +fail_local_root() { USER=root $luarocks install --local luasocket; } + +test_site_config() { mv ../src/luarocks/site_config.lua ../src/luarocks/site_config.lua.tmp; $luarocks; mv ../src/luarocks/site_config.lua.tmp ../src/luarocks/site_config.lua; } test_lint_ok() { $luarocks download --rockspec validate-args ${verrev_validate_args} && $luarocks lint ./validate-args-${verrev_validate_args}.rockspec && rm ./validate-args-${verrev_validate_args}.rockspec; } fail_lint_type_mismatch_string() { $luarocks lint "$testing_dir/testfiles/type_mismatch_string-1.0-1.rockspec"; } fail_lint_type_mismatch_version() { $luarocks lint "$testing_dir/testfiles/type_mismatch_version-1.0-1.rockspec"; } fail_lint_type_mismatch_table() { $luarocks lint "$testing_dir/testfiles/type_mismatch_table-1.0-1.rockspec"; } +fail_lint_no_build_table() { $luarocks lint "$testing_dir/testfiles/no_build_table-0.1-1.rockspec"; } test_list() { $luarocks list; } test_list_porcelain() { $luarocks list --porcelain; } -test_make_with_rockspec() { rm -rf ./luasocket-${verrev_luasocket} && $luarocks download --src luasocket && $luarocks unpack ./luasocket-${verrev_luasocket}.src.rock && cd luasocket-${verrev_luasocket}/${srcdir_luasocket} && $luarocks make luasocket-${verrev_luasocket}.rockspec && cd ../.. && rm -rf ./luasocket-${verrev_luasocket}; } -test_make_default_rockspec() { rm -rf ./lxsh-${verrev_lxsh} && $luarocks download --src lxsh ${verrev_lxsh} && $luarocks unpack ./lxsh-${verrev_lxsh}.src.rock && cd lxsh-${verrev_lxsh}/lxsh-${version_lxsh}-1 && $luarocks make && cd ../.. && rm -rf ./lxsh-${verrev_lxsh}; } -test_make_pack_binary_rock() { rm -rf ./lxsh-${verrev_lxsh} && $luarocks download --src lxsh ${verrev_lxsh} && $luarocks unpack ./lxsh-${verrev_lxsh}.src.rock && cd lxsh-${verrev_lxsh}/lxsh-${version_lxsh}-1 && $luarocks make --deps-mode=none --pack-binary-rock && [ -e ./lxsh-${verrev_lxsh}.all.rock ] && cd ../.. && rm -rf ./lxsh-${verrev_lxsh}; } -fail_make_which_rockspec() { rm -rf ./luasocket-${verrev_luasocket} && $luarocks download --src luasocket && $luarocks unpack ./luasocket-${verrev_luasocket}.src.rock && cd luasocket-${verrev_luasocket}/${srcdir_luasocket} && $luarocks make && cd ../.. && rm -rf ./luasocket-${verrev_luasocket}; } +test_make_with_rockspec() { rm -rf ./luasocket-${verrev_luasocket} && $luarocks download --source luasocket && $luarocks unpack ./luasocket-${verrev_luasocket}.src.rock && cd luasocket-${verrev_luasocket}/${srcdir_luasocket} && $luarocks make luasocket-${verrev_luasocket}.rockspec && cd ../.. && rm -rf ./luasocket-${verrev_luasocket}; } +test_make_default_rockspec() { rm -rf ./lxsh-${verrev_lxsh} && $luarocks download --source lxsh ${verrev_lxsh} && $luarocks unpack ./lxsh-${verrev_lxsh}.src.rock && cd lxsh-${verrev_lxsh}/lxsh-${version_lxsh}-1 && $luarocks make && cd ../.. && rm -rf ./lxsh-${verrev_lxsh}; } +test_make_pack_binary_rock() { rm -rf ./lxsh-${verrev_lxsh} && $luarocks download --source lxsh ${verrev_lxsh} && $luarocks unpack ./lxsh-${verrev_lxsh}.src.rock && cd lxsh-${verrev_lxsh}/lxsh-${version_lxsh}-1 && $luarocks make --deps-mode=none --pack-binary-rock && [ -e ./lxsh-${verrev_lxsh}.all.rock ] && cd ../.. && rm -rf ./lxsh-${verrev_lxsh}; } +fail_make_which_rockspec() { rm -rf ./luasocket-${verrev_luasocket} && $luarocks download --source luasocket && $luarocks unpack ./luasocket-${verrev_luasocket}.src.rock && cd luasocket-${verrev_luasocket}/${srcdir_luasocket} && $luarocks make && cd ../.. && rm -rf ./luasocket-${verrev_luasocket}; } test_new_version() { $luarocks download --rockspec luacov ${version_luacov} && $luarocks new_version ./luacov-${version_luacov}-1.rockspec 0.2 && rm ./luacov-0.*; } test_new_version_url() { $luarocks download --rockspec abelhas 1.0 && $luarocks new_version ./abelhas-1.0-1.rockspec 1.1 https://github.com/downloads/ittner/abelhas/abelhas-1.1.tar.gz && rm ./abelhas-*; } @@ -392,9 +443,10 @@ test_path_lr_bin() { $luarocks path --lr-bin; } fail_purge_missing_tree() { $luarocks purge --tree="$testing_tree"; } test_purge() { $luarocks purge --tree="$testing_sys_tree"; } -test_remove() { $luarocks build luacov ${version_luacov} && $luarocks remove luacov ${version_luacov}; } +test_remove() { $luarocks build abelhas ${version_abelhas} && $luarocks remove abelhas ${version_abelhas}; } test_remove_force() { need_luasocket; $luarocks build lualogging && $luarocks remove --force luasocket; } fail_remove_deps() { need_luasocket; $luarocks build lualogging && $luarocks remove luasocket; } +fail_remove_missing() { $luarocks remove missing_rock; } fail_remove_invalid_name() { $luarocks remove invalid.rock; } test_search_found() { $luarocks search zlib; } @@ -402,24 +454,30 @@ test_search_missing() { $luarocks search missing_rock; } test_show() { $luarocks show luacov; } test_show_modules() { $luarocks show --modules luacov; } +test_show_home() { $luarocks show --home luacov; } test_show_depends() { need_luasocket; $luarocks install $luasec && $luarocks show luasec; } test_show_oldversion() { $luarocks install luacov ${version_luacov} && $luarocks show luacov ${version_luacov}; } test_unpack_download() { rm -rf ./cprint-${verrev_cprint} && $luarocks unpack cprint && rm -rf ./cprint-${verrev_cprint}; } -test_unpack_src() { rm -rf ./cprint-${verrev_cprint} && $luarocks download --src cprint && $luarocks unpack ./cprint-${verrev_cprint}.src.rock && rm -rf ./cprint-${verrev_cprint}; } +test_unpack_src() { rm -rf ./cprint-${verrev_cprint} && $luarocks download --source cprint && $luarocks unpack ./cprint-${verrev_cprint}.src.rock && rm -rf ./cprint-${verrev_cprint}; } test_unpack_rockspec() { rm -rf ./cprint-${verrev_cprint} && $luarocks download --rockspec cprint && $luarocks unpack ./cprint-${verrev_cprint}.rockspec && rm -rf ./cprint-${verrev_cprint}; } test_unpack_binary() { rm -rf ./cprint-${verrev_cprint} && $luarocks build cprint && $luarocks pack cprint && $luarocks unpack ./cprint-${verrev_cprint}.${platform}.rock && rm -rf ./cprint-${verrev_cprint}; } +fail_unpack_invalidpatch() { need_luasocket; $luarocks unpack "$testing_dir/testfiles/invalid_patch-0.1-1.rockspec"; } +fail_unpack_invalidrockspec() { need_luasocket; $luarocks unpack "invalid.rockspec"; } + +fail_upload_invalidrockspec() { $luarocks upload "invalid.rockspec"; } +fail_upload_invalidkey() { $luarocks upload --api-key="invalid" "invalid.rockspec"; } test_admin_help() { $luarocks_admin help; } test_admin_make_manifest() { $luarocks_admin make_manifest; } -test_admin_add_rsync() { if [ "$travis" ]; then return; fi; $luarocks_admin --server=testing add "$testing_server/luasocket-${verrev_luasocket}.src.rock"; } -test_admin_add_sftp() { if [ "$travis" ]; then return; fi; export LUAROCKS_CONFIG="$testing_dir/testing_config_sftp.lua" && $luarocks_admin --server=testing add ./luasocket-${verrev_luasocket}.src.rock; export LUAROCKS_CONFIG="$testing_dir/testing_config.lua"; } +test_admin_add_rsync() { $luarocks_admin --server=testing add "$testing_server/luasocket-${verrev_luasocket}.src.rock"; } +test_admin_add_sftp() { export LUAROCKS_CONFIG="$testing_dir/testing_config_sftp.lua" && $luarocks_admin --server=testing add ./luasocket-${verrev_luasocket}.src.rock; export LUAROCKS_CONFIG="$testing_dir/testing_config.lua"; } fail_admin_add_missing() { $luarocks_admin --server=testing add; } fail_admin_invalidserver() { $luarocks_admin --server=invalid add "$testing_server/luasocket-${verrev_luasocket}.src.rock"; } -fail_admin_invalidrock() { if [ "$travis" ]; then return 1; fi; $luarocks_admin --server=testing add invalid; } -test_admin_refresh_cache() { if [ "$travis" ]; then return; fi; $luarocks_admin --server=testing refresh_cache; } -test_admin_remove() { if [ "$travis" ]; then return; fi; $luarocks_admin --server=testing remove luasocket-${verrev_luasocket}.src.rock; } +fail_admin_invalidrock() { $luarocks_admin --server=testing add invalid; } +test_admin_refresh_cache() { $luarocks_admin --server=testing refresh_cache; } +test_admin_remove() { $luarocks_admin --server=testing remove luasocket-${verrev_luasocket}.src.rock; } fail_admin_remove_missing() { $luarocks_admin --server=testing remove; } fail_deps_mode_invalid_arg() { $luarocks remove luacov --deps-mode; } @@ -429,17 +487,43 @@ test_deps_mode_order_sys() { $luarocks build --tree="$testing_tree" lpeg && $lua test_deps_mode_all_sys() { $luarocks build --tree="$testing_tree" lpeg && $luarocks build --deps-mode=all --tree="$testing_sys_tree" lxsh && [ `$luarocks_noecho list --tree="$testing_sys_tree" --porcelain lpeg | wc -l` = 0 ]; } test_deps_mode_none() { $luarocks build --tree="$testing_tree" --deps-mode=none lxsh; [ `$luarocks_noecho list --tree="$testing_tree" --porcelain lpeg | wc -l` = 0 ]; } test_deps_mode_nodeps_alias() { $luarocks build --tree="$testing_tree" --nodeps lxsh; [ `$luarocks_noecho list --tree="$testing_tree" --porcelain lpeg | wc -l` = 0 ]; } -test_deps_mode_make_order() { $luarocks build --tree="$testing_sys_tree" lpeg && rm -rf ./lxsh-${verrev_lxsh} && $luarocks download --src lxsh ${verrev_lxsh} && $luarocks unpack ./lxsh-${verrev_lxsh}.src.rock && cd lxsh-${verrev_lxsh}/lxsh-${version_lxsh}-1 && $luarocks make --tree="$testing_tree" --deps-mode=order && cd ../.. && [ `$luarocks_noecho list --tree="$testing_tree" --porcelain lpeg | wc -l` = 0 ] && rm -rf ./lxsh-${verrev_lxsh}; } -test_deps_mode_make_order_sys() { $luarocks build --tree="$testing_tree" lpeg && rm -rf ./lxsh-${verrev_lxsh} && $luarocks download --src lxsh ${verrev_lxsh} && $luarocks unpack ./lxsh-${verrev_lxsh}.src.rock && cd lxsh-${verrev_lxsh}/lxsh-${version_lxsh}-1 && $luarocks make --tree="$testing_sys_tree" --deps-mode=order && cd ../.. && [ `$luarocks_noecho list --tree="$testing_tree" --porcelain lpeg | wc -l` = 1 ] && rm -rf ./lxsh-${verrev_lxsh}; } +test_deps_mode_make_order() { $luarocks build --tree="$testing_sys_tree" lpeg && rm -rf ./lxsh-${verrev_lxsh} && $luarocks download --source lxsh ${verrev_lxsh} && $luarocks unpack ./lxsh-${verrev_lxsh}.src.rock && cd lxsh-${verrev_lxsh}/lxsh-${version_lxsh}-1 && $luarocks make --tree="$testing_tree" --deps-mode=order && cd ../.. && [ `$luarocks_noecho list --tree="$testing_tree" --porcelain lpeg | wc -l` = 0 ] && rm -rf ./lxsh-${verrev_lxsh}; } +test_deps_mode_make_order_sys() { $luarocks build --tree="$testing_tree" lpeg && rm -rf ./lxsh-${verrev_lxsh} && $luarocks download --source lxsh ${verrev_lxsh} && $luarocks unpack ./lxsh-${verrev_lxsh}.src.rock && cd lxsh-${verrev_lxsh}/lxsh-${version_lxsh}-1 && $luarocks make --tree="$testing_sys_tree" --deps-mode=order && cd ../.. && [ `$luarocks_noecho list --tree="$testing_tree" --porcelain lpeg | wc -l` = 1 ] && rm -rf ./lxsh-${verrev_lxsh}; } test_write_rockspec() { $luarocks write_rockspec git://github.com/keplerproject/luarocks; } test_write_rockspec_lib() { $luarocks write_rockspec git://github.com/mbalmer/luafcgi --lib=fcgi --license="3-clause BSD" --lua-version=5.1,5.2; } +test_write_rockspec_format() { $luarocks write_rockspec git://github.com/keplerproject/luarocks --rockspec-format=1.1 --lua-version=5.1,5.2; } test_write_rockspec_fullargs() { $luarocks write_rockspec git://github.com/keplerproject/luarocks --lua-version=5.1,5.2 --license="MIT/X11" --homepage="http://www.luarocks.org" --summary="A package manager for Lua modules"; } fail_write_rockspec_args() { $luarocks write_rockspec invalid; } fail_write_rockspec_args_url() { $luarocks write_rockspec http://example.com/invalid.zip; } test_write_rockspec_http() { $luarocks write_rockspec http://luarocks.org/releases/luarocks-2.1.0.tar.gz --lua-version=5.1; } test_write_rockspec_basedir() { $luarocks write_rockspec https://github.com/downloads/Olivine-Labs/luassert/luassert-1.2.tar.gz --lua-version=5.1; } +fail_config_noflags() { $luarocks config; } +test_config_lua_incdir() { $luarocks config --lua-incdir; } +test_config_lua_libdir() { $luarocks config --lua-libdir; } +test_config_lua_ver() { $luarocks config --lua-ver; } +fail_config_system_config() { rm -f "$testing_lrprefix/etc/luarocks/config.lua"; $luarocks config --system-config; } +test_config_system_config() { mkdir -p "$testing_lrprefix/etc/luarocks"; touch "$testing_lrprefix/etc/luarocks/config.lua"; $luarocks config --system-config; err=$?; rm -f "$testing_lrprefix/etc/luarocks/config.lua"; return $err; } +fail_config_system_config_invalid() { mkdir -p "$testing_lrprefix/etc/luarocks"; echo "if if if" > "$testing_lrprefix/etc/luarocks/config.lua"; $luarocks config --system-config; err=$?; rm -f "$testing_lrprefix/etc/luarocks/config.lua"; return $err; } +test_config_user_config() { $luarocks config --user-config; } +fail_config_user_config() { LUAROCKS_CONFIG="/missing_file.lua" $luarocks config --user-config; } +test_config_rock_trees() { $luarocks config --rock-trees; } +test_config_help() { $luarocks help config; } + +# Tests for https://github.com/keplerproject/luarocks/issues/375 +test_fetch_base_dir() { $lua <<EOF + local fetch = require "luarocks.fetch" + + assert("v0.3" == fetch.url_to_base_dir("https://github.com/hishamhm/lua-compat-5.2/archive/v0.3.zip")) + assert("lua-compat-5.2" == fetch.url_to_base_dir("https://github.com/hishamhm/lua-compat-5.2.zip")) + assert("lua-compat-5.2" == fetch.url_to_base_dir("https://github.com/hishamhm/lua-compat-5.2.tar.gz")) + assert("lua-compat-5.2" == fetch.url_to_base_dir("https://github.com/hishamhm/lua-compat-5.2.tar.bz2")) + assert("parser.moon" == fetch.url_to_base_dir("git://github.com/Cirru/parser.moon")) + assert("v0.3" == fetch.url_to_base_dir("https://github.com/hishamhm/lua-compat-5.2/archive/v0.3")) +EOF +} + test_doc() { $luarocks install luarepl; $luarocks doc luarepl; } # Driver ######################################### @@ -452,8 +536,13 @@ run_tests() { echo "-------------------------------------------" reset_environment if $test - then echo "OK: Expected success." - else echo "FAIL: Unexpected failure."; exit 1 + then + echo "OK: Expected success." + else + if [ $? = 99 ] + then echo "FAIL: Unexpected crash!"; exit 99 + fi + echo "FAIL: Unexpected failure."; exit 1 fi done grep "^fail_$1.*(" < $testing_dir/testing.sh | cut -d'(' -f1 | while read test @@ -464,7 +553,11 @@ run_tests() { reset_environment if $test then echo "FAIL: Unexpected success."; exit 1 - else echo "OK: Expected failure." + else + if [ $? = 99 ] + then echo "FAIL: Unexpected crash!"; exit 99 + fi + echo "OK: Expected failure." fi done } @@ -481,7 +574,11 @@ run_with_full_environment() { echo "===========================================" echo "Running with full environment" echo "===========================================" - build_environment luacov luafilesystem luasocket luabitop luaposix md5 lzlib + + local bitop= + [ "$luaversion" = "5.1.5" ] && bitop=luabitop + + build_environment luacov luafilesystem luasocket $bitop luaposix md5 lzlib run_tests $1 } @@ -493,12 +590,16 @@ run_all_tests() { run_all_tests $1 #run_with_minimal_environment $1 -$testing_sys_tree/bin/luacov -c $testing_dir/luacov.config src/luarocks src/bin - if [ "$travis" ] then + if [ "$TRAVIS" ] + then + build_environment luacov luafilesystem luacov-coveralls + ( cd $testing_dir; $testing_sys_tree/bin/luacov-coveralls || echo "ok" ) + fi + $testing_sys_tree/bin/luacov -c $testing_dir/luacov.config src/luarocks src/bin grep "Summary" -B1 -A1000 $testing_dir/luacov.report.out else + $testing_sys_tree/bin/luacov -c $testing_dir/luacov.config src/luarocks src/bin cat "$testing_dir/luacov.report.out" fi - diff --git a/win32/pe-parser.lua b/win32/pe-parser.lua index 30bb839..9cd36ff 100644 --- a/win32/pe-parser.lua +++ b/win32/pe-parser.lua @@ -1,7 +1,11 @@ --------------------------------------------------------------------------------------- -- Lua module to parse a Portable Executable (.exe , .dll, etc.) file and extract metadata. -- --- Version 0.1, [copyright (c) 2013 - Thijs Schreijer](http://www.thijsschreijer.nl) +-- NOTE: numerical information is extracted as strings (hex) to prevent numerical overflows in +-- case of 64 bit fields (bit/flag fields). Pointer arithmetic is still done numerically, so for +-- very large files this could lead to undefined results. Use with care! +-- +-- Version 0.4, [copyright (c) 2013-2015 Thijs Schreijer](http://www.thijsschreijer.nl) -- @name pe-parser -- @class module @@ -238,7 +242,7 @@ local function readstring(f) end --- Parses a file and extracts the information. --- All numbers are delivered as "string" types containing hex values, see `toHex` and `toDec` conversion functions. +-- All numbers are delivered as "string" types containing hex values (to prevent numerical overflows in case of 64bit sizes or bit-fields), see `toHex` and `toDec` conversion functions. -- @return table with data, or nil + error -- @usage local pe = require("pe-parser") -- local obj = pe.parse("c:\lua\lua.exe") @@ -524,9 +528,12 @@ function M.msvcrt(infile) for i, dll in ipairs(obj.DataDirectory.ImportTable) do dll = dll.Name:upper() - local result = dll:match('(MSVCR%d*)%.DLL') + local result = dll:match('(MSVCR%d*D?)%.DLL') + if not result then + result = dll:match('(MSVCRTD?)%.DLL') + end if not result then - result = dll:match('(MSVCRT)%.DLL') + result = dll:match('(VCRUNTIME%d*D?)%.DLL') end -- success, found it return name + binary where it was found if result then return result, infile end |