diff options
78 files changed, 3354 insertions, 1064 deletions
diff --git a/.appveyor/build.bat b/.appveyor/build.bat new file mode 100644 index 00000000..a4ff6378 --- /dev/null +++ b/.appveyor/build.bat | |||
@@ -0,0 +1,111 @@ | |||
1 | @echo off | ||
2 | Setlocal EnableDelayedExpansion EnableExtensions | ||
3 | |||
4 | cd %APPVEYOR_BUILD_FOLDER% | ||
5 | |||
6 | :: ========================================================= | ||
7 | :: Make sure some environment variables are set | ||
8 | if not defined LUA_VER call :die LUA_VER is not defined | ||
9 | if not defined LUA call :die LUA is not defined | ||
10 | if not defined LUA_SHORTV call :die LUA_SHORTV is not defined | ||
11 | if not defined LUA_DIR call :die LUA_DIR is not defined | ||
12 | |||
13 | :: ========================================================= | ||
14 | :: Set some defaults. Infer some variables. | ||
15 | :: | ||
16 | if not defined LUAROCKS_VER set LUAROCKS_VER=2.2.1 | ||
17 | |||
18 | set LUAROCKS_SHORTV=%LUAROCKS_VER:~0,3% | ||
19 | |||
20 | if not defined LR_EXTERNAL set LR_EXTERNAL=c:\external | ||
21 | if not defined LR_ROOT set LR_ROOT=%LUA_DIR%\LuaRocks | ||
22 | if not defined LR_SYSTREE set LR_SYSTREE=%LR_ROOT%\systree | ||
23 | |||
24 | :: | ||
25 | :: ========================================================= | ||
26 | |||
27 | |||
28 | if not exist %LUA_DIR%\bin\%LUA%.exe call :die "Missing Lua interpreter at %LUA_DIR%\bin\%LUA%.exe" | ||
29 | |||
30 | |||
31 | |||
32 | :: ========================================================= | ||
33 | :: LuaRocks | ||
34 | :: ========================================================= | ||
35 | |||
36 | cd %APPVEYOR_BUILD_FOLDER% | ||
37 | call install.bat /LUA %LUA_DIR% /Q /LV %LUA_SHORTV% /P "%LR_ROOT%" /TREE "%LR_SYSTREE%" | ||
38 | |||
39 | if not exist "%LR_ROOT%" call :die "LuaRocks not found at %LR_ROOT%" | ||
40 | |||
41 | set PATH=%LR_ROOT%;%LR_SYSTREE%\bin;%PATH% | ||
42 | |||
43 | :: Lua will use just the system rocks | ||
44 | set LUA_PATH=%LR_ROOT%\lua\?.lua;%LR_ROOT%\lua\?\init.lua | ||
45 | set LUA_PATH=%LUA_PATH%;%LR_SYSTREE%\share\lua\%LUA_SHORTV%\?.lua | ||
46 | set LUA_PATH=%LUA_PATH%;%LR_SYSTREE%\share\lua\%LUA_SHORTV%\?\init.lua | ||
47 | set LUA_CPATH=%LR_SYSTREE%\lib\lua\%LUA_SHORTV%\?.dll | ||
48 | |||
49 | call luarocks --version || call :die "Error with LuaRocks installation" | ||
50 | call luarocks list | ||
51 | |||
52 | |||
53 | if not exist "%LR_EXTERNAL%" ( | ||
54 | mkdir "%LR_EXTERNAL%" | ||
55 | mkdir "%LR_EXTERNAL%\lib" | ||
56 | mkdir "%LR_EXTERNAL%\include" | ||
57 | ) | ||
58 | |||
59 | set PATH=%LR_EXTERNAL%;%PATH% | ||
60 | |||
61 | :: Exports the following variables: | ||
62 | :: (beware of whitespace between & and ^ below) | ||
63 | endlocal & set PATH=%PATH%&^ | ||
64 | set LR_SYSTREE=%LR_SYSTREE%&^ | ||
65 | set LUA_PATH=%LUA_PATH%&^ | ||
66 | set LUA_CPATH=%LUA_CPATH%&^ | ||
67 | set LR_EXTERNAL=%LR_EXTERNAL% | ||
68 | |||
69 | echo. | ||
70 | echo ====================================================== | ||
71 | echo Installation of LuaRocks %LUAROCKS_VER% done. | ||
72 | echo . | ||
73 | echo LUA_PATH - %LUA_PATH% | ||
74 | echo LUA_CPATH - %LUA_CPATH% | ||
75 | echo. | ||
76 | echo LR_EXTERNAL - %LR_EXTERNAL% | ||
77 | echo ====================================================== | ||
78 | echo. | ||
79 | |||
80 | goto :eof | ||
81 | |||
82 | |||
83 | |||
84 | |||
85 | |||
86 | |||
87 | |||
88 | |||
89 | |||
90 | |||
91 | |||
92 | |||
93 | |||
94 | |||
95 | |||
96 | |||
97 | |||
98 | |||
99 | :: This blank space is intentional. If you see errors like "The system cannot find the batch label specified 'foo'" | ||
100 | :: then try adding or removing blank lines lines above. | ||
101 | :: Yes, really. | ||
102 | :: http://stackoverflow.com/questions/232651/why-the-system-cannot-find-the-batch-label-specified-is-thrown-even-if-label-e | ||
103 | |||
104 | :: helper functions: | ||
105 | |||
106 | :: for bailing out when an error occurred | ||
107 | :die %1 | ||
108 | echo %1 | ||
109 | exit /B 1 | ||
110 | goto :eof | ||
111 | |||
diff --git a/.appveyor/install.bat b/.appveyor/install.bat new file mode 100644 index 00000000..a2aefdd2 --- /dev/null +++ b/.appveyor/install.bat | |||
@@ -0,0 +1,154 @@ | |||
1 | @echo off | ||
2 | |||
3 | cd %APPVEYOR_BUILD_FOLDER% | ||
4 | |||
5 | :: ========================================================= | ||
6 | :: Set some defaults. Infer some variables. | ||
7 | :: | ||
8 | :: These are set globally | ||
9 | if "%LUA_VER%" NEQ "" ( | ||
10 | set LUA=lua | ||
11 | set LUA_SHORTV=%LUA_VER:~0,3% | ||
12 | ) else ( | ||
13 | set LUA=luajit | ||
14 | set LJ_SHORTV=%LJ_VER:~0,3% | ||
15 | set LUA_SHORTV=5.1 | ||
16 | ) | ||
17 | |||
18 | :: unless we specify a platform on appveyor.yaml, we won't get this variable | ||
19 | if not defined platform set platform=x86 | ||
20 | |||
21 | :: defines LUA_DIR so Cmake can find this Lua install | ||
22 | if "%LUA%"=="luajit" ( | ||
23 | set LUA_DIR=c:\lua\%platform%\lj%LJ_SHORTV% | ||
24 | ) else ( | ||
25 | set LUA_DIR=c:\lua\%platform%\%LUA_VER% | ||
26 | ) | ||
27 | |||
28 | :: Now we declare a scope | ||
29 | Setlocal EnableDelayedExpansion EnableExtensions | ||
30 | |||
31 | if not defined LUA_URL set LUA_URL=http://www.lua.org/ftp | ||
32 | if not defined LUAJIT_GIT_REPO set LUAJIT_GIT_REPO=http://luajit.org/git/luajit-2.0.git | ||
33 | if not defined LUAJIT_URL set LUAJIT_URL=http://luajit.org/download | ||
34 | |||
35 | if not defined SEVENZIP set SEVENZIP=7z | ||
36 | :: | ||
37 | :: ========================================================= | ||
38 | |||
39 | :: first create some necessary directories: | ||
40 | mkdir downloads 2>NUL | ||
41 | |||
42 | :: Download and compile Lua (or LuaJIT) | ||
43 | if "%LUA%"=="luajit" ( | ||
44 | if not exist %LUA_DIR% ( | ||
45 | if "%LJ_SHORTV%"=="2.1" ( | ||
46 | :: Clone repository and checkout 2.1 branch | ||
47 | set lj_source_folder=%APPVEYOR_BUILD_FOLDER%\downloads\luajit-%LJ_VER% | ||
48 | if not exist !lj_source_folder! ( | ||
49 | echo Cloning git repo %LUAJIT_GIT_REPO% !lj_source_folder! | ||
50 | git clone %LUAJIT_GIT_REPO% !lj_source_folder! || call :die "Failed to clone repository" | ||
51 | ) | ||
52 | cd !lj_source_folder!\src | ||
53 | git checkout v2.1 || call :die | ||
54 | ) else ( | ||
55 | set lj_source_folder=%APPVEYOR_BUILD_FOLDER%\downloads\luajit-%LJ_VER% | ||
56 | if not exist !lj_source_folder! ( | ||
57 | echo Downloading... %LUAJIT_URL%/LuaJIT-%LJ_VER%.tar.gz | ||
58 | 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 | ||
59 | ) | ||
60 | cd !lj_source_folder!\src | ||
61 | ) | ||
62 | :: Compiles LuaJIT | ||
63 | call msvcbuild.bat | ||
64 | |||
65 | mkdir %LUA_DIR% 2> NUL | ||
66 | for %%a in (bin include lib) do ( mkdir "%LUA_DIR%\%%a" ) | ||
67 | |||
68 | for %%a in (luajit.exe lua51.dll) do ( move "!lj_source_folder!\src\%%a" "%LUA_DIR%\bin" ) | ||
69 | |||
70 | move "!lj_source_folder!\src\lua51.lib" "%LUA_DIR%\lib" | ||
71 | for %%a in (lauxlib.h lua.h lua.hpp luaconf.h lualib.h luajit.h) do ( | ||
72 | copy "!lj_source_folder!\src\%%a" "%LUA_DIR%\include" | ||
73 | ) | ||
74 | |||
75 | ) else ( | ||
76 | echo LuaJIT %LJ_VER% already installed at %LUA_DIR% | ||
77 | ) | ||
78 | ) else ( | ||
79 | if not exist %LUA_DIR% ( | ||
80 | :: Download and compile Lua | ||
81 | if not exist downloads\lua-%LUA_VER% ( | ||
82 | 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 | ||
83 | ) | ||
84 | |||
85 | mkdir downloads\lua-%LUA_VER%\etc 2> NUL | ||
86 | if not exist downloads\lua-%LUA_VER%\etc\winmake.bat ( | ||
87 | 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 | ||
88 | ) | ||
89 | |||
90 | cd downloads\lua-%LUA_VER% | ||
91 | call etc\winmake | ||
92 | call etc\winmake install %LUA_DIR% | ||
93 | ) else ( | ||
94 | echo Lua %LUA_VER% already installed at %LUA_DIR% | ||
95 | ) | ||
96 | ) | ||
97 | |||
98 | if not exist %LUA_DIR%\bin\%LUA%.exe call :die "Missing Lua interpreter at %LUA_DIR%\bin\%LUA%.exe" | ||
99 | |||
100 | set PATH=%LUA_DIR%\bin;%PATH% | ||
101 | call %LUA% -v | ||
102 | |||
103 | |||
104 | |||
105 | :: Exports the following variables: | ||
106 | endlocal & set PATH=%PATH% | ||
107 | |||
108 | echo. | ||
109 | echo ====================================================== | ||
110 | if "%LUA%"=="luajit" ( | ||
111 | echo Installation of LuaJIT %LJ_VER% done. | ||
112 | ) else ( | ||
113 | echo Installation of Lua %LUA_VER% done. | ||
114 | ) | ||
115 | echo Platform - %platform% | ||
116 | echo LUA - %LUA% | ||
117 | echo LUA_SHORTV - %LUA_SHORTV% | ||
118 | echo LJ_SHORTV - %LJ_SHORTV% | ||
119 | echo. | ||
120 | echo ====================================================== | ||
121 | echo. | ||
122 | |||
123 | goto :eof | ||
124 | |||
125 | |||
126 | |||
127 | |||
128 | |||
129 | |||
130 | |||
131 | |||
132 | |||
133 | |||
134 | |||
135 | |||
136 | |||
137 | |||
138 | |||
139 | |||
140 | |||
141 | |||
142 | :: This blank space is intentional. If you see errors like "The system cannot find the batch label specified 'foo'" | ||
143 | :: then try adding or removing blank lines lines above. | ||
144 | :: Yes, really. | ||
145 | :: http://stackoverflow.com/questions/232651/why-the-system-cannot-find-the-batch-label-specified-is-thrown-even-if-label-e | ||
146 | |||
147 | :: helper functions: | ||
148 | |||
149 | :: for bailing out when an error occurred | ||
150 | :die %1 | ||
151 | echo %1 | ||
152 | exit /B 1 | ||
153 | goto :eof | ||
154 | |||
@@ -1,2 +1,4 @@ | |||
1 | /config.* | 1 | /config.* |
2 | /src/luarocks/site_config.lua | 2 | /src/luarocks/site_config.lua |
3 | /test/testing_* | ||
4 | /test/luacov.* | ||
diff --git a/.travis.yml b/.travis.yml index cf2b1e6b..69ec28f3 100644 --- a/.travis.yml +++ b/.travis.yml | |||
@@ -2,9 +2,12 @@ language: c | |||
2 | 2 | ||
3 | compiler: gcc | 3 | compiler: gcc |
4 | 4 | ||
5 | sudo: false | ||
6 | |||
5 | env: | 7 | env: |
6 | matrix: | 8 | matrix: |
7 | - LUA_VER=5.1.5 | 9 | - LUA_VER=5.1.5 |
8 | - LUA_VER=5.2.3 | 10 | - LUA_VER=5.2.4 |
11 | - LUA_VER=5.3.1 | ||
9 | 12 | ||
10 | script: cd test && ./testing.sh --travis --lua $LUA_VER | 13 | script: cd test && ./testing.sh --travis --lua $LUA_VER |
@@ -2,31 +2,13 @@ | |||
2 | include config.unix | 2 | include config.unix |
3 | 3 | ||
4 | .PHONY: all build dev build_bins luadoc check_makefile cleanup_bins clean \ | 4 | .PHONY: all build dev build_bins luadoc check_makefile cleanup_bins clean \ |
5 | install_bins install_luas install_site_config write_sysconfig \ | 5 | install_site_config write_sysconfig install bootstrap install_rock |
6 | install bootstrap install_rock | ||
7 | 6 | ||
8 | DESTDIR = | ||
9 | PREFIX ?= /usr/local | ||
10 | ROCKS_TREE ?= $(PREFIX) | 7 | ROCKS_TREE ?= $(PREFIX) |
11 | SYSCONFDIR ?= $(PREFIX)/etc/luarocks | 8 | SYSCONFDIR ?= $(PREFIX)/etc/luarocks |
12 | BINDIR ?= $(PREFIX)/bin | ||
13 | LUADIR ?= $(PREFIX)/share/lua/$(LUA_VERSION)/ | ||
14 | LUA_DIR ?= /usr/local | 9 | LUA_DIR ?= /usr/local |
15 | LUA_BINDIR ?= $(LUA_DIR)/bin | 10 | LUA_BINDIR ?= $(LUA_DIR)/bin |
16 | 11 | ||
17 | BIN_FILES = luarocks luarocks-admin | ||
18 | LUAROCKS_FILES = fs/unix/tools.lua fs/unix.lua fs/win32/tools.lua fs/win32.lua \ | ||
19 | fs/lua.lua persist.lua list.lua require.lua repos.lua dir.lua make_manifest.lua \ | ||
20 | command_line.lua install.lua build/command.lua build/cmake.lua build/make.lua \ | ||
21 | build/builtin.lua fetch/cvs.lua fetch/git.lua fetch/sscm.lua tools/patch.lua \ | ||
22 | fetch/svn.lua tools/zip.lua tools/tar.lua pack.lua type_check.lua make.lua \ | ||
23 | remove.lua fs.lua manif.lua add.lua deps.lua build.lua search.lua show.lua \ | ||
24 | manif_core.lua fetch.lua unpack.lua validate.lua cfg.lua download.lua \ | ||
25 | help.lua util.lua index.lua cache.lua refresh_cache.lua loader.lua \ | ||
26 | admin_remove.lua fetch/hg.lua fetch/git_file.lua new_version.lua lint.lua \ | ||
27 | purge.lua path.lua path_cmd.lua write_rockspec.lua doc.lua upload.lua \ | ||
28 | upload/api.lua upload/multipart.lua fetch/git_http.lua | ||
29 | |||
30 | CONFIG_FILE = $(SYSCONFDIR)/config-$(LUA_VERSION).lua | 12 | CONFIG_FILE = $(SYSCONFDIR)/config-$(LUA_VERSION).lua |
31 | 13 | ||
32 | SAFEPWD=`echo "$$PWD" | sed -e 's/\([][]\)\1/]]..'\''\1\1'\''..[[/g'` | 14 | SAFEPWD=`echo "$$PWD" | sed -e 's/\([][]\)\1/]]..'\''\1\1'\''..[[/g'` |
@@ -38,6 +20,9 @@ all: | |||
38 | @echo " to install LuaRocks in $(PREFIX) as a rock." | 20 | @echo " to install LuaRocks in $(PREFIX) as a rock." |
39 | @echo | 21 | @echo |
40 | 22 | ||
23 | include Makefile.setup.inc | ||
24 | include Makefile.install.inc | ||
25 | |||
41 | build: src/luarocks/site_config.lua build_bins | 26 | build: src/luarocks/site_config.lua build_bins |
42 | @echo | 27 | @echo |
43 | @echo "Done. Type 'make install' to install into $(PREFIX)." | 28 | @echo "Done. Type 'make install' to install into $(PREFIX)." |
@@ -139,23 +124,6 @@ cleanup_bins: | |||
139 | clean: cleanup_bins | 124 | clean: cleanup_bins |
140 | rm -f src/luarocks/site_config.lua | 125 | rm -f src/luarocks/site_config.lua |
141 | 126 | ||
142 | install_bins: | ||
143 | mkdir -p "$(DESTDIR)$(BINDIR)" | ||
144 | cd src/bin && for f in $(BIN_FILES); \ | ||
145 | do \ | ||
146 | cp "$$f" "$(DESTDIR)$(BINDIR)/$$f-$(LUA_VERSION)"; \ | ||
147 | ln -nfs "$$f-$(LUA_VERSION)" "$(DESTDIR)$(BINDIR)/$$f"; \ | ||
148 | done | ||
149 | |||
150 | install_luas: | ||
151 | mkdir -p "$(DESTDIR)$(LUADIR)/luarocks" | ||
152 | cd src/luarocks && for f in $(LUAROCKS_FILES); \ | ||
153 | do \ | ||
154 | d="$(DESTDIR)$(LUADIR)/luarocks"/`dirname "$$f"` && \ | ||
155 | mkdir -p "$$d" && \ | ||
156 | cp "$$f" "$$d" || exit 1; \ | ||
157 | done | ||
158 | |||
159 | install_site_config: src/luarocks/site_config.lua | 127 | install_site_config: src/luarocks/site_config.lua |
160 | mkdir -p "$(DESTDIR)$(LUADIR)/luarocks" | 128 | mkdir -p "$(DESTDIR)$(LUADIR)/luarocks" |
161 | cp src/luarocks/site_config.lua "$(DESTDIR)$(LUADIR)/luarocks" | 129 | 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 | |||
180 | '$(LUA_BINDIR)/lua$(LUA_SUFFIX)' -e "package.path=[[$(SAFEPWD)/src/?.lua;]]..package.path" src/bin/luarocks make rockspec --tree="$(PREFIX)" | 148 | '$(LUA_BINDIR)/lua$(LUA_SUFFIX)' -e "package.path=[[$(SAFEPWD)/src/?.lua;]]..package.path" src/bin/luarocks make rockspec --tree="$(PREFIX)" |
181 | 149 | ||
182 | install_rock: install_bins install_luas | 150 | install_rock: install_bins install_luas |
151 | |||
diff --git a/Makefile.install.inc b/Makefile.install.inc new file mode 100644 index 00000000..20d96a12 --- /dev/null +++ b/Makefile.install.inc | |||
@@ -0,0 +1,22 @@ | |||
1 | |||
2 | .PHONY: install_bins install_luas | ||
3 | |||
4 | install_bins: | ||
5 | mkdir -p "$(DESTDIR)$(BINDIR)" | ||
6 | cd src/bin && \ | ||
7 | luaver="$(LUA_VERSION)" && [ -n "$$luaver" ] || luaver=`$(LUA) -e 'print(_VERSION:sub(5))'`; \ | ||
8 | for f in $(BIN_FILES); \ | ||
9 | do \ | ||
10 | cp "$$f" "$(DESTDIR)$(BINDIR)/$$f-$$luaver"; \ | ||
11 | ln -nfs "$$f-$$luaver" "$(DESTDIR)$(BINDIR)/$$f"; \ | ||
12 | done | ||
13 | |||
14 | install_luas: | ||
15 | mkdir -p "$(DESTDIR)$(LUADIR)/luarocks" | ||
16 | cd src/luarocks && for f in $(LUAROCKS_FILES); \ | ||
17 | do \ | ||
18 | d="$(DESTDIR)$(LUADIR)/luarocks"/`dirname "$$f"` && \ | ||
19 | mkdir -p "$$d" && \ | ||
20 | cp "$$f" "$$d" || exit 1; \ | ||
21 | done | ||
22 | |||
diff --git a/Makefile.luarocks b/Makefile.luarocks new file mode 100644 index 00000000..1eecfeae --- /dev/null +++ b/Makefile.luarocks | |||
@@ -0,0 +1,15 @@ | |||
1 | |||
2 | include Makefile.setup.inc | ||
3 | include Makefile.install.inc | ||
4 | |||
5 | .PHONY: all install copy_site_config | ||
6 | |||
7 | all: | ||
8 | @echo This Makefile is used by the LuaRocks rockspec for upgrading itself. | ||
9 | |||
10 | install: install_bins install_luas copy_site_config | ||
11 | |||
12 | copy_site_config: | ||
13 | luaver="$(LUA_VERSION)" && [ -n "$$luaver" ] || luaver=`$(LUA) -e 'print(_VERSION:sub(5))'`; \ | ||
14 | mkdir -p "$(DESTDIR)$(LUADIR)/luarocks"; \ | ||
15 | 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 00000000..0a049bc4 --- /dev/null +++ b/Makefile.setup.inc | |||
@@ -0,0 +1,20 @@ | |||
1 | |||
2 | DESTDIR = | ||
3 | PREFIX ?= /usr/local | ||
4 | BINDIR ?= $(PREFIX)/bin | ||
5 | LUADIR ?= $(PREFIX)/share/lua/$(LUA_VERSION)/ | ||
6 | |||
7 | BIN_FILES = luarocks luarocks-admin | ||
8 | LUAROCKS_FILES = fs/unix/tools.lua fs/unix.lua fs/win32/tools.lua fs/win32.lua \ | ||
9 | fs/lua.lua persist.lua list.lua require.lua repos.lua dir.lua make_manifest.lua \ | ||
10 | command_line.lua config_cmd.lua install.lua build/command.lua build/cmake.lua \ | ||
11 | build/make.lua build/builtin.lua fetch/cvs.lua fetch/git.lua fetch/sscm.lua \ | ||
12 | tools/patch.lua fetch/svn.lua tools/zip.lua tools/tar.lua pack.lua type_check.lua \ | ||
13 | make.lua remove.lua fs.lua manif.lua add.lua deps.lua build.lua search.lua \ | ||
14 | show.lua manif_core.lua fetch.lua unpack.lua validate.lua cfg.lua download.lua \ | ||
15 | help.lua util.lua index.lua cache.lua refresh_cache.lua loader.lua \ | ||
16 | admin_remove.lua fetch/hg.lua fetch/git_file.lua new_version.lua lint.lua \ | ||
17 | purge.lua path.lua path_cmd.lua write_rockspec.lua doc.lua upload.lua \ | ||
18 | upload/api.lua upload/multipart.lua fetch/git_http.lua fetch/hg_http.lua \ | ||
19 | fetch/hg_https.lua fetch/hg_ssh.lua fetch/git_https.lua fetch/git_ssh.lua | ||
20 | |||
@@ -1,22 +1,23 @@ | |||
1 | LuaRocks | 1 | <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> |
2 | ======== | ||
3 | 2 | ||
4 | A package manager for Lua modules. | 3 | A package manager for Lua modules. |
5 | 4 | ||
6 | [](https://travis-ci.org/keplerproject/luarocks) | 5 | [](https://travis-ci.org/keplerproject/luarocks) |
6 | [](https://ci.appveyor.com/project/hishamhm/luarocks/branch/master) | ||
7 | [](https://coveralls.io/r/keplerproject/luarocks?branch=master) | ||
7 | 8 | ||
8 | Main website: [luarocks.org](http://www.luarocks.org) | 9 | Main website: [luarocks.org](http://www.luarocks.org) |
9 | 10 | ||
10 | It allows you to install Lua modules as self-contained packages called | 11 | It allows you to install Lua modules as self-contained packages called |
11 | [*rocks*][1], which also contain version [dependency][2] information. This | 12 | [*rocks*][1], which also contain version [dependency][2] information. This |
12 | information is used both during installation, so that when one rock is | 13 | information can be used both during installation, so that when one rock is |
13 | requested all rocks it depends on are installed as well, and at run time, so | 14 | requested all rocks it depends on are installed as well, and also optionally |
14 | that when a module is required, the correct version is loaded. LuaRocks | 15 | at run time, so that when a module is required, the correct version is loaded. |
15 | supports both local and [remote][3] repositories, and multiple local rocks | 16 | LuaRocks supports both local and [remote][3] repositories, and multiple local |
16 | trees. You can [download][4] and install LuaRocks on [Unix][5] and | 17 | rocks trees. You can [download][4] and install LuaRocks on [Unix][5] and |
17 | [Windows][6]. | 18 | [Windows][6]. |
18 | 19 | ||
19 | LuaRocks is free software and uses the same [license][7] as Lua 5.1. | 20 | LuaRocks is free software and uses the same [license][7] as Lua 5.x. |
20 | 21 | ||
21 | [1]: http://luarocks.org/en/Types_of_rocks | 22 | [1]: http://luarocks.org/en/Types_of_rocks |
22 | [2]: http://luarocks.org/en/Dependencies | 23 | [2]: http://luarocks.org/en/Dependencies |
diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 00000000..d7fc7cc2 --- /dev/null +++ b/appveyor.yml | |||
@@ -0,0 +1,30 @@ | |||
1 | version: 2.2.1.{build}-test | ||
2 | |||
3 | shallow_clone: true | ||
4 | |||
5 | environment: | ||
6 | LUAROCKS_VER: 2.2.1 | ||
7 | |||
8 | matrix: | ||
9 | - LUA_VER: 5.1.5 | ||
10 | - LUA_VER: 5.2.4 | ||
11 | - LUA_VER: 5.3.1 | ||
12 | - LJ_VER: 2.0.4 | ||
13 | - LJ_VER: 2.1 | ||
14 | |||
15 | init: | ||
16 | # Setup Lua development/build environment | ||
17 | # Make VS 2015 command line tools available | ||
18 | - call "%ProgramFiles(x86)%\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" %platform% | ||
19 | |||
20 | install: | ||
21 | # Setup Lua development/build environment | ||
22 | - call .appveyor\install.bat | ||
23 | |||
24 | build_script: | ||
25 | - call .appveyor\build.bat | ||
26 | |||
27 | test_script: | ||
28 | - echo "Testing..." | ||
29 | - cd test | ||
30 | - call testing.bat | ||
@@ -40,17 +40,20 @@ system's package manager. | |||
40 | Default is \$PREFIX | 40 | Default is \$PREFIX |
41 | 41 | ||
42 | --lua-version=VERSION Use specific Lua version: 5.1, 5.2, or 5.3 | 42 | --lua-version=VERSION Use specific Lua version: 5.1, 5.2, or 5.3 |
43 | Default is "$LUA_VERSION" | 43 | Default is auto-detected. |
44 | --lua-suffix=SUFFIX Versioning suffix to use in Lua filenames. | 44 | --lua-suffix=SUFFIX Versioning suffix to use in Lua filenames. |
45 | Default is "$LUA_SUFFIX" (lua$LUA_SUFFIX...) | 45 | Default is "$LUA_SUFFIX" (lua$LUA_SUFFIX...) |
46 | --with-lua=PREFIX Use Lua from given prefix. | 46 | --with-lua=PREFIX Use Lua from given prefix. |
47 | Default is $LUA_DIR | 47 | Default is auto-detected (the parent directory of \$LUA_BINDIR). |
48 | --with-lua-bin=DIR You can also specify Lua's bin dir. | ||
49 | Default is the directory of the auto-detected Lua interpreter, | ||
50 | or \$LUA_DIR/bin if --with-lua is used. | ||
48 | --with-lua-include=DIR You can also specify Lua's includes dir. | 51 | --with-lua-include=DIR You can also specify Lua's includes dir. |
49 | Default is \$LUA_DIR/include | 52 | Default is \$LUA_DIR/include |
50 | --with-lua-lib=DIR You can also specify Lua's libraries dir. | 53 | --with-lua-lib=DIR You can also specify Lua's libraries dir. |
51 | Default is \$LUA_DIR/lib | 54 | Default is \$LUA_DIR/lib |
52 | --with-downloader=TOOL Which tool to use as a downloader. | 55 | --with-downloader=TOOL Which tool to use as a downloader. |
53 | Valid options are: wget, curl. | 56 | Valid options are: curl, wget. |
54 | Default is to auto-detect. | 57 | Default is to auto-detect. |
55 | --with-md5-checker=TOOL Which tool to use as a downloader. | 58 | --with-md5-checker=TOOL Which tool to use as a downloader. |
56 | Valid options are: md5sum, openssl | 59 | Valid options are: md5sum, openssl |
@@ -68,25 +71,10 @@ EOF | |||
68 | # Helper functions | 71 | # Helper functions |
69 | 72 | ||
70 | find_program() { | 73 | find_program() { |
71 | path="$PATH" | 74 | prog=`command -v "$1" 2>/dev/null` |
72 | item="`echo "$path" | sed 's/\([^:]*\):.*/\1/'`" | 75 | if [ -n "$prog" ] |
73 | path="`echo "$path" | sed -n 's/[^:]*::*\(.*\)/\1/p'`" | ||
74 | found="no" | ||
75 | while [ -n "$item" ] | ||
76 | do | ||
77 | if [ -f "$item/$1" ] | ||
78 | then | ||
79 | found="yes" | ||
80 | break | ||
81 | fi | ||
82 | item="`echo "$path" | sed 's/\([^:]*\):.*/\1/'`" | ||
83 | path="`echo "$path" | sed -n 's/[^:]*::*\(.*\)/\1/p'`" | ||
84 | done | ||
85 | if [ "$found" = "yes" ] | ||
86 | then | 76 | then |
87 | echo "$item" | 77 | dirname "$prog" |
88 | else | ||
89 | echo "" | ||
90 | fi | 78 | fi |
91 | } | 79 | } |
92 | 80 | ||
@@ -113,7 +101,7 @@ find_helper() { | |||
113 | fi | 101 | fi |
114 | shift | 102 | shift |
115 | done | 103 | done |
116 | echo "Could not find a $explanation. Tried: $tried." | 104 | echo "Could not find $explanation. Tried: $tried." |
117 | die "Make sure one of them is installed and available in your PATH." | 105 | die "Make sure one of them is installed and available in your PATH." |
118 | } | 106 | } |
119 | 107 | ||
@@ -174,7 +162,7 @@ do | |||
174 | LUA_SUFFIX="$value" | 162 | LUA_SUFFIX="$value" |
175 | LUA_SUFFIX_SET=yes | 163 | LUA_SUFFIX_SET=yes |
176 | ;; | 164 | ;; |
177 | --lua-version) | 165 | --lua-version|--with-lua-version) |
178 | [ -n "$value" ] || die "Missing value in flag $key." | 166 | [ -n "$value" ] || die "Missing value in flag $key." |
179 | LUA_VERSION="$value" | 167 | LUA_VERSION="$value" |
180 | [ "$LUA_VERSION" = "5.1" -o "$LUA_VERSION" = "5.2" -o "$LUA_VERSION" = "5.3" ] || die "Invalid Lua version in flag $key." | 168 | [ "$LUA_VERSION" = "5.1" -o "$LUA_VERSION" = "5.2" -o "$LUA_VERSION" = "5.3" ] || die "Invalid Lua version in flag $key." |
@@ -185,6 +173,11 @@ do | |||
185 | LUA_DIR="$value" | 173 | LUA_DIR="$value" |
186 | LUA_DIR_SET=yes | 174 | LUA_DIR_SET=yes |
187 | ;; | 175 | ;; |
176 | --with-lua-bin) | ||
177 | [ -n "$value" ] || die "Missing value in flag $key." | ||
178 | LUA_BINDIR="$value" | ||
179 | LUA_BINDIR_SET=yes | ||
180 | ;; | ||
188 | --with-lua-include) | 181 | --with-lua-include) |
189 | [ -n "$value" ] || die "Missing value in flag $key." | 182 | [ -n "$value" ] || die "Missing value in flag $key." |
190 | LUA_INCDIR="$value" | 183 | LUA_INCDIR="$value" |
@@ -242,14 +235,17 @@ detect_lua_version() { | |||
242 | LUA_VERSION=$detected_lua | 235 | LUA_VERSION=$detected_lua |
243 | elif [ "$LUA_VERSION" != "$detected_lua" ] | 236 | elif [ "$LUA_VERSION" != "$detected_lua" ] |
244 | then | 237 | then |
245 | die "This clashes with the value of --with-lua-version. Please check your configuration." | 238 | die "This clashes with the value of --lua-version. Please check your configuration." |
246 | fi | 239 | fi |
247 | fi | 240 | fi |
248 | } | 241 | } |
249 | 242 | ||
250 | search_interpreter() { | 243 | search_interpreter() { |
251 | LUA_SUFFIX="$1" | 244 | suffix="$1" |
252 | if [ "$LUA_DIR_SET" = "yes" ] | 245 | if [ "$LUA_BINDIR_SET" = "yes" ] |
246 | then | ||
247 | find_lua="$LUA_BINDIR" | ||
248 | elif [ "$LUA_DIR_SET" = "yes" ] | ||
253 | then | 249 | then |
254 | if [ -f "$LUA_DIR/bin/lua$suffix" ] | 250 | if [ -f "$LUA_DIR/bin/lua$suffix" ] |
255 | then | 251 | then |
@@ -258,10 +254,11 @@ search_interpreter() { | |||
258 | else | 254 | else |
259 | find_lua=`find_program lua$suffix` | 255 | find_lua=`find_program lua$suffix` |
260 | fi | 256 | fi |
261 | if [ -n "$find_lua" ] | 257 | if [ -n "$find_lua" -a -x "$find_lua/lua$suffix" ] |
262 | then | 258 | then |
263 | echo "Lua interpreter found: $find_lua/lua$suffix..." | 259 | echo "Lua interpreter found: $find_lua/lua$suffix..." |
264 | detect_lua_version "$find_lua/lua$suffix" | 260 | LUA_SUFFIX=$suffix |
261 | detect_lua_version "$find_lua/lua$LUA_SUFFIX" | ||
265 | return 0 | 262 | return 0 |
266 | fi | 263 | fi |
267 | return 1 | 264 | return 1 |
@@ -281,9 +278,13 @@ then | |||
281 | else | 278 | else |
282 | suffixes="5.3 53 -5.3 -53 5.2 52 -5.2 -52 5.1 51 -5.1 -51" | 279 | suffixes="5.3 53 -5.3 -53 5.2 52 -5.2 -52 5.1 51 -5.1 -51" |
283 | fi | 280 | fi |
284 | for suffix in `echo $suffixes` "" | 281 | lua_interp_found=no |
282 | for suffix in "" `echo $suffixes` | ||
285 | do | 283 | do |
286 | search_interpreter "$suffix" && break | 284 | search_interpreter "$suffix" && { |
285 | lua_interp_found=yes | ||
286 | break | ||
287 | } | ||
287 | done | 288 | done |
288 | fi | 289 | fi |
289 | 290 | ||
@@ -302,7 +303,7 @@ then | |||
302 | echo "lua$LUA_SUFFIX found in \$PATH: $find_lua" | 303 | echo "lua$LUA_SUFFIX found in \$PATH: $find_lua" |
303 | else | 304 | else |
304 | echo "lua$LUA_SUFFIX not found in \$PATH." | 305 | echo "lua$LUA_SUFFIX not found in \$PATH." |
305 | die "You may want to use the flags --with-lua and/or --lua-suffix. See --help." | 306 | die "You may want to use the flags --with-lua, --with-lua-bin and/or --lua-suffix. See --help." |
306 | fi | 307 | fi |
307 | fi | 308 | fi |
308 | 309 | ||
@@ -316,11 +317,23 @@ then | |||
316 | LUA_LIBDIR="$LUA_DIR/lib" | 317 | LUA_LIBDIR="$LUA_DIR/lib" |
317 | fi | 318 | fi |
318 | 319 | ||
319 | if [ "$LUA_DIR_SET" = "yes" ] | 320 | if [ "$LUA_DIR_SET" = "yes" -a "$LUA_BINDIR_SET" != "yes" ] |
320 | then | 321 | then |
321 | LUA_BINDIR="$LUA_DIR/bin" | 322 | LUA_BINDIR="$LUA_DIR/bin" |
322 | fi | 323 | fi |
323 | 324 | ||
325 | if [ "$lua_interp_found" != "yes" ] | ||
326 | then | ||
327 | echo_n "Checking Lua interpreter... " | ||
328 | if [ -x "$LUA_BINDIR/lua$LUA_SUFFIX" ] | ||
329 | then | ||
330 | echo "lua$LUA_SUFFIX found in $LUA_BINDIR" | ||
331 | else | ||
332 | echo "lua$LUA_SUFFIX not found (looked in $LUA_BINDIR)" | ||
333 | die "You may want to use the flag --with-lua or --with-lua-bin. See --help." | ||
334 | fi | ||
335 | fi | ||
336 | |||
324 | echo_n "Checking Lua includes... " | 337 | echo_n "Checking Lua includes... " |
325 | lua_h="$LUA_INCDIR/lua.h" | 338 | lua_h="$LUA_INCDIR/lua.h" |
326 | if [ -f "$lua_h" ] | 339 | if [ -f "$lua_h" ] |
@@ -349,16 +362,18 @@ fi | |||
349 | 362 | ||
350 | if [ "$LUAROCKS_DOWNLOADER_SET" != "yes" ] | 363 | if [ "$LUAROCKS_DOWNLOADER_SET" != "yes" ] |
351 | then | 364 | then |
352 | find_helper "downloader helper program" wget curl fetch | 365 | find_helper "a downloader helper program" curl wget fetch |
353 | LUAROCKS_DOWNLOADER=$HELPER | 366 | LUAROCKS_DOWNLOADER=$HELPER |
354 | fi | 367 | fi |
355 | 368 | ||
356 | if [ "$LUAROCKS_MD5CHECKER_SET" != "yes" ] | 369 | if [ "$LUAROCKS_MD5CHECKER_SET" != "yes" ] |
357 | then | 370 | then |
358 | find_helper "MD5 checksum calculator" md5sum openssl md5 | 371 | find_helper "a MD5 checksum calculator" md5sum openssl md5 |
359 | LUAROCKS_MD5CHECKER=$HELPER | 372 | LUAROCKS_MD5CHECKER=$HELPER |
360 | fi | 373 | fi |
361 | 374 | ||
375 | find_helper "an 'unzip' program" unzip | ||
376 | |||
362 | echo_n "Configuring for system... " | 377 | echo_n "Configuring for system... " |
363 | if uname -s | 378 | if uname -s |
364 | then | 379 | then |
@@ -408,6 +423,10 @@ then | |||
408 | if [ -n "$GCC_ARCH" -a -d "/usr/lib/$GCC_ARCH" ] | 423 | if [ -n "$GCC_ARCH" -a -d "/usr/lib/$GCC_ARCH" ] |
409 | then | 424 | then |
410 | MULTIARCH_SUBDIR="lib/$GCC_ARCH" | 425 | MULTIARCH_SUBDIR="lib/$GCC_ARCH" |
426 | elif [ -d "/usr/lib64" ] | ||
427 | then | ||
428 | # Useful for Fedora systems | ||
429 | MULTIARCH_SUBDIR="lib64" | ||
411 | fi | 430 | fi |
412 | fi | 431 | fi |
413 | 432 | ||
diff --git a/install.bat b/install.bat index ddcbc71a..053fdfd6 100644 --- a/install.bat +++ b/install.bat | |||
@@ -6,8 +6,12 @@ local vars = {} | |||
6 | 6 | ||
7 | 7 | ||
8 | vars.PREFIX = nil | 8 | vars.PREFIX = nil |
9 | vars.VERSION = "2.1" | 9 | vars.VERSION = "2.2" |
10 | vars.SYSCONFDIR = nil | 10 | vars.SYSCONFDIR = nil |
11 | vars.SYSCONFFORCE = nil | ||
12 | vars.CONFBACKUPDIR = nil | ||
13 | vars.SYSCONFFILENAME = nil | ||
14 | vars.CONFIG_FILE = nil | ||
11 | vars.TREE_ROOT = nil | 15 | vars.TREE_ROOT = nil |
12 | vars.TREE_BIN = nil | 16 | vars.TREE_BIN = nil |
13 | vars.TREE_LMODULE = nil | 17 | vars.TREE_LMODULE = nil |
@@ -26,11 +30,13 @@ vars.LUA_SHORTV = nil -- "51" | |||
26 | vars.LUA_LIB_NAMES = "lua5.1.lib lua51.lib lua5.1.dll lua51.dll liblua.dll.a" | 30 | vars.LUA_LIB_NAMES = "lua5.1.lib lua51.lib lua5.1.dll lua51.dll liblua.dll.a" |
27 | vars.LUA_RUNTIME = nil | 31 | vars.LUA_RUNTIME = nil |
28 | vars.UNAME_M = nil | 32 | vars.UNAME_M = nil |
33 | vars.COMPILER_ENV_CMD = nil | ||
29 | 34 | ||
30 | local FORCE = false | 35 | local FORCE = false |
31 | local FORCE_CONFIG = false | 36 | local FORCE_CONFIG = false |
32 | local INSTALL_LUA = false | 37 | local INSTALL_LUA = false |
33 | local USE_MINGW = false | 38 | local USE_MINGW = false |
39 | local USE_MSVC_MANUAL = false | ||
34 | local REGISTRY = true | 40 | local REGISTRY = true |
35 | local NOADMIN = false | 41 | local NOADMIN = false |
36 | local PROMPT = true | 42 | local PROMPT = true |
@@ -77,7 +83,7 @@ end | |||
77 | 83 | ||
78 | local function exec(cmd) | 84 | local function exec(cmd) |
79 | --print(cmd) | 85 | --print(cmd) |
80 | local status = os.execute(cmd) | 86 | local status = os.execute("type NUL && "..cmd) |
81 | return (status == 0 or status == true) -- compat 5.1/5.2 | 87 | return (status == 0 or status == true) -- compat 5.1/5.2 |
82 | end | 88 | end |
83 | 89 | ||
@@ -90,12 +96,12 @@ local function mkdir (dir) | |||
90 | return exec([[.\win32\tools\mkdir -p "]]..dir..[[" >NUL]]) | 96 | return exec([[.\win32\tools\mkdir -p "]]..dir..[[" >NUL]]) |
91 | end | 97 | end |
92 | 98 | ||
93 | -- does the current user have admin priviledges ( = elevated) | 99 | -- does the current user have admin privileges ( = elevated) |
94 | local function permission() | 100 | local function permission() |
95 | return exec("net session >NUL 2>&1") -- fails if not admin | 101 | return exec("net session >NUL 2>&1") -- fails if not admin |
96 | end | 102 | end |
97 | 103 | ||
98 | -- rename file (full path) to backup (name only), appending number if required | 104 | -- rename filename (full path) to backupname (name only), appending number if required |
99 | -- returns the new name (name only) | 105 | -- returns the new name (name only) |
100 | local function backup(filename, backupname) | 106 | local function backup(filename, backupname) |
101 | local path = filename:match("(.+)%\\.-$").."\\" | 107 | local path = filename:match("(.+)%\\.-$").."\\" |
@@ -119,14 +125,12 @@ local function print_help() | |||
119 | Installs LuaRocks. | 125 | Installs LuaRocks. |
120 | 126 | ||
121 | /P [dir] Where to install LuaRocks. | 127 | /P [dir] Where to install LuaRocks. |
122 | Note that version; $VERSION, will be appended to this | ||
123 | path, so "/P c:\luarocks\" will install in | ||
124 | "c:\luarocks\$VERSION\" | ||
125 | Default is %PROGRAMFILES%\LuaRocks | 128 | Default is %PROGRAMFILES%\LuaRocks |
126 | 129 | ||
127 | Configuring the destinations: | 130 | Configuring the destinations: |
128 | /TREE [dir] Root of the local tree of installed rocks. | 131 | /TREE [dir] Root of the local system tree of installed rocks. |
129 | Default is %PROGRAMFILES%\LuaRocks\systree | 132 | Default is {BIN}\..\ if {BIN} ends with '\bin' |
133 | otherwise it is {BIN}\systree. | ||
130 | /SCRIPTS [dir] Where to install commandline scripts installed by | 134 | /SCRIPTS [dir] Where to install commandline scripts installed by |
131 | rocks. Default is {TREE}\bin. | 135 | rocks. Default is {TREE}\bin. |
132 | /LUAMOD [dir] Where to install Lua modules installed by rocks. | 136 | /LUAMOD [dir] Where to install Lua modules installed by rocks. |
@@ -165,7 +169,14 @@ Configuring the Lua interpreter: | |||
165 | (/LUA, /INC, /LIB, /BIN cannot be used with /L) | 169 | (/LUA, /INC, /LIB, /BIN cannot be used with /L) |
166 | 170 | ||
167 | Compiler configuration: | 171 | Compiler configuration: |
168 | /MW Use mingw as build system instead of MSVC | 172 | By default the installer will try to determine the |
173 | Microsoft toolchain to use. And will automatically use | ||
174 | a setup command to initialize that toolchain when | ||
175 | LuaRocks is run. If it cannot find it, it will default | ||
176 | to the /MSVC switch. | ||
177 | /MSVC Use MS toolchain, without a setup command (tools must | ||
178 | be in your path) | ||
179 | /MW Use mingw as build system (tools must be in your path) | ||
169 | 180 | ||
170 | Other options: | 181 | Other options: |
171 | /FORCECONFIG Use a single config location. Do not use the | 182 | /FORCECONFIG Use a single config location. Do not use the |
@@ -175,7 +186,7 @@ Other options: | |||
175 | /F Remove installation directory if it already exists. | 186 | /F Remove installation directory if it already exists. |
176 | /NOREG Do not load registry info to register '.rockspec' | 187 | /NOREG Do not load registry info to register '.rockspec' |
177 | extension with LuaRocks commands (right-click). | 188 | extension with LuaRocks commands (right-click). |
178 | /NOADMIN The installer requires admin priviledges. If not | 189 | /NOADMIN The installer requires admin privileges. If not |
179 | available it will elevate a new process. Use this | 190 | available it will elevate a new process. Use this |
180 | switch to prevent elevation, but make sure the | 191 | switch to prevent elevation, but make sure the |
181 | destination paths are all accessible for the current | 192 | destination paths are all accessible for the current |
@@ -198,6 +209,7 @@ local function parse_options(args) | |||
198 | vars.PREFIX = option.value | 209 | vars.PREFIX = option.value |
199 | elseif name == "/CONFIG" then | 210 | elseif name == "/CONFIG" then |
200 | vars.SYSCONFDIR = option.value | 211 | vars.SYSCONFDIR = option.value |
212 | vars.SYSCONFFORCE = true | ||
201 | elseif name == "/TREE" then | 213 | elseif name == "/TREE" then |
202 | vars.TREE_ROOT = option.value | 214 | vars.TREE_ROOT = option.value |
203 | elseif name == "/SCRIPTS" then | 215 | elseif name == "/SCRIPTS" then |
@@ -212,6 +224,8 @@ local function parse_options(args) | |||
212 | INSTALL_LUA = true | 224 | INSTALL_LUA = true |
213 | elseif name == "/MW" then | 225 | elseif name == "/MW" then |
214 | USE_MINGW = true | 226 | USE_MINGW = true |
227 | elseif name == "/MSVC" then | ||
228 | USE_MSVC_MANUAL = true | ||
215 | elseif name == "/LUA" then | 229 | elseif name == "/LUA" then |
216 | vars.LUA_PREFIX = option.value | 230 | vars.LUA_PREFIX = option.value |
217 | elseif name == "/LIB" then | 231 | elseif name == "/LIB" then |
@@ -253,7 +267,7 @@ local function check_flags() | |||
253 | die("Cannot combine option /L with any of /LUA /BIN /LIB /INC") | 267 | die("Cannot combine option /L with any of /LUA /BIN /LIB /INC") |
254 | end | 268 | end |
255 | if vars.LUA_VERSION ~= "5.1" then | 269 | if vars.LUA_VERSION ~= "5.1" then |
256 | die("Bundled Lua version is 5.1, cannot install 5.2") | 270 | die("Bundled Lua version is 5.1, cannot install "..vars.LUA_VERSION) |
257 | end | 271 | end |
258 | end | 272 | end |
259 | if vars.LUA_VERSION ~= "5.1" then | 273 | if vars.LUA_VERSION ~= "5.1" then |
@@ -265,6 +279,9 @@ local function check_flags() | |||
265 | die("Bad argument: /LV must either be 5.1, 5.2, or 5.3") | 279 | die("Bad argument: /LV must either be 5.1, 5.2, or 5.3") |
266 | end | 280 | end |
267 | end | 281 | end |
282 | if USE_MSVC_MANUAL and USE_MINGW then | ||
283 | die("Cannot combine option /MSVC and /MW") | ||
284 | end | ||
268 | end | 285 | end |
269 | 286 | ||
270 | -- *********************************************************** | 287 | -- *********************************************************** |
@@ -319,7 +336,7 @@ local function look_for_interpreter (directory) | |||
319 | return true | 336 | return true |
320 | end | 337 | end |
321 | end | 338 | end |
322 | print(" No Lua interpreter found") | 339 | --print(" No Lua interpreter found") |
323 | return false | 340 | return false |
324 | end | 341 | end |
325 | 342 | ||
@@ -360,7 +377,14 @@ local function look_for_headers (directory) | |||
360 | die(S"lua.h not found in $LUA_INCDIR") | 377 | die(S"lua.h not found in $LUA_INCDIR") |
361 | end | 378 | end |
362 | 379 | ||
363 | for _, e in ipairs{ [[\]], [[\include\]]} do | 380 | for _, e in ipairs{ |
381 | S([[\include\lua\$LUA_VERSION]]), | ||
382 | S([[\include\lua$LUA_SHORTV]]), | ||
383 | S([[\include\lua$LUA_VERSION]]), | ||
384 | S([[\include\$LUA_VERSION]]), | ||
385 | [[\include\]], | ||
386 | [[\]], | ||
387 | } do | ||
364 | print(" checking for "..directory..e.."\\lua.h") | 388 | print(" checking for "..directory..e.."\\lua.h") |
365 | if exists(directory..e.."\\lua.h") then | 389 | if exists(directory..e.."\\lua.h") then |
366 | vars.LUA_INCDIR = directory..e | 390 | vars.LUA_INCDIR = directory..e |
@@ -400,6 +424,117 @@ local function get_architecture() | |||
400 | return proc | 424 | return proc |
401 | end | 425 | end |
402 | 426 | ||
427 | -- get a string value from windows registry. | ||
428 | local function get_registry(key, value) | ||
429 | local keys = {key} | ||
430 | local key64, replaced = key:gsub("(%u+\\Software\\)", "%1Wow6432Node\\", 1) | ||
431 | |||
432 | if replaced == 1 then | ||
433 | keys = {key64, key} | ||
434 | end | ||
435 | |||
436 | for _, k in ipairs(keys) do | ||
437 | local h = io.popen('reg query "'..k..'" /v '..value..' 2>NUL') | ||
438 | local output = h:read("*a") | ||
439 | h:close() | ||
440 | |||
441 | local v = output:match("REG_SZ%s+([^\n]+)") | ||
442 | if v then | ||
443 | return v | ||
444 | end | ||
445 | end | ||
446 | return nil | ||
447 | end | ||
448 | |||
449 | local function get_visual_studio_directory() | ||
450 | assert(type(vars.LUA_RUNTIME)=="string", "requires vars.LUA_RUNTIME to be set before calling this function.") | ||
451 | local major, minor = vars.LUA_RUNTIME:match('VCR%u*(%d+)(%d)$') -- MSVCR<x><y> or VCRUNTIME<x><y> | ||
452 | if not major then | ||
453 | print(S[[ Cannot auto-detect Visual Studio version from $LUA_RUNTIME]]) | ||
454 | return nil | ||
455 | end | ||
456 | local keys = { | ||
457 | "HKLM\\Software\\Microsoft\\VisualStudio\\%d.%d\\Setup\\VC", | ||
458 | "HKLM\\Software\\Microsoft\\VCExpress\\%d.%d\\Setup\\VS" | ||
459 | } | ||
460 | for _, key in ipairs(keys) do | ||
461 | local versionedkey = key:format(major, minor) | ||
462 | local vcdir = get_registry(versionedkey, "ProductDir") | ||
463 | print(" checking: "..versionedkey) | ||
464 | if vcdir then | ||
465 | print(" Found: "..vcdir) | ||
466 | return vcdir | ||
467 | end | ||
468 | end | ||
469 | return nil | ||
470 | end | ||
471 | |||
472 | local function get_windows_sdk_directory() | ||
473 | assert(type(vars.LUA_RUNTIME) == "string", "requires vars.LUA_RUNTIME to be set before calling this function.") | ||
474 | -- Only v7.1 and v6.1 shipped with compilers | ||
475 | -- Other versions requires a separate installation of Visual Studio. | ||
476 | -- see https://github.com/keplerproject/luarocks/pull/443#issuecomment-152792516 | ||
477 | local wsdks = { | ||
478 | ["MSVCR100"] = "v7.1", -- shipped with Visual Studio 2010 compilers. | ||
479 | ["MSVCR100D"] = "v7.1", -- shipped with Visual Studio 2010 compilers. | ||
480 | ["MSVCR90"] = "v6.1", -- shipped with Visual Studio 2008 compilers. | ||
481 | ["MSVCR90D"] = "v6.1", -- shipped with Visual Studio 2008 compilers. | ||
482 | } | ||
483 | local wsdkver = wsdks[vars.LUA_RUNTIME] | ||
484 | if not wsdkver then | ||
485 | print(S[[ Cannot auto-detect Windows SDK version from $LUA_RUNTIME]]) | ||
486 | return nil | ||
487 | end | ||
488 | |||
489 | local key = "HKLM\\Software\\Microsoft\\Microsoft SDKs\\Windows\\"..wsdkver | ||
490 | print(" checking: "..key) | ||
491 | local dir = get_registry(key, "InstallationFolder") | ||
492 | if dir then | ||
493 | print(" Found: "..dir) | ||
494 | return dir | ||
495 | end | ||
496 | print(" No SDK found") | ||
497 | return nil | ||
498 | end | ||
499 | |||
500 | -- returns the batch command to setup msvc compiler path. | ||
501 | -- or an empty string (eg. "") if not found | ||
502 | local function get_msvc_env_setup_cmd() | ||
503 | print(S[[Looking for Microsoft toolchain matching runtime $LUA_RUNTIME and architecture $UNAME_M]]) | ||
504 | |||
505 | assert(type(vars.UNAME_M) == "string", "requires vars.UNAME_M to be set before calling this function.") | ||
506 | local x64 = vars.UNAME_M=="x86_64" | ||
507 | |||
508 | -- 1. try visual studio command line tools | ||
509 | local vcdir = get_visual_studio_directory() | ||
510 | if vcdir then | ||
511 | -- 1.1. try vcvarsall.bat | ||
512 | local vcvarsall = vcdir .. 'vcvarsall.bat' | ||
513 | if exists(vcvarsall) then | ||
514 | return ('call "%s"%s'):format(vcvarsall, x64 and ' amd64' or '') | ||
515 | end | ||
516 | |||
517 | -- 1.2. try vcvars32.bat / vcvars64.bat | ||
518 | local relative_path = x64 and "bin\\amd64\\vcvars64.bat" or "bin\\vcvars32.bat" | ||
519 | local full_path = vcdir .. relative_path | ||
520 | if exists(full_path) then | ||
521 | return ('call "%s"'):format(full_path) | ||
522 | end | ||
523 | end | ||
524 | |||
525 | -- 2. try for Windows SDKs command line tools. | ||
526 | local wsdkdir = get_windows_sdk_directory() | ||
527 | if wsdkdir then | ||
528 | local setenv = wsdkdir.."Bin\\SetEnv.cmd" | ||
529 | if exists(setenv) then | ||
530 | return ('call "%s" /%s'):format(setenv, x64 and "x64" or "x86") | ||
531 | end | ||
532 | end | ||
533 | |||
534 | -- finally, we can't detect more, just don't setup the msvc compiler in luarocks.bat. | ||
535 | return "" | ||
536 | end | ||
537 | |||
403 | local function look_for_lua_install () | 538 | local function look_for_lua_install () |
404 | print("Looking for Lua interpreter") | 539 | print("Looking for Lua interpreter") |
405 | local directories | 540 | local directories |
@@ -470,6 +605,28 @@ local function look_for_lua_install () | |||
470 | return false | 605 | return false |
471 | end | 606 | end |
472 | 607 | ||
608 | -- backup config[x.x].lua[.bak] and site_config[_x_x].lua | ||
609 | local function backup_config_files() | ||
610 | local temppath | ||
611 | while not temppath do | ||
612 | temppath = os.getenv("temp").."\\LR-config-backup-"..tostring(math.random(10000)) | ||
613 | if exists(temppath) then temppath = nil end | ||
614 | end | ||
615 | vars.CONFBACKUPDIR = temppath | ||
616 | mkdir(vars.CONFBACKUPDIR) | ||
617 | exec(S[[COPY "$PREFIX\config*.*" "$CONFBACKUPDIR" >NUL]]) | ||
618 | exec(S[[COPY "$PREFIX\lua\luarocks\site_config*.*" "$CONFBACKUPDIR" >NUL]]) | ||
619 | end | ||
620 | |||
621 | -- restore previously backed up config files | ||
622 | local function restore_config_files() | ||
623 | if not vars.CONFBACKUPDIR then return end -- there is no backup to restore | ||
624 | exec(S[[COPY "$CONFBACKUPDIR\config*.*" "$PREFIX" >NUL]]) | ||
625 | exec(S[[COPY "$CONFBACKUPDIR\site_config*.*" "$PREFIX\lua\luarocks" >NUL]]) | ||
626 | -- cleanup | ||
627 | exec(S[[RD /S /Q "$CONFBACKUPDIR"]]) | ||
628 | vars.CONFBACKUPDIR = nil | ||
629 | end | ||
473 | 630 | ||
474 | -- *********************************************************** | 631 | -- *********************************************************** |
475 | -- Installer script start | 632 | -- Installer script start |
@@ -550,12 +707,12 @@ check_flags() | |||
550 | 707 | ||
551 | if not permission() then | 708 | if not permission() then |
552 | if not NOADMIN then | 709 | if not NOADMIN then |
553 | -- must elevate the process with admin priviledges | 710 | -- must elevate the process with admin privileges |
554 | if not exec("PowerShell /? >NUL 2>&1") then | 711 | if not exec("PowerShell /? >NUL 2>&1") then |
555 | -- powershell is not available, so error out | 712 | -- powershell is not available, so error out |
556 | die("No administrative priviledges detected and cannot auto-elevate. Please run with admin priviledges or use the /NOADMIN switch") | 713 | die("No administrative privileges detected and cannot auto-elevate. Please run with admin privileges or use the /NOADMIN switch") |
557 | end | 714 | end |
558 | print("Need admin priviledges, now elevating a new process to continue installing...") | 715 | print("Need admin privileges, now elevating a new process to continue installing...") |
559 | local runner = os.getenv("TEMP").."\\".."LuaRocks_Installer.bat" | 716 | local runner = os.getenv("TEMP").."\\".."LuaRocks_Installer.bat" |
560 | local f = io.open(runner, "w") | 717 | local f = io.open(runner, "w") |
561 | f:write("@echo off\n") | 718 | f:write("@echo off\n") |
@@ -567,21 +724,20 @@ if not permission() then | |||
567 | f:close() | 724 | f:close() |
568 | -- run the created temp batch file in elevated mode | 725 | -- run the created temp batch file in elevated mode |
569 | exec("PowerShell -Command (New-Object -com 'Shell.Application').ShellExecute('"..runner.."', '', '', 'runas')\n") | 726 | exec("PowerShell -Command (New-Object -com 'Shell.Application').ShellExecute('"..runner.."', '', '', 'runas')\n") |
570 | print("Now exiting unpriviledged installer") | 727 | print("Now exiting unprivileged installer") |
571 | os.exit() -- exit here, the newly created elevated process will do the installing | 728 | os.exit() -- exit here, the newly created elevated process will do the installing |
572 | else | 729 | else |
573 | print("Attempting to install without admin priviledges...") | 730 | print("Attempting to install without admin privileges...") |
574 | end | 731 | end |
575 | else | 732 | else |
576 | print("Admin priviledges available for installing") | 733 | print("Admin privileges available for installing") |
577 | end | 734 | end |
578 | 735 | ||
579 | vars.PREFIX = vars.PREFIX or os.getenv("PROGRAMFILES")..[[\LuaRocks]] | 736 | vars.PREFIX = vars.PREFIX or os.getenv("PROGRAMFILES")..[[\LuaRocks]] |
580 | vars.FULL_PREFIX = S"$PREFIX\\$VERSION" | 737 | vars.BINDIR = vars.PREFIX |
581 | vars.BINDIR = vars.FULL_PREFIX | 738 | vars.LIBDIR = vars.PREFIX |
582 | vars.LIBDIR = vars.FULL_PREFIX | 739 | vars.LUADIR = S"$PREFIX\\lua" |
583 | vars.LUADIR = S"$FULL_PREFIX\\lua" | 740 | vars.INCDIR = S"$PREFIX\\include" |
584 | vars.INCDIR = S"$FULL_PREFIX\\include" | ||
585 | vars.LUA_SHORTV = vars.LUA_VERSION:gsub("%.", "") | 741 | vars.LUA_SHORTV = vars.LUA_VERSION:gsub("%.", "") |
586 | 742 | ||
587 | if INSTALL_LUA then | 743 | if INSTALL_LUA then |
@@ -602,20 +758,30 @@ else | |||
602 | vars.UNAME_M = get_architecture() -- can only do when installation was found | 758 | vars.UNAME_M = get_architecture() -- can only do when installation was found |
603 | end | 759 | end |
604 | 760 | ||
605 | local datapath | 761 | -- check location of system tree |
606 | if vars.UNAME_M == "x86" then | 762 | if not vars.TREE_ROOT then |
607 | datapath = os.getenv("PROGRAMFILES") .. [[\LuaRocks]] | 763 | -- no system tree location given, so we need to construct a default value |
608 | else | 764 | if vars.LUA_BINDIR:lower():match([[([\/]+bin[\/]*)$]]) then |
609 | -- our target interpreter is 64bit, so the tree (with binaries) should go into 64bit program files | 765 | -- lua binary is located in a 'bin' subdirectory, so assume |
610 | datapath = os.getenv("ProgramW6432") .. [[\LuaRocks]] | 766 | -- default Lua layout and match rocktree on top |
767 | vars.TREE_ROOT = vars.LUA_BINDIR:lower():gsub([[[\/]+bin[\/]*$]], [[\]]) | ||
768 | else | ||
769 | -- no 'bin', so use a named tree next to the Lua executable | ||
770 | vars.TREE_ROOT = vars.LUA_BINDIR .. [[\systree]] | ||
771 | end | ||
611 | end | 772 | end |
773 | |||
774 | local datapath | ||
612 | vars.SYSCONFDIR = vars.SYSCONFDIR or vars.PREFIX | 775 | vars.SYSCONFDIR = vars.SYSCONFDIR or vars.PREFIX |
613 | vars.TREE_ROOT = vars.TREE_ROOT or datapath..[[\systree]] | 776 | vars.SYSCONFFILENAME = S"config-$LUA_VERSION.lua" |
777 | vars.CONFIG_FILE = vars.SYSCONFDIR.."\\"..vars.SYSCONFFILENAME | ||
614 | if SELFCONTAINED then | 778 | if SELFCONTAINED then |
615 | vars.SYSCONFDIR = vars.PREFIX | 779 | vars.SYSCONFDIR = vars.PREFIX |
780 | vars.SYSCONFFORCE = true | ||
616 | vars.TREE_ROOT = vars.PREFIX..[[\systree]] | 781 | vars.TREE_ROOT = vars.PREFIX..[[\systree]] |
617 | REGISTRY = false | 782 | REGISTRY = false |
618 | end | 783 | end |
784 | vars.COMPILER_ENV_CMD = (USE_MINGW and "") or (USE_MSVC_MANUAL and "") or get_msvc_env_setup_cmd() | ||
619 | 785 | ||
620 | print(S[[ | 786 | print(S[[ |
621 | 787 | ||
@@ -624,8 +790,8 @@ print(S[[ | |||
624 | ========================== | 790 | ========================== |
625 | 791 | ||
626 | Will configure LuaRocks with the following paths: | 792 | Will configure LuaRocks with the following paths: |
627 | LuaRocks : $FULL_PREFIX | 793 | LuaRocks : $PREFIX |
628 | Config file : $SYSCONFDIR\config.lua | 794 | Config file : $CONFIG_FILE |
629 | Rocktree : $TREE_ROOT | 795 | Rocktree : $TREE_ROOT |
630 | 796 | ||
631 | Lua interpreter : $LUA_BINDIR\$LUA_INTERPRETER | 797 | Lua interpreter : $LUA_BINDIR\$LUA_INTERPRETER |
@@ -634,11 +800,20 @@ Lua interpreter : $LUA_BINDIR\$LUA_INTERPRETER | |||
634 | includes : $LUA_INCDIR | 800 | includes : $LUA_INCDIR |
635 | architecture: $UNAME_M | 801 | architecture: $UNAME_M |
636 | binary link : $LUA_LIBNAME with runtime $LUA_RUNTIME.dll | 802 | binary link : $LUA_LIBNAME with runtime $LUA_RUNTIME.dll |
637 | |||
638 | ]]) | 803 | ]]) |
639 | 804 | ||
805 | if USE_MINGW then | ||
806 | print("Compiler : MinGW (make sure it is in your path before using LuaRocks)") | ||
807 | else | ||
808 | if vars.COMPILER_ENV_CMD == "" then | ||
809 | print("Compiler : Microsoft (make sure it is in your path before using LuaRocks)") | ||
810 | else | ||
811 | print(S[[Compiler : Microsoft, using; $COMPILER_ENV_CMD]]) | ||
812 | end | ||
813 | end | ||
814 | |||
640 | if PROMPT then | 815 | if PROMPT then |
641 | print("Press <ENTER> to start installing, or press <CTRL>+<C> to abort. Use install /? for installation options.") | 816 | print("\nPress <ENTER> to start installing, or press <CTRL>+<C> to abort. Use install /? for installation options.") |
642 | io.read() | 817 | io.read() |
643 | end | 818 | end |
644 | 819 | ||
@@ -653,17 +828,19 @@ print([[ | |||
653 | -- *********************************************************** | 828 | -- *********************************************************** |
654 | -- Install LuaRocks files | 829 | -- Install LuaRocks files |
655 | -- *********************************************************** | 830 | -- *********************************************************** |
656 | if FORCE then | ||
657 | print(S"Removing $FULL_PREFIX...") | ||
658 | exec(S[[RD /S /Q "$FULL_PREFIX"]]) | ||
659 | print() | ||
660 | end | ||
661 | 831 | ||
662 | if exists(vars.FULL_PREFIX) then | 832 | if exists(vars.PREFIX) then |
663 | die(S"$FULL_PREFIX exists. Use /F to force removal and reinstallation.") | 833 | if not FORCE then |
834 | die(S"$PREFIX exists. Use /F to force removal and reinstallation.") | ||
835 | else | ||
836 | backup_config_files() | ||
837 | print(S"Removing $PREFIX...") | ||
838 | exec(S[[RD /S /Q "$PREFIX"]]) | ||
839 | print() | ||
840 | end | ||
664 | end | 841 | end |
665 | 842 | ||
666 | print(S"Installing LuaRocks in $FULL_PREFIX...") | 843 | print(S"Installing LuaRocks in $PREFIX...") |
667 | if not exists(vars.BINDIR) then | 844 | if not exists(vars.BINDIR) then |
668 | if not mkdir(vars.BINDIR) then | 845 | if not mkdir(vars.BINDIR) then |
669 | die() | 846 | die() |
@@ -719,7 +896,8 @@ for _, c in ipairs{"luarocks", "luarocks-admin"} do | |||
719 | local f = io.open(vars.BINDIR.."\\"..c..".bat", "w") | 896 | local f = io.open(vars.BINDIR.."\\"..c..".bat", "w") |
720 | f:write(S[[ | 897 | f:write(S[[ |
721 | @ECHO OFF | 898 | @ECHO OFF |
722 | SETLOCAL | 899 | SETLOCAL ENABLEDELAYEDEXPANSION ENABLEEXTENSIONS |
900 | $COMPILER_ENV_CMD | ||
723 | SET "LUA_PATH=$LUADIR\?.lua;$LUADIR\?\init.lua;%LUA_PATH%" | 901 | SET "LUA_PATH=$LUADIR\?.lua;$LUADIR\?\init.lua;%LUA_PATH%" |
724 | IF NOT "%LUA_PATH_5_2%"=="" ( | 902 | IF NOT "%LUA_PATH_5_2%"=="" ( |
725 | SET "LUA_PATH_5_2=$LUADIR\?.lua;$LUADIR\?\init.lua;%LUA_PATH_5_2%" | 903 | SET "LUA_PATH_5_2=$LUADIR\?.lua;$LUADIR\?\init.lua;%LUA_PATH_5_2%" |
@@ -729,7 +907,8 @@ IF NOT "%LUA_PATH_5_3%"=="" ( | |||
729 | ) | 907 | ) |
730 | SET "PATH=$BINDIR;%PATH%" | 908 | SET "PATH=$BINDIR;%PATH%" |
731 | "$LUA_BINDIR\$LUA_INTERPRETER" "$BINDIR\]]..c..[[.lua" %* | 909 | "$LUA_BINDIR\$LUA_INTERPRETER" "$BINDIR\]]..c..[[.lua" %* |
732 | IF NOT "%ERRORLEVEL%"=="2" GOTO EXITLR | 910 | SET EXITCODE=%ERRORLEVEL% |
911 | IF NOT "%EXITCODE%"=="2" GOTO EXITLR | ||
733 | 912 | ||
734 | REM Permission denied error, try and auto elevate... | 913 | REM Permission denied error, try and auto elevate... |
735 | REM already an admin? (checking to prevent loops) | 914 | REM already an admin? (checking to prevent loops) |
@@ -754,48 +933,33 @@ ECHO ECHO Press any key to close this window... >> "%TMPFILE%" | |||
754 | ECHO PAUSE ^> NUL >> "%TMPFILE%" | 933 | ECHO PAUSE ^> NUL >> "%TMPFILE%" |
755 | ECHO DEL "%TMPFILE%" >> "%TMPFILE%" | 934 | ECHO DEL "%TMPFILE%" >> "%TMPFILE%" |
756 | 935 | ||
757 | ECHO Now retrying as a priviledged user... | 936 | ECHO Now retrying as a privileged user... |
758 | PowerShell -Command (New-Object -com 'Shell.Application').ShellExecute('%TMPFILE%', '', '', 'runas') | 937 | PowerShell -Command (New-Object -com 'Shell.Application').ShellExecute('%TMPFILE%', '', '', 'runas') |
759 | 938 | ||
760 | :EXITLR | 939 | :EXITLR |
761 | ENDLOCAL | 940 | exit /b %EXITCODE% |
762 | ]]) | 941 | ]]) |
763 | f:close() | 942 | f:close() |
764 | print(S"Created LuaRocks command: $BINDIR\\"..c..".bat") | 943 | print(S"Created LuaRocks command: $BINDIR\\"..c..".bat") |
765 | end | 944 | end |
766 | 945 | ||
767 | -- part below was commented out as its purpose was unclear | ||
768 | -- see https://github.com/keplerproject/luarocks/pull/197#issuecomment-30176548 | ||
769 | |||
770 | -- configure 'scripts' directory | ||
771 | -- if vars.TREE_BIN then | ||
772 | -- mkdir(vars.TREE_BIN) | ||
773 | -- if not USE_MINGW then | ||
774 | -- -- definitly not for MinGW because of conflicting runtimes | ||
775 | -- -- but is it ok to do it for others??? | ||
776 | -- exec(S[[COPY lua5.1\bin\*.dll "$TREE_BIN" >NUL]]) | ||
777 | -- end | ||
778 | -- else | ||
779 | -- if not USE_MINGW then | ||
780 | -- mkdir(S[[$TREE_ROOT\bin]]) | ||
781 | -- -- definitly not for MinGW because of conflicting runtimes | ||
782 | -- -- but is it ok to do it for others??? | ||
783 | -- exec(S[[COPY lua5.1\bin\*.dll "$TREE_ROOT"\bin >NUL]]) | ||
784 | -- end | ||
785 | -- end | ||
786 | |||
787 | -- *********************************************************** | 946 | -- *********************************************************** |
788 | -- Configure LuaRocks | 947 | -- Configure LuaRocks |
789 | -- *********************************************************** | 948 | -- *********************************************************** |
790 | 949 | ||
950 | restore_config_files() | ||
791 | print() | 951 | print() |
792 | print("Configuring LuaRocks...") | 952 | print("Configuring LuaRocks...") |
793 | 953 | ||
794 | -- Create a site-config file | 954 | -- Create a site-config file |
795 | if exists(S[[$LUADIR\luarocks\site_config.lua]]) then | 955 | local site_config = S("site_config_$LUA_VERSION"):gsub("%.","_") |
796 | exec(S[[RENAME "$LUADIR\luarocks\site_config.lua" site_config.lua.bak]]) | 956 | if exists(S([[$LUADIR\luarocks\]]..site_config..[[.lua]])) then |
957 | local nname = backup(S([[$LUADIR\luarocks\]]..site_config..[[.lua]]), site_config..".lua.bak") | ||
958 | print("***************") | ||
959 | print("*** WARNING *** LuaRocks site_config file already exists: '"..site_config..".lua'. The old file has been renamed to '"..nname.."'") | ||
960 | print("***************") | ||
797 | end | 961 | end |
798 | local f = io.open(vars.LUADIR.."\\luarocks\\site_config.lua", "w") | 962 | local f = io.open(vars.LUADIR.."\\luarocks\\"..site_config..".lua", "w") |
799 | f:write(S[=[ | 963 | f:write(S[=[ |
800 | local site_config = {} | 964 | local site_config = {} |
801 | site_config.LUA_INCDIR=[[$LUA_INCDIR]] | 965 | site_config.LUA_INCDIR=[[$LUA_INCDIR]] |
@@ -810,7 +974,6 @@ else | |||
810 | end | 974 | end |
811 | f:write(S[=[ | 975 | f:write(S[=[ |
812 | site_config.LUAROCKS_UNAME_M=[[$UNAME_M]] | 976 | site_config.LUAROCKS_UNAME_M=[[$UNAME_M]] |
813 | site_config.LUAROCKS_SYSCONFIG=[[$SYSCONFDIR\config.lua]] | ||
814 | site_config.LUAROCKS_ROCKS_TREE=[[$TREE_ROOT]] | 977 | site_config.LUAROCKS_ROCKS_TREE=[[$TREE_ROOT]] |
815 | site_config.LUAROCKS_PREFIX=[[$PREFIX]] | 978 | site_config.LUAROCKS_PREFIX=[[$PREFIX]] |
816 | site_config.LUAROCKS_DOWNLOADER=[[wget]] | 979 | site_config.LUAROCKS_DOWNLOADER=[[wget]] |
@@ -819,24 +982,19 @@ site_config.LUAROCKS_MD5CHECKER=[[md5sum]] | |||
819 | if FORCE_CONFIG then | 982 | if FORCE_CONFIG then |
820 | f:write("site_config.LUAROCKS_FORCE_CONFIG=true\n") | 983 | f:write("site_config.LUAROCKS_FORCE_CONFIG=true\n") |
821 | end | 984 | end |
822 | if exists(vars.LUADIR.."\\luarocks\\site_config.lua.bak") then | 985 | if vars.SYSCONFFORCE then -- only write this value when explcitly given, otherwise rely on defaults |
823 | for line in io.lines(vars.LUADIR.."\\luarocks\\site_config.lua.bak", "r") do | 986 | f:write(S("site_config.LUAROCKS_SYSCONFIG=[[$CONFIG_FILE]]\n")) |
824 | f:write(line) | ||
825 | f:write("\n") | ||
826 | end | ||
827 | exec(S[[DEL /F /Q "$LUADIR\luarocks\site_config.lua.bak"]]) | ||
828 | end | 987 | end |
829 | f:write("return site_config\n") | 988 | f:write("return site_config\n") |
830 | f:close() | 989 | f:close() |
831 | print(S[[Created LuaRocks site-config file: $LUADIR\luarocks\site_config.lua]]) | 990 | print(S([[Created LuaRocks site-config file: $LUADIR\luarocks\]]..site_config..[[.lua]])) |
832 | 991 | ||
833 | -- create config file | 992 | -- create config file |
834 | vars.CONFIG_FILE = vars.SYSCONFDIR.."\\config.lua" | ||
835 | if not exists(vars.SYSCONFDIR) then | 993 | if not exists(vars.SYSCONFDIR) then |
836 | mkdir(vars.SYSCONFDIR) | 994 | mkdir(vars.SYSCONFDIR) |
837 | end | 995 | end |
838 | if exists(vars.CONFIG_FILE) then | 996 | if exists(vars.CONFIG_FILE) then |
839 | local nname = backup(vars.CONFIG_FILE, "config.bak") | 997 | local nname = backup(vars.CONFIG_FILE, vars.SYSCONFFILENAME..".bak") |
840 | print("***************") | 998 | print("***************") |
841 | print(S"*** WARNING *** LuaRocks config file already exists: '$CONFIG_FILE'. The old file has been renamed to '"..nname.."'") | 999 | print(S"*** WARNING *** LuaRocks config file already exists: '$CONFIG_FILE'. The old file has been renamed to '"..nname.."'") |
842 | print("***************") | 1000 | print("***************") |
@@ -901,17 +1059,17 @@ if REGISTRY then | |||
901 | -- expand template with correct path information | 1059 | -- expand template with correct path information |
902 | print() | 1060 | print() |
903 | print([[Loading registry information for ".rockspec" files]]) | 1061 | print([[Loading registry information for ".rockspec" files]]) |
904 | exec( S[[win32\lua5.1\bin\lua5.1.exe "$FULL_PREFIX\LuaRocks.reg.lua" "$FULL_PREFIX\LuaRocks.reg.template"]] ) | 1062 | exec( S[[win32\lua5.1\bin\lua5.1.exe "$PREFIX\LuaRocks.reg.lua" "$PREFIX\LuaRocks.reg.template"]] ) |
905 | exec( S[[regedit /S "$FULL_PREFIX\\LuaRocks.reg"]] ) | 1063 | exec( S[[regedit /S "$PREFIX\\LuaRocks.reg"]] ) |
906 | end | 1064 | end |
907 | 1065 | ||
908 | -- *********************************************************** | 1066 | -- *********************************************************** |
909 | -- Cleanup | 1067 | -- Cleanup |
910 | -- *********************************************************** | 1068 | -- *********************************************************** |
911 | -- remove regsitry related files, no longer needed | 1069 | -- remove regsitry related files, no longer needed |
912 | exec( S[[del "$FULL_PREFIX\LuaRocks.reg.*" >NUL]] ) | 1070 | exec( S[[del "$PREFIX\LuaRocks.reg.*" >NUL]] ) |
913 | -- remove pe-parser module | 1071 | -- remove pe-parser module |
914 | exec( S[[del "$FULL_PREFIX\pe-parser.lua" >NUL]] ) | 1072 | exec( S[[del "$PREFIX\pe-parser.lua" >NUL]] ) |
915 | 1073 | ||
916 | -- *********************************************************** | 1074 | -- *********************************************************** |
917 | -- Exit handlers | 1075 | -- Exit handlers |
@@ -931,8 +1089,8 @@ Lua interpreter; | |||
931 | PATH : $LUA_BINDIR | 1089 | PATH : $LUA_BINDIR |
932 | PATHEXT : .LUA | 1090 | PATHEXT : .LUA |
933 | LuaRocks; | 1091 | LuaRocks; |
934 | PATH : $FULL_PREFIX | 1092 | PATH : $PREFIX |
935 | LUA_PATH : $FULL_PREFIX\lua\?.lua;$FULL_PREFIX\lua\?\init.lua | 1093 | LUA_PATH : $PREFIX\lua\?.lua;$PREFIX\lua\?\init.lua |
936 | Local user rocktree (Note: %APPDATA% is user dependent); | 1094 | Local user rocktree (Note: %APPDATA% is user dependent); |
937 | PATH : %APPDATA%\LuaRocks\bin | 1095 | PATH : %APPDATA%\LuaRocks\bin |
938 | LUA_PATH : %APPDATA%\LuaRocks\share\lua\$LUA_VERSION\?.lua;%APPDATA%\LuaRocks\share\lua\$LUA_VERSION\?\init.lua | 1096 | LUA_PATH : %APPDATA%\LuaRocks\share\lua\$LUA_VERSION\?.lua;%APPDATA%\LuaRocks\share\lua\$LUA_VERSION\?\init.lua |
@@ -16,13 +16,40 @@ make clean || exit 1 | |||
16 | 16 | ||
17 | grep -q "\"$1\"" rockspec || { | 17 | grep -q "\"$1\"" rockspec || { |
18 | echo | 18 | echo |
19 | echo "Version in rockspec is incorrect. Please fix it." | 19 | echo "version in rockspec is incorrect. Please fix it." |
20 | exit 1 | 20 | exit 1 |
21 | } | 21 | } |
22 | 22 | ||
23 | grep -q "program_version = \"$1\"" src/luarocks/cfg.lua || { | 23 | grep -q "program_version = \"$1\"" src/luarocks/cfg.lua || { |
24 | echo | 24 | echo |
25 | echo "Version in src/luarocks/cfg.lua is incorrect. Please fix it." | 25 | echo "program_version in src/luarocks/cfg.lua is incorrect. Please fix it." |
26 | exit 1 | ||
27 | } | ||
28 | |||
29 | grep -q "version: $1\\." appveyor.yml || { | ||
30 | echo | ||
31 | echo "version in appveyor.yml is incorrect. Please fix it." | ||
32 | exit 1 | ||
33 | } | ||
34 | |||
35 | grep -q "LUAROCKS_VER: $1" appveyor.yml || { | ||
36 | echo | ||
37 | echo "LUAROCKS_VER in appveyor.yml is incorrect. Please fix it." | ||
38 | exit 1 | ||
39 | } | ||
40 | |||
41 | # e.g. if $1 is "2.3.0", $program_series is "2.3" | ||
42 | program_series=${1%.*} | ||
43 | |||
44 | grep -q "program_series = \"$program_series\"" src/luarocks/cfg.lua || { | ||
45 | echo | ||
46 | echo "program_series in src/luarocks/cfg.lua is incorrect. Please fix it." | ||
47 | exit 1 | ||
48 | } | ||
49 | |||
50 | grep -q "vars.VERSION = \"$program_series\"" install.bat || { | ||
51 | echo | ||
52 | echo "vars.VERSION in install.bat is incorrect. Please fix it." | ||
26 | exit 1 | 53 | exit 1 |
27 | } | 54 | } |
28 | 55 | ||
@@ -39,8 +66,8 @@ do | |||
39 | cp "$i" "$out/$dir" | 66 | cp "$i" "$out/$dir" |
40 | if echo "$i" | grep -v "/bin/" | grep -q "^src/" | 67 | if echo "$i" | grep -v "/bin/" | grep -q "^src/" |
41 | then | 68 | then |
42 | grep -qw `basename "$i"` Makefile || { | 69 | grep -qw `basename "$i"` Makefile.setup.inc || { |
43 | echo "Missing ref in makefile: $i" | 70 | echo "Missing ref in Makefile.setup.inc: $i" |
44 | touch "missing_ref" | 71 | touch "missing_ref" |
45 | exit 1 | 72 | exit 1 |
46 | } | 73 | } |
@@ -61,15 +88,14 @@ mkdir "release-windows" | |||
61 | mv "$out" "release-windows/$out-win32" | 88 | mv "$out" "release-windows/$out-win32" |
62 | 89 | ||
63 | cd "release-unix/$out" | 90 | cd "release-unix/$out" |
64 | rm -rf makedist install.bat COPYING_lua COPYING_7z COPYING_win win32 lfw | 91 | rm -rf makedist install.bat COPYING_lua COPYING_7z COPYING_win win32 lfw .travis.yml .gitignore appveyor* .appveyor |
65 | cd .. | 92 | cd .. |
66 | tar czvpf ../"$out.tar.gz" "$out" | 93 | tar czvpf ../"$out.tar.gz" "$out" |
67 | cd .. | 94 | cd .. |
68 | rm -rf "release-unix" | 95 | rm -rf "release-unix" |
69 | 96 | ||
70 | cd "release-windows/$out-win32" | 97 | cd "release-windows/$out-win32" |
71 | cp -va win32/* . | 98 | rm -rf makedist Makefile* configure lfw .travis.yml .gitignore test appveyor* .appveyor |
72 | rm -rf makedist Makefile configure lfw win32 | ||
73 | cd .. | 99 | cd .. |
74 | zip -r ../"$out-win32.zip" "$out-win32" | 100 | zip -r ../"$out-win32.zip" "$out-win32" |
75 | cd .. | 101 | cd .. |
@@ -1,7 +1,10 @@ | |||
1 | package = "LuaRocks" | 1 | package = "LuaRocks" |
2 | local VER = "2.2.0beta1" | 2 | local VER = "scm" |
3 | local REV = "1" | 3 | version = VER .. "-1" |
4 | version = VER.."-"..REV | 4 | |
5 | source = { | ||
6 | url = "--this rockspec is used by `make bootstrap` only--", | ||
7 | } | ||
5 | 8 | ||
6 | description = { | 9 | description = { |
7 | summary = "A deployment and management system for Lua modules.", | 10 | summary = "A deployment and management system for Lua modules.", |
@@ -23,16 +26,13 @@ dependencies = { | |||
23 | "lua >= 5.1" | 26 | "lua >= 5.1" |
24 | } | 27 | } |
25 | 28 | ||
26 | source = { | ||
27 | url = "http://luarocks.org/releases/luarocks-"..VER..".tar.gz", | ||
28 | } | ||
29 | |||
30 | build = { | 29 | build = { |
31 | type = "make", | 30 | type = "make", |
32 | install_target = "install_rock", | 31 | install_target = "install_rock", |
33 | build_pass=false, | 32 | build_pass=false, |
34 | install_variables = { | 33 | install_variables = { |
35 | BINDIR="$(BINDIR)", | 34 | BINDIR="$(BINDIR)", |
36 | LUADIR="$(LUADIR)" | 35 | LUADIR="$(LUADIR)", |
36 | LUA="$(LUA)", | ||
37 | } | 37 | } |
38 | } | 38 | } |
diff --git a/src/bin/luarocks b/src/bin/luarocks index 3c9e1b74..be6c2b81 100755 --- a/src/bin/luarocks +++ b/src/bin/luarocks | |||
@@ -1,5 +1,8 @@ | |||
1 | #!/usr/bin/env lua | 1 | #!/usr/bin/env lua |
2 | 2 | ||
3 | -- this should be loaded first. | ||
4 | local cfg = require("luarocks.cfg") | ||
5 | |||
3 | local loader = require("luarocks.loader") | 6 | local loader = require("luarocks.loader") |
4 | local command_line = require("luarocks.command_line") | 7 | local command_line = require("luarocks.command_line") |
5 | 8 | ||
@@ -24,6 +27,7 @@ commands = { | |||
24 | purge = "luarocks.purge", | 27 | purge = "luarocks.purge", |
25 | doc = "luarocks.doc", | 28 | doc = "luarocks.doc", |
26 | upload = "luarocks.upload", | 29 | upload = "luarocks.upload", |
30 | config = "luarocks.config_cmd", | ||
27 | } | 31 | } |
28 | 32 | ||
29 | command_line.run_command(...) | 33 | command_line.run_command(...) |
diff --git a/src/bin/luarocks-admin b/src/bin/luarocks-admin index e7f49c25..2890d1f1 100755 --- a/src/bin/luarocks-admin +++ b/src/bin/luarocks-admin | |||
@@ -1,5 +1,8 @@ | |||
1 | #!/usr/bin/env lua | 1 | #!/usr/bin/env lua |
2 | 2 | ||
3 | -- this should be loaded first. | ||
4 | local cfg = require("luarocks.cfg") | ||
5 | |||
3 | local loader = require("luarocks.loader") | 6 | local loader = require("luarocks.loader") |
4 | local command_line = require("luarocks.command_line") | 7 | local command_line = require("luarocks.command_line") |
5 | 8 | ||
diff --git a/src/luarocks/add.lua b/src/luarocks/add.lua index fc913c95..81adff9b 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) | |||
50 | if not ok then return nil, err end | 50 | if not ok then return nil, err end |
51 | 51 | ||
52 | local files = {} | 52 | local files = {} |
53 | for i, rockfile in ipairs(rockfiles) do | 53 | for _, rockfile in ipairs(rockfiles) do |
54 | if fs.exists(rockfile) then | 54 | if fs.exists(rockfile) then |
55 | util.printout("Copying file "..rockfile.." to "..local_cache.."...") | 55 | util.printout("Copying file "..rockfile.." to "..local_cache.."...") |
56 | local absolute = fs.absolute_name(rockfile) | 56 | local absolute = fs.absolute_name(rockfile) |
diff --git a/src/luarocks/admin_remove.lua b/src/luarocks/admin_remove.lua index 839121d1..5a1cf20b 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 | |||
46 | if not ok then return nil, err end | 46 | if not ok then return nil, err end |
47 | 47 | ||
48 | local nr_files = 0 | 48 | local nr_files = 0 |
49 | for i, rockfile in ipairs(rockfiles) do | 49 | for _, rockfile in ipairs(rockfiles) do |
50 | local basename = dir.base_name(rockfile) | 50 | local basename = dir.base_name(rockfile) |
51 | local file = dir.path(local_cache, basename) | 51 | local file = dir.path(local_cache, basename) |
52 | util.printout("Removing file "..file.."...") | 52 | util.printout("Removing file "..file.."...") |
diff --git a/src/luarocks/build.lua b/src/luarocks/build.lua index cc56c782..68f20264 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. | |||
37 | rockspec. Allows to specify a different branch to | 37 | rockspec. Allows to specify a different branch to |
38 | fetch. Particularly for SCM rocks. | 38 | fetch. Particularly for SCM rocks. |
39 | 39 | ||
40 | --only-deps Installs only the dependencies of the rock. | ||
41 | |||
40 | ]]..util.deps_mode_help() | 42 | ]]..util.deps_mode_help() |
41 | 43 | ||
42 | --- Install files to a given location. | 44 | --- Install files to a given location. |
@@ -130,17 +132,17 @@ function build.apply_patches(rockspec) | |||
130 | end | 132 | end |
131 | 133 | ||
132 | local function install_default_docs(name, version) | 134 | local function install_default_docs(name, version) |
133 | local patterns = { "readme", "license", "copying" } | 135 | local patterns = { "readme", "license", "copying", ".*%.md" } |
134 | local dest = dir.path(path.install_dir(name, version), "doc") | 136 | local dest = dir.path(path.install_dir(name, version), "doc") |
135 | local has_dir = false | 137 | local has_dir = false |
136 | for name in fs.dir() do | 138 | for file in fs.dir() do |
137 | for _, pattern in ipairs(patterns) do | 139 | for _, pattern in ipairs(patterns) do |
138 | if name:lower():match("^"..pattern) then | 140 | if file:lower():match("^"..pattern) then |
139 | if not has_dir then | 141 | if not has_dir then |
140 | fs.make_dir(dest) | 142 | fs.make_dir(dest) |
141 | has_dir = true | 143 | has_dir = true |
142 | end | 144 | end |
143 | fs.copy(name, dest) | 145 | fs.copy(file, dest) |
144 | break | 146 | break |
145 | end | 147 | end |
146 | end | 148 | end |
@@ -157,9 +159,10 @@ end | |||
157 | -- @param deps_mode string: Dependency mode: "one" for the current default tree, | 159 | -- @param deps_mode string: Dependency mode: "one" for the current default tree, |
158 | -- "all" for all trees, "order" for all trees with priority >= the current default, | 160 | -- "all" for all trees, "order" for all trees with priority >= the current default, |
159 | -- "none" for no trees. | 161 | -- "none" for no trees. |
162 | -- @param build_only_deps boolean: true to build the listed dependencies only. | ||
160 | -- @return (string, string) or (nil, string, [string]): Name and version of | 163 | -- @return (string, string) or (nil, string, [string]): Name and version of |
161 | -- installed rock if succeeded or nil and an error message followed by an error code. | 164 | -- installed rock if succeeded or nil and an error message followed by an error code. |
162 | function build.build_rockspec(rockspec_file, need_to_fetch, minimal_mode, deps_mode) | 165 | function build.build_rockspec(rockspec_file, need_to_fetch, minimal_mode, deps_mode, build_only_deps) |
163 | assert(type(rockspec_file) == "string") | 166 | assert(type(rockspec_file) == "string") |
164 | assert(type(need_to_fetch) == "boolean") | 167 | assert(type(need_to_fetch) == "boolean") |
165 | 168 | ||
@@ -181,12 +184,19 @@ function build.build_rockspec(rockspec_file, need_to_fetch, minimal_mode, deps_m | |||
181 | end | 184 | end |
182 | end | 185 | end |
183 | 186 | ||
184 | local ok, err, errcode = deps.check_external_deps(rockspec, "build") | 187 | local name, version = rockspec.name, rockspec.version |
188 | if build_only_deps then | ||
189 | util.printout("Stopping after installing dependencies for " ..name.." "..version) | ||
190 | util.printout() | ||
191 | return name, version | ||
192 | end | ||
193 | |||
194 | local ok | ||
195 | ok, err, errcode = deps.check_external_deps(rockspec, "build") | ||
185 | if err then | 196 | if err then |
186 | return nil, err, errcode | 197 | return nil, err, errcode |
187 | end | 198 | end |
188 | 199 | ||
189 | local name, version = rockspec.name, rockspec.version | ||
190 | if repos.is_installed(name, version) then | 200 | if repos.is_installed(name, version) then |
191 | repos.delete_version(name, version) | 201 | repos.delete_version(name, version) |
192 | end | 202 | end |
@@ -326,8 +336,8 @@ function build.build_rockspec(rockspec_file, need_to_fetch, minimal_mode, deps_m | |||
326 | end | 336 | end |
327 | 337 | ||
328 | local root_dir = path.root_dir(cfg.rocks_dir) | 338 | local root_dir = path.root_dir(cfg.rocks_dir) |
329 | util.printout() | ||
330 | util.printout(name.." "..version.." is now built and installed in "..root_dir.." "..license) | 339 | util.printout(name.." "..version.." is now built and installed in "..root_dir.." "..license) |
340 | util.printout() | ||
331 | 341 | ||
332 | util.remove_scheduled_function(rollback) | 342 | util.remove_scheduled_function(rollback) |
333 | return name, version | 343 | return name, version |
@@ -340,37 +350,41 @@ end | |||
340 | -- @param deps_mode: string: Which trees to check dependencies for: | 350 | -- @param deps_mode: string: Which trees to check dependencies for: |
341 | -- "one" for the current default tree, "all" for all trees, | 351 | -- "one" for the current default tree, "all" for all trees, |
342 | -- "order" for all trees with priority >= the current default, "none" for no trees. | 352 | -- "order" for all trees with priority >= the current default, "none" for no trees. |
353 | -- @param build_only_deps boolean: true to build the listed dependencies only. | ||
343 | -- @return boolean or (nil, string, [string]): True if build was successful, | 354 | -- @return boolean or (nil, string, [string]): True if build was successful, |
344 | -- or false and an error message and an optional error code. | 355 | -- or false and an error message and an optional error code. |
345 | function build.build_rock(rock_file, need_to_fetch, deps_mode) | 356 | function build.build_rock(rock_file, need_to_fetch, deps_mode, build_only_deps) |
346 | assert(type(rock_file) == "string") | 357 | assert(type(rock_file) == "string") |
347 | assert(type(need_to_fetch) == "boolean") | 358 | assert(type(need_to_fetch) == "boolean") |
348 | 359 | ||
349 | local unpack_dir, err, errcode = fetch.fetch_and_unpack_rock(rock_file) | 360 | local ok, err, errcode |
361 | local unpack_dir | ||
362 | unpack_dir, err, errcode = fetch.fetch_and_unpack_rock(rock_file) | ||
350 | if not unpack_dir then | 363 | if not unpack_dir then |
351 | return nil, err, errcode | 364 | return nil, err, errcode |
352 | end | 365 | end |
353 | local rockspec_file = path.rockspec_name_from_rock(rock_file) | 366 | local rockspec_file = path.rockspec_name_from_rock(rock_file) |
354 | local ok, err = fs.change_dir(unpack_dir) | 367 | ok, err = fs.change_dir(unpack_dir) |
355 | if not ok then return nil, err end | 368 | if not ok then return nil, err end |
356 | local ok, err, errcode = build.build_rockspec(rockspec_file, need_to_fetch, false, deps_mode) | 369 | ok, err, errcode = build.build_rockspec(rockspec_file, need_to_fetch, false, deps_mode, build_only_deps) |
357 | fs.pop_dir() | 370 | fs.pop_dir() |
358 | return ok, err, errcode | 371 | return ok, err, errcode |
359 | end | 372 | end |
360 | 373 | ||
361 | local function do_build(name, version, deps_mode) | 374 | local function do_build(name, version, deps_mode, build_only_deps) |
362 | if name:match("%.rockspec$") then | 375 | if name:match("%.rockspec$") then |
363 | return build.build_rockspec(name, true, false, deps_mode) | 376 | return build.build_rockspec(name, true, false, deps_mode, build_only_deps) |
364 | elseif name:match("%.src%.rock$") then | 377 | elseif name:match("%.src%.rock$") then |
365 | return build.build_rock(name, false, deps_mode) | 378 | return build.build_rock(name, false, deps_mode, build_only_deps) |
366 | elseif name:match("%.all%.rock$") then | 379 | elseif name:match("%.all%.rock$") then |
367 | local install = require("luarocks.install") | 380 | local install = require("luarocks.install") |
368 | return install.install_binary_rock(name, deps_mode) | 381 | local install_fun = build_only_deps and install.install_binary_rock_deps or install.install_binary_rock |
382 | return install_fun(name, deps_mode) | ||
369 | elseif name:match("%.rock$") then | 383 | elseif name:match("%.rock$") then |
370 | return build.build_rock(name, true, deps_mode) | 384 | return build.build_rock(name, true, deps_mode, build_only_deps) |
371 | elseif not name:match(dir.separator) then | 385 | elseif not name:match(dir.separator) then |
372 | local search = require("luarocks.search") | 386 | local search = require("luarocks.search") |
373 | return search.act_on_src_or_rockspec(build.run, name:lower(), version, deps.deps_mode_to_flag(deps_mode)) | 387 | 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") |
374 | end | 388 | end |
375 | return nil, "Don't know what to do with "..name | 389 | return nil, "Don't know what to do with "..name |
376 | end | 390 | end |
@@ -395,9 +409,12 @@ function build.run(...) | |||
395 | else | 409 | else |
396 | local ok, err = fs.check_command_permissions(flags) | 410 | local ok, err = fs.check_command_permissions(flags) |
397 | if not ok then return nil, err, cfg.errorcodes.PERMISSIONDENIED end | 411 | if not ok then return nil, err, cfg.errorcodes.PERMISSIONDENIED end |
398 | ok, err = do_build(name, version, deps.get_deps_mode(flags)) | 412 | ok, err = do_build(name, version, deps.get_deps_mode(flags), flags["only-deps"]) |
399 | if not ok then return nil, err end | 413 | if not ok then return nil, err end |
400 | local name, version = ok, err | 414 | local name, version = ok, err |
415 | if flags["only-deps"] then | ||
416 | return name, version | ||
417 | end | ||
401 | if (not flags["keep"]) and not cfg.keep_other_versions then | 418 | if (not flags["keep"]) and not cfg.keep_other_versions then |
402 | local ok, err = remove.remove_other_versions(name, version, flags["force"]) | 419 | local ok, err = remove.remove_other_versions(name, version, flags["force"]) |
403 | if not ok then util.printerr(err) end | 420 | if not ok then util.printerr(err) end |
diff --git a/src/luarocks/build/builtin.lua b/src/luarocks/build/builtin.lua index c855f48a..938262ef 100644 --- a/src/luarocks/build/builtin.lua +++ b/src/luarocks/build/builtin.lua | |||
@@ -74,7 +74,7 @@ function builtin.run(rockspec) | |||
74 | add_flags(extras, "-I%s", incdirs) | 74 | add_flags(extras, "-I%s", incdirs) |
75 | return execute(variables.CC.." "..variables.CFLAGS, "-c", "-o", object, "-I"..variables.LUA_INCDIR, source, unpack(extras)) | 75 | return execute(variables.CC.." "..variables.CFLAGS, "-c", "-o", object, "-I"..variables.LUA_INCDIR, source, unpack(extras)) |
76 | end | 76 | end |
77 | compile_library = function(library, objects, libraries, libdirs, name) | 77 | compile_library = function(library, objects, libraries, libdirs) |
78 | local extras = { unpack(objects) } | 78 | local extras = { unpack(objects) } |
79 | add_flags(extras, "-L%s", libdirs) | 79 | add_flags(extras, "-L%s", libdirs) |
80 | add_flags(extras, "-l%s", libraries) | 80 | add_flags(extras, "-l%s", libraries) |
@@ -149,7 +149,7 @@ function builtin.run(rockspec) | |||
149 | local resname = basename..".res" | 149 | local resname = basename..".res" |
150 | local wrapname = basename..".exe" | 150 | local wrapname = basename..".exe" |
151 | make_rc(fullname, fullbasename..".rc") | 151 | make_rc(fullname, fullbasename..".rc") |
152 | local ok = execute(variables.RC, "-r", "-fo"..resname, rcname) | 152 | local ok = execute(variables.RC, "-nologo", "-r", "-fo"..resname, rcname) |
153 | if not ok then return ok end | 153 | if not ok then return ok end |
154 | ok = execute(variables.CC.." "..variables.CFLAGS, "-c", "-Fo"..object, | 154 | ok = execute(variables.CC.." "..variables.CFLAGS, "-c", "-Fo"..object, |
155 | "-I"..variables.LUA_INCDIR, variables.WRAPPER) | 155 | "-I"..variables.LUA_INCDIR, variables.WRAPPER) |
@@ -188,11 +188,11 @@ function builtin.run(rockspec) | |||
188 | end | 188 | end |
189 | return ok | 189 | return ok |
190 | end | 190 | end |
191 | compile_wrapper_binary = function(fullname, name) return true, name end | 191 | compile_wrapper_binary = function(_, name) return true, name end |
192 | --TODO EXEWRAPPER | 192 | --TODO EXEWRAPPER |
193 | end | 193 | end |
194 | 194 | ||
195 | local ok = true | 195 | local ok, err |
196 | local built_modules = {} | 196 | local built_modules = {} |
197 | local luadir = path.lua_dir(rockspec.name, rockspec.version) | 197 | local luadir = path.lua_dir(rockspec.name, rockspec.version) |
198 | local libdir = path.lib_dir(rockspec.name, rockspec.version) | 198 | local libdir = path.lib_dir(rockspec.name, rockspec.version) |
@@ -214,11 +214,13 @@ function builtin.run(rockspec) | |||
214 | end | 214 | end |
215 | end | 215 | end |
216 | 216 | ||
217 | 217 | if not build.modules then | |
218 | return nil, "Missing build.modules table" | ||
219 | end | ||
218 | for name, info in pairs(build.modules) do | 220 | for name, info in pairs(build.modules) do |
219 | local moddir = path.module_to_path(name) | 221 | local moddir = path.module_to_path(name) |
220 | if type(info) == "string" then | 222 | if type(info) == "string" then |
221 | local ext = info:match(".([^.]+)$") | 223 | local ext = info:match("%.([^.]+)$") |
222 | if ext == "lua" then | 224 | if ext == "lua" then |
223 | local filename = dir.base_name(info) | 225 | local filename = dir.base_name(info) |
224 | if info:match("init%.lua$") and not name:match("%.init$") then | 226 | if info:match("init%.lua$") and not name:match("%.init$") then |
@@ -242,7 +244,7 @@ function builtin.run(rockspec) | |||
242 | if info[1] then sources = info end | 244 | if info[1] then sources = info end |
243 | if type(sources) == "string" then sources = {sources} end | 245 | if type(sources) == "string" then sources = {sources} end |
244 | for _, source in ipairs(sources) do | 246 | for _, source in ipairs(sources) do |
245 | local object = source:gsub(".[^.]*$", "."..cfg.obj_extension) | 247 | local object = source:gsub("%.[^.]*$", "."..cfg.obj_extension) |
246 | if not object then | 248 | if not object then |
247 | object = source.."."..cfg.obj_extension | 249 | object = source.."."..cfg.obj_extension |
248 | end | 250 | end |
@@ -252,11 +254,10 @@ function builtin.run(rockspec) | |||
252 | end | 254 | end |
253 | table.insert(objects, object) | 255 | table.insert(objects, object) |
254 | end | 256 | end |
255 | if not ok then break end | ||
256 | local module_name = name:match("([^.]*)$").."."..util.matchquote(cfg.lib_extension) | 257 | local module_name = name:match("([^.]*)$").."."..util.matchquote(cfg.lib_extension) |
257 | if moddir ~= "" then | 258 | if moddir ~= "" then |
258 | module_name = dir.path(moddir, module_name) | 259 | module_name = dir.path(moddir, module_name) |
259 | local ok, err = fs.make_dir(moddir) | 260 | ok, err = fs.make_dir(moddir) |
260 | if not ok then return nil, err end | 261 | if not ok then return nil, err end |
261 | end | 262 | end |
262 | built_modules[module_name] = dir.path(libdir, module_name) | 263 | built_modules[module_name] = dir.path(libdir, module_name) |
@@ -277,13 +278,13 @@ function builtin.run(rockspec) | |||
277 | end | 278 | end |
278 | for name, dest in pairs(built_modules) do | 279 | for name, dest in pairs(built_modules) do |
279 | fs.make_dir(dir.dir_name(dest)) | 280 | fs.make_dir(dir.dir_name(dest)) |
280 | ok = fs.copy(name, dest) | 281 | ok, err = fs.copy(name, dest) |
281 | if not ok then | 282 | if not ok then |
282 | return nil, "Failed installing "..name.." in "..dest | 283 | return nil, "Failed installing "..name.." in "..dest..": "..err |
283 | end | 284 | end |
284 | end | 285 | end |
285 | if fs.is_dir("lua") then | 286 | if fs.is_dir("lua") then |
286 | local ok, err = fs.copy_contents("lua", luadir) | 287 | ok, err = fs.copy_contents("lua", luadir) |
287 | if not ok then | 288 | if not ok then |
288 | return nil, "Failed copying contents of 'lua' directory: "..err | 289 | return nil, "Failed copying contents of 'lua' directory: "..err |
289 | end | 290 | end |
diff --git a/src/luarocks/build/cmake.lua b/src/luarocks/build/cmake.lua index ed2af3ff..7b16fa51 100644 --- a/src/luarocks/build/cmake.lua +++ b/src/luarocks/build/cmake.lua | |||
@@ -15,7 +15,7 @@ function cmake.run(rockspec) | |||
15 | assert(type(rockspec) == "table") | 15 | assert(type(rockspec) == "table") |
16 | local build = rockspec.build | 16 | local build = rockspec.build |
17 | local variables = build.variables or {} | 17 | local variables = build.variables or {} |
18 | 18 | ||
19 | -- Pass Env variables | 19 | -- Pass Env variables |
20 | variables.CMAKE_MODULE_PATH=os.getenv("CMAKE_MODULE_PATH") | 20 | variables.CMAKE_MODULE_PATH=os.getenv("CMAKE_MODULE_PATH") |
21 | variables.CMAKE_LIBRARY_PATH=os.getenv("CMAKE_LIBRARY_PATH") | 21 | variables.CMAKE_LIBRARY_PATH=os.getenv("CMAKE_LIBRARY_PATH") |
@@ -23,10 +23,11 @@ function cmake.run(rockspec) | |||
23 | 23 | ||
24 | util.variable_substitutions(variables, rockspec.variables) | 24 | util.variable_substitutions(variables, rockspec.variables) |
25 | 25 | ||
26 | if not fs.execute_quiet(rockspec.variables.CMAKE, "--help") then | 26 | local ok, err_msg = fs.is_tool_available(rockspec.variables.CMAKE, "CMake") |
27 | return nil, "'"..rockspec.variables.CMAKE.."' program not found. Is cmake installed? You may want to edit variables.CMAKE" | 27 | if not ok then |
28 | return nil, err_msg | ||
28 | end | 29 | end |
29 | 30 | ||
30 | -- If inline cmake is present create CMakeLists.txt from it. | 31 | -- If inline cmake is present create CMakeLists.txt from it. |
31 | if type(build.cmake) == "string" then | 32 | if type(build.cmake) == "string" then |
32 | local cmake_handler = assert(io.open(fs.current_dir().."/CMakeLists.txt", "w")) | 33 | local cmake_handler = assert(io.open(fs.current_dir().."/CMakeLists.txt", "w")) |
@@ -34,25 +35,29 @@ function cmake.run(rockspec) | |||
34 | cmake_handler:close() | 35 | cmake_handler:close() |
35 | end | 36 | end |
36 | 37 | ||
37 | |||
38 | -- Execute cmake with variables. | 38 | -- Execute cmake with variables. |
39 | local args = "" | 39 | local args = "" |
40 | |||
41 | -- Try to pick the best generator. With msvc and x64, CMake does not select it by default so we need to be explicit. | ||
40 | if cfg.cmake_generator then | 42 | if cfg.cmake_generator then |
41 | args = args .. ' -G"'..cfg.cmake_generator.. '"' | 43 | args = args .. ' -G"'..cfg.cmake_generator.. '"' |
44 | elseif cfg.is_platform("windows") and cfg.target_cpu:match("x86_64$") then | ||
45 | args = args .. " -DCMAKE_GENERATOR_PLATFORM=x64" | ||
42 | end | 46 | end |
47 | |||
43 | for k,v in pairs(variables) do | 48 | for k,v in pairs(variables) do |
44 | args = args .. ' -D' ..k.. '="' ..v.. '"' | 49 | args = args .. ' -D' ..k.. '="' ..tostring(v).. '"' |
45 | end | 50 | end |
46 | 51 | ||
47 | if not fs.execute_string(rockspec.variables.CMAKE.." . " ..args) then | 52 | if not fs.execute_string(rockspec.variables.CMAKE.." -H. -Bbuild.luarocks "..args) then |
48 | return nil, "Failed cmake." | 53 | return nil, "Failed cmake." |
49 | end | 54 | end |
50 | 55 | ||
51 | if not fs.execute_string(rockspec.variables.MAKE.." -fMakefile") then | 56 | if not fs.execute_string(rockspec.variables.CMAKE.." --build build.luarocks --config Release") then |
52 | return nil, "Failed building." | 57 | return nil, "Failed building." |
53 | end | 58 | end |
54 | 59 | ||
55 | if not fs.execute_string(rockspec.variables.MAKE.." -fMakefile install") then | 60 | if not fs.execute_string(rockspec.variables.CMAKE.." --build build.luarocks --target install --config Release") then |
56 | return nil, "Failed installing." | 61 | return nil, "Failed installing." |
57 | end | 62 | end |
58 | return true | 63 | return true |
diff --git a/src/luarocks/cache.lua b/src/luarocks/cache.lua index dbea8405..fb6344d8 100644 --- a/src/luarocks/cache.lua +++ b/src/luarocks/cache.lua | |||
@@ -45,25 +45,12 @@ function cache.split_server_url(server, url, user, password) | |||
45 | user = credentials | 45 | user = credentials |
46 | end | 46 | end |
47 | end | 47 | end |
48 | local local_cache | 48 | local local_cache = cfg.local_cache .. "/" .. server |
49 | if cfg.local_cache then | ||
50 | local_cache = cfg.local_cache .. "/" .. server | ||
51 | end | ||
52 | return local_cache, protocol, server_path, user, password | 49 | return local_cache, protocol, server_path, user, password |
53 | end | 50 | end |
54 | 51 | ||
55 | function cache.refresh_local_cache(server, url, user, password) | 52 | function cache.refresh_local_cache(server, url, user, password) |
56 | local local_cache, protocol, server_path, user, password = cache.split_server_url(server, url, user, password) | 53 | local local_cache, protocol, server_path, user, password = cache.split_server_url(server, url, user, password) |
57 | |||
58 | local ok, err = fs.make_dir(cfg.local_cache) | ||
59 | if not ok then return nil, err end | ||
60 | |||
61 | local tmp_cache = false | ||
62 | if not local_cache then | ||
63 | local err | ||
64 | local_cache, err = fs.make_temp_dir("local_cache") | ||
65 | tmp_cache = true | ||
66 | end | ||
67 | local ok, err = fs.make_dir(local_cache) | 54 | local ok, err = fs.make_dir(local_cache) |
68 | if not ok then | 55 | if not ok then |
69 | return nil, "Failed creating local cache dir: "..err | 56 | return nil, "Failed creating local cache dir: "..err |
diff --git a/src/luarocks/cfg.lua b/src/luarocks/cfg.lua index 8f73bec1..898b0854 100644 --- a/src/luarocks/cfg.lua +++ b/src/luarocks/cfg.lua | |||
@@ -17,6 +17,8 @@ local rawset, next, table, pairs, require, io, os, setmetatable, pcall, ipairs, | |||
17 | local cfg = {} | 17 | local cfg = {} |
18 | package.loaded["luarocks.cfg"] = cfg | 18 | package.loaded["luarocks.cfg"] = cfg |
19 | 19 | ||
20 | local util = require("luarocks.util") | ||
21 | |||
20 | cfg.lua_version = _VERSION:sub(5) | 22 | cfg.lua_version = _VERSION:sub(5) |
21 | local version_suffix = cfg.lua_version:gsub("%.", "_") | 23 | local version_suffix = cfg.lua_version:gsub("%.", "_") |
22 | 24 | ||
@@ -30,10 +32,12 @@ if not ok then | |||
30 | site_config = {} | 32 | site_config = {} |
31 | end | 33 | end |
32 | 34 | ||
33 | cfg.site_config = site_config | 35 | cfg.program_version = "scm" |
34 | 36 | cfg.program_series = "2.2" | |
35 | cfg.program_version = "2.2.0beta1" | 37 | cfg.major_version = (cfg.program_version:match("([^.]%.[^.])")) or cfg.program_series |
36 | cfg.major_version = cfg.program_version:match("([^.]%.[^.])") | 38 | cfg.variables = {} |
39 | cfg.rocks_trees = {} | ||
40 | cfg.platforms = {} | ||
37 | 41 | ||
38 | local persist = require("luarocks.persist") | 42 | local persist = require("luarocks.persist") |
39 | 43 | ||
@@ -41,6 +45,8 @@ cfg.errorcodes = setmetatable({ | |||
41 | OK = 0, | 45 | OK = 0, |
42 | UNSPECIFIED = 1, | 46 | UNSPECIFIED = 1, |
43 | PERMISSIONDENIED = 2, | 47 | PERMISSIONDENIED = 2, |
48 | CONFIGFILE = 3, | ||
49 | CRASH = 99 | ||
44 | },{ | 50 | },{ |
45 | __index = function(t, key) | 51 | __index = function(t, key) |
46 | local val = rawget(t, key) | 52 | local val = rawget(t, key) |
@@ -65,67 +71,94 @@ end | |||
65 | 71 | ||
66 | -- System detection: | 72 | -- System detection: |
67 | 73 | ||
68 | local detected = {} | ||
69 | local system,proc | ||
70 | |||
71 | -- A proper installation of LuaRocks will hardcode the system | 74 | -- A proper installation of LuaRocks will hardcode the system |
72 | -- and proc values with site_config.LUAROCKS_UNAME_S and site_config.LUAROCKS_UNAME_M, | 75 | -- and proc values with site_config.LUAROCKS_UNAME_S and site_config.LUAROCKS_UNAME_M, |
73 | -- so that this detection does not run every time. When it is | 76 | -- so that this detection does not run every time. When it is |
74 | -- performed, we use the Unix way to identify the system, | 77 | -- performed, we use the Unix way to identify the system, |
75 | -- even on Windows (assuming UnxUtils or Cygwin). | 78 | -- even on Windows (assuming UnxUtils or Cygwin). |
76 | system = site_config.LUAROCKS_UNAME_S or io.popen("uname -s"):read("*l") | 79 | local system = site_config.LUAROCKS_UNAME_S or io.popen("uname -s"):read("*l") |
77 | proc = site_config.LUAROCKS_UNAME_M or io.popen("uname -m"):read("*l") | 80 | local proc = site_config.LUAROCKS_UNAME_M or io.popen("uname -m"):read("*l") |
78 | if proc:match("i[%d]86") then | 81 | if proc:match("i[%d]86") then |
79 | proc = "x86" | 82 | cfg.target_cpu = "x86" |
80 | elseif proc:match("amd64") or proc:match("x86_64") then | 83 | elseif proc:match("amd64") or proc:match("x86_64") then |
81 | proc = "x86_64" | 84 | cfg.target_cpu = "x86_64" |
82 | elseif proc:match("Power Macintosh") then | 85 | elseif proc:match("Power Macintosh") then |
83 | proc = "powerpc" | 86 | cfg.target_cpu = "powerpc" |
87 | else | ||
88 | cfg.target_cpu = proc | ||
84 | end | 89 | end |
85 | 90 | ||
86 | if system == "FreeBSD" then | 91 | if system == "FreeBSD" then |
87 | detected.unix = true | 92 | cfg.platforms.unix = true |
88 | detected.freebsd = true | 93 | cfg.platforms.freebsd = true |
89 | detected.bsd = true | 94 | cfg.platforms.bsd = true |
90 | elseif system == "OpenBSD" then | 95 | elseif system == "OpenBSD" then |
91 | detected.unix = true | 96 | cfg.platforms.unix = true |
92 | detected.openbsd = true | 97 | cfg.platforms.openbsd = true |
93 | detected.bsd = true | 98 | cfg.platforms.bsd = true |
94 | elseif system == "NetBSD" then | 99 | elseif system == "NetBSD" then |
95 | detected.unix = true | 100 | cfg.platforms.unix = true |
96 | detected.netbsd = true | 101 | cfg.platforms.netbsd = true |
97 | detected.bsd = true | 102 | cfg.platforms.bsd = true |
98 | elseif system == "Darwin" then | 103 | elseif system == "Darwin" then |
99 | detected.unix = true | 104 | cfg.platforms.unix = true |
100 | detected.macosx = true | 105 | cfg.platforms.macosx = true |
101 | detected.bsd = true | 106 | cfg.platforms.bsd = true |
102 | elseif system == "Linux" then | 107 | elseif system == "Linux" then |
103 | detected.unix = true | 108 | cfg.platforms.unix = true |
104 | detected.linux = true | 109 | cfg.platforms.linux = true |
105 | elseif system == "SunOS" then | 110 | elseif system == "SunOS" then |
106 | detected.unix = true | 111 | cfg.platforms.unix = true |
107 | detected.solaris = true | 112 | cfg.platforms.solaris = true |
108 | elseif system and system:match("^CYGWIN") then | 113 | elseif system and system:match("^CYGWIN") then |
109 | detected.unix = true | 114 | cfg.platforms.unix = true |
110 | detected.cygwin = true | 115 | cfg.platforms.cygwin = true |
116 | elseif system and system:match("^MSYS") then | ||
117 | cfg.platforms.unix = true | ||
118 | cfg.platforms.msys = true | ||
119 | cfg.platforms.cygwin = true | ||
111 | elseif system and system:match("^Windows") then | 120 | elseif system and system:match("^Windows") then |
112 | detected.windows = true | 121 | cfg.platforms.windows = true |
122 | cfg.platforms.win32 = true | ||
113 | elseif system and system:match("^MINGW") then | 123 | elseif system and system:match("^MINGW") then |
114 | detected.windows = true | 124 | cfg.platforms.windows = true |
115 | detected.mingw32 = true | 125 | cfg.platforms.mingw32 = true |
126 | cfg.platforms.win32 = true | ||
127 | elseif system == "Haiku" then | ||
128 | cfg.platforms.unix = true | ||
129 | cfg.platforms.haiku = true | ||
116 | else | 130 | else |
117 | detected.unix = true | 131 | cfg.platforms.unix = true |
118 | -- Fall back to Unix in unknown systems. | 132 | -- Fall back to Unix in unknown systems. |
119 | end | 133 | end |
120 | 134 | ||
121 | -- Path configuration: | 135 | -- Set order for platform overrides |
136 | local platform_order = { | ||
137 | -- Unixes | ||
138 | unix = 1, | ||
139 | bsd = 2, | ||
140 | solaris = 3, | ||
141 | netbsd = 4, | ||
142 | openbsd = 5, | ||
143 | freebsd = 6, | ||
144 | linux = 7, | ||
145 | macosx = 8, | ||
146 | cygwin = 9, | ||
147 | msys = 10, | ||
148 | haiku = 11, | ||
149 | -- Windows | ||
150 | win32 = 12, | ||
151 | mingw32 = 13, | ||
152 | windows = 14 } | ||
122 | 153 | ||
154 | -- Path configuration: | ||
123 | local sys_config_file, home_config_file | 155 | local sys_config_file, home_config_file |
156 | local sys_config_file_default, home_config_file_default | ||
124 | local sys_config_dir, home_config_dir | 157 | local sys_config_dir, home_config_dir |
125 | local sys_config_ok, home_config_ok = false, false | 158 | local sys_config_ok, home_config_ok = false, false |
126 | local extra_luarocks_module_dir | 159 | local extra_luarocks_module_dir |
127 | sys_config_dir = site_config.LUAROCKS_SYSCONFDIR | 160 | sys_config_dir = site_config.LUAROCKS_SYSCONFDIR or site_config.LUAROCKS_PREFIX |
128 | if detected.windows then | 161 | if cfg.platforms.windows then |
129 | cfg.home = os.getenv("APPDATA") or "c:" | 162 | cfg.home = os.getenv("APPDATA") or "c:" |
130 | sys_config_dir = sys_config_dir or "c:/luarocks" | 163 | sys_config_dir = sys_config_dir or "c:/luarocks" |
131 | home_config_dir = cfg.home.."/luarocks" | 164 | home_config_dir = cfg.home.."/luarocks" |
@@ -134,55 +167,105 @@ else | |||
134 | cfg.home = os.getenv("HOME") or "" | 167 | cfg.home = os.getenv("HOME") or "" |
135 | sys_config_dir = sys_config_dir or "/etc/luarocks" | 168 | sys_config_dir = sys_config_dir or "/etc/luarocks" |
136 | home_config_dir = cfg.home.."/.luarocks" | 169 | home_config_dir = cfg.home.."/.luarocks" |
137 | cfg.home_tree = cfg.home.."/.luarocks/" | 170 | cfg.home_tree = (os.getenv("USER") ~= "root") and cfg.home.."/.luarocks/" |
138 | end | 171 | end |
139 | 172 | ||
140 | cfg.variables = {} | 173 | -- Create global environment for the config files; |
141 | cfg.rocks_trees = {} | 174 | local env_for_config_file = function() |
175 | local e | ||
176 | e = { | ||
177 | home = cfg.home, | ||
178 | lua_version = cfg.lua_version, | ||
179 | platforms = util.make_shallow_copy(cfg.platforms), | ||
180 | processor = cfg.target_cpu, -- remains for compat reasons | ||
181 | target_cpu = cfg.target_cpu, -- replaces `processor` | ||
182 | os_getenv = os.getenv, | ||
183 | dump_env = function() | ||
184 | -- debug function, calling it from a config file will show all | ||
185 | -- available globals to that config file | ||
186 | print(util.show_table(e, "global environment")) | ||
187 | end, | ||
188 | } | ||
189 | return e | ||
190 | end | ||
142 | 191 | ||
143 | sys_config_file = site_config.LUAROCKS_SYSCONFIG or sys_config_dir.."/config-"..cfg.lua_version..".lua" | 192 | -- Merge values from config files read into the `cfg` table |
144 | local err | 193 | local merge_overrides = function(overrides) |
145 | sys_config_ok, err = persist.load_into_table(sys_config_file, cfg) | 194 | -- remove some stuff we do not want to integrate |
195 | overrides.os_getenv = nil | ||
196 | overrides.dump_env = nil | ||
197 | -- remove tables to be copied verbatim instead of deeply merged | ||
198 | if overrides.rocks_trees then cfg.rocks_trees = nil end | ||
199 | if overrides.rocks_servers then cfg.rocks_servers = nil end | ||
200 | -- perform actual merge | ||
201 | util.deep_merge(cfg, overrides) | ||
202 | end | ||
146 | 203 | ||
147 | if not sys_config_ok then | 204 | -- load config file from a list until first succesful one. Info is |
148 | sys_config_file = sys_config_dir.."/config.lua" | 205 | -- added to `cfg` module table, returns filepath of succesfully loaded |
149 | sys_config_ok, err = persist.load_into_table(sys_config_file, cfg) | 206 | -- file or nil if it failed |
207 | local load_config_file = function(list) | ||
208 | for _, filepath in ipairs(list) do | ||
209 | local result, err, errcode = persist.load_into_table(filepath, env_for_config_file()) | ||
210 | if (not result) and errcode ~= "open" then | ||
211 | -- errcode is either "load" or "run"; bad config file, so error out | ||
212 | io.stderr:write(err.."\n") | ||
213 | os.exit(cfg.errorcodes.CONFIGFILE) | ||
214 | end | ||
215 | if result then | ||
216 | -- succes in loading and running, merge contents and exit | ||
217 | merge_overrides(result) | ||
218 | return filepath | ||
219 | end | ||
220 | end | ||
221 | return nil -- nothing was loaded | ||
150 | end | 222 | end |
151 | if err and sys_config_ok == nil then | 223 | |
152 | io.stderr:write(err.."\n") | 224 | |
225 | -- Load system configuration file | ||
226 | do | ||
227 | sys_config_file_default = sys_config_dir.."/config-"..cfg.lua_version..".lua" | ||
228 | sys_config_file = load_config_file({ | ||
229 | site_config.LUAROCKS_SYSCONFIG or sys_config_file_default, | ||
230 | sys_config_dir.."/config.lua", | ||
231 | }) | ||
232 | sys_config_ok = (sys_config_file ~= nil) | ||
153 | end | 233 | end |
154 | 234 | ||
235 | -- Load user configuration file (if allowed) | ||
155 | if not site_config.LUAROCKS_FORCE_CONFIG then | 236 | if not site_config.LUAROCKS_FORCE_CONFIG then |
156 | local home_overrides, err | 237 | |
157 | home_config_file = os.getenv("LUAROCKS_CONFIG_" .. version_suffix) or os.getenv("LUAROCKS_CONFIG") | 238 | home_config_file_default = home_config_dir.."/config-"..cfg.lua_version..".lua" |
158 | if home_config_file then | 239 | |
159 | home_overrides, err = persist.load_into_table(home_config_file, { home = cfg.home, lua_version = cfg.lua_version }) | 240 | local config_env_var = "LUAROCKS_CONFIG_" .. version_suffix |
160 | else | 241 | local config_env_value = os.getenv(config_env_var) |
161 | home_config_file = home_config_dir.."/config-"..cfg.lua_version..".lua" | 242 | if not config_env_value then |
162 | home_overrides, err = persist.load_into_table(home_config_file, { home = cfg.home, lua_version = cfg.lua_version }) | 243 | config_env_var = "LUAROCKS_CONFIG" |
163 | if not home_overrides then | 244 | config_env_value = os.getenv(config_env_var) |
164 | home_config_file = home_config_dir.."/config.lua" | ||
165 | home_overrides, err = persist.load_into_table(home_config_file, { home = cfg.home, lua_version = cfg.lua_version }) | ||
166 | end | ||
167 | end | 245 | end |
168 | if home_overrides then | 246 | |
169 | home_config_ok = true | 247 | -- first try environment provided file, so we can explicitly warn when it is missing |
170 | local util = require("luarocks.util") | 248 | if config_env_value then |
171 | if home_overrides.rocks_trees then | 249 | local list = { config_env_value } |
172 | cfg.rocks_trees = nil | 250 | home_config_file = load_config_file(list) |
173 | end | 251 | home_config_ok = (home_config_file ~= nil) |
174 | if home_overrides.rocks_servers then | 252 | if not home_config_ok then |
175 | cfg.rocks_servers = nil | 253 | io.stderr:write("Warning: could not load configuration file `"..config_env_value.."` given in environment variable "..config_env_var.."\n") |
176 | end | ||
177 | util.deep_merge(cfg, home_overrides) | ||
178 | else -- nil or false | ||
179 | home_config_ok = home_overrides | ||
180 | if err and home_config_ok == nil then | ||
181 | io.stderr:write(err.."\n") | ||
182 | end | 254 | end |
183 | end | 255 | end |
256 | |||
257 | -- try the alternative defaults if there was no environment specified file or it didn't work | ||
258 | if not home_config_ok then | ||
259 | local list = { | ||
260 | home_config_file_default, | ||
261 | home_config_dir.."/config.lua", | ||
262 | } | ||
263 | home_config_file = load_config_file(list) | ||
264 | home_config_ok = (home_config_file ~= nil) | ||
265 | end | ||
184 | end | 266 | end |
185 | 267 | ||
268 | |||
186 | if not next(cfg.rocks_trees) then | 269 | if not next(cfg.rocks_trees) then |
187 | if cfg.home_tree then | 270 | if cfg.home_tree then |
188 | table.insert(cfg.rocks_trees, { name = "user", root = cfg.home_tree } ) | 271 | table.insert(cfg.rocks_trees, { name = "user", root = cfg.home_tree } ) |
@@ -192,17 +275,37 @@ if not next(cfg.rocks_trees) then | |||
192 | end | 275 | end |
193 | end | 276 | end |
194 | 277 | ||
195 | -- Configure defaults: | ||
196 | 278 | ||
197 | local root = cfg.rocks_trees[#cfg.rocks_trees] | 279 | -- update platforms list; keyed -> array |
280 | do | ||
281 | local lst = {} -- use temp array to not confuse `pairs` in loop | ||
282 | for plat in pairs(cfg.platforms) do | ||
283 | if cfg.platforms[plat] then -- entries set to 'false' skipped | ||
284 | if not platform_order[plat] then | ||
285 | local pl = "" | ||
286 | for k,_ in pairs(platform_order) do pl = pl .. ", " .. k end | ||
287 | io.stderr:write("Bad platform given; "..tostring(plat)..". Valid entries are: "..pl:sub(3,-1) ..".\n") | ||
288 | os.exit(cfg.errorcodes.CONFIGFILE) | ||
289 | end | ||
290 | table.insert(lst, plat) | ||
291 | else | ||
292 | cfg.platforms[plat] = nil | ||
293 | end | ||
294 | end | ||
295 | -- platform overrides depent on the order, so set priorities | ||
296 | table.sort(lst, function(key1, key2) return platform_order[key1] < platform_order[key2] end) | ||
297 | util.deep_merge(cfg.platforms, lst) | ||
298 | end | ||
299 | |||
300 | -- Configure defaults: | ||
198 | local defaults = { | 301 | local defaults = { |
199 | 302 | ||
200 | local_by_default = false, | 303 | local_by_default = false, |
201 | use_extensions = false, | ||
202 | accept_unknown_fields = false, | 304 | accept_unknown_fields = false, |
203 | fs_use_modules = true, | 305 | fs_use_modules = true, |
204 | hooks_enabled = true, | 306 | hooks_enabled = true, |
205 | deps_mode = "one", | 307 | deps_mode = "one", |
308 | check_certificates = false, | ||
206 | 309 | ||
207 | lua_modules_path = "/share/lua/"..cfg.lua_version, | 310 | lua_modules_path = "/share/lua/"..cfg.lua_version, |
208 | lib_modules_path = "/lib/lua/"..cfg.lua_version, | 311 | lib_modules_path = "/lib/lua/"..cfg.lua_version, |
@@ -214,15 +317,17 @@ local defaults = { | |||
214 | 317 | ||
215 | rocks_servers = { | 318 | rocks_servers = { |
216 | { | 319 | { |
217 | "http://rocks.moonscript.org", | 320 | "https://luarocks.org", |
218 | "https://raw.githubusercontent.com/rocks-moonscript-org/moonrocks-mirror/master/", | 321 | "https://raw.githubusercontent.com/rocks-moonscript-org/moonrocks-mirror/master/", |
322 | "http://luafr.org/moonrocks/", | ||
323 | "http://luarocks.logiceditor.com/rocks", | ||
219 | } | 324 | } |
220 | }, | 325 | }, |
221 | disabled_servers = {}, | 326 | disabled_servers = {}, |
222 | 327 | ||
223 | upload = { | 328 | upload = { |
224 | server = "rocks.moonscript.org", | 329 | server = "https://luarocks.org", |
225 | tool_version = "0.0.1", | 330 | tool_version = "1.0.0", |
226 | api_version = "1", | 331 | api_version = "1", |
227 | }, | 332 | }, |
228 | 333 | ||
@@ -259,7 +364,7 @@ local defaults = { | |||
259 | FIND = "find", | 364 | FIND = "find", |
260 | TEST = "test", | 365 | TEST = "test", |
261 | CHMOD = "chmod", | 366 | CHMOD = "chmod", |
262 | PATCH = "patch", | 367 | MKTEMP = "mktemp", |
263 | 368 | ||
264 | ZIP = "zip", | 369 | ZIP = "zip", |
265 | UNZIP = "unzip -n", | 370 | UNZIP = "unzip -n", |
@@ -271,12 +376,15 @@ local defaults = { | |||
271 | OPENSSL = "openssl", | 376 | OPENSSL = "openssl", |
272 | MD5 = "md5", | 377 | MD5 = "md5", |
273 | STAT = "stat", | 378 | STAT = "stat", |
379 | TOUCH = "touch", | ||
274 | 380 | ||
275 | CMAKE = "cmake", | 381 | CMAKE = "cmake", |
276 | SEVENZ = "7z", | 382 | SEVENZ = "7z", |
277 | 383 | ||
278 | RSYNCFLAGS = "--exclude=.git -Oavz", | 384 | RSYNCFLAGS = "--exclude=.git -Oavz", |
279 | STATFLAG = "-c '%a'", | 385 | STATFLAG = "-c '%a'", |
386 | CURLNOCERTFLAG = "", | ||
387 | WGETNOCERTFLAG = "", | ||
280 | }, | 388 | }, |
281 | 389 | ||
282 | external_deps_subdirs = site_config.LUAROCKS_EXTERNAL_DEPS_SUBDIRS or { | 390 | external_deps_subdirs = site_config.LUAROCKS_EXTERNAL_DEPS_SUBDIRS or { |
@@ -293,14 +401,13 @@ local defaults = { | |||
293 | rocks_provided = {} | 401 | rocks_provided = {} |
294 | } | 402 | } |
295 | 403 | ||
296 | if detected.windows then | 404 | if cfg.platforms.windows then |
297 | local full_prefix = site_config.LUAROCKS_PREFIX.."\\"..cfg.major_version | 405 | local full_prefix = (site_config.LUAROCKS_PREFIX or (os.getenv("PROGRAMFILES")..[[\LuaRocks]])) |
298 | extra_luarocks_module_dir = full_prefix.."\\lua\\?.lua" | 406 | extra_luarocks_module_dir = full_prefix.."\\lua\\?.lua" |
299 | 407 | ||
300 | home_config_file = home_config_file and home_config_file:gsub("\\","/") | 408 | home_config_file = home_config_file and home_config_file:gsub("\\","/") |
301 | defaults.fs_use_modules = false | 409 | defaults.fs_use_modules = false |
302 | defaults.arch = "win32-"..proc | 410 | defaults.arch = "win32-"..cfg.target_cpu |
303 | defaults.platforms = {"win32", "windows" } | ||
304 | defaults.lib_extension = "dll" | 411 | defaults.lib_extension = "dll" |
305 | defaults.external_lib_extension = "dll" | 412 | defaults.external_lib_extension = "dll" |
306 | defaults.static_lib_extension = "lib" | 413 | defaults.static_lib_extension = "lib" |
@@ -309,7 +416,7 @@ if detected.windows then | |||
309 | defaults.variables.LUA_BINDIR = site_config.LUA_BINDIR and site_config.LUA_BINDIR:gsub("\\", "/") or "c:/lua"..cfg.lua_version.."/bin" | 416 | defaults.variables.LUA_BINDIR = site_config.LUA_BINDIR and site_config.LUA_BINDIR:gsub("\\", "/") or "c:/lua"..cfg.lua_version.."/bin" |
310 | defaults.variables.LUA_INCDIR = site_config.LUA_INCDIR and site_config.LUA_INCDIR:gsub("\\", "/") or "c:/lua"..cfg.lua_version.."/include" | 417 | defaults.variables.LUA_INCDIR = site_config.LUA_INCDIR and site_config.LUA_INCDIR:gsub("\\", "/") or "c:/lua"..cfg.lua_version.."/include" |
311 | defaults.variables.LUA_LIBDIR = site_config.LUA_LIBDIR and site_config.LUA_LIBDIR:gsub("\\", "/") or "c:/lua"..cfg.lua_version.."/lib" | 418 | defaults.variables.LUA_LIBDIR = site_config.LUA_LIBDIR and site_config.LUA_LIBDIR:gsub("\\", "/") or "c:/lua"..cfg.lua_version.."/lib" |
312 | defaults.cmake_generator = "MinGW Makefiles" | 419 | |
313 | defaults.makefile = "Makefile.win" | 420 | defaults.makefile = "Makefile.win" |
314 | defaults.variables.MAKE = "nmake" | 421 | defaults.variables.MAKE = "nmake" |
315 | defaults.variables.CC = "cl" | 422 | defaults.variables.CC = "cl" |
@@ -319,8 +426,8 @@ if detected.windows then | |||
319 | defaults.variables.MT = "mt" | 426 | defaults.variables.MT = "mt" |
320 | defaults.variables.AR = "lib" | 427 | defaults.variables.AR = "lib" |
321 | defaults.variables.LUALIB = "lua"..cfg.lua_version..".lib" | 428 | defaults.variables.LUALIB = "lua"..cfg.lua_version..".lib" |
322 | defaults.variables.CFLAGS = "/MD /O2" | 429 | defaults.variables.CFLAGS = "/nologo /MD /O2" |
323 | defaults.variables.LIBFLAG = "/dll" | 430 | defaults.variables.LIBFLAG = "/nologo /dll" |
324 | 431 | ||
325 | local bins = { "SEVENZ", "CP", "FIND", "LS", "MD5SUM", | 432 | local bins = { "SEVENZ", "CP", "FIND", "LS", "MD5SUM", |
326 | "MKDIR", "MV", "PWD", "RMDIR", "TEST", "UNAME", "WGET" } | 433 | "MKDIR", "MV", "PWD", "RMDIR", "TEST", "UNAME", "WGET" } |
@@ -355,8 +462,7 @@ if detected.windows then | |||
355 | defaults.web_browser = "start" | 462 | defaults.web_browser = "start" |
356 | end | 463 | end |
357 | 464 | ||
358 | if detected.mingw32 then | 465 | if cfg.platforms.mingw32 then |
359 | defaults.platforms = { "win32", "mingw32", "windows" } | ||
360 | defaults.obj_extension = "o" | 466 | defaults.obj_extension = "o" |
361 | defaults.static_lib_extension = "a" | 467 | defaults.static_lib_extension = "a" |
362 | defaults.cmake_generator = "MinGW Makefiles" | 468 | defaults.cmake_generator = "MinGW Makefiles" |
@@ -383,7 +489,7 @@ if detected.mingw32 then | |||
383 | 489 | ||
384 | end | 490 | end |
385 | 491 | ||
386 | if detected.unix then | 492 | if cfg.platforms.unix then |
387 | defaults.lib_extension = "so" | 493 | defaults.lib_extension = "so" |
388 | defaults.static_lib_extension = "a" | 494 | defaults.static_lib_extension = "a" |
389 | defaults.external_lib_extension = "so" | 495 | defaults.external_lib_extension = "so" |
@@ -394,7 +500,6 @@ if detected.unix then | |||
394 | defaults.variables.LUA_LIBDIR = site_config.LUA_LIBDIR or "/usr/local/lib" | 500 | defaults.variables.LUA_LIBDIR = site_config.LUA_LIBDIR or "/usr/local/lib" |
395 | defaults.variables.CFLAGS = "-O2" | 501 | defaults.variables.CFLAGS = "-O2" |
396 | defaults.cmake_generator = "Unix Makefiles" | 502 | defaults.cmake_generator = "Unix Makefiles" |
397 | defaults.platforms = { "unix" } | ||
398 | defaults.variables.CC = "gcc" | 503 | defaults.variables.CC = "gcc" |
399 | defaults.variables.LD = "gcc" | 504 | defaults.variables.LD = "gcc" |
400 | defaults.gcc_rpath = true | 505 | defaults.gcc_rpath = true |
@@ -421,63 +526,80 @@ if detected.unix then | |||
421 | defaults.web_browser = "xdg-open" | 526 | defaults.web_browser = "xdg-open" |
422 | end | 527 | end |
423 | 528 | ||
424 | if detected.cygwin then | 529 | if cfg.platforms.cygwin then |
425 | defaults.lib_extension = "so" -- can be overridden in the config file for mingw builds | 530 | defaults.lib_extension = "so" -- can be overridden in the config file for mingw builds |
426 | defaults.arch = "cygwin-"..proc | 531 | defaults.arch = "cygwin-"..cfg.target_cpu |
427 | defaults.platforms = {"unix", "cygwin"} | ||
428 | defaults.cmake_generator = "Unix Makefiles" | 532 | defaults.cmake_generator = "Unix Makefiles" |
429 | defaults.variables.CC = "echo -llua | xargs gcc" | 533 | defaults.variables.CC = "echo -llua | xargs gcc" |
430 | defaults.variables.LD = "echo -llua | xargs gcc" | 534 | defaults.variables.LD = "echo -llua | xargs gcc" |
431 | defaults.variables.LIBFLAG = "-shared" | 535 | defaults.variables.LIBFLAG = "-shared" |
432 | end | 536 | end |
433 | 537 | ||
434 | if detected.bsd then | 538 | if cfg.platforms.msys then |
539 | -- msys is basically cygwin made out of mingw, meaning the subsytem is unixish | ||
540 | -- enough, yet we can freely mix with native win32 | ||
541 | defaults.external_deps_patterns = { | ||
542 | bin = { "?.exe", "?.bat", "?" }, | ||
543 | lib = { "lib?.so", "lib?.so.*", "lib?.dll.a", "?.dll.a", | ||
544 | "lib?.a", "lib?.dll", "?.dll", "?.lib" }, | ||
545 | include = { "?.h" } | ||
546 | } | ||
547 | defaults.runtime_external_deps_patterns = { | ||
548 | bin = { "?.exe", "?.bat" }, | ||
549 | lib = { "lib?.so", "?.dll", "lib?.dll" }, | ||
550 | include = { "?.h" } | ||
551 | } | ||
552 | end | ||
553 | |||
554 | |||
555 | if cfg.platforms.bsd then | ||
435 | defaults.variables.MAKE = "gmake" | 556 | defaults.variables.MAKE = "gmake" |
436 | defaults.variables.STATFLAG = "-f '%OLp'" | 557 | defaults.variables.STATFLAG = "-f '%OLp'" |
437 | end | 558 | end |
438 | 559 | ||
439 | if detected.macosx then | 560 | if cfg.platforms.macosx then |
440 | defaults.variables.MAKE = "make" | 561 | defaults.variables.MAKE = "make" |
441 | defaults.external_lib_extension = "dylib" | 562 | defaults.external_lib_extension = "dylib" |
442 | defaults.arch = "macosx-"..proc | 563 | defaults.arch = "macosx-"..cfg.target_cpu |
443 | defaults.platforms = {"unix", "bsd", "macosx"} | ||
444 | defaults.variables.LIBFLAG = "-bundle -undefined dynamic_lookup -all_load" | 564 | defaults.variables.LIBFLAG = "-bundle -undefined dynamic_lookup -all_load" |
565 | defaults.variables.STAT = "/usr/bin/stat" | ||
445 | defaults.variables.STATFLAG = "-f '%A'" | 566 | defaults.variables.STATFLAG = "-f '%A'" |
446 | local version = io.popen("sw_vers -productVersion"):read("*l") | 567 | local version = io.popen("sw_vers -productVersion"):read("*l") |
447 | version = tonumber(version and version:match("^[^.]+%.([^.]+)")) or 3 | 568 | version = tonumber(version and version:match("^[^.]+%.([^.]+)")) or 3 |
448 | if version >= 5 then | 569 | if version >= 10 then |
570 | version = 8 | ||
571 | elseif version >= 5 then | ||
449 | version = 5 | 572 | version = 5 |
450 | else | 573 | else |
451 | defaults.gcc_rpath = false | 574 | defaults.gcc_rpath = false |
452 | end | 575 | end |
453 | defaults.variables.CC = "export MACOSX_DEPLOYMENT_TARGET=10."..version.."; gcc" | 576 | defaults.variables.CC = "env MACOSX_DEPLOYMENT_TARGET=10."..version.." gcc" |
454 | defaults.variables.LD = "export MACOSX_DEPLOYMENT_TARGET=10."..version.."; gcc" | 577 | defaults.variables.LD = "env MACOSX_DEPLOYMENT_TARGET=10."..version.." gcc" |
455 | defaults.web_browser = "open" | 578 | defaults.web_browser = "open" |
456 | end | 579 | end |
457 | 580 | ||
458 | if detected.linux then | 581 | if cfg.platforms.linux then |
459 | defaults.arch = "linux-"..proc | 582 | defaults.arch = "linux-"..cfg.target_cpu |
460 | defaults.platforms = {"unix", "linux"} | ||
461 | end | 583 | end |
462 | 584 | ||
463 | if detected.freebsd then | 585 | if cfg.platforms.freebsd then |
464 | defaults.arch = "freebsd-"..proc | 586 | defaults.arch = "freebsd-"..cfg.target_cpu |
465 | defaults.platforms = {"unix", "bsd", "freebsd"} | 587 | defaults.gcc_rpath = false |
588 | defaults.variables.CC = "cc" | ||
589 | defaults.variables.LD = "cc" | ||
466 | end | 590 | end |
467 | 591 | ||
468 | if detected.openbsd then | 592 | if cfg.platforms.openbsd then |
469 | defaults.arch = "openbsd-"..proc | 593 | defaults.arch = "openbsd-"..cfg.target_cpu |
470 | defaults.platforms = {"unix", "bsd", "openbsd"} | ||
471 | end | 594 | end |
472 | 595 | ||
473 | if detected.netbsd then | 596 | if cfg.platforms.netbsd then |
474 | defaults.arch = "netbsd-"..proc | 597 | defaults.arch = "netbsd-"..cfg.target_cpu |
475 | defaults.platforms = {"unix", "bsd", "netbsd"} | ||
476 | end | 598 | end |
477 | 599 | ||
478 | if detected.solaris then | 600 | if cfg.platforms.solaris then |
479 | defaults.arch = "solaris-"..proc | 601 | defaults.arch = "solaris-"..cfg.target_cpu |
480 | defaults.platforms = {"unix", "solaris"} | 602 | --defaults.platforms = {"unix", "solaris"} |
481 | defaults.variables.MAKE = "gmake" | 603 | defaults.variables.MAKE = "gmake" |
482 | end | 604 | end |
483 | 605 | ||
@@ -490,13 +612,11 @@ defaults.variables.LUA = site_config.LUA_DIR_SET and (defaults.variables.LUA_BIN | |||
490 | -- Add built-in modules to rocks_provided | 612 | -- Add built-in modules to rocks_provided |
491 | defaults.rocks_provided["lua"] = cfg.lua_version.."-1" | 613 | defaults.rocks_provided["lua"] = cfg.lua_version.."-1" |
492 | 614 | ||
493 | if cfg.lua_version >= "5.2" then | 615 | if bit32 then -- Lua 5.2+ |
494 | -- Lua 5.2+ | ||
495 | defaults.rocks_provided["bit32"] = cfg.lua_version.."-1" | 616 | defaults.rocks_provided["bit32"] = cfg.lua_version.."-1" |
496 | end | 617 | end |
497 | 618 | ||
498 | if cfg.lua_version >= "5.3" then | 619 | if utf8 then -- Lua 5.3+ |
499 | -- Lua 5.3+ | ||
500 | defaults.rocks_provided["utf8"] = cfg.lua_version.."-1" | 620 | defaults.rocks_provided["utf8"] = cfg.lua_version.."-1" |
501 | end | 621 | end |
502 | 622 | ||
@@ -534,33 +654,73 @@ local cfg_mt = { | |||
534 | } | 654 | } |
535 | setmetatable(cfg, cfg_mt) | 655 | setmetatable(cfg, cfg_mt) |
536 | 656 | ||
537 | function cfg.package_paths() | 657 | if not cfg.check_certificates then |
658 | cfg.variables.CURLNOCERTFLAG = "-k" | ||
659 | cfg.variables.WGETNOCERTFLAG = "--no-check-certificate" | ||
660 | end | ||
661 | |||
662 | function cfg.make_paths_from_tree(tree) | ||
663 | local lua_path, lib_path, bin_path | ||
664 | if type(tree) == "string" then | ||
665 | lua_path = tree..cfg.lua_modules_path | ||
666 | lib_path = tree..cfg.lib_modules_path | ||
667 | bin_path = tree.."/bin" | ||
668 | else | ||
669 | lua_path = tree.lua_dir or tree.root..cfg.lua_modules_path | ||
670 | lib_path = tree.lib_dir or tree.root..cfg.lib_modules_path | ||
671 | bin_path = tree.bin_dir or tree.root.."/bin" | ||
672 | end | ||
673 | return lua_path, lib_path, bin_path | ||
674 | end | ||
675 | |||
676 | function cfg.package_paths(current) | ||
538 | local new_path, new_cpath, new_bin = {}, {}, {} | 677 | local new_path, new_cpath, new_bin = {}, {}, {} |
678 | local function add_tree_to_paths(tree) | ||
679 | local lua_path, lib_path, bin_path = cfg.make_paths_from_tree(tree) | ||
680 | table.insert(new_path, lua_path.."/?.lua") | ||
681 | table.insert(new_path, lua_path.."/?/init.lua") | ||
682 | table.insert(new_cpath, lib_path.."/?."..cfg.lib_extension) | ||
683 | table.insert(new_bin, bin_path) | ||
684 | end | ||
685 | if current then | ||
686 | add_tree_to_paths(current) | ||
687 | end | ||
539 | for _,tree in ipairs(cfg.rocks_trees) do | 688 | for _,tree in ipairs(cfg.rocks_trees) do |
540 | if type(tree) == "string" then | 689 | add_tree_to_paths(tree) |
541 | table.insert(new_path, tree..cfg.lua_modules_path.."/?.lua") | ||
542 | table.insert(new_path, tree..cfg.lua_modules_path.."/?/init.lua") | ||
543 | table.insert(new_cpath, tree..cfg.lib_modules_path.."/?."..cfg.lib_extension) | ||
544 | table.insert(new_bin, tree.."/bin") | ||
545 | else | ||
546 | table.insert(new_path, (tree.lua_dir or tree.root..cfg.lua_modules_path).."/?.lua") | ||
547 | table.insert(new_path, (tree.lua_dir or tree.root..cfg.lua_modules_path).."/?/init.lua") | ||
548 | table.insert(new_cpath, (tree.lib_dir or tree.root..cfg.lib_modules_path).."/?."..cfg.lib_extension) | ||
549 | table.insert(new_bin, (tree.bin_dir or tree.root.."/bin")) | ||
550 | end | ||
551 | end | 690 | end |
552 | if extra_luarocks_module_dir then | 691 | if extra_luarocks_module_dir then |
553 | table.insert(new_path, extra_luarocks_module_dir) | 692 | table.insert(new_path, extra_luarocks_module_dir) |
554 | end | 693 | end |
555 | return table.concat(new_path, ";"), table.concat(new_cpath, ";"), table.concat(new_bin, ";") | 694 | return table.concat(new_path, ";"), table.concat(new_cpath, ";"), table.concat(new_bin, cfg.export_path_separator) |
695 | end | ||
696 | |||
697 | function cfg.init_package_paths() | ||
698 | local lr_path, lr_cpath, lr_bin = cfg.package_paths() | ||
699 | package.path = util.remove_path_dupes(package.path .. ";" .. lr_path, ";") | ||
700 | package.cpath = util.remove_path_dupes(package.cpath .. ";" .. lr_cpath, ";") | ||
556 | end | 701 | end |
557 | 702 | ||
558 | function cfg.which_config() | 703 | function cfg.which_config() |
559 | return sys_config_file, sys_config_ok, home_config_file, home_config_ok | 704 | local ret = { |
705 | system = { | ||
706 | file = sys_config_file or sys_config_file_default, | ||
707 | ok = sys_config_ok, | ||
708 | }, | ||
709 | user = { | ||
710 | file = home_config_file or home_config_file_default, | ||
711 | ok = home_config_ok, | ||
712 | } | ||
713 | } | ||
714 | ret.nearest = (ret.user.ok and ret.user.file) or ret.system.file | ||
715 | return ret | ||
560 | end | 716 | end |
561 | 717 | ||
562 | cfg.user_agent = "LuaRocks/"..cfg.program_version.." "..cfg.arch | 718 | cfg.user_agent = "LuaRocks/"..cfg.program_version.." "..cfg.arch |
563 | 719 | ||
720 | cfg.http_proxy = os.getenv("http_proxy") | ||
721 | cfg.https_proxy = os.getenv("https_proxy") | ||
722 | cfg.no_proxy = os.getenv("no_proxy") | ||
723 | |||
564 | --- Check if platform was detected | 724 | --- Check if platform was detected |
565 | -- @param query string: The platform name to check. | 725 | -- @param query string: The platform name to check. |
566 | -- @return boolean: true if LuaRocks is currently running on queried platform. | 726 | -- @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 cc2e1683..a016fc72 100644 --- a/src/luarocks/command_line.lua +++ b/src/luarocks/command_line.lua | |||
@@ -10,6 +10,7 @@ local cfg = require("luarocks.cfg") | |||
10 | local path = require("luarocks.path") | 10 | local path = require("luarocks.path") |
11 | local dir = require("luarocks.dir") | 11 | local dir = require("luarocks.dir") |
12 | local deps = require("luarocks.deps") | 12 | local deps = require("luarocks.deps") |
13 | local fs = require("luarocks.fs") | ||
13 | 14 | ||
14 | local program = util.this_program("luarocks") | 15 | local program = util.this_program("luarocks") |
15 | 16 | ||
@@ -21,7 +22,7 @@ local function die(message, exitcode) | |||
21 | 22 | ||
22 | local ok, err = pcall(util.run_scheduled_functions) | 23 | local ok, err = pcall(util.run_scheduled_functions) |
23 | if not ok then | 24 | if not ok then |
24 | util.printerr("\nLuaRocks "..cfg.program_version.." internal bug (please report at luarocks-developers@lists.sourceforge.net):\n"..err) | 25 | util.printerr("\nLuaRocks "..cfg.program_version.." internal bug (please report at https://github.com/keplerproject/luarocks/issues):\n"..err) |
25 | end | 26 | end |
26 | util.printerr("\nError: "..message) | 27 | util.printerr("\nError: "..message) |
27 | os.exit(exitcode or cfg.errorcodes.UNSPECIFIED) | 28 | os.exit(exitcode or cfg.errorcodes.UNSPECIFIED) |
@@ -30,12 +31,17 @@ end | |||
30 | local function replace_tree(flags, args, tree) | 31 | local function replace_tree(flags, args, tree) |
31 | tree = dir.normalize(tree) | 32 | tree = dir.normalize(tree) |
32 | flags["tree"] = tree | 33 | flags["tree"] = tree |
34 | local added = false | ||
33 | for i = 1, #args do | 35 | for i = 1, #args do |
34 | if args[i]:match("%-%-tree=") then | 36 | if args[i]:match("%-%-tree=") then |
35 | args[i] = "--tree="..tree | 37 | args[i] = "--tree="..tree |
38 | added = true | ||
36 | break | 39 | break |
37 | end | 40 | end |
38 | end | 41 | end |
42 | if not added then | ||
43 | args[#args + 1] = "--tree="..tree | ||
44 | end | ||
39 | path.use_tree(tree) | 45 | path.use_tree(tree) |
40 | end | 46 | end |
41 | 47 | ||
@@ -63,6 +69,9 @@ function command_line.run_command(...) | |||
63 | end | 69 | end |
64 | local nonflags = { util.parse_flags(unpack(args)) } | 70 | local nonflags = { util.parse_flags(unpack(args)) } |
65 | local flags = table.remove(nonflags, 1) | 71 | local flags = table.remove(nonflags, 1) |
72 | if flags.ERROR then | ||
73 | die(flags.ERROR.." See --help.") | ||
74 | end | ||
66 | 75 | ||
67 | if flags["from"] then flags["server"] = flags["from"] end | 76 | if flags["from"] then flags["server"] = flags["from"] end |
68 | if flags["only-from"] then flags["only-server"] = flags["only-from"] end | 77 | if flags["only-from"] then flags["only-server"] = flags["only-from"] end |
@@ -79,7 +88,6 @@ function command_line.run_command(...) | |||
79 | 88 | ||
80 | if flags["verbose"] then -- setting it in the config file will kick-in earlier in the process | 89 | if flags["verbose"] then -- setting it in the config file will kick-in earlier in the process |
81 | cfg.verbose = true | 90 | cfg.verbose = true |
82 | local fs = require("luarocks.fs") | ||
83 | fs.verbose() | 91 | fs.verbose() |
84 | end | 92 | end |
85 | 93 | ||
@@ -110,12 +118,6 @@ function command_line.run_command(...) | |||
110 | end | 118 | end |
111 | end | 119 | end |
112 | command = command:gsub("-", "_") | 120 | command = command:gsub("-", "_") |
113 | |||
114 | if flags["extensions"] then | ||
115 | cfg.use_extensions = true | ||
116 | local type_check = require("luarocks.type_check") | ||
117 | type_check.load_extensions() | ||
118 | end | ||
119 | 121 | ||
120 | if cfg.local_by_default then | 122 | if cfg.local_by_default then |
121 | flags["local"] = true | 123 | flags["local"] = true |
@@ -126,16 +128,10 @@ function command_line.run_command(...) | |||
126 | end | 128 | end |
127 | 129 | ||
128 | if flags["branch"] then | 130 | if flags["branch"] then |
129 | if flags["branch"] == true or flags["branch"] == "" then | ||
130 | die("Argument error: use --branch=<branch-name>") | ||
131 | end | ||
132 | cfg.branch = flags["branch"] | 131 | cfg.branch = flags["branch"] |
133 | end | 132 | end |
134 | 133 | ||
135 | if flags["tree"] then | 134 | if flags["tree"] then |
136 | if flags["tree"] == true or flags["tree"] == "" then | ||
137 | die("Argument error: use --tree=<path>") | ||
138 | end | ||
139 | local named = false | 135 | local named = false |
140 | for _, tree in ipairs(cfg.rocks_trees) do | 136 | for _, tree in ipairs(cfg.rocks_trees) do |
141 | if type(tree) == "table" and flags["tree"] == tree.name then | 137 | if type(tree) == "table" and flags["tree"] == tree.name then |
@@ -148,11 +144,15 @@ function command_line.run_command(...) | |||
148 | end | 144 | end |
149 | end | 145 | end |
150 | if not named then | 146 | if not named then |
151 | local fs = require("luarocks.fs") | ||
152 | local root_dir = fs.absolute_name(flags["tree"]) | 147 | local root_dir = fs.absolute_name(flags["tree"]) |
153 | replace_tree(flags, args, root_dir) | 148 | replace_tree(flags, args, root_dir) |
154 | end | 149 | end |
155 | elseif flags["local"] then | 150 | elseif flags["local"] then |
151 | if not cfg.home_tree then | ||
152 | die("The --local flag is meant for operating in a user's home directory.\n".. | ||
153 | "You are running as a superuser, which is intended for system-wide operation.\n".. | ||
154 | "To force using the superuser's home, use --tree explicitly.") | ||
155 | end | ||
156 | replace_tree(flags, args, cfg.home_tree) | 156 | replace_tree(flags, args, cfg.home_tree) |
157 | else | 157 | else |
158 | local trees = cfg.rocks_trees | 158 | local trees = cfg.rocks_trees |
@@ -173,17 +173,11 @@ function command_line.run_command(...) | |||
173 | cfg.variables.SCRIPTS_DIR = cfg.deploy_bin_dir | 173 | cfg.variables.SCRIPTS_DIR = cfg.deploy_bin_dir |
174 | 174 | ||
175 | if flags["server"] then | 175 | if flags["server"] then |
176 | if flags["server"] == true then | ||
177 | die("Argument error: use --server=<url>") | ||
178 | end | ||
179 | local protocol, path = dir.split_url(flags["server"]) | 176 | local protocol, path = dir.split_url(flags["server"]) |
180 | table.insert(cfg.rocks_servers, 1, protocol.."://"..path) | 177 | table.insert(cfg.rocks_servers, 1, protocol.."://"..path) |
181 | end | 178 | end |
182 | 179 | ||
183 | if flags["only-server"] then | 180 | if flags["only-server"] then |
184 | if flags["only-server"] == true then | ||
185 | die("Argument error: use --only-server=<url>") | ||
186 | end | ||
187 | cfg.rocks_servers = { flags["only-server"] } | 181 | cfg.rocks_servers = { flags["only-server"] } |
188 | end | 182 | end |
189 | 183 | ||
@@ -196,6 +190,10 @@ function command_line.run_command(...) | |||
196 | cfg.variables[k] = v | 190 | cfg.variables[k] = v |
197 | end | 191 | end |
198 | end | 192 | end |
193 | |||
194 | if not fs.current_dir() or fs.current_dir() == "" then | ||
195 | die("Current directory does not exist. Please run LuaRocks from an existing directory.") | ||
196 | end | ||
199 | 197 | ||
200 | if commands[command] then | 198 | if commands[command] then |
201 | -- TODO the interface of run should be modified, to receive the | 199 | -- TODO the interface of run should be modified, to receive the |
@@ -207,8 +205,8 @@ function command_line.run_command(...) | |||
207 | local cmd = require(commands[command]) | 205 | local cmd = require(commands[command]) |
208 | local xp, ok, err, exitcode = xpcall(function() return cmd.run(unpack(args)) end, function(err) | 206 | local xp, ok, err, exitcode = xpcall(function() return cmd.run(unpack(args)) end, function(err) |
209 | die(debug.traceback("LuaRocks "..cfg.program_version | 207 | die(debug.traceback("LuaRocks "..cfg.program_version |
210 | .." bug (please report at luarocks-developers@lists.sourceforge.net).\n" | 208 | .." bug (please report at https://github.com/keplerproject/luarocks/issues).\n" |
211 | ..err, 2)) | 209 | ..err, 2), cfg.errorcodes.CRASH) |
212 | end) | 210 | end) |
213 | if xp and (not ok) then | 211 | if xp and (not ok) then |
214 | die(err, exitcode) | 212 | die(err, exitcode) |
diff --git a/src/luarocks/config_cmd.lua b/src/luarocks/config_cmd.lua new file mode 100644 index 00000000..bf282a7a --- /dev/null +++ b/src/luarocks/config_cmd.lua | |||
@@ -0,0 +1,73 @@ | |||
1 | --- Module implementing the LuaRocks "config" command. | ||
2 | -- Queries information about the LuaRocks configuration. | ||
3 | local config_cmd = {} | ||
4 | |||
5 | local cfg = require("luarocks.cfg") | ||
6 | local util = require("luarocks.util") | ||
7 | local dir = require("luarocks.dir") | ||
8 | |||
9 | config_cmd.help_summary = "Query information about the LuaRocks configuration." | ||
10 | config_cmd.help_arguments = "<flag>" | ||
11 | config_cmd.help = [[ | ||
12 | --lua-incdir Path to Lua header files. | ||
13 | |||
14 | --lua-libdir Path to Lua library files. | ||
15 | |||
16 | --lua-ver Lua version (in major.minor format). e.g. 5.1 | ||
17 | |||
18 | --system-config Location of the system config file. | ||
19 | |||
20 | --user-config Location of the user config file. | ||
21 | |||
22 | --rock-trees Rocks trees in use. First the user tree, then the system tree. | ||
23 | ]] | ||
24 | |||
25 | local function config_file(conf) | ||
26 | print(dir.normalize(conf.file)) | ||
27 | if conf.ok then | ||
28 | return true | ||
29 | else | ||
30 | return nil, "file not found" | ||
31 | end | ||
32 | end | ||
33 | |||
34 | --- Driver function for "config" command. | ||
35 | -- @return boolean: True if succeeded, nil on errors. | ||
36 | function config_cmd.run(...) | ||
37 | local flags = util.parse_flags(...) | ||
38 | |||
39 | if flags["lua-incdir"] then | ||
40 | print(cfg.variables.LUA_INCDIR) | ||
41 | return true | ||
42 | end | ||
43 | if flags["lua-libdir"] then | ||
44 | print(cfg.variables.LUA_LIBDIR) | ||
45 | return true | ||
46 | end | ||
47 | if flags["lua-ver"] then | ||
48 | print(cfg.lua_version) | ||
49 | return true | ||
50 | end | ||
51 | local conf = cfg.which_config() | ||
52 | if flags["system-config"] then | ||
53 | return config_file(conf.system) | ||
54 | end | ||
55 | if flags["user-config"] then | ||
56 | return config_file(conf.user) | ||
57 | end | ||
58 | if flags["rock-trees"] then | ||
59 | for _, tree in ipairs(cfg.rocks_trees) do | ||
60 | if type(tree) == "string" then | ||
61 | util.printout(dir.normalize(tree)) | ||
62 | else | ||
63 | local name = tree.name and "\t"..tree.name or "" | ||
64 | util.printout(dir.normalize(tree.root)..name) | ||
65 | end | ||
66 | end | ||
67 | return true | ||
68 | end | ||
69 | |||
70 | return nil, "Please provide a flag for querying configuration values. "..util.see_help("config") | ||
71 | end | ||
72 | |||
73 | return config_cmd | ||
diff --git a/src/luarocks/deps.lua b/src/luarocks/deps.lua index 3f75f9be..812e6d18 100644 --- a/src/luarocks/deps.lua +++ b/src/luarocks/deps.lua | |||
@@ -247,12 +247,16 @@ end | |||
247 | function deps.show_dep(dep, internal) | 247 | function deps.show_dep(dep, internal) |
248 | assert(type(dep) == "table") | 248 | assert(type(dep) == "table") |
249 | assert(type(internal) == "boolean" or not internal) | 249 | assert(type(internal) == "boolean" or not internal) |
250 | 250 | ||
251 | local pretty = {} | 251 | if #dep.constraints > 0 then |
252 | for _, c in ipairs(dep.constraints) do | 252 | local pretty = {} |
253 | table.insert(pretty, c.op .. " " .. deps.show_version(c.version, internal)) | 253 | for _, c in ipairs(dep.constraints) do |
254 | table.insert(pretty, c.op .. " " .. deps.show_version(c.version, internal)) | ||
255 | end | ||
256 | return dep.name.." "..table.concat(pretty, ", ") | ||
257 | else | ||
258 | return dep.name | ||
254 | end | 259 | end |
255 | return dep.name.." "..table.concat(pretty, ", ") | ||
256 | end | 260 | end |
257 | 261 | ||
258 | --- A more lenient check for equivalence between versions. | 262 | --- A more lenient check for equivalence between versions. |
@@ -480,13 +484,13 @@ function deps.fulfill_dependencies(rockspec, deps_mode) | |||
480 | for _, dep in pairs(missing) do | 484 | for _, dep in pairs(missing) do |
481 | -- Double-check in case dependency was filled during recursion. | 485 | -- Double-check in case dependency was filled during recursion. |
482 | if not match_dep(dep, nil, deps_mode) then | 486 | if not match_dep(dep, nil, deps_mode) then |
483 | local rock = search.find_suitable_rock(dep) | 487 | local url, err = search.find_suitable_rock(dep) |
484 | if not rock then | 488 | if not url then |
485 | return nil, "Could not satisfy dependency: "..deps.show_dep(dep) | 489 | return nil, "Could not satisfy dependency "..deps.show_dep(dep)..": "..err |
486 | end | 490 | end |
487 | local ok, err, errcode = install.run(rock) | 491 | local ok, err, errcode = install.run(url, deps.deps_mode_to_flag(deps_mode)) |
488 | if not ok then | 492 | if not ok then |
489 | return nil, "Failed installing dependency: "..rock.." - "..err, errcode | 493 | return nil, "Failed installing dependency: "..url.." - "..err, errcode |
490 | end | 494 | end |
491 | end | 495 | end |
492 | end | 496 | end |
@@ -545,10 +549,11 @@ function deps.check_external_deps(rockspec, mode) | |||
545 | subdirs = cfg.runtime_external_deps_subdirs | 549 | subdirs = cfg.runtime_external_deps_subdirs |
546 | end | 550 | end |
547 | if rockspec.external_dependencies then | 551 | if rockspec.external_dependencies then |
548 | for name, files in pairs(rockspec.external_dependencies) do | 552 | for name, ext_files in util.sortedpairs(rockspec.external_dependencies) do |
549 | local ok = true | 553 | local ok = true |
550 | local failed_file = nil | 554 | local failed_files = {program = {}, header = {}, library = {}} |
551 | local failed_dirname = nil | 555 | local failed_dirname |
556 | local failed_testfile | ||
552 | for _, extdir in ipairs(cfg.external_deps_dirs) do | 557 | for _, extdir in ipairs(cfg.external_deps_dirs) do |
553 | ok = true | 558 | ok = true |
554 | local prefix = vars[name.."_DIR"] | 559 | local prefix = vars[name.."_DIR"] |
@@ -577,7 +582,7 @@ function deps.check_external_deps(rockspec, mode) | |||
577 | end | 582 | end |
578 | prefix = prefix.prefix | 583 | prefix = prefix.prefix |
579 | end | 584 | end |
580 | for dirname, dirdata in pairs(dirs) do | 585 | for dirname, dirdata in util.sortedpairs(dirs) do |
581 | local paths | 586 | local paths |
582 | local path_var_value = vars[name.."_"..dirname] | 587 | local path_var_value = vars[name.."_"..dirname] |
583 | if path_var_value then | 588 | if path_var_value then |
@@ -591,7 +596,7 @@ function deps.check_external_deps(rockspec, mode) | |||
591 | paths = { dir.path(prefix, dirdata.subdir) } | 596 | paths = { dir.path(prefix, dirdata.subdir) } |
592 | end | 597 | end |
593 | dirdata.dir = paths[1] | 598 | dirdata.dir = paths[1] |
594 | local file = files[dirdata.testfile] | 599 | local file = ext_files[dirdata.testfile] |
595 | if file then | 600 | if file then |
596 | local files = {} | 601 | local files = {} |
597 | if not file:match("%.") then | 602 | if not file:match("%.") then |
@@ -606,17 +611,23 @@ function deps.check_external_deps(rockspec, mode) | |||
606 | table.insert(files, file) | 611 | table.insert(files, file) |
607 | end | 612 | end |
608 | local found = false | 613 | local found = false |
609 | failed_file = nil | 614 | for _, f in ipairs(files) do |
610 | for _, f in pairs(files) do | 615 | |
611 | -- small convenience hack | 616 | -- small convenience hack |
612 | if f:match("%.so$") or f:match("%.dylib$") or f:match("%.dll$") then | 617 | if f:match("%.so$") or f:match("%.dylib$") or f:match("%.dll$") then |
613 | f = f:gsub("%.[^.]+$", "."..cfg.external_lib_extension) | 618 | f = f:gsub("%.[^.]+$", "."..cfg.external_lib_extension) |
614 | end | 619 | end |
620 | |||
621 | local pattern | ||
622 | if f:match("%*") then | ||
623 | pattern = f:gsub("%.", "%%."):gsub("%*", ".*") | ||
624 | f = "matching "..f | ||
625 | end | ||
626 | |||
615 | for _, d in ipairs(paths) do | 627 | for _, d in ipairs(paths) do |
616 | if f:match("%*") then | 628 | if pattern then |
617 | local replaced = f:gsub("%.", "%%."):gsub("%*", ".*") | ||
618 | for entry in fs.dir(d) do | 629 | for entry in fs.dir(d) do |
619 | if entry:match(replaced) then | 630 | if entry:match(pattern) then |
620 | found = true | 631 | found = true |
621 | break | 632 | break |
622 | end | 633 | end |
@@ -627,21 +638,18 @@ function deps.check_external_deps(rockspec, mode) | |||
627 | if found then | 638 | if found then |
628 | dirdata.dir = d | 639 | dirdata.dir = d |
629 | break | 640 | break |
641 | else | ||
642 | table.insert(failed_files[dirdata.testfile], f.." in "..d) | ||
630 | end | 643 | end |
631 | end | 644 | end |
632 | if found then | 645 | if found then |
633 | break | 646 | break |
634 | else | ||
635 | if failed_file then | ||
636 | failed_file = failed_file .. ", or " .. f | ||
637 | else | ||
638 | failed_file = f | ||
639 | end | ||
640 | end | 647 | end |
641 | end | 648 | end |
642 | if not found then | 649 | if not found then |
643 | ok = false | 650 | ok = false |
644 | failed_dirname = dirname | 651 | failed_dirname = dirname |
652 | failed_testfile = dirdata.testfile | ||
645 | break | 653 | break |
646 | end | 654 | end |
647 | end | 655 | end |
@@ -655,7 +663,20 @@ function deps.check_external_deps(rockspec, mode) | |||
655 | end | 663 | end |
656 | end | 664 | end |
657 | if not ok then | 665 | if not ok then |
658 | return nil, "Could not find expected file "..failed_file.." for "..name.." -- you may have to install "..name.." in your system and/or pass "..name.."_DIR or "..name.."_"..failed_dirname.." to the luarocks command. Example: luarocks install "..rockspec.name.." "..name.."_DIR=/usr/local", "dependency" | 666 | local lines = {"Could not find "..failed_testfile.." file for "..name} |
667 | |||
668 | local failed_paths = {} | ||
669 | for _, failed_file in ipairs(failed_files[failed_testfile]) do | ||
670 | if not failed_paths[failed_file] then | ||
671 | failed_paths[failed_file] = true | ||
672 | table.insert(lines, " No file "..failed_file) | ||
673 | end | ||
674 | end | ||
675 | |||
676 | table.insert(lines, "You may have to install "..name.." in your system and/or pass "..name.."_DIR or "..name.."_"..failed_dirname.." to the luarocks command.") | ||
677 | table.insert(lines, "Example: luarocks install "..rockspec.name.." "..name.."_DIR=/usr/local") | ||
678 | |||
679 | return nil, table.concat(lines, "\n"), "dependency" | ||
659 | end | 680 | end |
660 | end | 681 | end |
661 | end | 682 | end |
diff --git a/src/luarocks/doc.lua b/src/luarocks/doc.lua index 6dee1069..53ed0116 100644 --- a/src/luarocks/doc.lua +++ b/src/luarocks/doc.lua | |||
@@ -13,7 +13,7 @@ local fetch = require("luarocks.fetch") | |||
13 | local fs = require("luarocks.fs") | 13 | local fs = require("luarocks.fs") |
14 | local download = require("luarocks.download") | 14 | local download = require("luarocks.download") |
15 | 15 | ||
16 | doc.help_summary = "Shows documentation for an installed rock." | 16 | doc.help_summary = "Show documentation for an installed rock." |
17 | 17 | ||
18 | doc.help = [[ | 18 | doc.help = [[ |
19 | <argument> is an existing package name. | 19 | <argument> is an existing package name. |
@@ -21,7 +21,7 @@ Without any flags, tries to load the documentation | |||
21 | using a series of heuristics. | 21 | using a series of heuristics. |
22 | With these flags, return only the desired information: | 22 | With these flags, return only the desired information: |
23 | 23 | ||
24 | --homepage Open the home page of project. | 24 | --home Open the home page of project. |
25 | --list List documentation files only. | 25 | --list List documentation files only. |
26 | 26 | ||
27 | For more information about a rock, see the 'show' command. | 27 | For more information about a rock, see the 'show' command. |
@@ -75,7 +75,7 @@ function doc.run(...) | |||
75 | if not rockspec then return nil,err end | 75 | if not rockspec then return nil,err end |
76 | local descript = rockspec.description or {} | 76 | local descript = rockspec.description or {} |
77 | 77 | ||
78 | if flags["homepage"] then | 78 | if flags["home"] then |
79 | return show_homepage(descript.homepage, name, version) | 79 | return show_homepage(descript.homepage, name, version) |
80 | end | 80 | end |
81 | 81 | ||
diff --git a/src/luarocks/download.lua b/src/luarocks/download.lua index 74ed40e9..090f49aa 100644 --- a/src/luarocks/download.lua +++ b/src/luarocks/download.lua | |||
@@ -37,25 +37,23 @@ local function get_file(filename) | |||
37 | end | 37 | end |
38 | 38 | ||
39 | function download.download(arch, name, version, all) | 39 | function download.download(arch, name, version, all) |
40 | local results, err | ||
41 | local query = search.make_query(name, version) | 40 | local query = search.make_query(name, version) |
42 | if arch then query.arch = arch end | 41 | if arch then query.arch = arch end |
42 | local search_err | ||
43 | |||
43 | if all then | 44 | if all then |
44 | if name == "" then query.exact_name = false end | 45 | if name == "" then query.exact_name = false end |
45 | results = search.search_repos(query) | 46 | local results = search.search_repos(query) |
46 | else | 47 | local has_result = false |
47 | results, err = search.find_suitable_rock(query) | 48 | local all_ok = true |
48 | end | 49 | local any_err = "" |
49 | if type(results) == "string" then | 50 | for name, result in pairs(results) do |
50 | return get_file(results) | 51 | for version, items in pairs(result) do |
51 | elseif type(results) == "table" and next(results) then | 52 | for _, item in ipairs(items) do |
52 | if all then | 53 | -- Ignore provided rocks. |
53 | local all_ok = true | 54 | if item.arch ~= "installed" then |
54 | local any_err = "" | 55 | has_result = true |
55 | for name, result in pairs(results) do | 56 | local filename = path.make_url(item.repo, name, version, item.arch) |
56 | for version, versions in pairs(result) do | ||
57 | for _,items in pairs(versions) do | ||
58 | local filename = path.make_url(items.repo, name, version, items.arch) | ||
59 | local ok, err = get_file(filename) | 57 | local ok, err = get_file(filename) |
60 | if not ok then | 58 | if not ok then |
61 | all_ok = false | 59 | all_ok = false |
@@ -64,15 +62,20 @@ function download.download(arch, name, version, all) | |||
64 | end | 62 | end |
65 | end | 63 | end |
66 | end | 64 | end |
65 | end | ||
66 | |||
67 | if has_result then | ||
67 | return all_ok, any_err | 68 | return all_ok, any_err |
68 | else | 69 | end |
69 | util.printerr("Multiple search results were returned.") | 70 | else |
70 | util.title("Search results:") | 71 | local url |
71 | search.print_results(results) | 72 | url, search_err = search.find_suitable_rock(query) |
72 | return nil, "Please narrow your query or use --all." | 73 | if url then |
74 | return get_file(url) | ||
73 | end | 75 | end |
74 | end | 76 | end |
75 | return nil, "Could not find a result named "..name..(version and " "..version or "").."." | 77 | return nil, "Could not find a result named "..name..(version and " "..version or "").. |
78 | (search_err and ": "..search_err or ".") | ||
76 | end | 79 | end |
77 | 80 | ||
78 | --- Driver function for the "download" command. | 81 | --- Driver function for the "download" command. |
diff --git a/src/luarocks/fetch.lua b/src/luarocks/fetch.lua index 1d84b480..2c028771 100644 --- a/src/luarocks/fetch.lua +++ b/src/luarocks/fetch.lua | |||
@@ -37,11 +37,11 @@ function fetch.fetch_url(url, filename, cache) | |||
37 | if protocol == "file" then | 37 | if protocol == "file" then |
38 | return fs.absolute_name(pathname) | 38 | return fs.absolute_name(pathname) |
39 | elseif fetch.is_basic_protocol(protocol, true) then | 39 | elseif fetch.is_basic_protocol(protocol, true) then |
40 | local ok, filename = fs.download(url, filename, cache) | 40 | local ok, name = fs.download(url, filename, cache) |
41 | if not ok then | 41 | if not ok then |
42 | return nil, "Failed downloading "..url..(filename and " - "..filename or ""), "network" | 42 | return nil, "Failed downloading "..url..(filename and " - "..filename or ""), "network" |
43 | end | 43 | end |
44 | return filename | 44 | return name |
45 | else | 45 | else |
46 | return nil, "Unsupported protocol "..protocol | 46 | return nil, "Unsupported protocol "..protocol |
47 | end | 47 | end |
@@ -111,9 +111,15 @@ function fetch.find_base_dir(file, temp_dir, src_url, src_dir) | |||
111 | else | 111 | else |
112 | util.printerr("Directory "..inferred_dir.." not found") | 112 | util.printerr("Directory "..inferred_dir.." not found") |
113 | local files = fs.list_dir() | 113 | local files = fs.list_dir() |
114 | if files[1] and fs.is_dir(files[1]) then | 114 | if files then |
115 | util.printerr("Found "..files[1]) | 115 | table.sort(files) |
116 | found_dir = files[1] | 116 | for i,filename in ipairs(files) do |
117 | if fs.is_dir(filename) then | ||
118 | util.printerr("Found "..filename) | ||
119 | found_dir = filename | ||
120 | break | ||
121 | end | ||
122 | end | ||
117 | end | 123 | end |
118 | end | 124 | end |
119 | fs.pop_dir() | 125 | fs.pop_dir() |
@@ -164,8 +170,13 @@ function fetch.fetch_and_unpack_rock(rock_file, dest) | |||
164 | end | 170 | end |
165 | 171 | ||
166 | function fetch.url_to_base_dir(url) | 172 | function fetch.url_to_base_dir(url) |
173 | -- for extensions like foo.tar.gz, "gz" is stripped first | ||
174 | local known_exts = {} | ||
175 | for _, ext in ipairs{"zip", "git", "tgz", "tar", "gz", "bz2"} do | ||
176 | known_exts[ext] = "" | ||
177 | end | ||
167 | local base = dir.base_name(url) | 178 | local base = dir.base_name(url) |
168 | return base:gsub("%.[^.]*$", ""):gsub("%.tar$", "") | 179 | return (base:gsub("%.([^.]*)$", known_exts):gsub("%.tar", "")) |
169 | end | 180 | end |
170 | 181 | ||
171 | --- Back-end function that actually loads the local rockspec. | 182 | --- Back-end function that actually loads the local rockspec. |
@@ -187,9 +198,8 @@ function fetch.load_local_rockspec(filename, quick) | |||
187 | end | 198 | end |
188 | local globals = err | 199 | local globals = err |
189 | 200 | ||
190 | local ok, err = true, nil | ||
191 | if not quick then | 201 | if not quick then |
192 | ok, err = type_check.type_check_rockspec(rockspec, globals) | 202 | local ok, err = type_check.type_check_rockspec(rockspec, globals) |
193 | if not ok then | 203 | if not ok then |
194 | return nil, filename..": "..err | 204 | return nil, filename..": "..err |
195 | end | 205 | end |
@@ -313,9 +323,10 @@ function fetch.get_sources(rockspec, extract, dest_dir) | |||
313 | local url = rockspec.source.url | 323 | local url = rockspec.source.url |
314 | local name = rockspec.name.."-"..rockspec.version | 324 | local name = rockspec.name.."-"..rockspec.version |
315 | local filename = rockspec.source.file | 325 | local filename = rockspec.source.file |
316 | local source_file, store_dir, err, errcode | 326 | local source_file, store_dir |
327 | local ok, err, errcode | ||
317 | if dest_dir then | 328 | if dest_dir then |
318 | local ok, err = fs.change_dir(dest_dir) | 329 | ok, err = fs.change_dir(dest_dir) |
319 | if not ok then return nil, err, "dest_dir" end | 330 | if not ok then return nil, err, "dest_dir" end |
320 | source_file, err, errcode = fetch.fetch_url(url, filename) | 331 | source_file, err, errcode = fetch.fetch_url(url, filename) |
321 | fs.pop_dir() | 332 | fs.pop_dir() |
@@ -360,7 +371,7 @@ function fetch.fetch_sources(rockspec, extract, dest_dir) | |||
360 | local protocol = rockspec.source.protocol | 371 | local protocol = rockspec.source.protocol |
361 | local ok, proto | 372 | local ok, proto |
362 | if fetch.is_basic_protocol(protocol) then | 373 | if fetch.is_basic_protocol(protocol) then |
363 | proto = require("luarocks.fetch") | 374 | proto = fetch |
364 | else | 375 | else |
365 | ok, proto = pcall(require, "luarocks.fetch."..protocol:gsub("[+-]", "_")) | 376 | ok, proto = pcall(require, "luarocks.fetch."..protocol:gsub("[+-]", "_")) |
366 | if not ok then | 377 | if not ok then |
diff --git a/src/luarocks/fetch/cvs.lua b/src/luarocks/fetch/cvs.lua index cc9fd655..ccf928c4 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) | |||
20 | assert(type(rockspec) == "table") | 20 | assert(type(rockspec) == "table") |
21 | assert(type(dest_dir) == "string" or not dest_dir) | 21 | assert(type(dest_dir) == "string" or not dest_dir) |
22 | 22 | ||
23 | local cvs_cmd = rockspec.variables.CVS | ||
24 | local ok, err_msg = fs.is_tool_available(cvs_cmd, "CVS") | ||
25 | if not ok then | ||
26 | return nil, err_msg | ||
27 | end | ||
28 | |||
23 | local name_version = rockspec.name .. "-" .. rockspec.version | 29 | local name_version = rockspec.name .. "-" .. rockspec.version |
24 | local module = rockspec.source.module or dir.base_name(rockspec.source.url) | 30 | local module = rockspec.source.module or dir.base_name(rockspec.source.url) |
25 | local command = {rockspec.variables.CVS, "-d"..rockspec.source.pathname, "export", module} | 31 | local command = {cvs_cmd, "-d"..rockspec.source.pathname, "export", module} |
26 | if rockspec.source.tag then | 32 | if rockspec.source.tag then |
27 | table.insert(command, 4, "-r") | 33 | table.insert(command, 4, "-r") |
28 | table.insert(command, 5, rockspec.source.tag) | 34 | table.insert(command, 5, rockspec.source.tag) |
diff --git a/src/luarocks/fetch/git.lua b/src/luarocks/fetch/git.lua index 53fd4445..a635f190 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) | |||
40 | -- Strip off .git from base name if present | 40 | -- Strip off .git from base name if present |
41 | module = module:gsub("%.git$", "") | 41 | module = module:gsub("%.git$", "") |
42 | 42 | ||
43 | local ok, err_msg = fs.is_tool_available(git_cmd, "Git") | ||
44 | if not ok then | ||
45 | return nil, err_msg | ||
46 | end | ||
47 | |||
43 | local store_dir | 48 | local store_dir |
44 | if not dest_dir then | 49 | if not dest_dir then |
45 | store_dir = fs.make_temp_dir(name_version) | 50 | store_dir = fs.make_temp_dir(name_version) |
@@ -63,7 +68,7 @@ function git.get_sources(rockspec, extract, dest_dir, depth) | |||
63 | if git_can_clone_by_tag(git_cmd) then | 68 | if git_can_clone_by_tag(git_cmd) then |
64 | -- The argument to `--branch` can actually be a branch or a tag as of | 69 | -- The argument to `--branch` can actually be a branch or a tag as of |
65 | -- Git 1.7.10. | 70 | -- Git 1.7.10. |
66 | table.insert(command, 4, "--branch=" .. tag_or_branch) | 71 | table.insert(command, 3, "--branch=" .. tag_or_branch) |
67 | end | 72 | end |
68 | end | 73 | end |
69 | if not fs.execute(unpack(command)) then | 74 | 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 00000000..67f8ad6c --- /dev/null +++ b/src/luarocks/fetch/git_https.lua | |||
@@ -0,0 +1,7 @@ | |||
1 | --- Fetch back-end for retrieving sources from Git repositories | ||
2 | -- that use https:// transport. For example, for fetching a repository | ||
3 | -- that requires the following command line: | ||
4 | -- `git clone https://example.com/foo.git` | ||
5 | -- you can use this in the rockspec: | ||
6 | -- source = { url = "git+https://example.com/foo.git" } | ||
7 | return require "luarocks.fetch.git_http" | ||
diff --git a/src/luarocks/fetch/git_ssh.lua b/src/luarocks/fetch/git_ssh.lua new file mode 100644 index 00000000..0c2c0750 --- /dev/null +++ b/src/luarocks/fetch/git_ssh.lua | |||
@@ -0,0 +1,32 @@ | |||
1 | --- Fetch back-end for retrieving sources from Git repositories | ||
2 | -- that use ssh:// transport. For example, for fetching a repository | ||
3 | -- that requires the following command line: | ||
4 | -- `git clone ssh://git@example.com/path/foo.git | ||
5 | -- you can use this in the rockspec: | ||
6 | -- source = { url = "git+ssh://git@example.com/path/foo.git" } | ||
7 | -- It also handles scp-style ssh urls: git@example.com:path/foo.git, | ||
8 | -- but you have to prepend the "git+ssh://" and why not use the "newer" | ||
9 | -- style anyway? | ||
10 | local git_ssh = {} | ||
11 | |||
12 | local git = require("luarocks.fetch.git") | ||
13 | |||
14 | --- Fetch sources for building a rock from a local Git repository. | ||
15 | -- @param rockspec table: The rockspec table | ||
16 | -- @param extract boolean: Unused in this module (required for API purposes.) | ||
17 | -- @param dest_dir string or nil: If set, will extract to the given directory. | ||
18 | -- @return (string, string) or (nil, string): The absolute pathname of | ||
19 | -- the fetched source tarball and the temporary directory created to | ||
20 | -- store it; or nil and an error message. | ||
21 | function git_ssh.get_sources(rockspec, extract, dest_dir) | ||
22 | rockspec.source.url = rockspec.source.url:gsub("^git.", "") | ||
23 | |||
24 | -- Handle old-style scp-like git ssh urls | ||
25 | if rockspec.source.url:match("^ssh://[^/]+:[^%d]") then | ||
26 | rockspec.source.url = rockspec.source.url:gsub("^ssh://", "") | ||
27 | end | ||
28 | |||
29 | return git.get_sources(rockspec, extract, dest_dir, "--") | ||
30 | end | ||
31 | |||
32 | return git_ssh | ||
diff --git a/src/luarocks/fetch/hg.lua b/src/luarocks/fetch/hg.lua index b2ba56e9..518130b4 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) | |||
21 | assert(type(dest_dir) == "string" or not dest_dir) | 21 | assert(type(dest_dir) == "string" or not dest_dir) |
22 | 22 | ||
23 | local hg_cmd = rockspec.variables.HG | 23 | local hg_cmd = rockspec.variables.HG |
24 | local ok, err_msg = fs.is_tool_available(hg_cmd, "Mercurial") | ||
25 | if not ok then | ||
26 | return nil, err_msg | ||
27 | end | ||
28 | |||
24 | local name_version = rockspec.name .. "-" .. rockspec.version | 29 | local name_version = rockspec.name .. "-" .. rockspec.version |
25 | -- Strip off special hg:// protocol type | 30 | -- Strip off special hg:// protocol type |
26 | local url = rockspec.source.url:gsub("^hg://", "") | 31 | local url = rockspec.source.url:gsub("^hg://", "") |
27 | 32 | ||
28 | local module = dir.base_name(url) | 33 | local module = dir.base_name(url) |
29 | 34 | ||
30 | local command = {hg_cmd, "clone", url, module} | 35 | local command = {hg_cmd, "clone", url, module} |
31 | local tag_or_branch = rockspec.source.tag or rockspec.source.branch | 36 | local tag_or_branch = rockspec.source.tag or rockspec.source.branch |
32 | if tag_or_branch then | 37 | if tag_or_branch then |
33 | command = {hg_cmd, "clone", "--rev", url, module} | 38 | command = {hg_cmd, "clone", "--rev", tag_or_branch, url, module} |
34 | end | 39 | end |
35 | local store_dir | 40 | local store_dir |
36 | if not dest_dir then | 41 | 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 00000000..8f506daf --- /dev/null +++ b/src/luarocks/fetch/hg_http.lua | |||
@@ -0,0 +1,24 @@ | |||
1 | |||
2 | --- Fetch back-end for retrieving sources from hg repositories | ||
3 | -- that use http:// transport. For example, for fetching a repository | ||
4 | -- that requires the following command line: | ||
5 | -- `hg clone http://example.com/foo` | ||
6 | -- you can use this in the rockspec: | ||
7 | -- source = { url = "hg+http://example.com/foo" } | ||
8 | local hg_http = {} | ||
9 | |||
10 | local hg = require("luarocks.fetch.hg") | ||
11 | |||
12 | --- Download sources for building a rock, using hg over http. | ||
13 | -- @param rockspec table: The rockspec table | ||
14 | -- @param extract boolean: Unused in this module (required for API purposes.) | ||
15 | -- @param dest_dir string or nil: If set, will extract to the given directory. | ||
16 | -- @return (string, string) or (nil, string): The absolute pathname of | ||
17 | -- the fetched source tarball and the temporary directory created to | ||
18 | -- store it; or nil and an error message. | ||
19 | function hg_http.get_sources(rockspec, extract, dest_dir) | ||
20 | rockspec.source.url = rockspec.source.url:gsub("^hg.", "") | ||
21 | return hg.get_sources(rockspec, extract, dest_dir) | ||
22 | end | ||
23 | |||
24 | return hg_http | ||
diff --git a/src/luarocks/fetch/hg_https.lua b/src/luarocks/fetch/hg_https.lua new file mode 100644 index 00000000..e67417fe --- /dev/null +++ b/src/luarocks/fetch/hg_https.lua | |||
@@ -0,0 +1,8 @@ | |||
1 | |||
2 | --- Fetch back-end for retrieving sources from hg repositories | ||
3 | -- that use https:// transport. For example, for fetching a repository | ||
4 | -- that requires the following command line: | ||
5 | -- `hg clone https://example.com/foo` | ||
6 | -- you can use this in the rockspec: | ||
7 | -- source = { url = "hg+https://example.com/foo" } | ||
8 | 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 00000000..0c365fab --- /dev/null +++ b/src/luarocks/fetch/hg_ssh.lua | |||
@@ -0,0 +1,8 @@ | |||
1 | |||
2 | --- Fetch back-end for retrieving sources from hg repositories | ||
3 | -- that use ssh:// transport. For example, for fetching a repository | ||
4 | -- that requires the following command line: | ||
5 | -- `hg clone ssh://example.com/foo` | ||
6 | -- you can use this in the rockspec: | ||
7 | -- source = { url = "hg+ssh://example.com/foo" } | ||
8 | return require "luarocks.fetch.hg_http" | ||
diff --git a/src/luarocks/fetch/svn.lua b/src/luarocks/fetch/svn.lua index abeacf9a..755e5e32 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) | |||
21 | assert(type(dest_dir) == "string" or not dest_dir) | 21 | assert(type(dest_dir) == "string" or not dest_dir) |
22 | 22 | ||
23 | local svn_cmd = rockspec.variables.SVN | 23 | local svn_cmd = rockspec.variables.SVN |
24 | local ok, err_msg = fs.is_tool_available(svn_cmd, "--version", "Subversion") | ||
25 | if not ok then | ||
26 | return nil, err_msg | ||
27 | end | ||
28 | |||
24 | local name_version = rockspec.name .. "-" .. rockspec.version | 29 | local name_version = rockspec.name .. "-" .. rockspec.version |
25 | local module = rockspec.source.module or dir.base_name(rockspec.source.url) | 30 | local module = rockspec.source.module or dir.base_name(rockspec.source.url) |
26 | local url = rockspec.source.url:gsub("^svn://", "") | 31 | local url = rockspec.source.url:gsub("^svn://", "") |
diff --git a/src/luarocks/fs.lua b/src/luarocks/fs.lua index 72e11c09..57302c7f 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 | |||
31 | 31 | ||
32 | old_exec = os.execute | 32 | old_exec = os.execute |
33 | os.execute = function(cmd) | 33 | os.execute = function(cmd) |
34 | print("\nos.execute: ", cmd) | 34 | -- redact api keys if present |
35 | print("\nos.execute: ", (cmd:gsub("(/api/[^/]+/)([^/]+)/", function(cap, key) return cap.."<redacted>/" end)) ) | ||
35 | local code = pack(old_exec(cmd)) | 36 | local code = pack(old_exec(cmd)) |
36 | print("Results: "..tostring(code.n)) | 37 | print("Results: "..tostring(code.n)) |
37 | for i = 1,code.n do | 38 | for i = 1,code.n do |
diff --git a/src/luarocks/fs/lua.lua b/src/luarocks/fs/lua.lua index f18deac3..483b3e3c 100644 --- a/src/luarocks/fs/lua.lua +++ b/src/luarocks/fs/lua.lua | |||
@@ -28,8 +28,6 @@ local patch = require("luarocks.tools.patch") | |||
28 | 28 | ||
29 | local dir_stack = {} | 29 | local dir_stack = {} |
30 | 30 | ||
31 | math.randomseed(os.time()) | ||
32 | |||
33 | local dir_separator = "/" | 31 | local dir_separator = "/" |
34 | 32 | ||
35 | --- Quote argument for shell processing. | 33 | --- Quote argument for shell processing. |
@@ -67,23 +65,6 @@ function fs_lua.is_writable(file) | |||
67 | return result | 65 | return result |
68 | end | 66 | end |
69 | 67 | ||
70 | --- Create a temporary directory. | ||
71 | -- @param name string: name pattern to use for avoiding conflicts | ||
72 | -- when creating temporary directory. | ||
73 | -- @return string or (nil, string): name of temporary directory or (nil, error message) on failure. | ||
74 | function fs_lua.make_temp_dir(name) | ||
75 | assert(type(name) == "string") | ||
76 | name = dir.normalize(name) | ||
77 | |||
78 | local temp_dir = (os.getenv("TMP") or "/tmp") .. "/luarocks_" .. name:gsub(dir.separator, "_") .. "-" .. tostring(math.floor(math.random() * 10000)) | ||
79 | local ok, err = fs.make_dir(temp_dir) | ||
80 | if ok then | ||
81 | return temp_dir | ||
82 | else | ||
83 | return nil, err | ||
84 | end | ||
85 | end | ||
86 | |||
87 | local function quote_args(command, ...) | 68 | local function quote_args(command, ...) |
88 | local out = { command } | 69 | local out = { command } |
89 | for _, arg in ipairs({...}) do | 70 | for _, arg in ipairs({...}) do |
@@ -122,6 +103,27 @@ function fs_lua.execute_quiet(command, ...) | |||
122 | end | 103 | end |
123 | end | 104 | end |
124 | 105 | ||
106 | --- Checks if the given tool is available. | ||
107 | -- The tool is executed using a flag, usually just to ask its version. | ||
108 | -- @param tool_cmd string: The command to be used to check the tool's presence (e.g. hg in case of Mercurial) | ||
109 | -- @param tool_name string: The actual name of the tool (e.g. Mercurial) | ||
110 | -- @param arg string: The flag to pass to the tool. '--version' by default. | ||
111 | function fs_lua.is_tool_available(tool_cmd, tool_name, arg) | ||
112 | assert(type(tool_cmd) == "string") | ||
113 | assert(type(tool_name) == "string") | ||
114 | |||
115 | arg = arg or "--version" | ||
116 | assert(type(arg) == "string") | ||
117 | |||
118 | if not fs.execute_quiet(fs.Q(tool_cmd), arg) then | ||
119 | local msg = "'%s' program not found. Make sure %s is installed and is available in your PATH " .. | ||
120 | "(or you may want to edit the 'variables.%s' value in file '%s')" | ||
121 | return nil, msg:format(tool_cmd, tool_name, tool_name:upper(), cfg.which_config().nearest) | ||
122 | else | ||
123 | return true | ||
124 | end | ||
125 | end | ||
126 | |||
125 | --- Check the MD5 checksum for a file. | 127 | --- Check the MD5 checksum for a file. |
126 | -- @param file string: The file to be checked. | 128 | -- @param file string: The file to be checked. |
127 | -- @param md5sum string: The string with the expected MD5 checksum. | 129 | -- @param md5sum string: The string with the expected MD5 checksum. |
@@ -207,8 +209,13 @@ end | |||
207 | -- Allows leaving a directory (e.g. for deleting it) in | 209 | -- Allows leaving a directory (e.g. for deleting it) in |
208 | -- a crossplatform way. | 210 | -- a crossplatform way. |
209 | function fs_lua.change_dir_to_root() | 211 | function fs_lua.change_dir_to_root() |
210 | table.insert(dir_stack, lfs.currentdir()) | 212 | local current = lfs.currentdir() |
213 | if not current or current == "" then | ||
214 | return false | ||
215 | end | ||
216 | table.insert(dir_stack, current) | ||
211 | lfs.chdir("/") -- works on Windows too | 217 | lfs.chdir("/") -- works on Windows too |
218 | return true | ||
212 | end | 219 | end |
213 | 220 | ||
214 | --- Change working directory to the previous in the dir stack. | 221 | --- Change working directory to the previous in the dir stack. |
@@ -540,7 +547,7 @@ local redirect_protocols = { | |||
540 | local function request(url, method, http, loop_control) | 547 | local function request(url, method, http, loop_control) |
541 | local result = {} | 548 | local result = {} |
542 | 549 | ||
543 | local proxy = cfg.proxy | 550 | local proxy = cfg.http_proxy |
544 | if type(proxy) ~= "string" then proxy = nil end | 551 | if type(proxy) ~= "string" then proxy = nil end |
545 | -- LuaSocket's http.request crashes when given URLs missing the scheme part. | 552 | -- LuaSocket's http.request crashes when given URLs missing the scheme part. |
546 | if proxy and not proxy:find("://") then | 553 | if proxy and not proxy:find("://") then |
@@ -592,7 +599,7 @@ local function request(url, method, http, loop_control) | |||
592 | loop_control[url] = true | 599 | loop_control[url] = true |
593 | return request(location, method, redirect_protocols[protocol], loop_control) | 600 | return request(location, method, redirect_protocols[protocol], loop_control) |
594 | else | 601 | else |
595 | return nil, "URL redirected to unsupported protocol - install luasec to get HTTPS support." | 602 | return nil, "URL redirected to unsupported protocol - install luasec to get HTTPS support.", "https" |
596 | end | 603 | end |
597 | end | 604 | end |
598 | return nil, err | 605 | return nil, err |
@@ -614,7 +621,7 @@ local function http_request(url, http, cached) | |||
614 | return true | 621 | return true |
615 | end | 622 | end |
616 | if not result then | 623 | if not result then |
617 | return nil, status | 624 | return nil, status, headers |
618 | end | 625 | end |
619 | end | 626 | end |
620 | end | 627 | end |
@@ -629,10 +636,12 @@ local function http_request(url, http, cached) | |||
629 | end | 636 | end |
630 | return table.concat(result) | 637 | return table.concat(result) |
631 | else | 638 | else |
632 | return nil, status | 639 | return nil, status, headers |
633 | end | 640 | end |
634 | end | 641 | end |
635 | 642 | ||
643 | local downloader_warning = false | ||
644 | |||
636 | --- Download a remote file. | 645 | --- Download a remote file. |
637 | -- @param url string: URL to be fetched. | 646 | -- @param url string: URL to be fetched. |
638 | -- @param filename string or nil: this function attempts to detect the | 647 | -- @param filename string or nil: this function attempts to detect the |
@@ -646,21 +655,34 @@ function fs_lua.download(url, filename, cache) | |||
646 | assert(type(filename) == "string" or not filename) | 655 | assert(type(filename) == "string" or not filename) |
647 | 656 | ||
648 | filename = fs.absolute_name(filename or dir.base_name(url)) | 657 | filename = fs.absolute_name(filename or dir.base_name(url)) |
658 | |||
659 | -- delegate to the configured downloader so we don't have to deal with whitelists | ||
660 | if cfg.no_proxy then | ||
661 | return fs.use_downloader(url, filename, cache) | ||
662 | end | ||
649 | 663 | ||
650 | local content, err | 664 | local content, err, https_err |
651 | if util.starts_with(url, "http:") then | 665 | if util.starts_with(url, "http:") then |
652 | content, err = http_request(url, http, cache and filename) | 666 | content, err, https_err = http_request(url, http, cache and filename) |
653 | elseif util.starts_with(url, "ftp:") then | 667 | elseif util.starts_with(url, "ftp:") then |
654 | content, err = ftp.get(url) | 668 | content, err = ftp.get(url) |
655 | elseif util.starts_with(url, "https:") then | 669 | elseif util.starts_with(url, "https:") then |
656 | if luasec_ok then | 670 | -- skip LuaSec when proxy is enabled since it is not supported |
671 | if luasec_ok and not cfg.https_proxy then | ||
657 | content, err = http_request(url, https, cache and filename) | 672 | content, err = http_request(url, https, cache and filename) |
658 | else | 673 | else |
659 | err = "Unsupported protocol - install luasec to get HTTPS support." | 674 | https_err = true |
660 | end | 675 | end |
661 | else | 676 | else |
662 | err = "Unsupported protocol" | 677 | err = "Unsupported protocol" |
663 | end | 678 | end |
679 | if https_err then | ||
680 | if not downloader_warning then | ||
681 | util.printerr("Warning: falling back to "..cfg.downloader.." - install luasec to get native HTTPS support") | ||
682 | downloader_warning = true | ||
683 | end | ||
684 | return fs.use_downloader(url, filename, cache) | ||
685 | end | ||
664 | if cache and content == true then | 686 | if cache and content == true then |
665 | return true, filename | 687 | return true, filename |
666 | end | 688 | end |
@@ -674,6 +696,12 @@ function fs_lua.download(url, filename, cache) | |||
674 | return true, filename | 696 | return true, filename |
675 | end | 697 | end |
676 | 698 | ||
699 | else --...if socket_ok == false then | ||
700 | |||
701 | function fs_lua.download(url, filename, cache) | ||
702 | return fs.use_downloader(url, filename, cache) | ||
703 | end | ||
704 | |||
677 | end | 705 | end |
678 | --------------------------------------------------------------------- | 706 | --------------------------------------------------------------------- |
679 | -- MD5 functions | 707 | -- MD5 functions |
@@ -681,6 +709,14 @@ end | |||
681 | 709 | ||
682 | if md5_ok then | 710 | if md5_ok then |
683 | 711 | ||
712 | -- Support the interface of lmd5 by lhf in addition to md5 by Roberto | ||
713 | -- and the keplerproject. | ||
714 | if not md5.sumhexa and md5.digest then | ||
715 | md5.sumhexa = function(msg) | ||
716 | return md5.digest(msg) | ||
717 | end | ||
718 | end | ||
719 | |||
684 | --- Get the MD5 checksum for a file. | 720 | --- Get the MD5 checksum for a file. |
685 | -- @param file string: The file to be computed. | 721 | -- @param file string: The file to be computed. |
686 | -- @return string: The MD5 checksum or nil + error | 722 | -- @return string: The MD5 checksum or nil + error |
@@ -717,7 +753,7 @@ function fs_lua.chmod(file, mode) | |||
717 | -- LuaPosix (as of 5.1.15) does not support octal notation... | 753 | -- LuaPosix (as of 5.1.15) does not support octal notation... |
718 | if mode:sub(1,1) == "0" then | 754 | if mode:sub(1,1) == "0" then |
719 | local new_mode = {} | 755 | local new_mode = {} |
720 | for c in mode:sub(2):gmatch(".") do | 756 | for c in mode:sub(-3):gmatch(".") do |
721 | table.insert(new_mode, octal_to_rwx[c]) | 757 | table.insert(new_mode, octal_to_rwx[c]) |
722 | end | 758 | end |
723 | mode = table.concat(new_mode) | 759 | mode = table.concat(new_mode) |
@@ -730,6 +766,17 @@ function fs_lua.get_permissions(file) | |||
730 | return posix.stat(file, "mode") | 766 | return posix.stat(file, "mode") |
731 | end | 767 | end |
732 | 768 | ||
769 | --- Create a temporary directory. | ||
770 | -- @param name string: name pattern to use for avoiding conflicts | ||
771 | -- when creating temporary directory. | ||
772 | -- @return string or (nil, string): name of temporary directory or (nil, error message) on failure. | ||
773 | function fs_lua.make_temp_dir(name) | ||
774 | assert(type(name) == "string") | ||
775 | name = dir.normalize(name) | ||
776 | |||
777 | return posix.mkdtemp((os.getenv("TMPDIR") or "/tmp") .. "/luarocks_" .. name:gsub(dir.separator, "_") .. "-XXXXXX") | ||
778 | end | ||
779 | |||
733 | end | 780 | end |
734 | 781 | ||
735 | --------------------------------------------------------------------- | 782 | --------------------------------------------------------------------- |
@@ -786,10 +833,19 @@ function fs_lua.check_command_permissions(flags) | |||
786 | break | 833 | break |
787 | end | 834 | end |
788 | end | 835 | end |
789 | local root_parent = dir.dir_name(root_dir) | 836 | if ok and not fs.exists(root_dir) then |
790 | if ok and not fs.exists(root_dir) and not fs.is_writable(root_parent) then | 837 | local root = fs.root_of(root_dir) |
791 | ok = false | 838 | local parent = root_dir |
792 | err = root_dir.." does not exist and your user does not have write permissions in " .. root_parent | 839 | repeat |
840 | parent = dir.dir_name(parent) | ||
841 | if parent == "" then | ||
842 | parent = root | ||
843 | end | ||
844 | until parent == root or fs.exists(parent) | ||
845 | if not fs.is_writable(parent) then | ||
846 | ok = false | ||
847 | err = root_dir.." does not exist and your user does not have write permissions in " .. parent | ||
848 | end | ||
793 | end | 849 | end |
794 | if ok then | 850 | if ok then |
795 | return true | 851 | return true |
diff --git a/src/luarocks/fs/unix.lua b/src/luarocks/fs/unix.lua index a70ed116..570b26e4 100644 --- a/src/luarocks/fs/unix.lua +++ b/src/luarocks/fs/unix.lua | |||
@@ -9,8 +9,6 @@ local cfg = require("luarocks.cfg") | |||
9 | local dir = require("luarocks.dir") | 9 | local dir = require("luarocks.dir") |
10 | local util = require("luarocks.util") | 10 | local util = require("luarocks.util") |
11 | 11 | ||
12 | math.randomseed(os.time()) | ||
13 | |||
14 | --- Annotate command string for quiet execution. | 12 | --- Annotate command string for quiet execution. |
15 | -- @param cmd string: A command-line string. | 13 | -- @param cmd string: A command-line string. |
16 | -- @return string: The command-line, with silencing annotation. | 14 | -- @return string: The command-line, with silencing annotation. |
@@ -36,6 +34,14 @@ function unix.absolute_name(pathname, relative_to) | |||
36 | end | 34 | end |
37 | end | 35 | end |
38 | 36 | ||
37 | --- Return the root directory for the given path. | ||
38 | -- In Unix, root is always "/". | ||
39 | -- @param pathname string: pathname to use. | ||
40 | -- @return string: The root of the given pathname. | ||
41 | function unix.root_of(_) | ||
42 | return "/" | ||
43 | end | ||
44 | |||
39 | --- Create a wrapper to make a script executable from the command-line. | 45 | --- Create a wrapper to make a script executable from the command-line. |
40 | -- @param file string: Pathname of script to be made executable. | 46 | -- @param file string: Pathname of script to be made executable. |
41 | -- @param dest string: Directory where to put the wrapper. | 47 | -- @param dest string: Directory where to put the wrapper. |
@@ -107,4 +113,8 @@ function unix.replace_file(old_file, new_file) | |||
107 | return os.rename(new_file, old_file) | 113 | return os.rename(new_file, old_file) |
108 | end | 114 | end |
109 | 115 | ||
116 | function unix.tmpname() | ||
117 | return os.tmpname() | ||
118 | end | ||
119 | |||
110 | return unix | 120 | return unix |
diff --git a/src/luarocks/fs/unix/tools.lua b/src/luarocks/fs/unix/tools.lua index 69466931..ab55897e 100644 --- a/src/luarocks/fs/unix/tools.lua +++ b/src/luarocks/fs/unix/tools.lua | |||
@@ -12,7 +12,7 @@ local dir_stack = {} | |||
12 | local vars = cfg.variables | 12 | local vars = cfg.variables |
13 | 13 | ||
14 | local function command_at(directory, cmd) | 14 | local function command_at(directory, cmd) |
15 | return "cd " .. fs.Q(directory) .. " && " .. cmd | 15 | return "cd " .. fs.Q(fs.absolute_name(directory)) .. " && " .. cmd |
16 | end | 16 | end |
17 | 17 | ||
18 | --- Obtain current directory. | 18 | --- Obtain current directory. |
@@ -21,7 +21,7 @@ end | |||
21 | function tools.current_dir() | 21 | function tools.current_dir() |
22 | local current = cfg.cache_pwd | 22 | local current = cfg.cache_pwd |
23 | if not current then | 23 | if not current then |
24 | local pipe = io.popen(fs.Q(vars.PWD)) | 24 | local pipe = io.popen(fs.Q(vars.PWD).." 2> /dev/null") |
25 | current = pipe:read("*l") | 25 | current = pipe:read("*l") |
26 | pipe:close() | 26 | pipe:close() |
27 | cfg.cache_pwd = current | 27 | cfg.cache_pwd = current |
@@ -38,7 +38,9 @@ end | |||
38 | -- @return boolean: true if command succeeds (status code 0), false | 38 | -- @return boolean: true if command succeeds (status code 0), false |
39 | -- otherwise. | 39 | -- otherwise. |
40 | function tools.execute_string(cmd) | 40 | function tools.execute_string(cmd) |
41 | local code, err = os.execute(command_at(fs.current_dir(), cmd)) | 41 | local current = fs.current_dir() |
42 | if not current then return false end | ||
43 | local code, err = os.execute(command_at(current, cmd)) | ||
42 | if code == 0 or code == true then | 44 | if code == 0 or code == true then |
43 | return true | 45 | return true |
44 | else | 46 | else |
@@ -238,7 +240,7 @@ end | |||
238 | -- filename can be given explicitly as this second argument. | 240 | -- filename can be given explicitly as this second argument. |
239 | -- @return (boolean, string): true and the filename on success, | 241 | -- @return (boolean, string): true and the filename on success, |
240 | -- false and the error message on failure. | 242 | -- false and the error message on failure. |
241 | function tools.download(url, filename, cache) | 243 | function tools.use_downloader(url, filename, cache) |
242 | assert(type(url) == "string") | 244 | assert(type(url) == "string") |
243 | assert(type(filename) == "string" or not filename) | 245 | assert(type(filename) == "string" or not filename) |
244 | 246 | ||
@@ -246,7 +248,7 @@ function tools.download(url, filename, cache) | |||
246 | 248 | ||
247 | local ok | 249 | local ok |
248 | if cfg.downloader == "wget" then | 250 | if cfg.downloader == "wget" then |
249 | local wget_cmd = fs.Q(vars.WGET).." --no-check-certificate --no-cache --user-agent='"..cfg.user_agent.." via wget' --quiet " | 251 | local wget_cmd = fs.Q(vars.WGET).." "..vars.WGETNOCERTFLAG.." --no-cache --user-agent='"..cfg.user_agent.." via wget' --quiet " |
250 | if cfg.connection_timeout and cfg.connection_timeout > 0 then | 252 | if cfg.connection_timeout and cfg.connection_timeout > 0 then |
251 | wget_cmd = wget_cmd .. "--timeout="..tonumber(cfg.connection_timeout).." --tries=1 " | 253 | wget_cmd = wget_cmd .. "--timeout="..tonumber(cfg.connection_timeout).." --tries=1 " |
252 | end | 254 | end |
@@ -262,7 +264,7 @@ function tools.download(url, filename, cache) | |||
262 | ok = fs.execute_quiet(wget_cmd, url) | 264 | ok = fs.execute_quiet(wget_cmd, url) |
263 | end | 265 | end |
264 | elseif cfg.downloader == "curl" then | 266 | elseif cfg.downloader == "curl" then |
265 | local curl_cmd = fs.Q(vars.CURL).." -f -k -L --user-agent '"..cfg.user_agent.." via curl' " | 267 | local curl_cmd = fs.Q(vars.CURL).." "..vars.CURLNOCERTFLAG.." -f -L --user-agent '"..cfg.user_agent.." via curl' " |
266 | if cfg.connection_timeout and cfg.connection_timeout > 0 then | 268 | if cfg.connection_timeout and cfg.connection_timeout > 0 then |
267 | curl_cmd = curl_cmd .. "--connect-timeout "..tonumber(cfg.connection_timeout).." " | 269 | curl_cmd = curl_cmd .. "--connect-timeout "..tonumber(cfg.connection_timeout).." " |
268 | end | 270 | end |
@@ -283,12 +285,6 @@ function tools.chmod(pathname, mode) | |||
283 | end | 285 | end |
284 | end | 286 | end |
285 | 287 | ||
286 | --- Apply a patch. | ||
287 | -- @param patchname string: The filename of the patch. | ||
288 | function tools.apply_patch(patchname) | ||
289 | return fs.execute(vars.PATCH.." -p1 -f -i ", patchname) | ||
290 | end | ||
291 | |||
292 | --- Unpack an archive. | 288 | --- Unpack an archive. |
293 | -- Extract the contents of an archive, detecting its format by | 289 | -- Extract the contents of an archive, detecting its format by |
294 | -- filename extension. | 290 | -- filename extension. |
@@ -297,13 +293,19 @@ end | |||
297 | function tools.unpack_archive(archive) | 293 | function tools.unpack_archive(archive) |
298 | assert(type(archive) == "string") | 294 | assert(type(archive) == "string") |
299 | 295 | ||
296 | local pipe_to_tar = " | "..vars.TAR.." -xf -" | ||
297 | |||
298 | if not cfg.verbose then | ||
299 | pipe_to_tar = " 2> /dev/null"..fs.quiet(pipe_to_tar) | ||
300 | end | ||
301 | |||
300 | local ok | 302 | local ok |
301 | if archive:match("%.tar%.gz$") or archive:match("%.tgz$") then | 303 | if archive:match("%.tar%.gz$") or archive:match("%.tgz$") then |
302 | ok = fs.execute_string(vars.GUNZIP.." -c "..archive.."|"..vars.TAR.." -xf -") | 304 | ok = fs.execute_string(vars.GUNZIP.." -c "..fs.Q(archive)..pipe_to_tar) |
303 | elseif archive:match("%.tar%.bz2$") then | 305 | elseif archive:match("%.tar%.bz2$") then |
304 | ok = fs.execute_string(vars.BUNZIP2.." -c "..archive.."|tar -xf -") | 306 | ok = fs.execute_string(vars.BUNZIP2.." -c "..fs.Q(archive)..pipe_to_tar) |
305 | elseif archive:match("%.zip$") then | 307 | elseif archive:match("%.zip$") then |
306 | ok = fs.execute(vars.UNZIP, archive) | 308 | ok = fs.execute_quiet(vars.UNZIP, archive) |
307 | elseif archive:match("%.lua$") or archive:match("%.c$") then | 309 | elseif archive:match("%.lua$") or archive:match("%.c$") then |
308 | -- Ignore .lua and .c files; they don't need to be extracted. | 310 | -- Ignore .lua and .c files; they don't need to be extracted. |
309 | return true | 311 | return true |
@@ -350,4 +352,27 @@ function tools.browser(url) | |||
350 | return fs.execute(cfg.web_browser, url) | 352 | return fs.execute(cfg.web_browser, url) |
351 | end | 353 | end |
352 | 354 | ||
355 | function tools.set_time(file, time) | ||
356 | file = dir.normalize(file) | ||
357 | return fs.execute(vars.TOUCH, "-d", "@"..tostring(time), file) | ||
358 | end | ||
359 | |||
360 | --- Create a temporary directory. | ||
361 | -- @param name string: name pattern to use for avoiding conflicts | ||
362 | -- when creating temporary directory. | ||
363 | -- @return string or (nil, string): name of temporary directory or (nil, error message) on failure. | ||
364 | function tools.make_temp_dir(name) | ||
365 | assert(type(name) == "string") | ||
366 | name = dir.normalize(name) | ||
367 | |||
368 | local template = (os.getenv("TMPDIR") or "/tmp") .. "/luarocks_" .. name:gsub(dir.separator, "_") .. "-XXXXXX" | ||
369 | local pipe = io.popen(vars.MKTEMP.." -d "..fs.Q(template)) | ||
370 | local dirname = pipe:read("*l") | ||
371 | pipe:close() | ||
372 | if dirname and dirname:match("^/") then | ||
373 | return dirname | ||
374 | end | ||
375 | return nil, "Failed to create temporary directory "..tostring(dirname) | ||
376 | end | ||
377 | |||
353 | return tools | 378 | return tools |
diff --git a/src/luarocks/fs/win32.lua b/src/luarocks/fs/win32.lua index 238a25e9..c14c421b 100644 --- a/src/luarocks/fs/win32.lua +++ b/src/luarocks/fs/win32.lua | |||
@@ -10,6 +10,8 @@ local cfg = require("luarocks.cfg") | |||
10 | local dir = require("luarocks.dir") | 10 | local dir = require("luarocks.dir") |
11 | local util = require("luarocks.util") | 11 | local util = require("luarocks.util") |
12 | 12 | ||
13 | math.randomseed(os.time()) | ||
14 | |||
13 | -- Monkey patch io.popen and os.execute to make sure quoting | 15 | -- Monkey patch io.popen and os.execute to make sure quoting |
14 | -- works as expected. | 16 | -- works as expected. |
15 | -- See http://lua-users.org/lists/lua-l/2013-11/msg00367.html | 17 | -- See http://lua-users.org/lists/lua-l/2013-11/msg00367.html |
@@ -18,7 +20,6 @@ local _popen, _execute = io.popen, os.execute | |||
18 | io.popen = function(cmd, ...) return _popen(_prefix..cmd, ...) end | 20 | io.popen = function(cmd, ...) return _popen(_prefix..cmd, ...) end |
19 | os.execute = function(cmd, ...) return _execute(_prefix..cmd, ...) end | 21 | os.execute = function(cmd, ...) return _execute(_prefix..cmd, ...) end |
20 | 22 | ||
21 | |||
22 | --- Annotate command string for quiet execution. | 23 | --- Annotate command string for quiet execution. |
23 | -- @param cmd string: A command-line string. | 24 | -- @param cmd string: A command-line string. |
24 | -- @return string: The command-line, with silencing annotation. | 25 | -- @return string: The command-line, with silencing annotation. |
@@ -26,6 +27,7 @@ function win32.quiet(cmd) | |||
26 | return cmd.." 2> NUL 1> NUL" | 27 | return cmd.." 2> NUL 1> NUL" |
27 | end | 28 | end |
28 | 29 | ||
30 | local drive_letter = "[%.a-zA-Z]?:?[\\/]" | ||
29 | 31 | ||
30 | local win_escape_chars = { | 32 | local win_escape_chars = { |
31 | ["%"] = "%%", | 33 | ["%"] = "%%", |
@@ -47,7 +49,7 @@ end | |||
47 | function win32.Q(arg) | 49 | function win32.Q(arg) |
48 | assert(type(arg) == "string") | 50 | assert(type(arg) == "string") |
49 | -- Quote DIR for Windows | 51 | -- Quote DIR for Windows |
50 | if arg:match("^[%.a-zA-Z]?:?[\\/]") then | 52 | if arg:match("^"..drive_letter) then |
51 | arg = arg:gsub("/", "\\") | 53 | arg = arg:gsub("/", "\\") |
52 | end | 54 | end |
53 | if arg == "\\" then | 55 | if arg == "\\" then |
@@ -68,7 +70,7 @@ end | |||
68 | function win32.Qb(arg) | 70 | function win32.Qb(arg) |
69 | assert(type(arg) == "string") | 71 | assert(type(arg) == "string") |
70 | -- Quote DIR for Windows | 72 | -- Quote DIR for Windows |
71 | if arg:match("^[%.a-zA-Z]?:?[\\/]") then | 73 | if arg:match("^"..drive_letter) then |
72 | arg = arg:gsub("/", "\\") | 74 | arg = arg:gsub("/", "\\") |
73 | end | 75 | end |
74 | if arg == "\\" then | 76 | if arg == "\\" then |
@@ -92,15 +94,21 @@ function win32.absolute_name(pathname, relative_to) | |||
92 | assert(type(relative_to) == "string" or not relative_to) | 94 | assert(type(relative_to) == "string" or not relative_to) |
93 | 95 | ||
94 | relative_to = relative_to or fs.current_dir() | 96 | relative_to = relative_to or fs.current_dir() |
95 | -- FIXME I'm not sure this first \\ should be there at all. | 97 | if pathname:match("^"..drive_letter) then |
96 | -- What are the Windows rules for drive letters? | ||
97 | if pathname:match("^[\\.a-zA-Z]?:?[\\/]") then | ||
98 | return pathname | 98 | return pathname |
99 | else | 99 | else |
100 | return relative_to .. "/" .. pathname | 100 | return relative_to .. "/" .. pathname |
101 | end | 101 | end |
102 | end | 102 | end |
103 | 103 | ||
104 | --- Return the root directory for the given path. | ||
105 | -- For example, for "c:\hello", returns "c:\" | ||
106 | -- @param pathname string: pathname to use. | ||
107 | -- @return string: The root of the given pathname. | ||
108 | function win32.root_of(pathname) | ||
109 | return (fs.absolute_name(pathname):match("^("..drive_letter..")")) | ||
110 | end | ||
111 | |||
104 | --- Create a wrapper to make a script executable from the command-line. | 112 | --- Create a wrapper to make a script executable from the command-line. |
105 | -- @param file string: Pathname of script to be made executable. | 113 | -- @param file string: Pathname of script to be made executable. |
106 | -- @param dest string: Directory where to put the wrapper. | 114 | -- @param dest string: Directory where to put the wrapper. |
@@ -125,6 +133,7 @@ function win32.wrap_script(file, dest, name, version) | |||
125 | local ppaths = "package.path="..util.LQ(lpath..";").."..package.path; package.cpath="..util.LQ(lcpath..";").."..package.cpath" | 133 | local ppaths = "package.path="..util.LQ(lpath..";").."..package.path; package.cpath="..util.LQ(lcpath..";").."..package.cpath" |
126 | local addctx = "local k,l,_=pcall(require,"..util.LQ("luarocks.loader")..") _=k and l.add_context("..util.LQ(name)..","..util.LQ(version)..")" | 134 | local addctx = "local k,l,_=pcall(require,"..util.LQ("luarocks.loader")..") _=k and l.add_context("..util.LQ(name)..","..util.LQ(version)..")" |
127 | wrapper:write(fs.Qb(lua)..' -e '..fs.Qb(ppaths)..' -e '..fs.Qb(addctx)..' '..fs.Qb(file)..' %*\n') | 135 | wrapper:write(fs.Qb(lua)..' -e '..fs.Qb(ppaths)..' -e '..fs.Qb(addctx)..' '..fs.Qb(file)..' %*\n') |
136 | wrapper:write("exit /b %ERRORLEVEL%\n") | ||
128 | wrapper:close() | 137 | wrapper:close() |
129 | return true | 138 | return true |
130 | end | 139 | end |
@@ -214,4 +223,25 @@ function win32.is_writable(file) | |||
214 | return result | 223 | return result |
215 | end | 224 | end |
216 | 225 | ||
226 | --- Create a temporary directory. | ||
227 | -- @param name string: name pattern to use for avoiding conflicts | ||
228 | -- when creating temporary directory. | ||
229 | -- @return string or (nil, string): name of temporary directory or (nil, error message) on failure. | ||
230 | function win32.make_temp_dir(name) | ||
231 | assert(type(name) == "string") | ||
232 | name = dir.normalize(name) | ||
233 | |||
234 | local temp_dir = os.getenv("TMP") .. "/luarocks_" .. name:gsub(dir.separator, "_") .. "-" .. tostring(math.floor(math.random() * 10000)) | ||
235 | local ok, err = fs.make_dir(temp_dir) | ||
236 | if ok then | ||
237 | return temp_dir | ||
238 | else | ||
239 | return nil, err | ||
240 | end | ||
241 | end | ||
242 | |||
243 | function win32.tmpname() | ||
244 | return os.getenv("TMP")..os.tmpname() | ||
245 | end | ||
246 | |||
217 | return win32 | 247 | return win32 |
diff --git a/src/luarocks/fs/win32/tools.lua b/src/luarocks/fs/win32/tools.lua index a8b2a1db..b9dce85c 100644 --- a/src/luarocks/fs/win32/tools.lua +++ b/src/luarocks/fs/win32/tools.lua | |||
@@ -39,7 +39,7 @@ end | |||
39 | function tools.current_dir() | 39 | function tools.current_dir() |
40 | local current = cfg.cache_pwd | 40 | local current = cfg.cache_pwd |
41 | if not current then | 41 | if not current then |
42 | local pipe = io.popen(fs.Q(vars.PWD)) | 42 | local pipe = io.popen(fs.Q(vars.PWD).. " 2> NUL") |
43 | current = pipe:read("*l") | 43 | current = pipe:read("*l") |
44 | pipe:close() | 44 | pipe:close() |
45 | cfg.cache_pwd = current | 45 | cfg.cache_pwd = current |
@@ -56,7 +56,9 @@ end | |||
56 | -- @return boolean: true if command succeeds (status code 0), false | 56 | -- @return boolean: true if command succeeds (status code 0), false |
57 | -- otherwise. | 57 | -- otherwise. |
58 | function tools.execute_string(cmd) | 58 | function tools.execute_string(cmd) |
59 | cmd = command_at(fs.current_dir(), cmd) | 59 | local current = fs.current_dir() |
60 | if not current then return false end | ||
61 | cmd = command_at(current, cmd) | ||
60 | local code = os.execute(cmd) | 62 | local code = os.execute(cmd) |
61 | if code == 0 or code == true then | 63 | if code == 0 or code == true then |
62 | return true | 64 | return true |
@@ -149,7 +151,7 @@ end | |||
149 | -- plus an error message. | 151 | -- plus an error message. |
150 | function tools.copy_contents(src, dest) | 152 | function tools.copy_contents(src, dest) |
151 | assert(src and dest) | 153 | assert(src and dest) |
152 | if fs.execute_quiet(fs.Q(vars.CP).." -dR "..src.."\\*.* "..fs.Q(dest)) then | 154 | if fs.execute_quiet(fs.Q(vars.CP), "-dR", src.."\\*.*", dest) then |
153 | return true | 155 | return true |
154 | else | 156 | else |
155 | return false, "Failed copying "..src.." to "..dest | 157 | return false, "Failed copying "..src.." to "..dest |
@@ -248,7 +250,7 @@ end | |||
248 | -- filename can be given explicitly as this second argument. | 250 | -- filename can be given explicitly as this second argument. |
249 | -- @return (boolean, string): true and the filename on success, | 251 | -- @return (boolean, string): true and the filename on success, |
250 | -- false and the error message on failure. | 252 | -- false and the error message on failure. |
251 | function tools.download(url, filename, cache) | 253 | function tools.use_downloader(url, filename, cache) |
252 | assert(type(url) == "string") | 254 | assert(type(url) == "string") |
253 | assert(type(filename) == "string" or not filename) | 255 | assert(type(filename) == "string" or not filename) |
254 | 256 | ||
@@ -256,7 +258,7 @@ function tools.download(url, filename, cache) | |||
256 | 258 | ||
257 | local ok | 259 | local ok |
258 | if cfg.downloader == "wget" then | 260 | if cfg.downloader == "wget" then |
259 | local wget_cmd = fs.Q(vars.WGET).." --no-check-certificate --no-cache --user-agent=\""..cfg.user_agent.." via wget\" --quiet " | 261 | local wget_cmd = fs.Q(vars.WGET).." "..vars.WGETNOCERTFLAG.." --no-cache --user-agent=\""..cfg.user_agent.." via wget\" --quiet " |
260 | if cfg.connection_timeout and cfg.connection_timeout > 0 then | 262 | if cfg.connection_timeout and cfg.connection_timeout > 0 then |
261 | wget_cmd = wget_cmd .. "--timeout="..tonumber(cfg.connection_timeout).." --tries=1 " | 263 | wget_cmd = wget_cmd .. "--timeout="..tonumber(cfg.connection_timeout).." --tries=1 " |
262 | end | 264 | end |
@@ -272,7 +274,7 @@ function tools.download(url, filename, cache) | |||
272 | ok = fs.execute_quiet(wget_cmd, url) | 274 | ok = fs.execute_quiet(wget_cmd, url) |
273 | end | 275 | end |
274 | elseif cfg.downloader == "curl" then | 276 | elseif cfg.downloader == "curl" then |
275 | local curl_cmd = vars.CURL.." -f -k -L --user-agent \""..cfg.user_agent.." via curl\" " | 277 | local curl_cmd = fs.Q(vars.CURL).." "..vars.CURLNOCERTFLAG.." -f -L --user-agent \""..cfg.user_agent.." via curl\" " |
276 | if cfg.connection_timeout and cfg.connection_timeout > 0 then | 278 | if cfg.connection_timeout and cfg.connection_timeout > 0 then |
277 | curl_cmd = curl_cmd .. "--connect-timeout "..tonumber(cfg.connection_timeout).." " | 279 | curl_cmd = curl_cmd .. "--connect-timeout "..tonumber(cfg.connection_timeout).." " |
278 | end | 280 | end |
diff --git a/src/luarocks/help.lua b/src/luarocks/help.lua index 0a155509..5a2681a3 100644 --- a/src/luarocks/help.lua +++ b/src/luarocks/help.lua | |||
@@ -31,10 +31,8 @@ end | |||
31 | local function get_status(status) | 31 | local function get_status(status) |
32 | if status then | 32 | if status then |
33 | return "ok" | 33 | return "ok" |
34 | elseif status == false then | ||
35 | return "not found" | ||
36 | else | 34 | else |
37 | return "failed" | 35 | return "not found" |
38 | end | 36 | end |
39 | end | 37 | end |
40 | 38 | ||
@@ -47,7 +45,7 @@ function help.run(...) | |||
47 | local flags, command = util.parse_flags(...) | 45 | local flags, command = util.parse_flags(...) |
48 | 46 | ||
49 | if not command then | 47 | if not command then |
50 | local sys_file, sys_ok, home_file, home_ok = cfg.which_config() | 48 | local conf = cfg.which_config() |
51 | print_banner() | 49 | print_banner() |
52 | print_section("NAME") | 50 | print_section("NAME") |
53 | util.printout("\t"..program..[[ - ]]..program_description) | 51 | util.printout("\t"..program..[[ - ]]..program_description) |
@@ -83,9 +81,9 @@ function help.run(...) | |||
83 | print_section("CONFIGURATION") | 81 | print_section("CONFIGURATION") |
84 | util.printout("\tLua version: " .. cfg.lua_version) | 82 | util.printout("\tLua version: " .. cfg.lua_version) |
85 | util.printout("\tConfiguration files:") | 83 | util.printout("\tConfiguration files:") |
86 | util.printout("\t\tSystem: ".. dir.normalize(sys_file) .. " (" .. get_status(sys_ok) ..")") | 84 | util.printout("\t\tSystem: ".. dir.normalize(conf.system.file) .. " (" .. get_status(conf.system.ok) ..")") |
87 | if home_file then | 85 | if conf.user.file then |
88 | util.printout("\t\tUser : ".. dir.normalize(home_file) .. " (" .. get_status(home_ok) ..")\n") | 86 | util.printout("\t\tUser : ".. dir.normalize(conf.user.file) .. " (" .. get_status(conf.user.ok) ..")\n") |
89 | else | 87 | else |
90 | util.printout("\t\tUser : disabled in this LuaRocks installation.\n") | 88 | util.printout("\t\tUser : disabled in this LuaRocks installation.\n") |
91 | end | 89 | end |
@@ -100,7 +98,7 @@ function help.run(...) | |||
100 | end | 98 | end |
101 | else | 99 | else |
102 | command = command:gsub("-", "_") | 100 | command = command:gsub("-", "_") |
103 | local cmd = require(commands[command]) | 101 | local cmd = commands[command] and require(commands[command]) |
104 | if cmd then | 102 | if cmd then |
105 | local arguments = cmd.help_arguments or "<argument>" | 103 | local arguments = cmd.help_arguments or "<argument>" |
106 | print_banner() | 104 | print_banner() |
@@ -113,7 +111,7 @@ function help.run(...) | |||
113 | print_section("SEE ALSO") | 111 | print_section("SEE ALSO") |
114 | util.printout("","'"..program.." help' for general options and configuration.\n") | 112 | util.printout("","'"..program.." help' for general options and configuration.\n") |
115 | else | 113 | else |
116 | return nil, "Unknown command '"..command.."'" | 114 | return nil, "Unknown command: "..command |
117 | end | 115 | end |
118 | end | 116 | end |
119 | return true | 117 | return true |
diff --git a/src/luarocks/install.lua b/src/luarocks/install.lua index 7678c0cc..c938aa9f 100644 --- a/src/luarocks/install.lua +++ b/src/luarocks/install.lua | |||
@@ -26,6 +26,8 @@ or a filename of a locally available rock. | |||
26 | rock after installing a new one. This behavior can | 26 | rock after installing a new one. This behavior can |
27 | be made permanent by setting keep_other_versions=true | 27 | be made permanent by setting keep_other_versions=true |
28 | in the configuration file. | 28 | in the configuration file. |
29 | |||
30 | --only-deps Installs only the dependencies of the rock. | ||
29 | ]]..util.deps_mode_help() | 31 | ]]..util.deps_mode_help() |
30 | 32 | ||
31 | 33 | ||
@@ -109,6 +111,43 @@ function install.install_binary_rock(rock_file, deps_mode) | |||
109 | return name, version | 111 | return name, version |
110 | end | 112 | end |
111 | 113 | ||
114 | --- Installs the dependencies of a binary rock. | ||
115 | -- @param rock_file string: local or remote filename of a rock. | ||
116 | -- @param deps_mode: string: Which trees to check dependencies for: | ||
117 | -- "one" for the current default tree, "all" for all trees, | ||
118 | -- "order" for all trees with priority >= the current default, "none" for no trees. | ||
119 | -- @return (string, string) or (nil, string, [string]): Name and version of | ||
120 | -- the rock whose dependencies were installed if succeeded or nil and an error message | ||
121 | -- followed by an error code. | ||
122 | function install.install_binary_rock_deps(rock_file, deps_mode) | ||
123 | assert(type(rock_file) == "string") | ||
124 | |||
125 | local name, version, arch = path.parse_name(rock_file) | ||
126 | if not name then | ||
127 | return nil, "Filename "..rock_file.." does not match format 'name-version-revision.arch.rock'." | ||
128 | end | ||
129 | |||
130 | if arch ~= "all" and arch ~= cfg.arch then | ||
131 | return nil, "Incompatible architecture "..arch, "arch" | ||
132 | end | ||
133 | |||
134 | local ok, err, errcode = fetch.fetch_and_unpack_rock(rock_file, path.install_dir(name, version)) | ||
135 | if not ok then return nil, err, errcode end | ||
136 | |||
137 | local rockspec, err, errcode = fetch.load_rockspec(path.rockspec_file(name, version)) | ||
138 | if err then | ||
139 | return nil, "Failed loading rockspec for installed package: "..err, errcode | ||
140 | end | ||
141 | |||
142 | ok, err, errcode = deps.fulfill_dependencies(rockspec, deps_mode) | ||
143 | if err then return nil, err, errcode end | ||
144 | |||
145 | util.printout() | ||
146 | util.printout("Succesfully installed dependencies for " ..name.." "..version) | ||
147 | |||
148 | return name, version | ||
149 | end | ||
150 | |||
112 | --- Driver function for the "install" command. | 151 | --- Driver function for the "install" command. |
113 | -- @param name string: name of a binary rock. If an URL or pathname | 152 | -- @param name string: name of a binary rock. If an URL or pathname |
114 | -- to a binary rock is given, fetches and installs it. If a rockspec or a | 153 | -- to a binary rock is given, fetches and installs it. If a rockspec or a |
@@ -131,32 +170,28 @@ function install.run(...) | |||
131 | if name:match("%.rockspec$") or name:match("%.src%.rock$") then | 170 | if name:match("%.rockspec$") or name:match("%.src%.rock$") then |
132 | util.printout("Using "..name.."... switching to 'build' mode") | 171 | util.printout("Using "..name.."... switching to 'build' mode") |
133 | local build = require("luarocks.build") | 172 | local build = require("luarocks.build") |
134 | return build.run(name, util.forward_flags(flags, "local", "keep", "deps-mode")) | 173 | return build.run(name, util.forward_flags(flags, "local", "keep", "deps-mode", "only-deps")) |
135 | elseif name:match("%.rock$") then | 174 | elseif name:match("%.rock$") then |
136 | ok, err = install.install_binary_rock(name, deps.get_deps_mode(flags)) | 175 | if flags["only-deps"] then |
176 | ok, err = install.install_binary_rock_deps(name, deps.get_deps_mode(flags)) | ||
177 | else | ||
178 | ok, err = install.install_binary_rock(name, deps.get_deps_mode(flags)) | ||
179 | end | ||
137 | if not ok then return nil, err end | 180 | if not ok then return nil, err end |
138 | local name, version = ok, err | 181 | local name, version = ok, err |
139 | if (not flags["keep"]) and not cfg.keep_other_versions then | 182 | if (not flags["only-deps"]) and (not flags["keep"]) and not cfg.keep_other_versions then |
140 | local ok, err = remove.remove_other_versions(name, version, flags["force"]) | 183 | local ok, err = remove.remove_other_versions(name, version, flags["force"]) |
141 | if not ok then util.printerr(err) end | 184 | if not ok then util.printerr(err) end |
142 | end | 185 | end |
143 | return name, version | 186 | return name, version |
144 | else | 187 | else |
145 | local search = require("luarocks.search") | 188 | local search = require("luarocks.search") |
146 | local results, err = search.find_suitable_rock(search.make_query(name:lower(), version)) | 189 | local url, err = search.find_suitable_rock(search.make_query(name:lower(), version)) |
147 | if err then | 190 | if not url then |
148 | return nil, err | 191 | return nil, err |
149 | elseif type(results) == "string" then | ||
150 | local url = results | ||
151 | util.printout("Installing "..url.."...") | ||
152 | return install.run(url, util.forward_flags(flags)) | ||
153 | else | ||
154 | util.printout() | ||
155 | util.printerr("Could not determine which rock to install.") | ||
156 | util.title("Search results:") | ||
157 | search.print_results(results) | ||
158 | return nil, (next(results) and "Please narrow your query." or "No results found.") | ||
159 | end | 192 | end |
193 | util.printout("Installing "..url.."...") | ||
194 | return install.run(url, util.forward_flags(flags)) | ||
160 | end | 195 | end |
161 | end | 196 | end |
162 | 197 | ||
diff --git a/src/luarocks/list.lua b/src/luarocks/list.lua index 319909d3..99868028 100644 --- a/src/luarocks/list.lua +++ b/src/luarocks/list.lua | |||
@@ -6,33 +6,97 @@ local list = {} | |||
6 | package.loaded["luarocks.list"] = list | 6 | package.loaded["luarocks.list"] = list |
7 | 7 | ||
8 | local search = require("luarocks.search") | 8 | local search = require("luarocks.search") |
9 | local deps = require("luarocks.deps") | ||
9 | local cfg = require("luarocks.cfg") | 10 | local cfg = require("luarocks.cfg") |
10 | local util = require("luarocks.util") | 11 | local util = require("luarocks.util") |
11 | local path = require("luarocks.path") | 12 | local path = require("luarocks.path") |
12 | 13 | ||
13 | list.help_summary = "Lists currently installed rocks." | 14 | list.help_summary = "List currently installed rocks." |
14 | list.help_arguments = "[--porcelain] <filter>" | 15 | list.help_arguments = "[--porcelain] <filter>" |
15 | list.help = [[ | 16 | list.help = [[ |
16 | <filter> is a substring of a rock name to filter by. | 17 | <filter> is a substring of a rock name to filter by. |
17 | 18 | ||
19 | --outdated List only rocks for which there is a | ||
20 | higher version available in the rocks server. | ||
21 | |||
18 | --porcelain Produce machine-friendly output. | 22 | --porcelain Produce machine-friendly output. |
19 | ]] | 23 | ]] |
20 | 24 | ||
25 | local function check_outdated(trees, query) | ||
26 | local results_installed = {} | ||
27 | for _, tree in ipairs(trees) do | ||
28 | search.manifest_search(results_installed, path.rocks_dir(tree), query) | ||
29 | end | ||
30 | local outdated = {} | ||
31 | for name, versions in util.sortedpairs(results_installed) do | ||
32 | local latest_installed | ||
33 | local latest_available, latest_available_repo | ||
34 | |||
35 | for version, _ in util.sortedpairs(versions) do | ||
36 | latest_installed = version | ||
37 | break | ||
38 | end | ||
39 | |||
40 | local query_available = search.make_query(name:lower()) | ||
41 | query.exact_name = true | ||
42 | local results_available, err = search.search_repos(query_available) | ||
43 | |||
44 | if results_available[name] then | ||
45 | for version, repos in util.sortedpairs(results_available[name], deps.compare_versions) do | ||
46 | latest_available = version | ||
47 | for _, repo in ipairs(repos) do | ||
48 | latest_available_repo = repo.repo | ||
49 | break | ||
50 | end | ||
51 | break | ||
52 | end | ||
53 | |||
54 | if deps.compare_versions(latest_available, latest_installed) then | ||
55 | table.insert(outdated, { name = name, installed = latest_installed, available = latest_available, repo = latest_available_repo }) | ||
56 | end | ||
57 | end | ||
58 | end | ||
59 | return outdated | ||
60 | end | ||
61 | |||
62 | local function list_outdated(trees, query, porcelain) | ||
63 | util.title("Outdated rocks:", porcelain) | ||
64 | local outdated = check_outdated(trees, query) | ||
65 | for _, item in ipairs(outdated) do | ||
66 | if porcelain then | ||
67 | util.printout(item.name, item.installed, item.available, item.repo) | ||
68 | else | ||
69 | util.printout(item.name) | ||
70 | util.printout(" "..item.installed.." < "..item.available.." at "..item.repo) | ||
71 | util.printout() | ||
72 | end | ||
73 | end | ||
74 | return true | ||
75 | end | ||
76 | |||
21 | --- Driver function for "list" command. | 77 | --- Driver function for "list" command. |
22 | -- @param filter string or nil: A substring of a rock name to filter by. | 78 | -- @param filter string or nil: A substring of a rock name to filter by. |
23 | -- @param version string or nil: a version may also be passed. | 79 | -- @param version string or nil: a version may also be passed. |
24 | -- @return boolean: True if succeeded, nil on errors. | 80 | -- @return boolean: True if succeeded, nil on errors. |
25 | function list.run(...) | 81 | function list.run(...) |
26 | local flags, filter, version = util.parse_flags(...) | 82 | local flags, filter, version = util.parse_flags(...) |
27 | local results = {} | ||
28 | local query = search.make_query(filter and filter:lower() or "", version) | 83 | local query = search.make_query(filter and filter:lower() or "", version) |
29 | query.exact_name = false | 84 | query.exact_name = false |
30 | local trees = cfg.rocks_trees | 85 | local trees = cfg.rocks_trees |
31 | if flags["tree"] then | 86 | if flags["tree"] then |
32 | trees = { flags["tree"] } | 87 | trees = { flags["tree"] } |
33 | end | 88 | end |
89 | |||
90 | if flags["outdated"] then | ||
91 | return list_outdated(trees, query, flags["porcelain"]) | ||
92 | end | ||
93 | |||
94 | local results = {} | ||
34 | for _, tree in ipairs(trees) do | 95 | for _, tree in ipairs(trees) do |
35 | search.manifest_search(results, path.rocks_dir(tree), query) | 96 | local ok, err, errcode = search.manifest_search(results, path.rocks_dir(tree), query) |
97 | if not ok and errcode ~= "open" then | ||
98 | util.warning(err) | ||
99 | end | ||
36 | end | 100 | end |
37 | util.title("Installed rocks:", flags["porcelain"]) | 101 | util.title("Installed rocks:", flags["porcelain"]) |
38 | search.print_results(results, flags["porcelain"]) | 102 | search.print_results(results, flags["porcelain"]) |
diff --git a/src/luarocks/loader.lua b/src/luarocks/loader.lua index 3d36723f..26280e94 100644 --- a/src/luarocks/loader.lua +++ b/src/luarocks/loader.lua | |||
@@ -6,18 +6,21 @@ | |||
6 | -- used to load previous modules, so that the loader chooses versions | 6 | -- used to load previous modules, so that the loader chooses versions |
7 | -- that are declared to be compatible with the ones loaded earlier. | 7 | -- that are declared to be compatible with the ones loaded earlier. |
8 | local loaders = package.loaders or package.searchers | 8 | local loaders = package.loaders or package.searchers |
9 | local package, require, ipairs, pairs, table, type, next, tostring, error = | 9 | local package, require, ipairs, table, type, next, tostring, error = |
10 | package, require, ipairs, pairs, table, type, next, tostring, error | 10 | package, require, ipairs, table, type, next, tostring, error |
11 | local unpack = unpack or table.unpack | 11 | local unpack = unpack or table.unpack |
12 | 12 | ||
13 | --module("luarocks.loader") | 13 | --module("luarocks.loader") |
14 | local loader = {} | 14 | local loader = {} |
15 | package.loaded["luarocks.loader"] = loader | 15 | package.loaded["luarocks.loader"] = loader |
16 | 16 | ||
17 | local cfg = require("luarocks.cfg") | ||
18 | cfg.init_package_paths() | ||
19 | |||
17 | local path = require("luarocks.path") | 20 | local path = require("luarocks.path") |
18 | local manif_core = require("luarocks.manif_core") | 21 | local manif_core = require("luarocks.manif_core") |
19 | local deps = require("luarocks.deps") | 22 | local deps = require("luarocks.deps") |
20 | local cfg = require("luarocks.cfg") | 23 | local util = require("luarocks.util") |
21 | 24 | ||
22 | loader.context = {} | 25 | loader.context = {} |
23 | 26 | ||
@@ -77,7 +80,7 @@ function loader.add_context(name, version) | |||
77 | for _, tree in ipairs(loader.rocks_trees) do | 80 | for _, tree in ipairs(loader.rocks_trees) do |
78 | local entries = tree.manifest.repository[pkg] | 81 | local entries = tree.manifest.repository[pkg] |
79 | if entries then | 82 | if entries then |
80 | for version, pkgs in pairs(entries) do | 83 | for version, pkgs in util.sortedpairs(entries, deps.compare_versions) do |
81 | if (not constraints) or deps.match_constraints(deps.parse_version(version), constraints) then | 84 | if (not constraints) or deps.match_constraints(deps.parse_version(version), constraints) then |
82 | loader.add_context(pkg, version) | 85 | loader.add_context(pkg, version) |
83 | end | 86 | end |
@@ -123,16 +126,17 @@ end | |||
123 | 126 | ||
124 | --- Search for a module in the rocks trees | 127 | --- Search for a module in the rocks trees |
125 | -- @param module string: module name (eg. "socket.core") | 128 | -- @param module string: module name (eg. "socket.core") |
126 | -- @param filter_module_name function(string, string, string, string, number): | 129 | -- @param filter_file_name function(string, string, string, string, number): |
127 | -- a function that takes the module name (eg "socket.core"), the rock name | 130 | -- a function that takes the module file name (eg "socket/core.so"), the rock name |
128 | -- (eg "luasocket"), the version (eg "2.0.2-1"), the path of the rocks tree | 131 | -- (eg "luasocket"), the version (eg "2.0.2-1"), the path of the rocks tree |
129 | -- (eg "/usr/local"), and the numeric index of the matching entry, so the | 132 | -- (eg "/usr/local"), and the numeric index of the matching entry, so the |
130 | -- filter function can know if the matching module was the first entry or not. | 133 | -- filter function can know if the matching module was the first entry or not. |
131 | -- @return string, string, string: name of the rock containing the module | 134 | -- @return string, string, string, (string or table): |
132 | -- (eg. "luasocket"), version of the rock (eg. "2.0.2-1"), | 135 | -- * name of the rock containing the module (eg. "luasocket") |
133 | -- name of the module (eg. "socket.core", or "socket.core_2_0_2" if file is | 136 | -- * version of the rock (eg. "2.0.2-1") |
134 | -- stored versioned). | 137 | -- * return value of filter_file_name |
135 | local function select_module(module, filter_module_name) | 138 | -- * tree of the module (string or table in `rocks_trees` format) |
139 | local function select_module(module, filter_file_name) | ||
136 | --assert(type(module) == "string") | 140 | --assert(type(module) == "string") |
137 | --assert(type(filter_module_name) == "function") | 141 | --assert(type(filter_module_name) == "function") |
138 | 142 | ||
@@ -146,16 +150,16 @@ local function select_module(module, filter_module_name) | |||
146 | if entries then | 150 | if entries then |
147 | for i, entry in ipairs(entries) do | 151 | for i, entry in ipairs(entries) do |
148 | local name, version = entry:match("^([^/]*)/(.*)$") | 152 | local name, version = entry:match("^([^/]*)/(.*)$") |
149 | local module_name = tree.manifest.repository[name][version][1].modules[module] | 153 | local file_name = tree.manifest.repository[name][version][1].modules[module] |
150 | if type(module_name) ~= "string" then | 154 | if type(file_name) ~= "string" then |
151 | error("Invalid data in manifest file for module "..tostring(module).." (invalid data for "..tostring(name).." "..tostring(version)..")") | 155 | error("Invalid data in manifest file for module "..tostring(module).." (invalid data for "..tostring(name).." "..tostring(version)..")") |
152 | end | 156 | end |
153 | module_name = filter_module_name(module_name, name, version, tree.tree, i) | 157 | file_name = filter_file_name(file_name, name, version, tree.tree, i) |
154 | if loader.context[name] == version then | 158 | if loader.context[name] == version then |
155 | return name, version, module_name | 159 | return name, version, file_name |
156 | end | 160 | end |
157 | version = deps.parse_version(version) | 161 | version = deps.parse_version(version) |
158 | table.insert(providers, {name = name, version = version, module_name = module_name}) | 162 | table.insert(providers, {name = name, version = version, module_name = file_name, tree = tree}) |
159 | end | 163 | end |
160 | end | 164 | end |
161 | end | 165 | end |
@@ -163,24 +167,24 @@ local function select_module(module, filter_module_name) | |||
163 | if next(providers) then | 167 | if next(providers) then |
164 | table.sort(providers, sort_versions) | 168 | table.sort(providers, sort_versions) |
165 | local first = providers[1] | 169 | local first = providers[1] |
166 | return first.name, first.version.string, first.module_name | 170 | return first.name, first.version.string, first.module_name, first.tree |
167 | end | 171 | end |
168 | end | 172 | end |
169 | 173 | ||
170 | --- Search for a module | 174 | --- Search for a module |
171 | -- @param module string: module name (eg. "socket.core") | 175 | -- @param module string: module name (eg. "socket.core") |
172 | -- @return string, string, string: name of the rock containing the module | 176 | -- @return string, string, string, (string or table): |
173 | -- (eg. "luasocket"), version of the rock (eg. "2.0.2-1"), | 177 | -- * name of the rock containing the module (eg. "luasocket") |
174 | -- name of the module (eg. "socket.core", or "socket.core_2_0_2" if file is | 178 | -- * version of the rock (eg. "2.0.2-1") |
175 | -- stored versioned). | 179 | -- * name of the module (eg. "socket.core", or "socket.core_2_0_2" if file is stored versioned). |
180 | -- * tree of the module (string or table in `rocks_trees` format) | ||
176 | local function pick_module(module) | 181 | local function pick_module(module) |
177 | return | 182 | return |
178 | select_module(module, function(module_name, name, version, tree, i) | 183 | select_module(module, function(file_name, name, version, tree, i) |
179 | if i > 1 then | 184 | if i > 1 then |
180 | module_name = path.versioned_name(module_name, "", name, version) | 185 | file_name = path.versioned_name(file_name, "", name, version) |
181 | end | 186 | end |
182 | module_name = path.path_to_module(module_name) | 187 | return path.path_to_module(file_name) |
183 | return module_name | ||
184 | end) | 188 | end) |
185 | end | 189 | end |
186 | 190 | ||
@@ -188,8 +192,8 @@ end | |||
188 | -- @param module string: module name (eg. "socket.core") | 192 | -- @param module string: module name (eg. "socket.core") |
189 | -- @return string: filename of the module (eg. "/usr/local/lib/lua/5.1/socket/core.so") | 193 | -- @return string: filename of the module (eg. "/usr/local/lib/lua/5.1/socket/core.so") |
190 | function loader.which(module) | 194 | function loader.which(module) |
191 | local name, version, module_name = select_module(module, path.which_i) | 195 | local _, _, file_name = select_module(module, path.which_i) |
192 | return module_name | 196 | return file_name |
193 | end | 197 | end |
194 | 198 | ||
195 | --- Package loader for LuaRocks support. | 199 | --- Package loader for LuaRocks support. |
diff --git a/src/luarocks/make.lua b/src/luarocks/make.lua index 1dfe6473..94cf4414 100644 --- a/src/luarocks/make.lua +++ b/src/luarocks/make.lua | |||
@@ -9,6 +9,8 @@ package.loaded["luarocks.make"] = make | |||
9 | 9 | ||
10 | local build = require("luarocks.build") | 10 | local build = require("luarocks.build") |
11 | local fs = require("luarocks.fs") | 11 | local fs = require("luarocks.fs") |
12 | local dir = require("luarocks.dir") | ||
13 | local path = require("luarocks.path") | ||
12 | local util = require("luarocks.util") | 14 | local util = require("luarocks.util") |
13 | local cfg = require("luarocks.cfg") | 15 | local cfg = require("luarocks.cfg") |
14 | local fetch = require("luarocks.fetch") | 16 | local fetch = require("luarocks.fetch") |
@@ -22,8 +24,11 @@ make.help = [[ | |||
22 | Builds sources in the current directory, but unlike "build", | 24 | Builds sources in the current directory, but unlike "build", |
23 | it does not fetch sources, etc., assuming everything is | 25 | it does not fetch sources, etc., assuming everything is |
24 | available in the current directory. If no argument is given, | 26 | available in the current directory. If no argument is given, |
25 | look for a rockspec in the current directory. If more than one | 27 | it looks for a rockspec in the current directory and in "rockspec/" |
26 | is found, you must specify which to use, through the command-line. | 28 | and "rockspecs/" subdirectories, picking the rockspec with newest version |
29 | or without version name. If rockspecs for different rocks are found | ||
30 | or there are several rockspecs without version, you must specify which to use, | ||
31 | through the command-line. | ||
27 | 32 | ||
28 | This command is useful as a tool for debugging rockspecs. | 33 | This command is useful as a tool for debugging rockspecs. |
29 | To install rocks, you'll normally want to use the "install" and | 34 | To install rocks, you'll normally want to use the "install" and |
@@ -44,6 +49,33 @@ To install rocks, you'll normally want to use the "install" and | |||
44 | 49 | ||
45 | ]] | 50 | ]] |
46 | 51 | ||
52 | --- Collect rockspecs located in a subdirectory. | ||
53 | -- @param versions table: A table mapping rock names to newest rockspec versions. | ||
54 | -- @param paths table: A table mapping rock names to newest rockspec paths. | ||
55 | -- @param unnamed_paths table: An array of rockspec paths that don't contain rock | ||
56 | -- name and version in regular format. | ||
57 | -- @param subdir string: path to subdirectory. | ||
58 | local function collect_rockspecs(versions, paths, unnamed_paths, subdir) | ||
59 | if fs.is_dir(subdir) then | ||
60 | for file in fs.dir(subdir) do | ||
61 | file = dir.path(subdir, file) | ||
62 | |||
63 | if file:match("rockspec$") and fs.is_file(file) then | ||
64 | local rock, version = path.parse_name(file) | ||
65 | |||
66 | if rock then | ||
67 | if not versions[rock] or deps.compare_versions(version, versions[rock]) then | ||
68 | versions[rock] = version | ||
69 | paths[rock] = file | ||
70 | end | ||
71 | else | ||
72 | table.insert(unnamed_paths, file) | ||
73 | end | ||
74 | end | ||
75 | end | ||
76 | end | ||
77 | end | ||
78 | |||
47 | --- Driver function for "make" command. | 79 | --- Driver function for "make" command. |
48 | -- @param name string: A local rockspec. | 80 | -- @param name string: A local rockspec. |
49 | -- @return boolean or (nil, string, exitcode): True if build was successful; nil and an | 81 | -- @return boolean or (nil, string, exitcode): True if build was successful; nil and an |
@@ -53,18 +85,35 @@ function make.run(...) | |||
53 | assert(type(rockspec) == "string" or not rockspec) | 85 | assert(type(rockspec) == "string" or not rockspec) |
54 | 86 | ||
55 | if not rockspec then | 87 | if not rockspec then |
56 | for file in fs.dir() do | 88 | -- Try to infer default rockspec name. |
57 | if file:match("rockspec$") then | 89 | local versions, paths, unnamed_paths = {}, {}, {} |
58 | if rockspec then | 90 | -- Look for rockspecs in some common locations. |
91 | collect_rockspecs(versions, paths, unnamed_paths, ".") | ||
92 | collect_rockspecs(versions, paths, unnamed_paths, "rockspec") | ||
93 | collect_rockspecs(versions, paths, unnamed_paths, "rockspecs") | ||
94 | |||
95 | if #unnamed_paths > 0 then | ||
96 | -- There are rockspecs not following "name-version.rockspec" format. | ||
97 | -- More than one are ambiguous. | ||
98 | if #unnamed_paths > 1 then | ||
99 | return nil, "Please specify which rockspec file to use." | ||
100 | else | ||
101 | rockspec = unnamed_paths[1] | ||
102 | end | ||
103 | else | ||
104 | local rock = next(versions) | ||
105 | |||
106 | if rock then | ||
107 | -- If there are rockspecs for multiple rocks it's ambiguous. | ||
108 | if next(versions, rock) then | ||
59 | return nil, "Please specify which rockspec file to use." | 109 | return nil, "Please specify which rockspec file to use." |
60 | else | 110 | else |
61 | rockspec = file | 111 | rockspec = paths[rock] |
62 | end | 112 | end |
113 | else | ||
114 | return nil, "Argument missing: please specify a rockspec to use on current directory." | ||
63 | end | 115 | end |
64 | end | 116 | end |
65 | if not rockspec then | ||
66 | return nil, "Argument missing: please specify a rockspec to use on current directory." | ||
67 | end | ||
68 | end | 117 | end |
69 | if not rockspec:match("rockspec$") then | 118 | if not rockspec:match("rockspec$") then |
70 | return nil, "Invalid argument: 'make' takes a rockspec as a parameter. "..util.see_help("make") | 119 | return nil, "Invalid argument: 'make' takes a rockspec as a parameter. "..util.see_help("make") |
diff --git a/src/luarocks/manif.lua b/src/luarocks/manif.lua index f1d1629c..05621315 100644 --- a/src/luarocks/manif.lua +++ b/src/luarocks/manif.lua | |||
@@ -105,18 +105,22 @@ end | |||
105 | -- All functions that use manifest tables assume they were obtained | 105 | -- All functions that use manifest tables assume they were obtained |
106 | -- through either this function or load_local_manifest. | 106 | -- through either this function or load_local_manifest. |
107 | -- @param repo_url string: URL or pathname for the repository. | 107 | -- @param repo_url string: URL or pathname for the repository. |
108 | -- @param lua_version string: Lua version in "5.x" format, defaults to installed version. | ||
108 | -- @return table or (nil, string, [string]): A table representing the manifest, | 109 | -- @return table or (nil, string, [string]): A table representing the manifest, |
109 | -- or nil followed by an error message and an optional error code. | 110 | -- or nil followed by an error message and an optional error code. |
110 | function manif.load_manifest(repo_url) | 111 | function manif.load_manifest(repo_url, lua_version) |
111 | assert(type(repo_url) == "string") | 112 | assert(type(repo_url) == "string") |
113 | assert(type(lua_version) == "string" or not lua_version) | ||
114 | lua_version = lua_version or cfg.lua_version | ||
112 | 115 | ||
113 | if manif_core.manifest_cache[repo_url] then | 116 | local cached_manifest = manif_core.get_cached_manifest(repo_url, lua_version) |
114 | return manif_core.manifest_cache[repo_url] | 117 | if cached_manifest then |
118 | return cached_manifest | ||
115 | end | 119 | end |
116 | 120 | ||
117 | local filenames = { | 121 | local filenames = { |
118 | "manifest-"..cfg.lua_version..".zip", | 122 | "manifest-"..lua_version..".zip", |
119 | "manifest-"..cfg.lua_version, | 123 | "manifest-"..lua_version, |
120 | "manifest", | 124 | "manifest", |
121 | } | 125 | } |
122 | 126 | ||
@@ -156,7 +160,7 @@ function manif.load_manifest(repo_url) | |||
156 | end | 160 | end |
157 | pathname = nozip | 161 | pathname = nozip |
158 | end | 162 | end |
159 | return manif_core.manifest_loader(pathname, repo_url) | 163 | return manif_core.manifest_loader(pathname, repo_url, lua_version) |
160 | end | 164 | end |
161 | 165 | ||
162 | --- Output a table listing items of a package. | 166 | --- Output a table listing items of a package. |
@@ -381,7 +385,7 @@ function manif.make_manifest(repo, deps_mode, remote) | |||
381 | local results = search.disk_search(repo, query) | 385 | local results = search.disk_search(repo, query) |
382 | local manifest = { repository = {}, modules = {}, commands = {} } | 386 | local manifest = { repository = {}, modules = {}, commands = {} } |
383 | 387 | ||
384 | manif_core.manifest_cache[repo] = manifest | 388 | manif_core.cache_manifest(repo, nil, manifest) |
385 | 389 | ||
386 | local dep_handler = nil | 390 | local dep_handler = nil |
387 | if not remote then | 391 | if not remote then |
@@ -414,7 +418,7 @@ end | |||
414 | -- @param name string: Name of a package from the repository. | 418 | -- @param name string: Name of a package from the repository. |
415 | -- @param version string: Version of a package from the repository. | 419 | -- @param version string: Version of a package from the repository. |
416 | -- @param repo string or nil: Pathname of a local repository. If not given, | 420 | -- @param repo string or nil: Pathname of a local repository. If not given, |
417 | -- the default local repository configured as cfg.rocks_dir is used. | 421 | -- the default local repository is used. |
418 | -- @param deps_mode string: Dependency mode: "one" for the current default tree, | 422 | -- @param deps_mode string: Dependency mode: "one" for the current default tree, |
419 | -- "all" for all trees, "order" for all trees with priority >= the current default, | 423 | -- "all" for all trees, "order" for all trees with priority >= the current default, |
420 | -- "none" for using the default dependency mode from the configuration. | 424 | -- "none" for using the default dependency mode from the configuration. |
diff --git a/src/luarocks/manif_core.lua b/src/luarocks/manif_core.lua index 1a2c111f..610f9860 100644 --- a/src/luarocks/manif_core.lua +++ b/src/luarocks/manif_core.lua | |||
@@ -7,32 +7,56 @@ package.loaded["luarocks.manif_core"] = manif_core | |||
7 | 7 | ||
8 | local persist = require("luarocks.persist") | 8 | local persist = require("luarocks.persist") |
9 | local type_check = require("luarocks.type_check") | 9 | local type_check = require("luarocks.type_check") |
10 | local cfg = require("luarocks.cfg") | ||
10 | local dir = require("luarocks.dir") | 11 | local dir = require("luarocks.dir") |
11 | local util = require("luarocks.util") | 12 | local util = require("luarocks.util") |
12 | local cfg = require("luarocks.cfg") | ||
13 | local path = require("luarocks.path") | 13 | local path = require("luarocks.path") |
14 | 14 | ||
15 | manif_core.manifest_cache = {} | 15 | -- Table with repository identifiers as keys and tables mapping |
16 | -- Lua versions to cached loaded manifests as values. | ||
17 | local manifest_cache = {} | ||
18 | |||
19 | --- Cache a loaded manifest. | ||
20 | -- @param repo_url string: The repository identifier. | ||
21 | -- @param lua_version string: Lua version in "5.x" format, defaults to installed version. | ||
22 | -- @param manifest table: the manifest to be cached. | ||
23 | function manif_core.cache_manifest(repo_url, lua_version, manifest) | ||
24 | lua_version = lua_version or cfg.lua_version | ||
25 | manifest_cache[repo_url] = manifest_cache[repo_url] or {} | ||
26 | manifest_cache[repo_url][lua_version] = manifest | ||
27 | end | ||
28 | |||
29 | --- Attempt to get cached loaded manifest. | ||
30 | -- @param repo_url string: The repository identifier. | ||
31 | -- @param lua_version string: Lua version in "5.x" format, defaults to installed version. | ||
32 | -- @return table or nil: loaded manifest or nil if cache is empty. | ||
33 | function manif_core.get_cached_manifest(repo_url, lua_version) | ||
34 | lua_version = lua_version or cfg.lua_version | ||
35 | return manifest_cache[repo_url] and manifest_cache[repo_url][lua_version] | ||
36 | end | ||
16 | 37 | ||
17 | --- Back-end function that actually loads the manifest | 38 | --- Back-end function that actually loads the manifest |
18 | -- and stores it in the manifest cache. | 39 | -- and stores it in the manifest cache. |
19 | -- @param file string: The local filename of the manifest file. | 40 | -- @param file string: The local filename of the manifest file. |
20 | -- @param repo_url string: The repository identifier. | 41 | -- @param repo_url string: The repository identifier. |
42 | -- @param lua_version string: Lua version in "5.x" format, defaults to installed version. | ||
21 | -- @param quick boolean: If given, skips type checking. | 43 | -- @param quick boolean: If given, skips type checking. |
22 | function manif_core.manifest_loader(file, repo_url, quick) | 44 | -- @return table or (nil, string, string): the manifest or nil, |
23 | local manifest, err = persist.load_into_table(file) | 45 | -- error message and error code ("open", "load", "run" or "type"). |
46 | function manif_core.manifest_loader(file, repo_url, lua_version, quick) | ||
47 | local manifest, err, errcode = persist.load_into_table(file) | ||
24 | if not manifest then | 48 | if not manifest then |
25 | return nil, "Failed loading manifest for "..repo_url..": "..err | 49 | return nil, "Failed loading manifest for "..repo_url..": "..err, errcode |
26 | end | 50 | end |
27 | local globals = err | 51 | local globals = err |
28 | if not quick then | 52 | if not quick then |
29 | local ok, err = type_check.type_check_manifest(manifest, globals) | 53 | local ok, err = type_check.type_check_manifest(manifest, globals) |
30 | if not ok then | 54 | if not ok then |
31 | return nil, "Error checking manifest: "..err | 55 | return nil, "Error checking manifest: "..err, "type" |
32 | end | 56 | end |
33 | end | 57 | end |
34 | 58 | ||
35 | manif_core.manifest_cache[repo_url] = manifest | 59 | manif_core.cache_manifest(repo_url, lua_version, manifest) |
36 | return manifest | 60 | return manifest |
37 | end | 61 | end |
38 | 62 | ||
@@ -40,18 +64,18 @@ end | |||
40 | -- All functions that use manifest tables assume they were obtained | 64 | -- All functions that use manifest tables assume they were obtained |
41 | -- through either this function or load_manifest. | 65 | -- through either this function or load_manifest. |
42 | -- @param repo_url string: URL or pathname for the repository. | 66 | -- @param repo_url string: URL or pathname for the repository. |
43 | -- @return table or (nil, string): A table representing the manifest, | 67 | -- @return table or (nil, string, string): A table representing the manifest, |
44 | -- or nil followed by an error message. | 68 | -- or nil followed by an error message and an error code, see manifest_loader. |
45 | function manif_core.load_local_manifest(repo_url) | 69 | function manif_core.load_local_manifest(repo_url) |
46 | assert(type(repo_url) == "string") | 70 | assert(type(repo_url) == "string") |
47 | 71 | ||
48 | if manif_core.manifest_cache[repo_url] then | 72 | local cached_manifest = manif_core.get_cached_manifest(repo_url) |
49 | return manif_core.manifest_cache[repo_url] | 73 | if cached_manifest then |
74 | return cached_manifest | ||
50 | end | 75 | end |
51 | 76 | ||
52 | local pathname = dir.path(repo_url, "manifest") | 77 | local pathname = dir.path(repo_url, "manifest") |
53 | 78 | return manif_core.manifest_loader(pathname, repo_url, nil, true) | |
54 | return manif_core.manifest_loader(pathname, repo_url, true) | ||
55 | end | 79 | end |
56 | 80 | ||
57 | --- Get all versions of a package listed in a manifest file. | 81 | --- Get all versions of a package listed in a manifest file. |
diff --git a/src/luarocks/new_version.lua b/src/luarocks/new_version.lua index 9ef0cfbb..6969d4b2 100644 --- a/src/luarocks/new_version.lua +++ b/src/luarocks/new_version.lua | |||
@@ -1,9 +1,7 @@ | |||
1 | 1 | ||
2 | --- Module implementing the LuaRocks "new_version" command. | 2 | --- Module implementing the LuaRocks "new_version" command. |
3 | -- Utility function that writes a new rockspec, updating data from a previous one. | 3 | -- Utility function that writes a new rockspec, updating data from a previous one. |
4 | --module("luarocks.new_version", package.seeall) | ||
5 | local new_version = {} | 4 | local new_version = {} |
6 | package.loaded["luarocks.new_version"] = new_version | ||
7 | 5 | ||
8 | local util = require("luarocks.util") | 6 | local util = require("luarocks.util") |
9 | local download = require("luarocks.download") | 7 | local download = require("luarocks.download") |
@@ -13,7 +11,7 @@ local fs = require("luarocks.fs") | |||
13 | local type_check = require("luarocks.type_check") | 11 | local type_check = require("luarocks.type_check") |
14 | 12 | ||
15 | new_version.help_summary = "Auto-write a rockspec for a new version of a rock." | 13 | new_version.help_summary = "Auto-write a rockspec for a new version of a rock." |
16 | new_version.help_arguments = "{<package>|<rockspec>} [<new_version>] [<new_url>]" | 14 | new_version.help_arguments = "[--tag=<tag>] {<package>|<rockspec>} [<new_version>] [<new_url>]" |
17 | new_version.help = [[ | 15 | new_version.help = [[ |
18 | This is a utility function that writes a new rockspec, updating data | 16 | This is a utility function that writes a new rockspec, updating data |
19 | from a previous one. | 17 | from a previous one. |
@@ -21,8 +19,10 @@ from a previous one. | |||
21 | If a package name is given, it downloads the latest rockspec from the | 19 | If a package name is given, it downloads the latest rockspec from the |
22 | default server. If a rockspec is given, it uses it instead. | 20 | default server. If a rockspec is given, it uses it instead. |
23 | 21 | ||
24 | If the version number is not given, it only increments the revision | 22 | If the version number is not given and tag is passed using --tag, |
25 | number of the given (or downloaded) rockspec. | 23 | it is used as the version, with 'v' removed from beginning. |
24 | Otherwise, it only increments the revision number of the given | ||
25 | (or downloaded) rockspec. | ||
26 | 26 | ||
27 | If a URL is given, it replaces the one from the old rockspec with the | 27 | If a URL is given, it replaces the one from the old rockspec with the |
28 | given URL. If a URL is not given and a new version is given, it tries | 28 | given URL. If a URL is not given and a new version is given, it tries |
@@ -30,6 +30,9 @@ to guess the new URL by replacing occurrences of the version number | |||
30 | in the URL or tag. It also tries to download the new URL to determine | 30 | in the URL or tag. It also tries to download the new URL to determine |
31 | the new MD5 checksum. | 31 | the new MD5 checksum. |
32 | 32 | ||
33 | If a tag is given, it replaces the one from the old rockspec. If there is | ||
34 | an old tag but no new one passed, it is guessed in the same way URL is. | ||
35 | |||
33 | WARNING: it writes the new rockspec to the current directory, | 36 | WARNING: it writes the new rockspec to the current directory, |
34 | overwriting the file if it already exists. | 37 | overwriting the file if it already exists. |
35 | ]] | 38 | ]] |
@@ -48,58 +51,73 @@ local function try_replace(tbl, field, old, new) | |||
48 | return false | 51 | return false |
49 | end | 52 | end |
50 | 53 | ||
51 | local function check_url_and_update_md5(out_rs, out_name) | 54 | -- Try to download source file using URL from a rockspec. |
52 | local old_md5 = out_rs.source.md5 | 55 | -- If it specified MD5, update it. |
53 | out_rs.source.md5 = nil | 56 | -- @return (true, false) if MD5 was not specified or it stayed same, |
54 | local file, temp_dir = fetch.fetch_url_at_temp_dir(out_rs.source.url, "luarocks-new-version-"..out_name) | 57 | -- (true, true) if MD5 changed, (nil, string) on error. |
58 | local function check_url_and_update_md5(out_rs) | ||
59 | local file, temp_dir = fetch.fetch_url_at_temp_dir(out_rs.source.url, "luarocks-new-version-"..out_rs.package) | ||
55 | if not file then | 60 | if not file then |
56 | util.printerr("Warning: invalid URL - "..temp_dir) | 61 | util.printerr("Warning: invalid URL - "..temp_dir) |
57 | return true | 62 | return true, false |
58 | end | 63 | end |
59 | util.printout("File successfully downloaded. Updating MD5 checksum...") | 64 | |
60 | out_rs.source.md5 = fs.get_md5(file) | ||
61 | local inferred_dir, found_dir = fetch.find_base_dir(file, temp_dir, out_rs.source.url, out_rs.source.dir) | 65 | local inferred_dir, found_dir = fetch.find_base_dir(file, temp_dir, out_rs.source.url, out_rs.source.dir) |
62 | if not inferred_dir then | 66 | if not inferred_dir then |
63 | return nil, found_dir | 67 | return nil, found_dir |
64 | end | 68 | end |
69 | |||
65 | if found_dir and found_dir ~= inferred_dir then | 70 | if found_dir and found_dir ~= inferred_dir then |
66 | out_rs.source.dir = found_dir | 71 | out_rs.source.dir = found_dir |
67 | end | 72 | end |
68 | return out_rs.source.md5 ~= old_md5 | 73 | |
74 | if file then | ||
75 | if out_rs.source.md5 then | ||
76 | util.printout("File successfully downloaded. Updating MD5 checksum...") | ||
77 | local new_md5, err = fs.get_md5(file) | ||
78 | if not new_md5 then | ||
79 | return nil, err | ||
80 | end | ||
81 | local old_md5 = out_rs.source.md5 | ||
82 | out_rs.source.md5 = new_md5 | ||
83 | return true, new_md5 ~= old_md5 | ||
84 | else | ||
85 | util.printout("File successfully downloaded.") | ||
86 | return true, false | ||
87 | end | ||
88 | end | ||
69 | end | 89 | end |
70 | 90 | ||
71 | local function update_source_section(out_rs, out_name, url, old_ver, new_ver) | 91 | local function update_source_section(out_rs, url, tag, old_ver, new_ver) |
92 | if tag then | ||
93 | out_rs.source.tag = tag | ||
94 | end | ||
72 | if url then | 95 | if url then |
73 | out_rs.source.url = url | 96 | out_rs.source.url = url |
74 | check_url_and_update_md5(out_rs, out_name) | 97 | return check_url_and_update_md5(out_rs) |
75 | return true | ||
76 | end | 98 | end |
77 | if new_ver == old_ver then | 99 | if new_ver == old_ver then |
78 | return true | 100 | return true |
79 | end | 101 | end |
80 | if not out_rs.source then | ||
81 | return nil, "'source' table is missing. Invalid rockspec?" | ||
82 | end | ||
83 | if out_rs.source.dir then | 102 | if out_rs.source.dir then |
84 | try_replace(out_rs.source, "dir", old_ver, new_ver) | 103 | try_replace(out_rs.source, "dir", old_ver, new_ver) |
85 | end | 104 | end |
86 | if out_rs.source.file then | 105 | if out_rs.source.file then |
87 | try_replace(out_rs.source, "file", old_ver, new_ver) | 106 | try_replace(out_rs.source, "file", old_ver, new_ver) |
88 | end | 107 | end |
89 | local ok = try_replace(out_rs.source, "url", old_ver, new_ver) | 108 | if try_replace(out_rs.source, "url", old_ver, new_ver) then |
90 | if ok then | 109 | return check_url_and_update_md5(out_rs) |
91 | check_url_and_update_md5(out_rs, out_name) | 110 | end |
111 | if tag or try_replace(out_rs.source, "tag", old_ver, new_ver) then | ||
92 | return true | 112 | return true |
93 | end | 113 | end |
94 | ok = try_replace(out_rs.source, "tag", old_ver, new_ver) | 114 | -- Couldn't replace anything significant, use the old URL. |
115 | local ok, md5_changed = check_url_and_update_md5(out_rs) | ||
95 | if not ok then | 116 | if not ok then |
96 | ok = check_url_and_update_md5(out_rs, out_name) | 117 | return nil, md5_changed |
97 | if ok then | ||
98 | util.printerr("Warning: URL is the same, but MD5 has changed. Old rockspec is broken.") | ||
99 | end | ||
100 | end | 118 | end |
101 | if not ok then | 119 | if md5_changed then |
102 | return nil, "Failed to determine the location of the new version." | 120 | util.printerr("Warning: URL is the same, but MD5 has changed. Old rockspec is broken.") |
103 | end | 121 | end |
104 | return true | 122 | return true |
105 | end | 123 | end |
@@ -107,7 +125,7 @@ end | |||
107 | function new_version.run(...) | 125 | function new_version.run(...) |
108 | local flags, input, version, url = util.parse_flags(...) | 126 | local flags, input, version, url = util.parse_flags(...) |
109 | if not input then | 127 | if not input then |
110 | return nil, "Missing arguments: expected program or rockspec. "..util.see_help("new_version") | 128 | return nil, "Missing argument: expected package or rockspec. "..util.see_help("new_version") |
111 | end | 129 | end |
112 | assert(type(input) == "string") | 130 | assert(type(input) == "string") |
113 | 131 | ||
@@ -127,6 +145,10 @@ function new_version.run(...) | |||
127 | 145 | ||
128 | local old_ver, old_rev = valid_rs.version:match("(.*)%-(%d+)$") | 146 | local old_ver, old_rev = valid_rs.version:match("(.*)%-(%d+)$") |
129 | local new_ver, new_rev | 147 | local new_ver, new_rev |
148 | |||
149 | if flags.tag and not version then | ||
150 | version = flags.tag:gsub("^v", "") | ||
151 | end | ||
130 | 152 | ||
131 | if version then | 153 | if version then |
132 | new_ver, new_rev = version:match("(.*)%-(%d+)$") | 154 | new_ver, new_rev = version:match("(.*)%-(%d+)$") |
@@ -145,7 +167,7 @@ function new_version.run(...) | |||
145 | local out_name = out_rs.package:lower() | 167 | local out_name = out_rs.package:lower() |
146 | out_rs.version = new_rockver.."-"..new_rev | 168 | out_rs.version = new_rockver.."-"..new_rev |
147 | 169 | ||
148 | local ok, err = update_source_section(out_rs, out_name, url, old_ver, new_ver) | 170 | local ok, err = update_source_section(out_rs, url, flags.tag, old_ver, new_ver) |
149 | if not ok then return nil, err end | 171 | if not ok then return nil, err end |
150 | 172 | ||
151 | if out_rs.build and out_rs.build.type == "module" then | 173 | if out_rs.build and out_rs.build.type == "module" then |
diff --git a/src/luarocks/path.lua b/src/luarocks/path.lua index 519f32b0..37ff846a 100644 --- a/src/luarocks/path.lua +++ b/src/luarocks/path.lua | |||
@@ -344,44 +344,48 @@ function path.map_trees(deps_mode, fn, ...) | |||
344 | return result | 344 | return result |
345 | end | 345 | end |
346 | 346 | ||
347 | local is_src_extension = { [".lua"] = true, [".tl"] = true, [".tld"] = true, [".moon"] = true } | ||
348 | |||
347 | --- Return the pathname of the file that would be loaded for a module, indexed. | 349 | --- Return the pathname of the file that would be loaded for a module, indexed. |
348 | -- @param module_name string: module name (eg. "socket.core") | 350 | -- @param file_name string: module file name as in manifest (eg. "socket/core.so") |
349 | -- @param name string: name of the package (eg. "luasocket") | 351 | -- @param name string: name of the package (eg. "luasocket") |
350 | -- @param version string: version number (eg. "2.0.2-1") | 352 | -- @param version string: version number (eg. "2.0.2-1") |
351 | -- @param tree string: repository path (eg. "/usr/local") | 353 | -- @param tree string: repository path (eg. "/usr/local") |
352 | -- @param i number: the index, 1 if version is the current default, > 1 otherwise. | 354 | -- @param i number: the index, 1 if version is the current default, > 1 otherwise. |
353 | -- This is done this way for use by select_module in luarocks.loader. | 355 | -- This is done this way for use by select_module in luarocks.loader. |
354 | -- @return string: filename of the module (eg. "/usr/local/lib/lua/5.1/socket/core.so") | 356 | -- @return string: filename of the module (eg. "/usr/local/lib/lua/5.1/socket/core.so") |
355 | function path.which_i(module_name, name, version, tree, i) | 357 | function path.which_i(file_name, name, version, tree, i) |
356 | local deploy_dir | 358 | local deploy_dir |
357 | if module_name:match("%.lua$") then | 359 | local extension = file_name:match("%.[a-z]+$") |
360 | if is_src_extension[extension] then | ||
358 | deploy_dir = path.deploy_lua_dir(tree) | 361 | deploy_dir = path.deploy_lua_dir(tree) |
359 | module_name = dir.path(deploy_dir, module_name) | 362 | file_name = dir.path(deploy_dir, file_name) |
360 | else | 363 | else |
361 | deploy_dir = path.deploy_lib_dir(tree) | 364 | deploy_dir = path.deploy_lib_dir(tree) |
362 | module_name = dir.path(deploy_dir, module_name) | 365 | file_name = dir.path(deploy_dir, file_name) |
363 | end | 366 | end |
364 | if i > 1 then | 367 | if i > 1 then |
365 | module_name = path.versioned_name(module_name, deploy_dir, name, version) | 368 | file_name = path.versioned_name(file_name, deploy_dir, name, version) |
366 | end | 369 | end |
367 | return module_name | 370 | return file_name |
368 | end | 371 | end |
369 | 372 | ||
370 | --- Return the pathname of the file that would be loaded for a module, | 373 | --- Return the pathname of the file that would be loaded for a module, |
371 | -- returning the versioned pathname if given version is not the default version | 374 | -- returning the versioned pathname if given version is not the default version |
372 | -- in the given manifest. | 375 | -- in the given manifest. |
373 | -- @param module_name string: module name (eg. "socket.core") | 376 | -- @param module_name string: module name (eg. "socket.core") |
377 | -- @param file_name string: module file name as in manifest (eg. "socket/core.so") | ||
374 | -- @param name string: name of the package (eg. "luasocket") | 378 | -- @param name string: name of the package (eg. "luasocket") |
375 | -- @param version string: version number (eg. "2.0.2-1") | 379 | -- @param version string: version number (eg. "2.0.2-1") |
376 | -- @param tree string: repository path (eg. "/usr/local") | 380 | -- @param tree string: repository path (eg. "/usr/local") |
377 | -- @param manifest table: the manifest table for the tree. | 381 | -- @param manifest table: the manifest table for the tree. |
378 | -- @return string: filename of the module (eg. "/usr/local/lib/lua/5.1/socket/core.so") | 382 | -- @return string: filename of the module (eg. "/usr/local/lib/lua/5.1/socket/core.so") |
379 | function path.which(module_name, filename, name, version, tree, manifest) | 383 | function path.which(module_name, file_name, name, version, tree, manifest) |
380 | local versions = manifest.modules[module_name] | 384 | local versions = manifest.modules[module_name] |
381 | assert(versions) | 385 | assert(versions) |
382 | for i, name_version in ipairs(versions) do | 386 | for i, name_version in ipairs(versions) do |
383 | if name_version == name.."/"..version then | 387 | if name_version == name.."/"..version then |
384 | return path.which_i(filename, name, version, tree, i):gsub("//", "/") | 388 | return path.which_i(file_name, name, version, tree, i):gsub("//", "/") |
385 | end | 389 | end |
386 | end | 390 | end |
387 | assert(false) | 391 | assert(false) |
diff --git a/src/luarocks/path_cmd.lua b/src/luarocks/path_cmd.lua index 4aeba41c..ecd6d4b1 100644 --- a/src/luarocks/path_cmd.lua +++ b/src/luarocks/path_cmd.lua | |||
@@ -6,7 +6,6 @@ local path_cmd = {} | |||
6 | local util = require("luarocks.util") | 6 | local util = require("luarocks.util") |
7 | local deps = require("luarocks.deps") | 7 | local deps = require("luarocks.deps") |
8 | local cfg = require("luarocks.cfg") | 8 | local cfg = require("luarocks.cfg") |
9 | local path = require("luarocks.path") | ||
10 | 9 | ||
11 | path_cmd.help_summary = "Return the currently configured package path." | 10 | path_cmd.help_summary = "Return the currently configured package path." |
12 | path_cmd.help_arguments = "" | 11 | path_cmd.help_arguments = "" |
@@ -38,7 +37,8 @@ function path_cmd.run(...) | |||
38 | local flags = util.parse_flags(...) | 37 | local flags = util.parse_flags(...) |
39 | local deps_mode = deps.get_deps_mode(flags) | 38 | local deps_mode = deps.get_deps_mode(flags) |
40 | 39 | ||
41 | local lr_path, lr_cpath, lr_bin = cfg.package_paths() | 40 | local lr_path, lr_cpath, lr_bin = cfg.package_paths(flags["tree"]) |
41 | local path_sep = cfg.export_path_separator | ||
42 | 42 | ||
43 | if flags["lr-path"] then | 43 | if flags["lr-path"] then |
44 | util.printout(util.remove_path_dupes(lr_path, ';')) | 44 | util.printout(util.remove_path_dupes(lr_path, ';')) |
@@ -47,24 +47,24 @@ function path_cmd.run(...) | |||
47 | util.printout(util.remove_path_dupes(lr_cpath, ';')) | 47 | util.printout(util.remove_path_dupes(lr_cpath, ';')) |
48 | return true | 48 | return true |
49 | elseif flags["lr-bin"] then | 49 | elseif flags["lr-bin"] then |
50 | util.printout(util.remove_path_dupes(lr_bin, ';')) | 50 | util.printout(util.remove_path_dupes(lr_bin, path_sep)) |
51 | return true | 51 | return true |
52 | end | 52 | end |
53 | 53 | ||
54 | if flags["append"] then | 54 | if flags["append"] then |
55 | lr_path = package.path .. ";" .. lr_path | 55 | lr_path = package.path .. ";" .. lr_path |
56 | lr_cpath = package.cpath .. ";" .. lr_cpath | 56 | lr_cpath = package.cpath .. ";" .. lr_cpath |
57 | lr_bin = os.getenv("PATH") .. ";" .. lr_bin | 57 | lr_bin = os.getenv("PATH") .. path_sep .. lr_bin |
58 | else | 58 | else |
59 | lr_path = lr_path.. ";" .. package.path | 59 | lr_path = lr_path.. ";" .. package.path |
60 | lr_cpath = lr_cpath .. ";" .. package.cpath | 60 | lr_cpath = lr_cpath .. ";" .. package.cpath |
61 | lr_bin = lr_bin .. ";" .. os.getenv("PATH") | 61 | lr_bin = lr_bin .. path_sep .. os.getenv("PATH") |
62 | end | 62 | end |
63 | 63 | ||
64 | util.printout(cfg.export_lua_path:format(util.remove_path_dupes(lr_path, ';'))) | 64 | util.printout(cfg.export_lua_path:format(util.remove_path_dupes(lr_path, ';'))) |
65 | util.printout(cfg.export_lua_cpath:format(util.remove_path_dupes(lr_cpath, ';'))) | 65 | util.printout(cfg.export_lua_cpath:format(util.remove_path_dupes(lr_cpath, ';'))) |
66 | if flags["bin"] then | 66 | if flags["bin"] then |
67 | util.printout(cfg.export_path:format(util.remove_path_dupes(lr_bin,';'))) | 67 | util.printout(cfg.export_path:format(util.remove_path_dupes(lr_bin, path_sep))) |
68 | end | 68 | end |
69 | return true | 69 | return true |
70 | end | 70 | end |
diff --git a/src/luarocks/persist.lua b/src/luarocks/persist.lua index 9d601a43..354b17c3 100644 --- a/src/luarocks/persist.lua +++ b/src/luarocks/persist.lua | |||
@@ -9,60 +9,85 @@ package.loaded["luarocks.persist"] = persist | |||
9 | 9 | ||
10 | local util = require("luarocks.util") | 10 | local util = require("luarocks.util") |
11 | 11 | ||
12 | --- Load and run a Lua file in an environment. | ||
13 | -- @param filename string: the name of the file. | ||
14 | -- @param env table: the environment table. | ||
15 | -- @return (true, any) or (nil, string, string): true and the return value | ||
16 | -- of the file, or nil, an error message and an error code ("open", "load" | ||
17 | -- or "run") in case of errors. | ||
18 | local function run_file(filename, env) | ||
19 | local fd, err = io.open(filename) | ||
20 | if not fd then | ||
21 | return nil, err, "open" | ||
22 | end | ||
23 | local str, err = fd:read("*a") | ||
24 | fd:close() | ||
25 | if not str then | ||
26 | return nil, err, "open" | ||
27 | end | ||
28 | str = str:gsub("^#![^\n]*\n", "") | ||
29 | local chunk, ran | ||
30 | if _VERSION == "Lua 5.1" then -- Lua 5.1 | ||
31 | chunk, err = loadstring(str, filename) | ||
32 | if chunk then | ||
33 | setfenv(chunk, env) | ||
34 | ran, err = pcall(chunk) | ||
35 | end | ||
36 | else -- Lua 5.2 | ||
37 | chunk, err = load(str, filename, "t", env) | ||
38 | if chunk then | ||
39 | ran, err = pcall(chunk) | ||
40 | end | ||
41 | end | ||
42 | if not chunk then | ||
43 | return nil, "Error loading file: "..err, "load" | ||
44 | end | ||
45 | if not ran then | ||
46 | return nil, "Error running file: "..err, "run" | ||
47 | end | ||
48 | return true, err | ||
49 | end | ||
50 | |||
12 | --- Load a Lua file containing assignments, storing them in a table. | 51 | --- Load a Lua file containing assignments, storing them in a table. |
13 | -- The global environment is not propagated to the loaded file. | 52 | -- The global environment is not propagated to the loaded file. |
14 | -- @param filename string: the name of the file. | 53 | -- @param filename string: the name of the file. |
15 | -- @param tbl table or nil: if given, this table is used to store | 54 | -- @param tbl table or nil: if given, this table is used to store |
16 | -- loaded values. | 55 | -- loaded values. |
17 | -- @return table or (nil, string): a table with the file's assignments | 56 | -- @return (table, table) or (nil, string, string): a table with the file's assignments |
18 | -- as fields, or nil and a message in case of errors. | 57 | -- as fields and set of undefined globals accessed in file, |
58 | -- or nil, an error message and an error code ("open"; couldn't open the file, | ||
59 | -- "load"; compile-time error, or "run"; run-time error) | ||
60 | -- in case of errors. | ||
19 | function persist.load_into_table(filename, tbl) | 61 | function persist.load_into_table(filename, tbl) |
20 | assert(type(filename) == "string") | 62 | assert(type(filename) == "string") |
21 | assert(type(tbl) == "table" or not tbl) | 63 | assert(type(tbl) == "table" or not tbl) |
22 | 64 | ||
23 | local result, chunk, ran, err | 65 | local result = tbl or {} |
24 | result = tbl or {} | ||
25 | local globals = {} | 66 | local globals = {} |
26 | local globals_mt = { | 67 | local globals_mt = { |
27 | __index = function(t, n) | 68 | __index = function(t, k) |
28 | globals[n] = true | 69 | globals[k] = true |
29 | return rawget(t, n) | ||
30 | end | 70 | end |
31 | } | 71 | } |
32 | local save_mt = getmetatable(result) | 72 | local save_mt = getmetatable(result) |
33 | setmetatable(result, globals_mt) | 73 | setmetatable(result, globals_mt) |
34 | if _VERSION == "Lua 5.1" then -- Lua 5.1 | ||
35 | chunk, err = loadfile(filename) | ||
36 | if chunk then | ||
37 | setfenv(chunk, result) | ||
38 | ran, err = pcall(chunk) | ||
39 | end | ||
40 | else -- Lua 5.2 | ||
41 | chunk, err = loadfile(filename, "t", result) | ||
42 | if chunk then | ||
43 | ran, err = pcall(chunk) | ||
44 | end | ||
45 | end | ||
46 | setmetatable(result, save_mt) | ||
47 | 74 | ||
48 | if not chunk then | 75 | local ok, err, errcode = run_file(filename, result) |
49 | if err:sub(1,5) ~= filename:sub(1,5) then | 76 | |
50 | return false, err | 77 | setmetatable(result, save_mt) |
51 | end | 78 | |
52 | return nil, "Error loading file: "..err | 79 | if not ok then |
53 | end | 80 | return nil, err, errcode |
54 | if not ran then | ||
55 | return nil, "Error running file: "..err | ||
56 | end | 81 | end |
57 | return result, globals | 82 | return result, globals |
58 | end | 83 | end |
59 | 84 | ||
60 | local write_table | 85 | local write_table |
61 | 86 | ||
62 | --- Write a value as Lua code, invoking write_table. | 87 | --- Write a value as Lua code. |
63 | -- This function handles only numbers, strings and tables | 88 | -- This function handles only numbers and strings, invoking write_table |
64 | -- are keys (tables are handled recursively). | 89 | -- to write tables. |
65 | -- @param out userdata: a file object, open for writing. | 90 | -- @param out table or userdata: a writer object supporting :write() method. |
66 | -- @param v: the value to be written. | 91 | -- @param v: the value to be written. |
67 | -- @param level number: the indentation level | 92 | -- @param level number: the indentation level |
68 | -- @param sub_order table: optional prioritization table | 93 | -- @param sub_order table: optional prioritization table |
@@ -71,28 +96,27 @@ local function write_value(out, v, level, sub_order) | |||
71 | if type(v) == "table" then | 96 | if type(v) == "table" then |
72 | write_table(out, v, level + 1, sub_order) | 97 | write_table(out, v, level + 1, sub_order) |
73 | elseif type(v) == "string" then | 98 | elseif type(v) == "string" then |
74 | if v:match("\n") then | 99 | if v:match("[\r\n]") then |
75 | local open, close = "[[", "]]" | 100 | local open, close = "[[", "]]" |
76 | local equals = 0 | 101 | local equals = 0 |
77 | while v:find(open,1,true) or v:find(close,1,true) do | 102 | while v:find(close, 1, true) do |
78 | equals = equals + 1 | 103 | equals = equals + 1 |
79 | local eqs = ("="):rep(equals) | 104 | local eqs = ("="):rep(equals) |
80 | open, close = "["..eqs.."[", "]"..eqs.."]" | 105 | open, close = "["..eqs.."[", "]"..eqs.."]" |
81 | end | 106 | end |
82 | out:write(open.."\n"..v..close) | 107 | out:write(open.."\n"..v..close) |
83 | else | 108 | else |
84 | out:write("\""..v:gsub("\"", "\\\"").."\"") | 109 | out:write("\""..v:gsub("\\", "\\\\"):gsub("\"", "\\\"").."\"") |
85 | end | 110 | end |
86 | else | 111 | else |
87 | out:write(tostring(v)) | 112 | out:write(tostring(v)) |
88 | end | 113 | end |
89 | end | 114 | end |
90 | 115 | ||
91 | --- Write a table as Lua code representing a table to disk | 116 | --- Write a table as Lua code in curly brackets notation to a writer object. |
92 | -- (that is, in curly brackets notation). | 117 | -- Only numbers, strings and tables (containing numbers, strings |
93 | -- This function handles only numbers, strings and tables | 118 | -- or other recursively processed tables) are supported. |
94 | -- are keys (tables are handled recursively). | 119 | -- @param out table or userdata: a writer object supporting :write() method. |
95 | -- @param out userdata: a file object, open for writing. | ||
96 | -- @param tbl table: the table to be written. | 120 | -- @param tbl table: the table to be written. |
97 | -- @param level number: the indentation level | 121 | -- @param level number: the indentation level |
98 | -- @param field_order table: optional prioritization table | 122 | -- @param field_order table: optional prioritization table |
@@ -107,28 +131,29 @@ write_table = function(out, tbl, level, field_order) | |||
107 | if indent then | 131 | if indent then |
108 | for n = 1,level do out:write(indentation) end | 132 | for n = 1,level do out:write(indentation) end |
109 | end | 133 | end |
110 | sep = ",\n" | 134 | |
111 | indent = true | 135 | if k == i then |
112 | if type(k) == "number" then | 136 | i = i + 1 |
113 | if k ~= i then | ||
114 | out:write("["..tostring(k).."]=") | ||
115 | else | ||
116 | i = i + 1 | ||
117 | end | ||
118 | indent = false | ||
119 | sep = ", " | ||
120 | elseif type(k) == "table" then | ||
121 | out:write("[") | ||
122 | write_table(out, k, level + 1) | ||
123 | out:write("] = ") | ||
124 | else | 137 | else |
125 | if k:match("^[a-zA-Z_][a-zA-Z0-9_]*$") then | 138 | if type(k) == "string" and k:match("^[a-zA-Z_][a-zA-Z0-9_]*$") then |
126 | out:write(k.." = ") | 139 | out:write(k) |
127 | else | 140 | else |
128 | out:write("['"..k:gsub("'", "\\'").."'] = ") | 141 | out:write("[") |
142 | write_value(out, k, level) | ||
143 | out:write("]") | ||
129 | end | 144 | end |
145 | |||
146 | out:write(" = ") | ||
130 | end | 147 | end |
148 | |||
131 | write_value(out, v, level, sub_order) | 149 | write_value(out, v, level, sub_order) |
150 | if type(k) == "number" then | ||
151 | sep = ", " | ||
152 | indent = false | ||
153 | else | ||
154 | sep = ",\n" | ||
155 | indent = true | ||
156 | end | ||
132 | end | 157 | end |
133 | if sep ~= "\n" then | 158 | if sep ~= "\n" then |
134 | out:write("\n") | 159 | out:write("\n") |
@@ -137,18 +162,16 @@ write_table = function(out, tbl, level, field_order) | |||
137 | out:write("}") | 162 | out:write("}") |
138 | end | 163 | end |
139 | 164 | ||
140 | --- Writes a table to an io-like object. | 165 | --- Write a table as series of assignments to a writer object. |
141 | -- @param out userdata: a file object, open for writing. | 166 | -- @param out table or userdata: a writer object supporting :write() method. |
142 | -- @param tbl table: the table to be written. | 167 | -- @param tbl table: the table to be written. |
143 | -- @param field_order table: optional prioritization table | 168 | -- @param field_order table: optional prioritization table |
144 | -- @return userdata The file object originally passed in as the `out` parameter. | 169 | local function write_table_as_assignments(out, tbl, field_order) |
145 | local function write_table(out, tbl, field_order) | ||
146 | for k, v, sub_order in util.sortedpairs(tbl, field_order) do | 170 | for k, v, sub_order in util.sortedpairs(tbl, field_order) do |
147 | out:write(k.." = ") | 171 | out:write(k.." = ") |
148 | write_value(out, v, 0, sub_order) | 172 | write_value(out, v, 0, sub_order) |
149 | out:write("\n") | 173 | out:write("\n") |
150 | end | 174 | end |
151 | return out | ||
152 | end | 175 | end |
153 | 176 | ||
154 | --- Save the contents of a table to a string. | 177 | --- Save the contents of a table to a string. |
@@ -161,7 +184,7 @@ end | |||
161 | function persist.save_from_table_to_string(tbl, field_order) | 184 | function persist.save_from_table_to_string(tbl, field_order) |
162 | local out = {buffer = {}} | 185 | local out = {buffer = {}} |
163 | function out:write(data) table.insert(self.buffer, data) end | 186 | function out:write(data) table.insert(self.buffer, data) end |
164 | write_table(out, tbl, field_order) | 187 | write_table_as_assignments(out, tbl, field_order) |
165 | return table.concat(out.buffer) | 188 | return table.concat(out.buffer) |
166 | end | 189 | end |
167 | 190 | ||
@@ -179,7 +202,7 @@ function persist.save_from_table(filename, tbl, field_order) | |||
179 | if not out then | 202 | if not out then |
180 | return nil, "Cannot create file at "..filename | 203 | return nil, "Cannot create file at "..filename |
181 | end | 204 | end |
182 | write_table(out, tbl, field_order) | 205 | write_table_as_assignments(out, tbl, field_order) |
183 | out:close() | 206 | out:close() |
184 | return true | 207 | return true |
185 | end | 208 | end |
diff --git a/src/luarocks/remove.lua b/src/luarocks/remove.lua index 595df8f4..5d419817 100644 --- a/src/luarocks/remove.lua +++ b/src/luarocks/remove.lua | |||
@@ -159,7 +159,7 @@ function remove.run(...) | |||
159 | local results = {} | 159 | local results = {} |
160 | search.manifest_search(results, cfg.rocks_dir, search.make_query(name, version)) | 160 | search.manifest_search(results, cfg.rocks_dir, search.make_query(name, version)) |
161 | if not results[name] then | 161 | if not results[name] then |
162 | return nil, "Could not find rock '"..name..(version and " "..version or "").."' in local tree." | 162 | return nil, "Could not find rock '"..name..(version and " "..version or "").."' in "..path.rocks_tree_to_string(cfg.root_dir) |
163 | end | 163 | end |
164 | 164 | ||
165 | return remove.remove_search_results(results, name, deps_mode, flags["force"]) | 165 | return remove.remove_search_results(results, name, deps_mode, flags["force"]) |
diff --git a/src/luarocks/search.lua b/src/luarocks/search.lua index 53439386..6c0020c0 100644 --- a/src/luarocks/search.lua +++ b/src/luarocks/search.lua | |||
@@ -48,7 +48,8 @@ end | |||
48 | 48 | ||
49 | --- Store a search result (a rock or rockspec) in the results table. | 49 | --- Store a search result (a rock or rockspec) in the results table. |
50 | -- @param results table: The results table, where keys are package names and | 50 | -- @param results table: The results table, where keys are package names and |
51 | -- versions are tables matching version strings to an array of servers. | 51 | -- values are tables matching version strings to arrays of |
52 | -- tables with fields "arch" and "repo". | ||
52 | -- @param name string: Package name. | 53 | -- @param name string: Package name. |
53 | -- @param version string: Package version. | 54 | -- @param version string: Package version. |
54 | -- @param arch string: Architecture of rock ("all", "src" or platform | 55 | -- @param arch string: Architecture of rock ("all", "src" or platform |
@@ -92,7 +93,8 @@ end | |||
92 | -- table, optionally checking if version and arch (if given) match | 93 | -- table, optionally checking if version and arch (if given) match |
93 | -- a query. | 94 | -- a query. |
94 | -- @param results table: The results table, where keys are package names and | 95 | -- @param results table: The results table, where keys are package names and |
95 | -- versions are tables matching version strings to an array of servers. | 96 | -- values are tables matching version strings to arrays of |
97 | -- tables with fields "arch" and "repo". | ||
96 | -- @param repo string: URL or pathname of the repository. | 98 | -- @param repo string: URL or pathname of the repository. |
97 | -- @param name string: The name of the package being tested. | 99 | -- @param name string: The name of the package being tested. |
98 | -- @param version string: The version of the package being tested. | 100 | -- @param version string: The version of the package being tested. |
@@ -123,8 +125,9 @@ end | |||
123 | -- matches regardless of architecture. | 125 | -- matches regardless of architecture. |
124 | -- @param results table or nil: If given, this table will store the | 126 | -- @param results table or nil: If given, this table will store the |
125 | -- results; if not given, a new table will be created. | 127 | -- results; if not given, a new table will be created. |
126 | -- @param table: The results table, where keys are package names and | 128 | -- @return table: The results table, where keys are package names and |
127 | -- versions are tables matching version strings to an array of servers. | 129 | -- values are tables matching version strings to arrays of |
130 | -- tables with fields "arch" and "repo". | ||
128 | -- If a table was given in the "results" parameter, that is the result value. | 131 | -- If a table was given in the "results" parameter, that is the result value. |
129 | function search.disk_search(repo, query, results) | 132 | function search.disk_search(repo, query, results) |
130 | assert(type(repo) == "string") | 133 | assert(type(repo) == "string") |
@@ -155,24 +158,27 @@ function search.disk_search(repo, query, results) | |||
155 | return results | 158 | return results |
156 | end | 159 | end |
157 | 160 | ||
158 | --- Perform search on a rocks server. | 161 | --- Perform search on a rocks server or tree. |
159 | -- @param results table: The results table, where keys are package names and | 162 | -- @param results table: The results table, where keys are package names and |
160 | -- versions are tables matching version strings to an array of servers. | 163 | -- values are tables matching version strings to arrays of |
161 | -- @param repo string: The URL of the rocks server. | 164 | -- tables with fields "arch" and "repo". |
165 | -- @param repo string: The URL of a rocks server or | ||
166 | -- the pathname of a rocks tree (as returned by path.rocks_dir()). | ||
162 | -- @param query table: A table describing the query in dependency | 167 | -- @param query table: A table describing the query in dependency |
163 | -- format (for example, {name = "filesystem", exact_name = false, | 168 | -- format (for example, {name = "filesystem", exact_name = false, |
164 | -- constraints = {op = "~>", version = {1,0}}}, arch = "rockspec"). | 169 | -- constraints = {op = "~>", version = {1,0}}}, arch = "rockspec"). |
165 | -- If the arch field is omitted, the local architecture (cfg.arch) | 170 | -- If the arch field is omitted, the local architecture (cfg.arch) |
166 | -- is used. The special value "any" is also recognized, returning all | 171 | -- is used. The special value "any" is also recognized, returning all |
167 | -- matches regardless of architecture. | 172 | -- matches regardless of architecture. |
168 | -- @return true or, in case of errors, nil and an error message. | 173 | -- @param lua_version string: Lua version in "5.x" format, defaults to installed version. |
169 | function search.manifest_search(results, repo, query) | 174 | -- @return true or, in case of errors, nil, an error message and an optional error code. |
175 | function search.manifest_search(results, repo, query, lua_version) | ||
170 | assert(type(results) == "table") | 176 | assert(type(results) == "table") |
171 | assert(type(repo) == "string") | 177 | assert(type(repo) == "string") |
172 | assert(type(query) == "table") | 178 | assert(type(query) == "table") |
173 | 179 | ||
174 | query_arch_as_table(query) | 180 | query_arch_as_table(query) |
175 | local manifest, err, errcode = manif.load_manifest(repo) | 181 | local manifest, err, errcode = manif.load_manifest(repo, lua_version) |
176 | if not manifest then | 182 | if not manifest then |
177 | return nil, err, errcode | 183 | return nil, err, errcode |
178 | end | 184 | end |
@@ -188,10 +194,11 @@ end | |||
188 | 194 | ||
189 | --- Search on all configured rocks servers. | 195 | --- Search on all configured rocks servers. |
190 | -- @param query table: A dependency query. | 196 | -- @param query table: A dependency query. |
197 | -- @param lua_version string: Lua version in "5.x" format, defaults to installed version. | ||
191 | -- @return table: A table where keys are package names | 198 | -- @return table: A table where keys are package names |
192 | -- and values are tables matching version strings to an array of | 199 | -- and values are tables matching version strings to arrays of |
193 | -- rocks servers; if no results are found, an empty table is returned. | 200 | -- tables with fields "arch" and "repo". |
194 | function search.search_repos(query) | 201 | function search.search_repos(query, lua_version) |
195 | assert(type(query) == "table") | 202 | assert(type(query) == "table") |
196 | 203 | ||
197 | local results = {} | 204 | local results = {} |
@@ -205,7 +212,7 @@ function search.search_repos(query) | |||
205 | if protocol == "file" then | 212 | if protocol == "file" then |
206 | mirror = pathname | 213 | mirror = pathname |
207 | end | 214 | end |
208 | local ok, err, errcode = search.manifest_search(results, mirror, query) | 215 | local ok, err, errcode = search.manifest_search(results, mirror, query, lua_version) |
209 | if errcode == "network" then | 216 | if errcode == "network" then |
210 | cfg.disabled_servers[repo] = true | 217 | cfg.disabled_servers[repo] = true |
211 | end | 218 | end |
@@ -273,28 +280,66 @@ local function pick_latest_version(name, versions) | |||
273 | return nil | 280 | return nil |
274 | end | 281 | end |
275 | 282 | ||
276 | --- Attempt to get a single URL for a given search. | 283 | -- Find out which other Lua versions provide rock versions matching a query, |
277 | -- @param query table: A dependency query. | 284 | -- @param query table: A dependency query matching a single rock. |
278 | -- @return string or table or (nil, string): URL for matching rock if | 285 | -- @return table: array of Lua versions supported, in "5.x" format. |
279 | -- a single one was found, a table of candidates if it could not narrow to | 286 | local function supported_lua_versions(query) |
280 | -- a single result, or nil followed by an error message. | 287 | local results = {} |
288 | |||
289 | for lua_version in util.lua_versions() do | ||
290 | if lua_version ~= cfg.lua_version then | ||
291 | if search.search_repos(query, lua_version)[query.name] then | ||
292 | table.insert(results, lua_version) | ||
293 | end | ||
294 | end | ||
295 | end | ||
296 | |||
297 | return results | ||
298 | end | ||
299 | |||
300 | --- Attempt to get a single URL for a given search for a rock. | ||
301 | -- @param query table: A dependency query matching a single rock. | ||
302 | -- @return string or (nil, string): URL for latest matching version | ||
303 | -- of the rock if it was found, or nil followed by an error message. | ||
281 | function search.find_suitable_rock(query) | 304 | function search.find_suitable_rock(query) |
282 | assert(type(query) == "table") | 305 | assert(type(query) == "table") |
283 | 306 | ||
284 | local results = search.search_repos(query) | 307 | local results = search.search_repos(query) |
285 | local first = next(results) | 308 | local first_rock = next(results) |
286 | if not first then | 309 | if not first_rock then |
287 | return nil, "No results matching query were found." | 310 | if cfg.rocks_provided[query.name] == nil then |
288 | elseif not next(results, first) then | 311 | -- Check if constraints are satisfiable with other Lua versions. |
289 | if cfg.rocks_provided[query.name] ~= nil then | 312 | local lua_versions = supported_lua_versions(query) |
290 | -- do not install versions that listed in cfg.rocks_provided | 313 | |
291 | return nil, "Rock "..query.name.. | 314 | if #lua_versions ~= 0 then |
292 | " "..cfg.rocks_provided[query.name].. | 315 | -- Build a nice message in "only Lua 5.x and 5.y but not 5.z." format |
293 | " was found but it is provided by VM or 'rocks_provided' in the config file." | 316 | for i, lua_version in ipairs(lua_versions) do |
317 | lua_versions[i] = "Lua "..lua_version | ||
318 | end | ||
319 | |||
320 | local versions_message = "only "..table.concat(lua_versions, " and ").. | ||
321 | " but not Lua "..cfg.lua_version.."." | ||
322 | |||
323 | if #query.constraints == 0 then | ||
324 | return nil, query.name.." supports "..versions_message | ||
325 | elseif #query.constraints == 1 and query.constraints[1].op == "==" then | ||
326 | return nil, query.name.." "..query.constraints[1].version.string.." supports "..versions_message | ||
327 | else | ||
328 | return nil, "Matching "..query.name.." versions support "..versions_message | ||
329 | end | ||
330 | end | ||
294 | end | 331 | end |
295 | return pick_latest_version(query.name, results[first]) | 332 | |
333 | return nil, "No results matching query were found." | ||
334 | elseif next(results, first_rock) then | ||
335 | -- Shouldn't happen as query must match only one package. | ||
336 | return nil, "Several rocks matched query." | ||
337 | elseif cfg.rocks_provided[query.name] ~= nil then | ||
338 | -- Do not install versions listed in cfg.rocks_provided. | ||
339 | return nil, "Rock "..query.name.." "..cfg.rocks_provided[query.name].. | ||
340 | " was found but it is provided by VM or 'rocks_provided' in the config file." | ||
296 | else | 341 | else |
297 | return results | 342 | return pick_latest_version(query.name, results[first_rock]) |
298 | end | 343 | end |
299 | end | 344 | end |
300 | 345 | ||
@@ -364,12 +409,11 @@ function search.act_on_src_or_rockspec(action, name, version, ...) | |||
364 | 409 | ||
365 | local query = search.make_query(name, version) | 410 | local query = search.make_query(name, version) |
366 | query.arch = "src|rockspec" | 411 | query.arch = "src|rockspec" |
367 | local results, err = search.find_suitable_rock(query) | 412 | local url, err = search.find_suitable_rock(query) |
368 | if type(results) == "string" then | 413 | if not url then |
369 | return action(results, ...) | 414 | return nil, "Could not find a result named "..name..(version and " "..version or "")..": "..err |
370 | else | ||
371 | return nil, "Could not find a result named "..name..(version and " "..version or "").."." | ||
372 | end | 415 | end |
416 | return action(url, ...) | ||
373 | end | 417 | end |
374 | 418 | ||
375 | --- Driver function for "search" command. | 419 | --- Driver function for "search" command. |
diff --git a/src/luarocks/show.lua b/src/luarocks/show.lua index 3243c0ce..ae41a513 100644 --- a/src/luarocks/show.lua +++ b/src/luarocks/show.lua | |||
@@ -11,7 +11,7 @@ local path = require("luarocks.path") | |||
11 | local deps = require("luarocks.deps") | 11 | local deps = require("luarocks.deps") |
12 | local fetch = require("luarocks.fetch") | 12 | local fetch = require("luarocks.fetch") |
13 | local manif = require("luarocks.manif") | 13 | local manif = require("luarocks.manif") |
14 | show.help_summary = "Shows information about an installed rock." | 14 | show.help_summary = "Show information about an installed rock." |
15 | 15 | ||
16 | show.help = [[ | 16 | show.help = [[ |
17 | <argument> is an existing package name. | 17 | <argument> is an existing package name. |
@@ -28,7 +28,9 @@ With these flags, return only the desired information: | |||
28 | ]] | 28 | ]] |
29 | 29 | ||
30 | local function keys_as_string(t, sep) | 30 | local function keys_as_string(t, sep) |
31 | return table.concat(util.keys(t), sep or " ") | 31 | local keys = util.keys(t) |
32 | table.sort(keys) | ||
33 | return table.concat(keys, sep or " ") | ||
32 | end | 34 | end |
33 | 35 | ||
34 | local function word_wrap(line) | 36 | local function word_wrap(line) |
@@ -88,6 +90,16 @@ function show.pick_installed_rock(name, version, tree) | |||
88 | return name, version, repo, repo_url | 90 | return name, version, repo, repo_url |
89 | end | 91 | end |
90 | 92 | ||
93 | local function installed_rock_label(name, tree) | ||
94 | local installed, version | ||
95 | if cfg.rocks_provided[name] then | ||
96 | installed, version = true, cfg.rocks_provided[name] | ||
97 | else | ||
98 | installed, version = show.pick_installed_rock(name, nil, tree) | ||
99 | end | ||
100 | return installed and "(using "..version..")" or "(missing)" | ||
101 | end | ||
102 | |||
91 | --- Driver function for "show" command. | 103 | --- Driver function for "show" command. |
92 | -- @param name or nil: an existing package name. | 104 | -- @param name or nil: an existing package name. |
93 | -- @param version string or nil: a version may also be passed. | 105 | -- @param version string or nil: a version may also be passed. |
@@ -143,10 +155,26 @@ function show.run(...) | |||
143 | util.printout("\t"..mod.." ("..path.which(mod, filename, name, version, repo, manifest)..")") | 155 | util.printout("\t"..mod.." ("..path.which(mod, filename, name, version, repo, manifest)..")") |
144 | end | 156 | end |
145 | end | 157 | end |
146 | if next(minfo.dependencies) then | 158 | local direct_deps = {} |
159 | if #rockspec.dependencies > 0 then | ||
147 | util.printout() | 160 | util.printout() |
148 | util.printout("Depends on:") | 161 | util.printout("Depends on:") |
149 | util.printout("\t"..keys_as_string(minfo.dependencies, "\n\t")) | 162 | for _, dep in ipairs(rockspec.dependencies) do |
163 | direct_deps[dep.name] = true | ||
164 | util.printout("\t"..deps.show_dep(dep).." "..installed_rock_label(dep.name, flags["tree"])) | ||
165 | end | ||
166 | end | ||
167 | local has_indirect_deps | ||
168 | for dep_name in util.sortedpairs(minfo.dependencies) do | ||
169 | if not direct_deps[dep_name] then | ||
170 | if not has_indirect_deps then | ||
171 | util.printout() | ||
172 | util.printout("Indirectly pulling:") | ||
173 | has_indirect_deps = true | ||
174 | end | ||
175 | |||
176 | util.printout("\t"..dep_name.." "..installed_rock_label(dep_name, flags["tree"])) | ||
177 | end | ||
150 | end | 178 | end |
151 | util.printout() | 179 | util.printout() |
152 | end | 180 | end |
diff --git a/src/luarocks/tools/patch.lua b/src/luarocks/tools/patch.lua index 8df3093d..debaf636 100644 --- a/src/luarocks/tools/patch.lua +++ b/src/luarocks/tools/patch.lua | |||
@@ -22,8 +22,8 @@ local format = string.format | |||
22 | 22 | ||
23 | -- logging | 23 | -- logging |
24 | local debugmode = false | 24 | local debugmode = false |
25 | local function debug(s) end | 25 | local function debug(_) end |
26 | local function info(s) end | 26 | local function info(_) end |
27 | local function warning(s) io.stderr:write(s .. '\n') end | 27 | local function warning(s) io.stderr:write(s .. '\n') end |
28 | 28 | ||
29 | -- Returns boolean whether string s2 starts with string s. | 29 | -- Returns boolean whether string s2 starts with string s. |
@@ -57,27 +57,30 @@ end | |||
57 | local function isfile() return true end --FIX? | 57 | local function isfile() return true end --FIX? |
58 | 58 | ||
59 | local function read_file(filename) | 59 | local function read_file(filename) |
60 | local fh, err, oserr = io.open(filename, 'rb') | 60 | local fh, data, err, oserr |
61 | fh, err, oserr = io.open(filename, 'rb') | ||
61 | if not fh then return fh, err, oserr end | 62 | if not fh then return fh, err, oserr end |
62 | local data, err, oserr = fh:read'*a' | 63 | data, err, oserr = fh:read'*a' |
63 | fh:close() | 64 | fh:close() |
64 | if not data then return nil, err, oserr end | 65 | if not data then return nil, err, oserr end |
65 | return data | 66 | return data |
66 | end | 67 | end |
67 | 68 | ||
68 | local function write_file(filename, data) | 69 | local function write_file(filename, data) |
69 | local fh, err, oserr = io.open(filename 'wb') | 70 | local fh, status, err, oserr |
71 | fh, err, oserr = io.open(filename 'wb') | ||
70 | if not fh then return fh, err, oserr end | 72 | if not fh then return fh, err, oserr end |
71 | local status, err, oserr = fh:write(data) | 73 | status, err, oserr = fh:write(data) |
72 | fh:close() | 74 | fh:close() |
73 | if not status then return nil, err, oserr end | 75 | if not status then return nil, err, oserr end |
74 | return true | 76 | return true |
75 | end | 77 | end |
76 | 78 | ||
77 | local function file_copy(src, dest) | 79 | local function file_copy(src, dest) |
78 | local data, err, oserr = read_file(src) | 80 | local data, status, err, oserr |
81 | data, err, oserr = read_file(src) | ||
79 | if not data then return data, err, oserr end | 82 | if not data then return data, err, oserr end |
80 | local status, err, oserr = write_file(dest) | 83 | status, err, oserr = write_file(dest) |
81 | if not status then return status, err, oserr end | 84 | if not status then return status, err, oserr end |
82 | return true | 85 | return true |
83 | end | 86 | end |
@@ -197,8 +200,13 @@ function patch.read_patch(filename, data) | |||
197 | if state == 'hunkbody' then | 200 | if state == 'hunkbody' then |
198 | -- skip hunkskip and hunkbody code until definition of hunkhead read | 201 | -- skip hunkskip and hunkbody code until definition of hunkhead read |
199 | 202 | ||
203 | if line:match"^[\r\n]*$" then | ||
204 | -- prepend space to empty lines to interpret them as context properly | ||
205 | line = " " .. line | ||
206 | end | ||
207 | |||
200 | -- process line first | 208 | -- process line first |
201 | if line:match"^[- +\\]" or line:match"^[\r\n]*$" then | 209 | if line:match"^[- +\\]" then |
202 | -- gather stats about line endings | 210 | -- gather stats about line endings |
203 | local he = files.hunkends[nextfileno] | 211 | local he = files.hunkends[nextfileno] |
204 | if endswith(line, "\r\n") then | 212 | if endswith(line, "\r\n") then |
@@ -420,7 +428,7 @@ local function find_hunk(file, h, hno) | |||
420 | end | 428 | end |
421 | h.startsrc = location | 429 | h.startsrc = location |
422 | h.starttgt = h.starttgt + offset | 430 | h.starttgt = h.starttgt + offset |
423 | for i=1,fuzz do | 431 | for _=1,fuzz do |
424 | table.remove(h.text, 1) | 432 | table.remove(h.text, 1) |
425 | table.remove(h.text, #h.text) | 433 | table.remove(h.text, #h.text) |
426 | end | 434 | end |
@@ -452,16 +460,15 @@ local function find_hunks(file, hunks) | |||
452 | end | 460 | end |
453 | 461 | ||
454 | local function check_patched(file, hunks) | 462 | local function check_patched(file, hunks) |
455 | local matched = true | ||
456 | local lineno = 1 | 463 | local lineno = 1 |
457 | local ok, err = pcall(function() | 464 | local ok, err = pcall(function() |
458 | if #file == 0 then | 465 | if #file == 0 then |
459 | error 'nomatch' | 466 | error('nomatch', 0) |
460 | end | 467 | end |
461 | for hno, h in ipairs(hunks) do | 468 | for hno, h in ipairs(hunks) do |
462 | -- skip to line just before hunk starts | 469 | -- skip to line just before hunk starts |
463 | if #file < h.starttgt then | 470 | if #file < h.starttgt then |
464 | error 'nomatch' | 471 | error('nomatch', 0) |
465 | end | 472 | end |
466 | lineno = h.starttgt | 473 | lineno = h.starttgt |
467 | for _, hline in ipairs(h.text) do | 474 | for _, hline in ipairs(h.text) do |
@@ -470,22 +477,18 @@ local function check_patched(file, hunks) | |||
470 | local line = file[lineno] | 477 | local line = file[lineno] |
471 | lineno = lineno + 1 | 478 | lineno = lineno + 1 |
472 | if #line == 0 then | 479 | if #line == 0 then |
473 | error 'nomatch' | 480 | error('nomatch', 0) |
474 | end | 481 | end |
475 | if endlstrip(line) ~= endlstrip(hline:sub(2)) then | 482 | if endlstrip(line) ~= endlstrip(hline:sub(2)) then |
476 | warning(format("file is not patched - failed hunk: %d", hno)) | 483 | warning(format("file is not patched - failed hunk: %d", hno)) |
477 | error 'nomatch' | 484 | error('nomatch', 0) |
478 | end | 485 | end |
479 | end | 486 | end |
480 | end | 487 | end |
481 | end | 488 | end |
482 | end) | 489 | end) |
483 | if err == 'nomatch' then | 490 | -- todo: display failed hunk, i.e. expected/found |
484 | matched = false | 491 | return err ~= 'nomatch' |
485 | end | ||
486 | -- todo: display failed hunk, i.e. expected/found | ||
487 | |||
488 | return matched | ||
489 | end | 492 | end |
490 | 493 | ||
491 | local function patch_hunks(srcname, tgtname, hunks) | 494 | local function patch_hunks(srcname, tgtname, hunks) |
@@ -532,7 +535,7 @@ local function patch_hunks(srcname, tgtname, hunks) | |||
532 | local line2write = hline:sub(2) | 535 | local line2write = hline:sub(2) |
533 | -- detect if line ends are consistent in source file | 536 | -- detect if line ends are consistent in source file |
534 | local sum = 0 | 537 | local sum = 0 |
535 | for k,v in pairs(lineends) do if v > 0 then sum=sum+1 end end | 538 | for _,v in pairs(lineends) do if v > 0 then sum=sum+1 end end |
536 | if sum == 1 then | 539 | if sum == 1 then |
537 | local newline | 540 | local newline |
538 | for k,v in pairs(lineends) do if v ~= 0 then newline = k end end | 541 | for k,v in pairs(lineends) do if v ~= 0 then newline = k end end |
@@ -553,7 +556,7 @@ end | |||
553 | 556 | ||
554 | local function strip_dirs(filename, strip) | 557 | local function strip_dirs(filename, strip) |
555 | if strip == nil then return filename end | 558 | if strip == nil then return filename end |
556 | for i=1,strip do | 559 | for _=1,strip do |
557 | filename=filename:gsub("^[^/]*/", "") | 560 | filename=filename:gsub("^[^/]*/", "") |
558 | end | 561 | end |
559 | return filename | 562 | return filename |
@@ -593,7 +596,6 @@ function patch.apply_patch(the_patch, strip) | |||
593 | local hunkno = 1 | 596 | local hunkno = 1 |
594 | local hunk = hunks[hunkno] | 597 | local hunk = hunks[hunkno] |
595 | local hunkfind = {} | 598 | local hunkfind = {} |
596 | local hunkreplace = {} | ||
597 | local validhunks = 0 | 599 | local validhunks = 0 |
598 | local canpatch = false | 600 | local canpatch = false |
599 | local hunklineno | 601 | local hunklineno |
@@ -610,15 +612,10 @@ function patch.apply_patch(the_patch, strip) | |||
610 | elseif lineno == hunk.startsrc then | 612 | elseif lineno == hunk.startsrc then |
611 | hunkfind = {} | 613 | hunkfind = {} |
612 | for _,x in ipairs(hunk.text) do | 614 | for _,x in ipairs(hunk.text) do |
613 | if x:sub(1,1) == ' ' or x:sub(1,1) == '-' then | 615 | if x:sub(1,1) == ' ' or x:sub(1,1) == '-' then |
614 | hunkfind[#hunkfind+1] = endlstrip(x:sub(2)) | 616 | hunkfind[#hunkfind+1] = endlstrip(x:sub(2)) |
615 | end end | 617 | end |
616 | hunkreplace = {} | 618 | end |
617 | for _,x in ipairs(hunk.text) do | ||
618 | if x:sub(1,1) == ' ' or x:sub(1,1) == '+' then | ||
619 | hunkreplace[#hunkreplace+1] = endlstrip(x:sub(2)) | ||
620 | end end | ||
621 | --pprint(hunkreplace) | ||
622 | hunklineno = 1 | 619 | hunklineno = 1 |
623 | 620 | ||
624 | -- todo \ No newline at end of file | 621 | -- todo \ No newline at end of file |
diff --git a/src/luarocks/tools/tar.lua b/src/luarocks/tools/tar.lua index 03f7de3c..b2bd930a 100644 --- a/src/luarocks/tools/tar.lua +++ b/src/luarocks/tools/tar.lua | |||
@@ -31,9 +31,10 @@ local function octal_to_number(octal) | |||
31 | local number = 0 | 31 | local number = 0 |
32 | for i = #octal,1,-1 do | 32 | for i = #octal,1,-1 do |
33 | local digit = tonumber(octal:sub(i,i)) | 33 | local digit = tonumber(octal:sub(i,i)) |
34 | if not digit then break end | 34 | if digit then |
35 | number = number + (digit * 8^exp) | 35 | number = number + (digit * 8^exp) |
36 | exp = exp + 1 | 36 | exp = exp + 1 |
37 | end | ||
37 | end | 38 | end |
38 | return number | 39 | return number |
39 | end | 40 | end |
@@ -143,6 +144,7 @@ function tar.untar(filename, destdir) | |||
143 | util.printout() | 144 | util.printout() |
144 | --]] | 145 | --]] |
145 | end | 146 | end |
147 | tar_handle:close() | ||
146 | return true | 148 | return true |
147 | end | 149 | end |
148 | 150 | ||
diff --git a/src/luarocks/tools/zip.lua b/src/luarocks/tools/zip.lua index 40cc089a..e6d9e36a 100644 --- a/src/luarocks/tools/zip.lua +++ b/src/luarocks/tools/zip.lua | |||
@@ -1,16 +1,38 @@ | |||
1 | 1 | ||
2 | --- A Lua implementation of .zip file archiving (used for creating .rock files), | 2 | --- A Lua implementation of .zip file archiving (used for creating .rock files), |
3 | -- using only lua-zlib. | 3 | -- using only lzlib or lua-lzib. |
4 | --module("luarocks.tools.zip", package.seeall) | ||
5 | local zip = {} | 4 | local zip = {} |
6 | 5 | ||
7 | local zlib = require("zlib") | 6 | local zlib = require("zlib") |
8 | local fs = require("luarocks.fs") | 7 | local fs = require("luarocks.fs") |
9 | local dir = require("luarocks.dir") | 8 | local dir = require("luarocks.dir") |
10 | 9 | ||
10 | -- zlib module can be provided by both lzlib and lua-lzib packages. | ||
11 | -- Create a compatibility layer. | ||
12 | local zlib_compress, zlib_crc32 | ||
13 | if zlib._VERSION:match "^lua%-zlib" then | ||
14 | function zlib_compress(data) | ||
15 | return (zlib.deflate()(data, "finish")) | ||
16 | end | ||
17 | |||
18 | function zlib_crc32(data) | ||
19 | return zlib.crc32()(data) | ||
20 | end | ||
21 | elseif zlib._VERSION:match "^lzlib" then | ||
22 | function zlib_compress(data) | ||
23 | return zlib.compress(data) | ||
24 | end | ||
25 | |||
26 | function zlib_crc32(data) | ||
27 | return zlib.crc32(zlib.crc32(), data) | ||
28 | end | ||
29 | else | ||
30 | error("unknown zlib library", 0) | ||
31 | end | ||
32 | |||
11 | local function number_to_bytestring(number, nbytes) | 33 | local function number_to_bytestring(number, nbytes) |
12 | local out = {} | 34 | local out = {} |
13 | for i = 1, nbytes do | 35 | for _ = 1, nbytes do |
14 | local byte = number % 256 | 36 | local byte = number % 256 |
15 | table.insert(out, string.char(byte)) | 37 | table.insert(out, string.char(byte)) |
16 | number = (number - byte) / 256 | 38 | number = (number - byte) / 256 |
@@ -31,32 +53,28 @@ local function zipwriter_open_new_file_in_zip(self, filename) | |||
31 | self.local_file_header = lfh | 53 | self.local_file_header = lfh |
32 | lfh.last_mod_file_time = 0 -- TODO | 54 | lfh.last_mod_file_time = 0 -- TODO |
33 | lfh.last_mod_file_date = 0 -- TODO | 55 | lfh.last_mod_file_date = 0 -- TODO |
34 | lfh.crc32 = 0 -- initial value | ||
35 | lfh.compressed_size = 0 -- unknown yet | ||
36 | lfh.uncompressed_size = 0 -- unknown yet | ||
37 | lfh.file_name_length = #filename | 56 | lfh.file_name_length = #filename |
38 | lfh.extra_field_length = 0 | 57 | lfh.extra_field_length = 0 |
39 | lfh.file_name = filename:gsub("\\", "/") | 58 | lfh.file_name = filename:gsub("\\", "/") |
40 | lfh.external_attr = 0 -- TODO properly store permissions | 59 | lfh.external_attr = 0 -- TODO properly store permissions |
41 | self.in_open_file = true | 60 | self.in_open_file = true |
42 | self.data = {} | ||
43 | return true | 61 | return true |
44 | end | 62 | end |
45 | 63 | ||
46 | --- Write data to the file currently being stored in the zipfile. | 64 | --- Write data to the file currently being stored in the zipfile. |
47 | -- @param self handle of the zipfile being written. | 65 | -- @param self handle of the zipfile being written. |
48 | -- @param buf string containing data to be written. | 66 | -- @param data string containing full contents of the file. |
49 | -- @return true if succeeded, nil in case of failure. | 67 | -- @return true if succeeded, nil in case of failure. |
50 | local function zipwriter_write_file_in_zip(self, buf) | 68 | local function zipwriter_write_file_in_zip(self, data) |
51 | if not self.in_open_file then | 69 | if not self.in_open_file then |
52 | return nil | 70 | return nil |
53 | end | 71 | end |
54 | local lfh = self.local_file_header | 72 | local lfh = self.local_file_header |
55 | local cbuf = zlib.compress(buf):sub(3, -5) | 73 | local compressed = zlib_compress(data):sub(3, -5) |
56 | lfh.crc32 = zlib.crc32(lfh.crc32, buf) | 74 | lfh.crc32 = zlib_crc32(data) |
57 | lfh.compressed_size = lfh.compressed_size + #cbuf | 75 | lfh.compressed_size = #compressed |
58 | lfh.uncompressed_size = lfh.uncompressed_size + #buf | 76 | lfh.uncompressed_size = #data |
59 | table.insert(self.data, cbuf) | 77 | self.data = compressed |
60 | return true | 78 | return true |
61 | end | 79 | end |
62 | 80 | ||
@@ -86,10 +104,8 @@ local function zipwriter_close_file_in_zip(self) | |||
86 | zh:write(number_to_bytestring(lfh.extra_field_length, 2)) | 104 | zh:write(number_to_bytestring(lfh.extra_field_length, 2)) |
87 | zh:write(lfh.file_name) | 105 | zh:write(lfh.file_name) |
88 | 106 | ||
89 | -- File data | 107 | -- File data |
90 | for _, cbuf in ipairs(self.data) do | 108 | zh:write(self.data) |
91 | zh:write(cbuf) | ||
92 | end | ||
93 | 109 | ||
94 | -- Data descriptor | 110 | -- Data descriptor |
95 | zh:write(number_to_bytestring(lfh.crc32, 4)) | 111 | zh:write(number_to_bytestring(lfh.crc32, 4)) |
@@ -117,12 +133,12 @@ local function zipwriter_add(self, file) | |||
117 | end | 133 | end |
118 | end | 134 | end |
119 | if ok then | 135 | if ok then |
120 | local buf = fin:read("*a") | 136 | local data = fin:read("*a") |
121 | if not buf then | 137 | if not data then |
122 | err = "error reading "..file | 138 | err = "error reading "..file |
123 | ok = false | 139 | ok = false |
124 | else | 140 | else |
125 | ok = self:write_file_in_zip(buf) | 141 | ok = self:write_file_in_zip(data) |
126 | if not ok then | 142 | if not ok then |
127 | err = "error in writing "..file.." in the zipfile" | 143 | err = "error in writing "..file.." in the zipfile" |
128 | end | 144 | end |
@@ -237,7 +253,7 @@ function zip.zip(zipfile, ...) | |||
237 | end | 253 | end |
238 | end | 254 | end |
239 | 255 | ||
240 | local ok = zw:close() | 256 | ok = zw:close() |
241 | if not ok then | 257 | if not ok then |
242 | return false, "error closing "..zipfile | 258 | return false, "error closing "..zipfile |
243 | end | 259 | end |
diff --git a/src/luarocks/type_check.lua b/src/luarocks/type_check.lua index a78c4848..65b4fc15 100644 --- a/src/luarocks/type_check.lua +++ b/src/luarocks/type_check.lua | |||
@@ -6,72 +6,97 @@ local type_check = {} | |||
6 | package.loaded["luarocks.type_check"] = type_check | 6 | package.loaded["luarocks.type_check"] = type_check |
7 | 7 | ||
8 | local cfg = require("luarocks.cfg") | 8 | local cfg = require("luarocks.cfg") |
9 | local deps = require("luarocks.deps") | ||
9 | 10 | ||
10 | type_check.rockspec_format = "1.0" | 11 | type_check.rockspec_format = "1.1" |
12 | |||
13 | local string_1 = { _type = "string" } | ||
14 | local number_1 = { _type = "number" } | ||
15 | local mandatory_string_1 = { _type = "string", _mandatory = true } | ||
16 | |||
17 | -- Syntax for type-checking tables: | ||
18 | -- | ||
19 | -- A type-checking table describes typing data for a value. | ||
20 | -- Any key starting with an underscore has a special meaning: | ||
21 | -- _type (string) is the Lua type of the value. Default is "table". | ||
22 | -- _version (string) is the minimum rockspec_version that supports this value. Default is "1.0". | ||
23 | -- _mandatory (boolean) indicates if the value is a mandatory key in its container table. Default is false. | ||
24 | -- For "string" types only: | ||
25 | -- _pattern (string) is the string-matching pattern, valid for string types only. Default is ".*". | ||
26 | -- For "table" types only: | ||
27 | -- _any (table) is the type-checking table for unspecified keys, recursively checked. | ||
28 | -- _more (boolean) indicates that the table accepts unspecified keys and does not type-check them. | ||
29 | -- Any other string keys that don't start with an underscore represent known keys and are type-checking tables, recursively checked. | ||
11 | 30 | ||
12 | local rockspec_types = { | 31 | local rockspec_types = { |
13 | rockspec_format = "string", | 32 | rockspec_format = string_1, |
14 | MUST_package = "string", | 33 | package = mandatory_string_1, |
15 | MUST_version = "[%w.]+-[%d]+", | 34 | version = { _type = "string", _pattern = "[%w.]+-[%d]+", _mandatory = true }, |
16 | description = { | 35 | description = { |
17 | summary = "string", | 36 | summary = string_1, |
18 | detailed = "string", | 37 | detailed = string_1, |
19 | homepage = "string", | 38 | homepage = string_1, |
20 | license = "string", | 39 | license = string_1, |
21 | maintainer = "string" | 40 | maintainer = string_1, |
22 | }, | 41 | }, |
23 | dependencies = { | 42 | dependencies = { |
24 | platforms = {}, | 43 | platforms = {}, -- recursively defined below |
25 | ANY = "string" | 44 | _any = string_1, |
26 | }, | 45 | }, |
27 | supported_platforms = { | 46 | supported_platforms = { |
28 | ANY = "string" | 47 | _any = string_1, |
29 | }, | 48 | }, |
30 | external_dependencies = { | 49 | external_dependencies = { |
31 | platforms = {}, | 50 | platforms = {}, -- recursively defined below |
32 | ANY = { | 51 | _any = { |
33 | program = "string", | 52 | program = string_1, |
34 | header = "string", | 53 | header = string_1, |
35 | library = "string" | 54 | library = string_1, |
36 | } | 55 | } |
37 | }, | 56 | }, |
38 | MUST_source = { | 57 | source = { |
39 | platforms = {}, | 58 | _mandatory = true, |
40 | MUST_url = "string", | 59 | platforms = {}, -- recursively defined below |
41 | md5 = "string", | 60 | url = mandatory_string_1, |
42 | file = "string", | 61 | md5 = string_1, |
43 | dir = "string", | 62 | file = string_1, |
44 | tag = "string", | 63 | dir = string_1, |
45 | branch = "string", | 64 | tag = string_1, |
46 | module = "string", | 65 | branch = string_1, |
47 | cvs_tag = "string", | 66 | module = string_1, |
48 | cvs_module = "string" | 67 | cvs_tag = string_1, |
68 | cvs_module = string_1, | ||
49 | }, | 69 | }, |
50 | build = { | 70 | build = { |
51 | platforms = {}, | 71 | platforms = {}, -- recursively defined below |
52 | type = "string", | 72 | type = string_1, |
53 | install = { | 73 | install = { |
54 | lua = { | 74 | lua = { |
55 | MORE = true | 75 | _more = true |
56 | }, | 76 | }, |
57 | lib = { | 77 | lib = { |
58 | MORE = true | 78 | _more = true |
59 | }, | 79 | }, |
60 | conf = { | 80 | conf = { |
61 | MORE = true | 81 | _more = true |
62 | }, | 82 | }, |
63 | bin = { | 83 | bin = { |
64 | MORE = true | 84 | _more = true |
65 | } | 85 | } |
66 | }, | 86 | }, |
67 | copy_directories = { | 87 | copy_directories = { |
68 | ANY = "string" | 88 | _any = string_1, |
69 | }, | 89 | }, |
70 | MORE = true | 90 | _more = true, |
91 | _mandatory = true | ||
71 | }, | 92 | }, |
72 | hooks = { | 93 | hooks = { |
73 | platforms = {}, | 94 | platforms = {}, -- recursively defined below |
74 | post_install = "string" | 95 | post_install = string_1, |
96 | }, | ||
97 | deploy = { | ||
98 | _version = "1.1", | ||
99 | wrap_bin_scripts = { _type = "boolean", _version = "1.1" }, | ||
75 | } | 100 | } |
76 | } | 101 | } |
77 | 102 | ||
@@ -82,69 +107,61 @@ type_check.rockspec_order = {"rockspec_format", "package", "version", | |||
82 | { "build", {"type", "modules", "copy_directories", "platforms"} }, | 107 | { "build", {"type", "modules", "copy_directories", "platforms"} }, |
83 | "hooks"} | 108 | "hooks"} |
84 | 109 | ||
85 | function type_check.load_extensions() | 110 | rockspec_types.build.platforms._any = rockspec_types.build |
86 | type_check.rockspec_format = "1.1" | 111 | rockspec_types.dependencies.platforms._any = rockspec_types.dependencies |
87 | rockspec_types.deploy = { | 112 | rockspec_types.external_dependencies.platforms._any = rockspec_types.external_dependencies |
88 | wrap_bin_scripts = true, | 113 | rockspec_types.source.platforms._any = rockspec_types.source |
89 | } | 114 | rockspec_types.hooks.platforms._any = rockspec_types.hooks |
90 | end | ||
91 | |||
92 | if cfg.use_extensions then | ||
93 | type_check.load_extensions() | ||
94 | end | ||
95 | |||
96 | rockspec_types.build.platforms.ANY = rockspec_types.build | ||
97 | rockspec_types.dependencies.platforms.ANY = rockspec_types.dependencies | ||
98 | rockspec_types.external_dependencies.platforms.ANY = rockspec_types.external_dependencies | ||
99 | rockspec_types.MUST_source.platforms.ANY = rockspec_types.MUST_source | ||
100 | rockspec_types.hooks.platforms.ANY = rockspec_types.hooks | ||
101 | 115 | ||
102 | local manifest_types = { | 116 | local manifest_types = { |
103 | MUST_repository = { | 117 | repository = { |
118 | _mandatory = true, | ||
104 | -- packages | 119 | -- packages |
105 | ANY = { | 120 | _any = { |
106 | -- versions | 121 | -- versions |
107 | ANY = { | 122 | _any = { |
108 | -- items | 123 | -- items |
109 | ANY = { | 124 | _any = { |
110 | MUST_arch = "string", | 125 | arch = mandatory_string_1, |
111 | modules = { ANY = "string" }, | 126 | modules = { _any = string_1 }, |
112 | commands = { ANY = "string" }, | 127 | commands = { _any = string_1 }, |
113 | dependencies = { ANY = "string" }, | 128 | dependencies = { _any = string_1 }, |
114 | -- TODO: to be extended with more metadata. | 129 | -- TODO: to be extended with more metadata. |
115 | } | 130 | } |
116 | } | 131 | } |
117 | } | 132 | } |
118 | }, | 133 | }, |
119 | MUST_modules = { | 134 | modules = { |
135 | _mandatory = true, | ||
120 | -- modules | 136 | -- modules |
121 | ANY = { | 137 | _any = { |
122 | -- providers | 138 | -- providers |
123 | ANY = "string" | 139 | _any = string_1 |
124 | } | 140 | } |
125 | }, | 141 | }, |
126 | MUST_commands = { | 142 | commands = { |
143 | _mandatory = true, | ||
127 | -- modules | 144 | -- modules |
128 | ANY = { | 145 | _any = { |
129 | -- commands | 146 | -- commands |
130 | ANY = "string" | 147 | _any = string_1 |
131 | } | 148 | } |
132 | }, | 149 | }, |
133 | dependencies = { | 150 | dependencies = { |
134 | -- each module | 151 | -- each module |
135 | ANY = { | 152 | _any = { |
136 | -- each version | 153 | -- each version |
137 | ANY = { | 154 | _any = { |
138 | -- each dependency | 155 | -- each dependency |
139 | ANY = { | 156 | _any = { |
140 | name = "string", | 157 | name = string_1, |
141 | constraints = { | 158 | constraints = { |
142 | ANY = { | 159 | _any = { |
143 | no_upgrade = "boolean", | 160 | no_upgrade = { _type = "boolean" }, |
144 | op = "string", | 161 | op = string_1, |
145 | version = { | 162 | version = { |
146 | string = "string", | 163 | string = string_1, |
147 | ANY = 0, | 164 | _any = number_1, |
148 | } | 165 | } |
149 | } | 166 | } |
150 | } | 167 | } |
@@ -154,54 +171,75 @@ local manifest_types = { | |||
154 | } | 171 | } |
155 | } | 172 | } |
156 | 173 | ||
174 | local function check_version(version, typetbl, context) | ||
175 | local typetbl_version = typetbl._version or "1.0" | ||
176 | if deps.compare_versions(typetbl_version, version) then | ||
177 | if context == "" then | ||
178 | return nil, "Invalid rockspec_format version number in rockspec? Please fix rockspec accordingly." | ||
179 | else | ||
180 | return nil, context.." is not supported in rockspec format "..version.." (requires version "..typetbl_version.."), please fix the rockspec_format field accordingly." | ||
181 | end | ||
182 | end | ||
183 | return true | ||
184 | end | ||
185 | |||
157 | local type_check_table | 186 | local type_check_table |
158 | 187 | ||
159 | --- Type check an object. | 188 | --- Type check an object. |
160 | -- The object is compared against an archetypical value | 189 | -- The object is compared against an archetypical value |
161 | -- matching the expected type -- the actual values don't matter, | 190 | -- matching the expected type -- the actual values don't matter, |
162 | -- only their types. Tables are type checked recursively. | 191 | -- only their types. Tables are type checked recursively. |
163 | -- @param name any: The object name (for error messages). | 192 | -- @param version string: The version of the item. |
164 | -- @param item any: The object being checked. | 193 | -- @param item any: The object being checked. |
165 | -- @param expected any: The reference object. In case of a table, | 194 | -- @param typetbl any: The type-checking table for the object. |
166 | -- its is structured as a type reference table. | ||
167 | -- @param context string: A string indicating the "context" where the | 195 | -- @param context string: A string indicating the "context" where the |
168 | -- error occurred (such as the name of the table the item is a part of), | 196 | -- error occurred (the full table path), for error messages. |
169 | -- to be used by error messages. | ||
170 | -- @return boolean or (nil, string): true if type checking | 197 | -- @return boolean or (nil, string): true if type checking |
171 | -- succeeded, or nil and an error message if it failed. | 198 | -- succeeded, or nil and an error message if it failed. |
172 | -- @see type_check_table | 199 | -- @see type_check_table |
173 | local function type_check_item(name, item, expected, context) | 200 | local function type_check_item(version, item, typetbl, context) |
174 | name = tostring(name) | 201 | assert(type(version) == "string") |
175 | 202 | ||
176 | local item_type = type(item) | 203 | local ok, err = check_version(version, typetbl, context) |
177 | local expected_type = type(expected) | 204 | if not ok then |
205 | return nil, err | ||
206 | end | ||
207 | |||
208 | local item_type = type(item) or "nil" | ||
209 | local expected_type = typetbl._type or "table" | ||
210 | |||
178 | if expected_type == "number" then | 211 | if expected_type == "number" then |
179 | if not tonumber(item) then | 212 | if not tonumber(item) then |
180 | return nil, "Type mismatch on field "..context..name..": expected a number" | 213 | return nil, "Type mismatch on field "..context..": expected a number" |
181 | end | 214 | end |
182 | elseif expected_type == "string" then | 215 | elseif expected_type == "string" then |
183 | if type(item) ~= "string" then | 216 | if item_type ~= "string" then |
184 | return nil, "Type mismatch on field "..context..name..": expected a string" | 217 | return nil, "Type mismatch on field "..context..": expected a string, got "..item_type |
185 | end | 218 | end |
186 | if expected ~= "string" then | 219 | if typetbl._pattern then |
187 | if item_type ~= "string" then | 220 | if not item:match("^"..typetbl._pattern.."$") then |
188 | return nil, "Type mismatch on field "..context..name..": expected a string, got a "..type(item) | 221 | return nil, "Type mismatch on field "..context..": invalid value "..item.." does not match '"..typetbl._pattern.."'" |
189 | elseif not item:match("^"..expected.."$") then | ||
190 | return nil, "Type mismatch on field "..context..name..": invalid value "..item.." does not match '"..expected.."'" | ||
191 | end | 222 | end |
192 | end | 223 | end |
193 | elseif expected_type == "table" then | 224 | elseif expected_type == "table" then |
194 | if item_type ~= expected_type then | 225 | if item_type ~= expected_type then |
195 | return nil, "Type mismatch on field "..context..name..": expected a table" | 226 | return nil, "Type mismatch on field "..context..": expected a table" |
196 | else | 227 | else |
197 | return type_check_table(item, expected, context..name..".") | 228 | return type_check_table(version, item, typetbl, context) |
198 | end | 229 | end |
199 | elseif item_type ~= expected_type then | 230 | elseif item_type ~= expected_type then |
200 | return nil, "Type mismatch on field "..context..name..": expected a "..expected_type | 231 | return nil, "Type mismatch on field "..context..": expected "..expected_type |
201 | end | 232 | end |
202 | return true | 233 | return true |
203 | end | 234 | end |
204 | 235 | ||
236 | local function mkfield(context, field) | ||
237 | if context == "" then | ||
238 | return field | ||
239 | end | ||
240 | return context.."."..field | ||
241 | end | ||
242 | |||
205 | --- Type check the contents of a table. | 243 | --- Type check the contents of a table. |
206 | -- The table's contents are compared against a reference table, | 244 | -- The table's contents are compared against a reference table, |
207 | -- which contains the recognized fields, with archetypical values | 245 | -- which contains the recognized fields, with archetypical values |
@@ -215,23 +253,31 @@ end | |||
215 | -- with MUST_, it is mandatory; its absence from the table is | 253 | -- with MUST_, it is mandatory; its absence from the table is |
216 | -- a type error. | 254 | -- a type error. |
217 | -- Tables are type checked recursively. | 255 | -- Tables are type checked recursively. |
256 | -- @param version string: The version of tbl. | ||
218 | -- @param tbl table: The table to be type checked. | 257 | -- @param tbl table: The table to be type checked. |
219 | -- @param types table: The reference table, containing | 258 | -- @param typetbl table: The type-checking table, containing |
220 | -- values for recognized fields in the checked table. | 259 | -- values for recognized fields in the checked table. |
221 | -- @param context string: A string indicating the "context" where the | 260 | -- @param context string: A string indicating the "context" where the |
222 | -- error occurred (such as the name of the table the item is a part of), | 261 | -- error occurred (such as the name of the table the item is a part of), |
223 | -- to be used by error messages. | 262 | -- to be used by error messages. |
224 | -- @return boolean or (nil, string): true if type checking | 263 | -- @return boolean or (nil, string): true if type checking |
225 | -- succeeded, or nil and an error message if it failed. | 264 | -- succeeded, or nil and an error message if it failed. |
226 | type_check_table = function(tbl, types, context) | 265 | type_check_table = function(version, tbl, typetbl, context) |
266 | assert(type(version) == "string") | ||
227 | assert(type(tbl) == "table") | 267 | assert(type(tbl) == "table") |
228 | assert(type(types) == "table") | 268 | assert(type(typetbl) == "table") |
269 | |||
270 | local ok, err = check_version(version, typetbl, context) | ||
271 | if not ok then | ||
272 | return nil, err | ||
273 | end | ||
274 | |||
229 | for k, v in pairs(tbl) do | 275 | for k, v in pairs(tbl) do |
230 | local t = types[k] or (type(k) == "string" and types["MUST_"..k]) or types.ANY | 276 | local t = typetbl[k] or typetbl._any |
231 | if t then | 277 | if t then |
232 | local ok, err = type_check_item(k, v, t, context) | 278 | local ok, err = type_check_item(version, v, t, mkfield(context, k)) |
233 | if not ok then return nil, err end | 279 | if not ok then return nil, err end |
234 | elseif types.MORE then | 280 | elseif typetbl._more then |
235 | -- Accept unknown field | 281 | -- Accept unknown field |
236 | else | 282 | else |
237 | if not cfg.accept_unknown_fields then | 283 | if not cfg.accept_unknown_fields then |
@@ -239,21 +285,20 @@ type_check_table = function(tbl, types, context) | |||
239 | end | 285 | end |
240 | end | 286 | end |
241 | end | 287 | end |
242 | for k, v in pairs(types) do | 288 | for k, v in pairs(typetbl) do |
243 | local mandatory_key = k:match("^MUST_(.+)") | 289 | if k:sub(1,1) ~= "_" and v._mandatory then |
244 | if mandatory_key then | 290 | if not tbl[k] then |
245 | if not tbl[mandatory_key] then | 291 | return nil, "Mandatory field "..mkfield(context, k).." is missing." |
246 | return nil, "Mandatory field "..context..mandatory_key.." is missing." | ||
247 | end | 292 | end |
248 | end | 293 | end |
249 | end | 294 | end |
250 | return true | 295 | return true |
251 | end | 296 | end |
252 | 297 | ||
253 | local function check_undeclared_globals(globals, types) | 298 | local function check_undeclared_globals(globals, typetbl) |
254 | local undeclared = {} | 299 | local undeclared = {} |
255 | for glob, _ in pairs(globals) do | 300 | for glob, _ in pairs(globals) do |
256 | if not (types[glob] or types["MUST_"..glob]) then | 301 | if not (typetbl[glob] or typetbl["MUST_"..glob]) then |
257 | table.insert(undeclared, glob) | 302 | table.insert(undeclared, glob) |
258 | end | 303 | end |
259 | end | 304 | end |
@@ -273,13 +318,12 @@ end | |||
273 | -- succeeded, or nil and an error message if it failed. | 318 | -- succeeded, or nil and an error message if it failed. |
274 | function type_check.type_check_rockspec(rockspec, globals) | 319 | function type_check.type_check_rockspec(rockspec, globals) |
275 | assert(type(rockspec) == "table") | 320 | assert(type(rockspec) == "table") |
276 | if rockspec.rockspec_format then | 321 | if not rockspec.rockspec_format then |
277 | -- relies on global state | 322 | rockspec.rockspec_format = "1.0" |
278 | type_check.load_extensions() | ||
279 | end | 323 | end |
280 | local ok, err = check_undeclared_globals(globals, rockspec_types) | 324 | local ok, err = check_undeclared_globals(globals, rockspec_types) |
281 | if not ok then return nil, err end | 325 | if not ok then return nil, err end |
282 | return type_check_table(rockspec, rockspec_types, "") | 326 | return type_check_table(rockspec.rockspec_format, rockspec, rockspec_types, "") |
283 | end | 327 | end |
284 | 328 | ||
285 | --- Type check a manifest table. | 329 | --- Type check a manifest table. |
@@ -292,7 +336,7 @@ function type_check.type_check_manifest(manifest, globals) | |||
292 | assert(type(manifest) == "table") | 336 | assert(type(manifest) == "table") |
293 | local ok, err = check_undeclared_globals(globals, manifest_types) | 337 | local ok, err = check_undeclared_globals(globals, manifest_types) |
294 | if not ok then return nil, err end | 338 | if not ok then return nil, err end |
295 | return type_check_table(manifest, manifest_types, "") | 339 | return type_check_table("1.0", manifest, manifest_types, "") |
296 | end | 340 | end |
297 | 341 | ||
298 | return type_check | 342 | return type_check |
diff --git a/src/luarocks/unpack.lua b/src/luarocks/unpack.lua index 9204e265..a889bac5 100644 --- a/src/luarocks/unpack.lua +++ b/src/luarocks/unpack.lua | |||
@@ -43,9 +43,10 @@ local function unpack_rockspec(rockspec_file, dir_name) | |||
43 | end | 43 | end |
44 | ok, err = fs.change_dir(sources_dir) | 44 | ok, err = fs.change_dir(sources_dir) |
45 | if not ok then return nil, err end | 45 | if not ok then return nil, err end |
46 | build.apply_patches(rockspec) | 46 | ok, err = build.apply_patches(rockspec) |
47 | fs.pop_dir() | 47 | fs.pop_dir() |
48 | fs.pop_dir() | 48 | fs.pop_dir() |
49 | if not ok then return nil, err end | ||
49 | return rockspec | 50 | return rockspec |
50 | end | 51 | end |
51 | 52 | ||
@@ -79,8 +80,9 @@ local function unpack_rock(rock_file, dir_name, kind) | |||
79 | end | 80 | end |
80 | ok, err = fs.change_dir(rockspec.source.dir) | 81 | ok, err = fs.change_dir(rockspec.source.dir) |
81 | if not ok then return nil, err end | 82 | if not ok then return nil, err end |
82 | build.apply_patches(rockspec) | 83 | ok, err = build.apply_patches(rockspec) |
83 | fs.pop_dir() | 84 | fs.pop_dir() |
85 | if not ok then return nil, err end | ||
84 | end | 86 | end |
85 | end | 87 | end |
86 | return rockspec | 88 | return rockspec |
diff --git a/src/luarocks/upload.lua b/src/luarocks/upload.lua index 018e702d..19ddee8d 100644 --- a/src/luarocks/upload.lua +++ b/src/luarocks/upload.lua | |||
@@ -4,6 +4,7 @@ local upload = {} | |||
4 | local util = require("luarocks.util") | 4 | local util = require("luarocks.util") |
5 | local fetch = require("luarocks.fetch") | 5 | local fetch = require("luarocks.fetch") |
6 | local pack = require("luarocks.pack") | 6 | local pack = require("luarocks.pack") |
7 | local cfg = require("luarocks.cfg") | ||
7 | local Api = require("luarocks.upload.api") | 8 | local Api = require("luarocks.upload.api") |
8 | 9 | ||
9 | upload.help_summary = "Upload a rockspec to the public rocks repository." | 10 | upload.help_summary = "Upload a rockspec to the public rocks repository." |
@@ -29,6 +30,9 @@ function upload.run(...) | |||
29 | if not api then | 30 | if not api then |
30 | return nil, err | 31 | return nil, err |
31 | end | 32 | end |
33 | if cfg.verbose then | ||
34 | api.debug = true | ||
35 | end | ||
32 | 36 | ||
33 | local rockspec, err, errcode = fetch.load_rockspec(fname) | 37 | local rockspec, err, errcode = fetch.load_rockspec(fname) |
34 | if err then | 38 | if err then |
@@ -50,7 +54,7 @@ function upload.run(...) | |||
50 | end | 54 | end |
51 | 55 | ||
52 | local rock_fname | 56 | local rock_fname |
53 | if not flags["skip-pack"] then | 57 | if not flags["skip-pack"] and not rockspec.version:match("^scm") then |
54 | util.printout("Packing " .. tostring(rockspec.package)) | 58 | util.printout("Packing " .. tostring(rockspec.package)) |
55 | rock_fname, err = pack.pack_source_rock(fname) | 59 | rock_fname, err = pack.pack_source_rock(fname) |
56 | if not rock_fname then | 60 | if not rock_fname then |
@@ -73,7 +77,7 @@ function upload.run(...) | |||
73 | 77 | ||
74 | if rock_fname then | 78 | if rock_fname then |
75 | util.printout(("Sending " .. tostring(rock_fname) .. " ...")) | 79 | util.printout(("Sending " .. tostring(rock_fname) .. " ...")) |
76 | res, err = api:method("upload_rock/" .. tostring(res.version.id), nil, { | 80 | res, err = api:method("upload_rock/" .. ("%d"):format(res.version.id), nil, { |
77 | rock_file = multipart.new_file(rock_fname) | 81 | rock_file = multipart.new_file(rock_fname) |
78 | }) | 82 | }) |
79 | if not res then return nil, err end | 83 | if not res then return nil, err end |
diff --git a/src/luarocks/upload/api.lua b/src/luarocks/upload/api.lua index 818d293e..6df24569 100644 --- a/src/luarocks/upload/api.lua +++ b/src/luarocks/upload/api.lua | |||
@@ -5,20 +5,20 @@ local cfg = require("luarocks.cfg") | |||
5 | local fs = require("luarocks.fs") | 5 | local fs = require("luarocks.fs") |
6 | local util = require("luarocks.util") | 6 | local util = require("luarocks.util") |
7 | local persist = require("luarocks.persist") | 7 | local persist = require("luarocks.persist") |
8 | local multipart = require("luarocks.upload.multipart") | ||
8 | 9 | ||
9 | local Api = {} | 10 | local Api = {} |
10 | 11 | ||
11 | local function upload_config_file() | 12 | local function upload_config_file() |
12 | local _, _, home_conf, home_ok = cfg.which_config() | 13 | local conf = cfg.which_config() |
13 | if not home_conf then | 14 | if not conf.user.file then |
14 | return nil | 15 | return nil |
15 | end | 16 | end |
16 | return (home_conf:gsub("/[^/]+$", "/upload_config.lua")) | 17 | return (conf.user.file:gsub("/[^/]+$", "/upload_config.lua")) |
17 | end | 18 | end |
18 | 19 | ||
19 | function Api:load_config() | 20 | function Api:load_config() |
20 | local upload_conf = upload_config_file() | 21 | local upload_conf = upload_config_file() |
21 | print(upload_conf) | ||
22 | if not upload_conf then return nil end | 22 | if not upload_conf then return nil end |
23 | local cfg, err = persist.load_into_table(upload_conf) | 23 | local cfg, err = persist.load_into_table(upload_conf) |
24 | return cfg | 24 | return cfg |
@@ -43,7 +43,7 @@ end | |||
43 | function Api:check_version() | 43 | function Api:check_version() |
44 | if not self._server_tool_version then | 44 | if not self._server_tool_version then |
45 | local tool_version = cfg.upload.tool_version | 45 | local tool_version = cfg.upload.tool_version |
46 | local res, err = self:request("http://" .. tostring(self.config.server) .. "/api/tool_version", { | 46 | local res, err = self:request(tostring(self.config.server) .. "/api/tool_version", { |
47 | current = tool_version | 47 | current = tool_version |
48 | }) | 48 | }) |
49 | if not res then | 49 | if not res then |
@@ -80,12 +80,11 @@ end | |||
80 | 80 | ||
81 | function Api:raw_method(path, ...) | 81 | function Api:raw_method(path, ...) |
82 | self:check_version() | 82 | self:check_version() |
83 | local url = "http://" .. tostring(self.config.server) .. "/api/" .. tostring(cfg.upload.api_version) .. "/" .. tostring(self.config.key) .. "/" .. tostring(path) | 83 | local url = tostring(self.config.server) .. "/api/" .. tostring(cfg.upload.api_version) .. "/" .. tostring(self.config.key) .. "/" .. tostring(path) |
84 | return self:request(url, ...) | 84 | return self:request(url, ...) |
85 | end | 85 | end |
86 | 86 | ||
87 | local function encode_query_string(t, sep) | 87 | local function encode_query_string(t, sep) |
88 | local url = require("socket.url") | ||
89 | if sep == nil then | 88 | if sep == nil then |
90 | sep = "&" | 89 | sep = "&" |
91 | end | 90 | end |
@@ -95,9 +94,9 @@ local function encode_query_string(t, sep) | |||
95 | if type(k) == "number" and type(v) == "table" then | 94 | if type(k) == "number" and type(v) == "table" then |
96 | k, v = v[1], v[2] | 95 | k, v = v[1], v[2] |
97 | end | 96 | end |
98 | buf[i + 1] = url.escape(k) | 97 | buf[i + 1] = multipart.url_escape(k) |
99 | buf[i + 2] = "=" | 98 | buf[i + 2] = "=" |
100 | buf[i + 3] = url.escape(v) | 99 | buf[i + 3] = multipart.url_escape(v) |
101 | buf[i + 4] = sep | 100 | buf[i + 4] = sep |
102 | i = i + 4 | 101 | i = i + 4 |
103 | end | 102 | end |
@@ -107,21 +106,125 @@ end | |||
107 | 106 | ||
108 | -- An ode to the multitude of JSON libraries out there... | 107 | -- An ode to the multitude of JSON libraries out there... |
109 | local function require_json() | 108 | local function require_json() |
110 | for _, lib in ipairs({ "cjson", "dkjson", "json" }) do | 109 | local list = { "cjson", "dkjson", "json" } |
110 | for _, lib in ipairs(list) do | ||
111 | local json_ok, json = pcall(require, lib) | 111 | local json_ok, json = pcall(require, lib) |
112 | if json_ok then | 112 | if json_ok then |
113 | return json_ok, json | 113 | return json_ok, json |
114 | end | 114 | end |
115 | end | 115 | end |
116 | return nil | 116 | local errmsg = "Failed loading " |
117 | for i, name in ipairs(list) do | ||
118 | if i == #list then | ||
119 | errmsg = errmsg .."and '"..name.."'. Use 'luarocks search <partial-name>' to search for a library and 'luarocks install <name>' to install one." | ||
120 | else | ||
121 | errmsg = errmsg .."'"..name.."', " | ||
122 | end | ||
123 | end | ||
124 | return nil, errmsg | ||
125 | end | ||
126 | |||
127 | local function redact_api_url(url) | ||
128 | url = tostring(url) | ||
129 | return (url:gsub(".*/api/[^/]+/[^/]+", "")) or "" | ||
117 | end | 130 | end |
118 | 131 | ||
132 | local ltn12_ok, ltn12 = pcall(require, "ltn12") | ||
133 | if not ltn12_ok then -- If not using LuaSocket and/or LuaSec... | ||
134 | |||
119 | function Api:request(url, params, post_params) | 135 | function Api:request(url, params, post_params) |
120 | local http_ok, http = pcall(require, "socket.http") | 136 | local vars = cfg.variables |
121 | local ltn12_ok, ltn12 = pcall(require, "ltn12") | ||
122 | local json_ok, json = require_json() | 137 | local json_ok, json = require_json() |
123 | if not http_ok then return nil, "LuaSocket is required for this command." end | 138 | if not json_ok then return nil, "A JSON library is required for this command. "..json end |
124 | if not json_ok then return nil, "A JSON library is required for this command." end | 139 | |
140 | if cfg.downloader == "wget" then | ||
141 | local curl_ok, err = fs.is_tool_available(vars.CURL, "curl") | ||
142 | if not curl_ok then | ||
143 | return nil, err | ||
144 | end | ||
145 | end | ||
146 | |||
147 | if not self.config.key then | ||
148 | return nil, "Must have API key before performing any actions." | ||
149 | end | ||
150 | local body | ||
151 | local headers = {} | ||
152 | if params and next(params) then | ||
153 | url = url .. ("?" .. encode_query_string(params)) | ||
154 | end | ||
155 | local method = "GET" | ||
156 | local out | ||
157 | local tmpfile = fs.tmpname() | ||
158 | if post_params then | ||
159 | method = "POST" | ||
160 | local curl_cmd = fs.Q(vars.CURL).." -f -k -L --silent --user-agent \""..cfg.user_agent.." via curl\" " | ||
161 | for k,v in pairs(post_params) do | ||
162 | local var = v | ||
163 | if type(v) == "table" then | ||
164 | var = "@"..v.fname | ||
165 | end | ||
166 | curl_cmd = curl_cmd .. "--form \""..k.."="..var.."\" " | ||
167 | end | ||
168 | if cfg.connection_timeout and cfg.connection_timeout > 0 then | ||
169 | curl_cmd = curl_cmd .. "--connect-timeout "..tonumber(cfg.connection_timeout).." " | ||
170 | end | ||
171 | local ok = fs.execute_string(curl_cmd..fs.Q(url).." -o "..fs.Q(tmpfile)) | ||
172 | if not ok then | ||
173 | return nil, "API failure: " .. redact_api_url(url) | ||
174 | end | ||
175 | else | ||
176 | local ok, err = fs.download(url, tmpfile) | ||
177 | if not ok then | ||
178 | return nil, "API failure: " .. tostring(err) .. " - " .. redact_api_url(url) | ||
179 | end | ||
180 | end | ||
181 | |||
182 | local tmpfd = io.open(tmpfile) | ||
183 | if not tmpfd then | ||
184 | os.remove(tmpfile) | ||
185 | return nil, "API failure reading temporary file - " .. redact_api_url(url) | ||
186 | end | ||
187 | out = tmpfd:read("*a") | ||
188 | tmpfd:close() | ||
189 | os.remove(tmpfile) | ||
190 | |||
191 | if self.debug then | ||
192 | util.printout("[" .. tostring(method) .. " via curl] " .. redact_api_url(url) .. " ... ") | ||
193 | end | ||
194 | |||
195 | return json.decode(out) | ||
196 | end | ||
197 | |||
198 | else -- use LuaSocket and LuaSec | ||
199 | |||
200 | local warned_luasec = false | ||
201 | |||
202 | function Api:request(url, params, post_params) | ||
203 | local json_ok, json = require_json() | ||
204 | if not json_ok then return nil, "A JSON library is required for this command. "..json end | ||
205 | local server = tostring(self.config.server) | ||
206 | local http_ok, http | ||
207 | local via = "luasocket" | ||
208 | if server:match("^https://") then | ||
209 | http_ok, http = pcall(require, "ssl.https") | ||
210 | if http_ok then | ||
211 | via = "luasec" | ||
212 | else | ||
213 | if not warned_luasec then | ||
214 | util.printerr("LuaSec is not available; using plain HTTP. Install 'luasec' to enable HTTPS.") | ||
215 | warned_luasec = true | ||
216 | end | ||
217 | http_ok, http = pcall(require, "socket.http") | ||
218 | server = server:gsub("^https", "http") | ||
219 | url = url:gsub("^https", "http") | ||
220 | via = "luasocket" | ||
221 | end | ||
222 | else | ||
223 | http_ok, http = pcall(require, "socket.http") | ||
224 | end | ||
225 | if not http_ok then | ||
226 | return nil, "Failed loading socket library!" | ||
227 | end | ||
125 | 228 | ||
126 | if not self.config.key then | 229 | if not self.config.key then |
127 | return nil, "Must have API key before performing any actions." | 230 | return nil, "Must have API key before performing any actions." |
@@ -132,7 +235,6 @@ function Api:request(url, params, post_params) | |||
132 | url = url .. ("?" .. encode_query_string(params)) | 235 | url = url .. ("?" .. encode_query_string(params)) |
133 | end | 236 | end |
134 | if post_params then | 237 | if post_params then |
135 | local multipart = require("luarocks.upload.multipart") | ||
136 | local boundary | 238 | local boundary |
137 | body, boundary = multipart.encode(post_params) | 239 | body, boundary = multipart.encode(post_params) |
138 | headers["Content-length"] = #body | 240 | headers["Content-length"] = #body |
@@ -140,7 +242,7 @@ function Api:request(url, params, post_params) | |||
140 | end | 242 | end |
141 | local method = post_params and "POST" or "GET" | 243 | local method = post_params and "POST" or "GET" |
142 | if self.debug then | 244 | if self.debug then |
143 | util.printout("[" .. tostring(method) .. "] " .. tostring(url) .. " ... ") | 245 | util.printout("[" .. tostring(method) .. " via "..via.."] " .. redact_api_url(url) .. " ... ") |
144 | end | 246 | end |
145 | local out = {} | 247 | local out = {} |
146 | local _, status = http.request({ | 248 | local _, status = http.request({ |
@@ -154,12 +256,14 @@ function Api:request(url, params, post_params) | |||
154 | util.printout(tostring(status)) | 256 | util.printout(tostring(status)) |
155 | end | 257 | end |
156 | if status ~= 200 then | 258 | if status ~= 200 then |
157 | return nil, "API returned " .. tostring(status) .. " - " .. tostring(url) | 259 | return nil, "API returned " .. tostring(status) .. " - " .. redact_api_url(url) |
158 | end | 260 | end |
159 | return json.decode(table.concat(out)) | 261 | return json.decode(table.concat(out)) |
160 | end | 262 | end |
161 | 263 | ||
162 | function api.new(flags, name) | 264 | end |
265 | |||
266 | function api.new(flags) | ||
163 | local self = {} | 267 | local self = {} |
164 | setmetatable(self, { __index = Api }) | 268 | setmetatable(self, { __index = Api }) |
165 | self.config = self:load_config() or {} | 269 | self.config = self:load_config() or {} |
@@ -169,7 +273,7 @@ function api.new(flags, name) | |||
169 | self.debug = flags["debug"] | 273 | self.debug = flags["debug"] |
170 | if not self.config.key then | 274 | if not self.config.key then |
171 | return nil, "You need an API key to upload rocks.\n" .. | 275 | return nil, "You need an API key to upload rocks.\n" .. |
172 | "Navigate to http://"..self.config.server.."/settings to get a key\n" .. | 276 | "Navigate to "..self.config.server.."/settings to get a key\n" .. |
173 | "and then pass it through the --api-key=<key> flag." | 277 | "and then pass it through the --api-key=<key> flag." |
174 | end | 278 | end |
175 | if flags["api-key"] then | 279 | if flags["api-key"] then |
diff --git a/src/luarocks/upload/multipart.lua b/src/luarocks/upload/multipart.lua index 95afe1b3..aad2e439 100644 --- a/src/luarocks/upload/multipart.lua +++ b/src/luarocks/upload/multipart.lua | |||
@@ -1,28 +1,32 @@ | |||
1 | 1 | ||
2 | local multipart = {} | 2 | local multipart = {} |
3 | 3 | ||
4 | local url = require("socket.url") | ||
5 | |||
6 | local File = {} | 4 | local File = {} |
7 | 5 | ||
8 | local unpack = unpack or table.unpack | 6 | local unpack = unpack or table.unpack |
9 | 7 | ||
10 | math.randomseed(os.time()) | 8 | math.randomseed(os.time()) |
11 | 9 | ||
10 | -- socket.url.escape(s) from LuaSocket 3.0rc1 | ||
11 | function multipart.url_escape(s) | ||
12 | return (string.gsub(s, "([^A-Za-z0-9_])", function(c) | ||
13 | return string.format("%%%02x", string.byte(c)) | ||
14 | end)) | ||
15 | end | ||
16 | |||
12 | function File:mime() | 17 | function File:mime() |
13 | if not self.mimetype then | 18 | if not self.mimetype then |
14 | local mimetypes_ok, mimetypes = pcall(require, "mimetypes") | 19 | local mimetypes_ok, mimetypes = pcall(require, "mimetypes") |
15 | if mimetypes_ok then | 20 | if mimetypes_ok then |
16 | self.mimetype = mimetypes.guess(self.fname) | 21 | self.mimetype = mimetypes.guess(self.fname) |
17 | else | ||
18 | self.mimetype = "application/octet-stream" | ||
19 | end | 22 | end |
23 | self.mimetype = self.mimetype or "application/octet-stream" | ||
20 | end | 24 | end |
21 | return self.mimetype | 25 | return self.mimetype |
22 | end | 26 | end |
23 | 27 | ||
24 | function File:content() | 28 | function File:content() |
25 | local fd = io.open(self.fname) | 29 | local fd = io.open(self.fname, "rb") |
26 | if not fd then | 30 | if not fd then |
27 | return nil, "Failed to open file: "..self.fname | 31 | return nil, "Failed to open file: "..self.fname |
28 | end | 32 | end |
@@ -64,7 +68,7 @@ function multipart.encode(params) | |||
64 | local chunks = {} | 68 | local chunks = {} |
65 | for _, tuple in ipairs(tuples) do | 69 | for _, tuple in ipairs(tuples) do |
66 | local k,v = unpack(tuple) | 70 | local k,v = unpack(tuple) |
67 | k = url.escape(k) | 71 | k = multipart.url_escape(k) |
68 | local buffer = { 'Content-Disposition: form-data; name="' .. k .. '"' } | 72 | local buffer = { 'Content-Disposition: form-data; name="' .. k .. '"' } |
69 | local content | 73 | local content |
70 | if type(v) == "table" and v.__class == File then | 74 | if type(v) == "table" and v.__class == File then |
diff --git a/src/luarocks/util.lua b/src/luarocks/util.lua index a70e726d..c06c8354 100644 --- a/src/luarocks/util.lua +++ b/src/luarocks/util.lua | |||
@@ -63,6 +63,76 @@ function util.matchquote(s) | |||
63 | return (s:gsub("[?%-+*%[%].%%()$^]","%%%1")) | 63 | return (s:gsub("[?%-+*%[%].%%()$^]","%%%1")) |
64 | end | 64 | end |
65 | 65 | ||
66 | --- List of supported arguments. | ||
67 | -- Arguments that take no parameters are marked with the boolean true. | ||
68 | -- Arguments that take a parameter are marked with a descriptive string. | ||
69 | -- Arguments that may take an empty string are described in quotes, | ||
70 | -- (as in the value for --detailed="<text>"). | ||
71 | -- For all other string values, it means the parameter is mandatory. | ||
72 | local supported_flags = { | ||
73 | ["all"] = true, | ||
74 | ["api-key"] = "<key>", | ||
75 | ["append"] = true, | ||
76 | ["arch"] = "<arch>", | ||
77 | ["bin"] = true, | ||
78 | ["binary"] = true, | ||
79 | ["branch"] = "<branch-name>", | ||
80 | ["debug"] = true, | ||
81 | ["deps"] = true, | ||
82 | ["deps-mode"] = "<mode>", | ||
83 | ["detailed"] = "\"<text>\"", | ||
84 | ["force"] = true, | ||
85 | ["from"] = "<server>", | ||
86 | ["help"] = true, | ||
87 | ["home"] = true, | ||
88 | ["homepage"] = "\"<url>\"", | ||
89 | ["keep"] = true, | ||
90 | ["lib"] = "<library>", | ||
91 | ["license"] = "\"<text>\"", | ||
92 | ["list"] = true, | ||
93 | ["local"] = true, | ||
94 | ["local-tree"] = true, | ||
95 | ["lr-bin"] = true, | ||
96 | ["lr-cpath"] = true, | ||
97 | ["lr-path"] = true, | ||
98 | ["lua-version"] = "<vers>", | ||
99 | ["lua-ver"] = true, | ||
100 | ["lua-incdir"] = true, | ||
101 | ["lua-libdir"] = true, | ||
102 | ["modules"] = true, | ||
103 | ["mversion"] = true, | ||
104 | ["no-refresh"] = true, | ||
105 | ["nodeps"] = true, | ||
106 | ["old-versions"] = true, | ||
107 | ["only-deps"] = true, | ||
108 | ["only-from"] = "<server>", | ||
109 | ["only-server"] = "<server>", | ||
110 | ["only-sources"] = "<url>", | ||
111 | ["only-sources-from"] = "<url>", | ||
112 | ["outdated"] = true, | ||
113 | ["output"] = "<file>", | ||
114 | ["pack-binary-rock"] = true, | ||
115 | ["porcelain"] = true, | ||
116 | ["quick"] = true, | ||
117 | ["rock-dir"] = true, | ||
118 | ["rock-tree"] = true, | ||
119 | ["rock-trees"] = true, | ||
120 | ["rockspec"] = true, | ||
121 | ["rockspec-format"] = "<ver>", | ||
122 | ["server"] = "<server>", | ||
123 | ["skip-pack"] = true, | ||
124 | ["source"] = true, | ||
125 | ["summary"] = "\"<text>\"", | ||
126 | ["system-config"] = true, | ||
127 | ["tag"] = "<tag>", | ||
128 | ["timeout"] = "<seconds>", | ||
129 | ["to"] = "<path>", | ||
130 | ["tree"] = "<path>", | ||
131 | ["user-config"] = true, | ||
132 | ["verbose"] = true, | ||
133 | ["version"] = true, | ||
134 | } | ||
135 | |||
66 | --- Extract flags from an arguments list. | 136 | --- Extract flags from an arguments list. |
67 | -- Given string arguments, extract flag arguments into a flags set. | 137 | -- Given string arguments, extract flag arguments into a flags set. |
68 | -- For example, given "foo", "--tux=beep", "--bla", "bar", "--baz", | 138 | -- For example, given "foo", "--tux=beep", "--bla", "bar", "--baz", |
@@ -71,19 +141,59 @@ end | |||
71 | function util.parse_flags(...) | 141 | function util.parse_flags(...) |
72 | local args = {...} | 142 | local args = {...} |
73 | local flags = {} | 143 | local flags = {} |
74 | for i = #args, 1, -1 do | 144 | local i = 1 |
145 | local out = {} | ||
146 | local ignore_flags = false | ||
147 | while i <= #args do | ||
75 | local flag = args[i]:match("^%-%-(.*)") | 148 | local flag = args[i]:match("^%-%-(.*)") |
76 | if flag then | 149 | if flag == "--" then |
150 | ignore_flags = true | ||
151 | end | ||
152 | if flag and not ignore_flags then | ||
77 | local var,val = flag:match("([a-z_%-]*)=(.*)") | 153 | local var,val = flag:match("([a-z_%-]*)=(.*)") |
78 | if val then | 154 | if val then |
79 | flags[var] = val | 155 | local vartype = supported_flags[var] |
156 | if type(vartype) == "string" then | ||
157 | if val == "" and vartype:sub(1,1) ~= '"' then | ||
158 | return { ERROR = "Invalid argument: parameter to flag --"..var.."="..vartype.." cannot be empty." } | ||
159 | end | ||
160 | flags[var] = val | ||
161 | else | ||
162 | if vartype then | ||
163 | return { ERROR = "Invalid argument: flag --"..var.." does not take an parameter." } | ||
164 | else | ||
165 | return { ERROR = "Invalid argument: unknown flag --"..var.."." } | ||
166 | end | ||
167 | end | ||
80 | else | 168 | else |
81 | flags[flag] = true | 169 | local var = flag |
170 | local vartype = supported_flags[var] | ||
171 | if type(vartype) == "string" then | ||
172 | i = i + 1 | ||
173 | local val = args[i] | ||
174 | if not val then | ||
175 | return { ERROR = "Invalid argument: flag --"..var.."="..vartype.." expects a parameter." } | ||
176 | end | ||
177 | if val:match("^%-%-.*") then | ||
178 | 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..")." } | ||
179 | else | ||
180 | if val == "" and vartype:sub(1,1) ~= '"' then | ||
181 | return { ERROR = "Invalid argument: parameter to flag --"..var.."="..vartype.." cannot be empty." } | ||
182 | end | ||
183 | flags[var] = val | ||
184 | end | ||
185 | elseif vartype == true then | ||
186 | flags[var] = true | ||
187 | else | ||
188 | return { ERROR = "Invalid argument: unknown flag --"..var.."." } | ||
189 | end | ||
82 | end | 190 | end |
83 | table.remove(args, i) | 191 | else |
192 | table.insert(out, args[i]) | ||
84 | end | 193 | end |
194 | i = i + 1 | ||
85 | end | 195 | end |
86 | return flags, unpack(args) | 196 | return flags, unpack(out) |
87 | end | 197 | end |
88 | 198 | ||
89 | --- Build a sequence of flags for forwarding from one command to | 199 | --- Build a sequence of flags for forwarding from one command to |
@@ -177,7 +287,7 @@ local var_format_pattern = "%$%((%a[%a%d_]+)%)" | |||
177 | -- the original table (ie, does not copy recursively). | 287 | -- the original table (ie, does not copy recursively). |
178 | -- @param tbl table: the input table | 288 | -- @param tbl table: the input table |
179 | -- @return table: a new table with the same contents. | 289 | -- @return table: a new table with the same contents. |
180 | local function make_shallow_copy(tbl) | 290 | function util.make_shallow_copy(tbl) |
181 | local copy = {} | 291 | local copy = {} |
182 | for k,v in pairs(tbl) do | 292 | for k,v in pairs(tbl) do |
183 | copy[k] = v | 293 | copy[k] = v |
@@ -196,7 +306,7 @@ end | |||
196 | -- needed variables. | 306 | -- needed variables. |
197 | -- @param msg string: the warning message to display. | 307 | -- @param msg string: the warning message to display. |
198 | function util.warn_if_not_used(var_defs, needed_set, msg) | 308 | function util.warn_if_not_used(var_defs, needed_set, msg) |
199 | needed_set = make_shallow_copy(needed_set) | 309 | needed_set = util.make_shallow_copy(needed_set) |
200 | for _, val in pairs(var_defs) do | 310 | for _, val in pairs(var_defs) do |
201 | for used in val:gmatch(var_format_pattern) do | 311 | for used in val:gmatch(var_format_pattern) do |
202 | needed_set[used] = nil | 312 | needed_set[used] = nil |
@@ -392,7 +502,7 @@ function util.deps_mode_help(program) | |||
392 | end | 502 | end |
393 | 503 | ||
394 | function util.see_help(command, program) | 504 | function util.see_help(command, program) |
395 | return "See '"..util.this_program(program or "luarocks")..' help '..command.."'." | 505 | return "See '"..util.this_program(program or "luarocks")..' help'..(command and " "..command or "").."'." |
396 | end | 506 | end |
397 | 507 | ||
398 | -- from http://lua-users.org/wiki/SplitJoin | 508 | -- from http://lua-users.org/wiki/SplitJoin |
@@ -432,6 +542,7 @@ function util.remove_path_dupes(list, sep) | |||
432 | local parts = util.split_string(list, sep) | 542 | local parts = util.split_string(list, sep) |
433 | local final, entries = {}, {} | 543 | local final, entries = {}, {} |
434 | for _, part in ipairs(parts) do | 544 | for _, part in ipairs(parts) do |
545 | part = part:gsub("//", "/") | ||
435 | if not entries[part] then | 546 | if not entries[part] then |
436 | table.insert(final, part) | 547 | table.insert(final, part) |
437 | entries[part] = true | 548 | entries[part] = true |
diff --git a/src/luarocks/write_rockspec.lua b/src/luarocks/write_rockspec.lua index 20d35701..972562c3 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. | |||
24 | Note that the generated file is a _starting point_ for writing a | 24 | Note that the generated file is a _starting point_ for writing a |
25 | rockspec, and is not guaranteed to be complete or correct. | 25 | rockspec, and is not guaranteed to be complete or correct. |
26 | 26 | ||
27 | --output=<file> Write the rockspec with the given filename. | 27 | --output=<file> Write the rockspec with the given filename. |
28 | If not given, a file is written in the current | 28 | If not given, a file is written in the current |
29 | directory with a filename based on given name and version. | 29 | directory with a filename based on given name and version. |
30 | --license="<string>" A license string, such as "MIT/X11" or "GNU GPL v3". | 30 | --license="<string>" A license string, such as "MIT/X11" or "GNU GPL v3". |
31 | --summary="<txt>" A short one-line description summary. | 31 | --summary="<txt>" A short one-line description summary. |
32 | --description="<txt>" A longer description string. | 32 | --detailed="<txt>" A longer description string. |
33 | --homepage=<url> Project homepage. | 33 | --homepage=<url> Project homepage. |
34 | --lua-version=<ver> Supported Lua versions. Accepted values are "5.1", "5.2", | 34 | --lua-version=<ver> Supported Lua versions. Accepted values are "5.1", "5.2", |
35 | "5.3", "5.1,5.2", "5.2,5.3", or "5.1,5.2,5.3". | 35 | "5.3", "5.1,5.2", "5.2,5.3", or "5.1,5.2,5.3". |
36 | --tag=<tag> Tag to use. Will attempt to extract version number from it. | 36 | --rockspec-format=<ver> Rockspec format version, such as "1.0" or "1.1". |
37 | --lib=<lib>[,<lib>] A comma-separated list of libraries that C files need to | 37 | --tag=<tag> Tag to use. Will attempt to extract version number from it. |
38 | link to. | 38 | --lib=<lib>[,<lib>] A comma-separated list of libraries that C files need to |
39 | link to. | ||
39 | ]] | 40 | ]] |
40 | 41 | ||
41 | local function open_file(name) | 42 | local function open_file(name) |
@@ -76,25 +77,24 @@ local function configure_lua_version(rockspec, luaver) | |||
76 | end | 77 | end |
77 | end | 78 | end |
78 | 79 | ||
79 | local function detect_description(rockspec) | 80 | local function detect_description() |
80 | local fd = open_file("README.md") or open_file("README") | 81 | local fd = open_file("README.md") or open_file("README") |
81 | if not fd then return end | 82 | if not fd then return end |
82 | local data = fd:read("*a") | 83 | local data = fd:read("*a") |
83 | fd:close() | 84 | fd:close() |
84 | local paragraph = data:match("\n\n([^%[].-)\n\n") | 85 | local paragraph = data:match("\n\n([^%[].-)\n\n") |
85 | if not paragraph then paragraph = data:match("\n\n(.*)") end | 86 | if not paragraph then paragraph = data:match("\n\n(.*)") end |
87 | local summary, detailed | ||
86 | if paragraph then | 88 | if paragraph then |
89 | detailed = paragraph | ||
90 | |||
87 | if #paragraph < 80 then | 91 | if #paragraph < 80 then |
88 | rockspec.description.summary = paragraph:gsub("\n", "") | 92 | summary = paragraph:gsub("\n", "") |
89 | rockspec.description.detailed = paragraph | ||
90 | else | 93 | else |
91 | local summary = paragraph:gsub("\n", " "):match("([^.]*%.) ") | 94 | summary = paragraph:gsub("\n", " "):match("([^.]*%.) ") |
92 | if summary then | ||
93 | rockspec.description.summary = summary:gsub("\n", "") | ||
94 | end | ||
95 | rockspec.description.detailed = paragraph | ||
96 | end | 95 | end |
97 | end | 96 | end |
97 | return summary, detailed | ||
98 | end | 98 | end |
99 | 99 | ||
100 | local function detect_mit_license(data) | 100 | local function detect_mit_license(data) |
@@ -209,17 +209,13 @@ function write_rockspec.run(...) | |||
209 | elseif not url_or_dir then | 209 | elseif not url_or_dir then |
210 | url_or_dir = version | 210 | url_or_dir = version |
211 | end | 211 | end |
212 | |||
213 | if flags["tag"] == true then | ||
214 | return nil, "Incorrect usage: --tag requires an argument. "..util.see_help("write_rockspec") | ||
215 | end | ||
216 | 212 | ||
217 | if flags["tag"] then | 213 | if flags["tag"] then |
218 | if not version then | 214 | if not version then |
219 | version = flags["tag"]:gsub("^v", "") | 215 | version = flags["tag"]:gsub("^v", "") |
220 | end | 216 | end |
221 | end | 217 | end |
222 | 218 | ||
223 | local protocol, pathname = dir.split_url(url_or_dir) | 219 | local protocol, pathname = dir.split_url(url_or_dir) |
224 | if not fetch.is_basic_protocol(protocol) then | 220 | if not fetch.is_basic_protocol(protocol) then |
225 | if not name then | 221 | if not name then |
@@ -251,6 +247,7 @@ function write_rockspec.run(...) | |||
251 | end | 247 | end |
252 | 248 | ||
253 | local rockspec = { | 249 | local rockspec = { |
250 | rockspec_format = flags["rockspec-format"], | ||
254 | package = name, | 251 | package = name, |
255 | name = name:lower(), | 252 | name = name:lower(), |
256 | version = version.."-1", | 253 | version = version.."-1", |
@@ -316,7 +313,11 @@ function write_rockspec.run(...) | |||
316 | local ok, err = fs.change_dir(local_dir) | 313 | local ok, err = fs.change_dir(local_dir) |
317 | if not ok then return nil, "Failed reaching files from project - error entering directory "..local_dir end | 314 | if not ok then return nil, "Failed reaching files from project - error entering directory "..local_dir end |
318 | 315 | ||
319 | detect_description(rockspec) | 316 | if (not flags["summary"]) or (not flags["detailed"]) then |
317 | local summary, detailed = detect_description() | ||
318 | rockspec.description.summary = flags["summary"] or summary | ||
319 | rockspec.description.detailed = flags["detailed"] or detailed | ||
320 | end | ||
320 | 321 | ||
321 | local is_mit = show_license(rockspec) | 322 | local is_mit = show_license(rockspec) |
322 | 323 | ||
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 00000000..c2ecd160 --- /dev/null +++ b/test/testfiles/invalid_patch-0.1-1.rockspec | |||
@@ -0,0 +1,29 @@ | |||
1 | package = "invalid_patch" | ||
2 | version = "0.1-1" | ||
3 | source = { | ||
4 | -- any valid URL | ||
5 | url = "https://raw.github.com/keplerproject/luarocks/master/src/luarocks/build.lua" | ||
6 | } | ||
7 | description = { | ||
8 | summary = "A rockspec with an invalid patch", | ||
9 | } | ||
10 | dependencies = { | ||
11 | "lua >= 5.1" | ||
12 | } | ||
13 | build = { | ||
14 | type = "builtin", | ||
15 | modules = { | ||
16 | build = "build.lua" | ||
17 | }, | ||
18 | patches = { | ||
19 | ["I_am_an_invalid_patch.patch"] = | ||
20 | [[ | ||
21 | diff -Naur luadoc-3.0.1/src/luadoc/doclet/html.lua luadoc-3.0.1-new/src/luadoc/doclet/html.lua | ||
22 | --- luadoc-3.0.1/src/luadoc/doclet/html.lua2007-12-21 15:50:48.000000000 -0200 | ||
23 | +++ luadoc-3.0.1-new/src/luadoc/doclet/html.lua2008-02-28 01:59:53.000000000 -0300 | ||
24 | @@ -18,6 +18,7 @@ | ||
25 | - gabba gabba gabba | ||
26 | + gobo gobo gobo | ||
27 | ]] | ||
28 | } | ||
29 | } | ||
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 00000000..5d79e9a0 --- /dev/null +++ b/test/testfiles/no_build_table-0.1-1.rockspec | |||
@@ -0,0 +1,12 @@ | |||
1 | package = "no_build_table" | ||
2 | version = "0.1-1" | ||
3 | source = { | ||
4 | -- any valid URL | ||
5 | url = "https://raw.github.com/keplerproject/luarocks/master/src/luarocks/build.lua" | ||
6 | } | ||
7 | description = { | ||
8 | summary = "A rockspec with no build field", | ||
9 | } | ||
10 | dependencies = { | ||
11 | "lua >= 5.1" | ||
12 | } | ||
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 00000000..e36f8bbe --- /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 00000000..7a607cfd --- /dev/null +++ b/test/testfiles/type_mismatch_string-1.0-1.rockspec | |||
@@ -0,0 +1,4 @@ | |||
1 | |||
2 | package="type_mismatch_version" | ||
3 | version=1.0 | ||
4 | |||
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 00000000..f348b798 --- /dev/null +++ b/test/testfiles/type_mismatch_table-1.0-1.rockspec | |||
@@ -0,0 +1,5 @@ | |||
1 | |||
2 | package="type_mismatch_table" | ||
3 | version="1.0-1" | ||
4 | |||
5 | 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 00000000..5e30dae6 --- /dev/null +++ b/test/testfiles/type_mismatch_version-1.0-1.rockspec | |||
@@ -0,0 +1,4 @@ | |||
1 | |||
2 | package="type_mismatch_version" | ||
3 | version="1.0" | ||
4 | |||
diff --git a/test/testing.bat b/test/testing.bat new file mode 100644 index 00000000..7083678b --- /dev/null +++ b/test/testing.bat | |||
@@ -0,0 +1,9 @@ | |||
1 | @echo off | ||
2 | Setlocal EnableDelayedExpansion EnableExtensions | ||
3 | |||
4 | if not defined LUAROCKS_REPO set LUAROCKS_REPO=https://luarocks.org | ||
5 | |||
6 | appveyor DownloadFile %LUAROCKS_REPO%/stdlib-41.0.0-1.src.rock | ||
7 | luarocks build stdlib | ||
8 | |||
9 | endlocal | ||
diff --git a/test/testing.lua b/test/testing.lua new file mode 100644 index 00000000..c37293ee --- /dev/null +++ b/test/testing.lua | |||
@@ -0,0 +1,464 @@ | |||
1 | |||
2 | local variables = {} | ||
3 | |||
4 | -- Expand variables in the format $foo or ${foo} according | ||
5 | -- to the variables table. | ||
6 | local function expand_variables(str) | ||
7 | return str:gsub("%$({?)([A-Za-z0-9_]+)(}?)", function(o, v, c) | ||
8 | return #o <= #c and (variables[v] or "") .. (#o < #c and c or "") | ||
9 | end) | ||
10 | end | ||
11 | |||
12 | -- @param cmd command to run | ||
13 | -- @param envtable optional table of temporary environment variables | ||
14 | local function run(cmd, envtable) | ||
15 | cmd = expand_variables(cmd) | ||
16 | local env = {} | ||
17 | for var, val in pairs(envtable) do | ||
18 | table.insert(env, var.."='"..expand_variables(val).."' ") | ||
19 | end | ||
20 | local code = os.execute(table.concat(env)..cmd) | ||
21 | return (code == 0 or code == true) | ||
22 | end | ||
23 | |||
24 | local function cd_run(dir, cmd, envtable) | ||
25 | return run("cd "..dir.." && "..cmd, envtable) | ||
26 | end | ||
27 | |||
28 | local function run_get_contents(cmd) | ||
29 | end | ||
30 | |||
31 | local function mkdir(dirname) | ||
32 | cmd = expand_variables(dirname) | ||
33 | -- TODO | ||
34 | end | ||
35 | |||
36 | local function rm_rf(...) | ||
37 | -- TODO | ||
38 | end | ||
39 | |||
40 | local function mv(src, dst) | ||
41 | -- TODO | ||
42 | end | ||
43 | |||
44 | local function exists(filename) | ||
45 | filename = expand_variables(filename) | ||
46 | -- TODO | ||
47 | end | ||
48 | |||
49 | local function glob(patt) | ||
50 | -- TODO | ||
51 | end | ||
52 | |||
53 | local function touch(filename) | ||
54 | -- TODO | ||
55 | end | ||
56 | |||
57 | local function rm(...) | ||
58 | for _, filename in ipairs {...} do | ||
59 | filename = expand_variables(filename) | ||
60 | -- TODO | ||
61 | end | ||
62 | return true | ||
63 | end | ||
64 | |||
65 | local function file_set_contents(filename, contents) | ||
66 | filename = expand_variables(filename) | ||
67 | |||
68 | local fd, err = io.open(filename, "w") | ||
69 | if not fd then return nil, err end | ||
70 | fd:write(contents) | ||
71 | fd:close() | ||
72 | return true | ||
73 | end | ||
74 | |||
75 | local function need_luasocket() | ||
76 | -- TODO | ||
77 | end | ||
78 | |||
79 | local tests = { | ||
80 | |||
81 | test_version = function() return run "$luarocks --version" end, | ||
82 | fail_unknown_command = function() return run "$luarocks unknown_command" end, | ||
83 | fail_arg_boolean_parameter = function() return run "$luarocks --porcelain=invalid" end, | ||
84 | fail_arg_boolean_unknown = function() return run "$luarocks --invalid-flag" end, | ||
85 | fail_arg_string_no_parameter = function() return run "$luarocks --server" end, | ||
86 | fail_arg_string_followed_by_flag = function() return run "$luarocks --server --porcelain" end, | ||
87 | fail_arg_string_unknown = function() return run "$luarocks --invalid-flag=abc" end, | ||
88 | test_empty_list = function() return run "$luarocks list" end, | ||
89 | test_list_outdated = function () return run "$luarocks list --outdated" end, | ||
90 | fail_sysconfig_err = function() | ||
91 | mkdir "$testing_lrprefix/etc/luarocks" | ||
92 | file_set_contents("$testing_lrprefix/etc/luarocks/config.lua", "aoeui") | ||
93 | return run "$luarocks list" | ||
94 | and rm "$testing_lrprefix/etc/luarocks/config.lua" | ||
95 | end, | ||
96 | fail_sysconfig_default_err = function() | ||
97 | mkdir "$testing_lrprefix/etc/luarocks" | ||
98 | file_set_contents("$testing_lrprefix/etc/luarocks/config-$luashortversion.lua", "aoeui") | ||
99 | return run "$luarocks list" | ||
100 | and rm "$testing_lrprefix/etc/luarocks/config-$luashortversion.lua" | ||
101 | end, | ||
102 | fail_build_noarg = function() return run "$luarocks build" end, | ||
103 | fail_download_noarg = function() return run "$luarocks download" end, | ||
104 | fail_install_noarg = function() return run "$luarocks install" end, | ||
105 | fail_lint_noarg = function() return run "$luarocks lint" end, | ||
106 | fail_search_noarg = function() return run "$luarocks search" end, | ||
107 | fail_show_noarg = function() return run "$luarocks show" end, | ||
108 | fail_unpack_noarg = function() return run "$luarocks unpack" end, | ||
109 | fail_upload_noarg = function() return run "$luarocks upload" end, | ||
110 | fail_remove_noarg = function() return run "$luarocks remove" end, | ||
111 | fail_doc_noarg = function() return run "$luarocks doc" end, | ||
112 | fail_new_version_noarg = function() return run "$luarocks new_version" end, | ||
113 | fail_write_rockspec_noarg = function() return run "$luarocks write_rockspec" end, | ||
114 | fail_build_invalid = function() return run "$luarocks build invalid" end, | ||
115 | fail_download_invalid = function() return run "$luarocks download invalid" end, | ||
116 | fail_install_invalid = function() return run "$luarocks install invalid" end, | ||
117 | fail_lint_invalid = function() return run "$luarocks lint invalid" end, | ||
118 | fail_show_invalid = function() return run "$luarocks show invalid" end, | ||
119 | fail_new_version_invalid = function() return run "$luarocks new_version invalid" end, | ||
120 | test_list_invalidtree = function() return run "$luarocks --tree=/some/invalid/tree list" end, | ||
121 | fail_inexistent_dir = function() | ||
122 | -- Unix only? | ||
123 | return run "mkdir idontexist; cd idontexist; rmdir ../idontexist; $luarocks; err=$?; cd ..; return $err" | ||
124 | end, | ||
125 | fail_make_norockspec = function() return run "$luarocks make" end, | ||
126 | fail_build_permissions = function() return run "$luarocks build --tree=/usr lpeg" end, | ||
127 | fail_build_permissions_parent = function() return run "$luarocks build --tree=/usr/invalid lpeg" end, | ||
128 | test_build_verbose = function() return run "$luarocks build --verbose lpeg" end, | ||
129 | fail_build_blank_arg = function() return run "$luarocks build --tree="" lpeg" end, | ||
130 | test_build_withpatch = function() need_luasocket(); return run "$luarocks build luadoc" end, | ||
131 | test_build_diffversion = function() return run "$luarocks build luacov ${version_luacov}" end, | ||
132 | test_build_command = function() return run "$luarocks build stdlib" end, | ||
133 | test_build_install_bin = function() return run "$luarocks build luarepl" end, | ||
134 | test_build_nohttps = function() | ||
135 | need_luasocket() | ||
136 | return run "$luarocks download --rockspec validate-args ${verrev_validate_args}" | ||
137 | and run "$luarocks build ./validate-args-${version_validate_args}-1.rockspec" | ||
138 | and rm "./validate-args-${version_validate_args}-1.rockspec" | ||
139 | end, | ||
140 | test_build_https = function() | ||
141 | need_luasocket() | ||
142 | return run "$luarocks download --rockspec validate-args ${verrev_validate_args}" | ||
143 | and run "$luarocks install luasec" | ||
144 | and run "$luarocks build ./validate-args-${verrev_validate_args}.rockspec" | ||
145 | and rm "./validate-args-${verrev_validate_args}.rockspec" | ||
146 | end, | ||
147 | test_build_supported_platforms = function() return run "$luarocks build lpty" end, | ||
148 | test_build_only_deps_rockspec = function() | ||
149 | return run "$luarocks download --rockspec lxsh ${verrev_lxsh}" | ||
150 | and run "$luarocks build ./lxsh-${verrev_lxsh}.rockspec --only-deps" | ||
151 | and (not run "$luarocks show lxsh") | ||
152 | end, | ||
153 | test_build_only_deps_src_rock = function() | ||
154 | return run "$luarocks download --source lxsh ${verrev_lxsh}" | ||
155 | and run "$luarocks build ./lxsh-${verrev_lxsh}.src.rock --only-deps" | ||
156 | and (not run "$luarocks show lxsh") | ||
157 | end, | ||
158 | test_build_only_deps = function() return run "$luarocks build luasec --only-deps" and (not run "$luarocks show luasec") end, | ||
159 | test_install_only_deps = function() return run "$luarocks install lxsh ${verrev_lxsh} --only-deps" and (not run "$luarocks show lxsh") end, | ||
160 | fail_build_missing_external = function() return run '$luarocks build "$testing_dir/testfiles/missing_external-0.1-1.rockspec" INEXISTENT_INCDIR="/invalid/dir"' end, | ||
161 | fail_build_invalidpatch = function() | ||
162 | need_luasocket() | ||
163 | return run '$luarocks build "$testing_dir/testfiles/invalid_patch-0.1-1.rockspec"' | ||
164 | end, | ||
165 | test_build_deps_partial_match = function() return run "$luarocks build lmathx" end, | ||
166 | test_build_show_downloads = function() | ||
167 | return run("$luarocks build alien", { LUAROCKS_CONFIG="$testing_dir/testing_config_show_downloads.lua" }) | ||
168 | end, | ||
169 | test_download_all = function() | ||
170 | return run "$luarocks download --all validate-args" | ||
171 | and rm(glob("validate-args-*")) | ||
172 | end, | ||
173 | test_download_rockspecversion = function() | ||
174 | return run "$luarocks download --rockspec validate-args ${verrev_validate_args}" | ||
175 | and rm(glob("validate-args-*")) | ||
176 | end, | ||
177 | test_help = function() return run "$luarocks help" end, | ||
178 | fail_help_invalid = function() return run "$luarocks help invalid" end, | ||
179 | test_install_binaryrock = function() | ||
180 | return run "$luarocks build --pack-binary-rock cprint" | ||
181 | and run "$luarocks install ./cprint-${verrev_cprint}.${platform}.rock" | ||
182 | and rm "./cprint-${verrev_cprint}.${platform}.rock" | ||
183 | end, | ||
184 | test_install_with_bin = function() return run "$luarocks install wsapi" end, | ||
185 | fail_install_notazipfile = function() return run '$luarocks install "$testing_dir/testfiles/not_a_zipfile-1.0-1.src.rock"' end, | ||
186 | fail_install_invalidpatch = function() | ||
187 | need_luasocket() | ||
188 | return run '$luarocks install "$testing_dir/testfiles/invalid_patch-0.1-1.rockspec"' | ||
189 | end, | ||
190 | fail_install_invalid_filename = function() return run '$luarocks install "invalid.rock"' end, | ||
191 | fail_install_invalid_arch = function() return run '$luarocks install "foo-1.0-1.impossible-x86.rock"' end, | ||
192 | test_install_reinstall = function() | ||
193 | return run '$luarocks install "$testing_cache/luasocket-$verrev_luasocket.$platform.rock"' | ||
194 | and run '$luarocks install --deps-mode=none "$testing_cache/luasocket-$verrev_luasocket.$platform.rock"' | ||
195 | end, | ||
196 | fail_local_root = function() return run("$luarocks install --local luasocket", { USER="root" }) end, | ||
197 | test_site_config = function() | ||
198 | mv("../src/luarocks/site_config.lua", "../src/luarocks/site_config.lua.tmp") | ||
199 | local ok = run "$luarocks" | ||
200 | mv("../src/luarocks/site_config.lua.tmp", "../src/luarocks/site_config.lua") | ||
201 | return ok | ||
202 | end, | ||
203 | test_lint_ok = function() | ||
204 | return run "$luarocks download --rockspec validate-args ${verrev_validate_args}" | ||
205 | and run "$luarocks lint ./validate-args-${verrev_validate_args}.rockspec" | ||
206 | and rm "./validate-args-${verrev_validate_args}.rockspec" | ||
207 | end, | ||
208 | fail_lint_type_mismatch_string = function() return run '$luarocks lint "$testing_dir/testfiles/type_mismatch_string-1.0-1.rockspec"' end, | ||
209 | fail_lint_type_mismatch_version = function() return run '$luarocks lint "$testing_dir/testfiles/type_mismatch_version-1.0-1.rockspec"' end, | ||
210 | fail_lint_type_mismatch_table = function() return run '$luarocks lint "$testing_dir/testfiles/type_mismatch_table-1.0-1.rockspec"' end, | ||
211 | fail_lint_no_build_table = function() return run '$luarocks lint "$testing_dir/testfiles/no_build_table-0.1-1.rockspec"' end, | ||
212 | test_list = function() return run "$luarocks list" end, | ||
213 | test_list_porcelain = function() return run "$luarocks list --porcelain" end, | ||
214 | test_make_with_rockspec = function() | ||
215 | return rm_rf "./luasocket-${verrev_luasocket}" | ||
216 | and run "$luarocks download --source luasocket" | ||
217 | and run "$luarocks unpack ./luasocket-${verrev_luasocket}.src.rock" | ||
218 | and cd_run("luasocket-${verrev_luasocket}/${srcdir_luasocket}", "$luarocks make luasocket-${verrev_luasocket}.rockspec") | ||
219 | and rm_rf "./luasocket-${verrev_luasocket}" | ||
220 | end, | ||
221 | test_make_default_rockspec = function() | ||
222 | return rm_rf "./lxsh-${verrev_lxsh}" | ||
223 | and run "$luarocks download --source lxsh ${verrev_lxsh}" | ||
224 | and run "$luarocks unpack ./lxsh-${verrev_lxsh}.src.rock" | ||
225 | and cd_run("lxsh-${verrev_lxsh}/lxsh-${version_lxsh}-1", "$luarocks make") | ||
226 | and rm_rf "./lxsh-${verrev_lxsh}" | ||
227 | end, | ||
228 | test_make_pack_binary_rock = function() | ||
229 | return rm_rf "./lxsh-${verrev_lxsh}" | ||
230 | and run "$luarocks download --source lxsh ${verrev_lxsh}" | ||
231 | and run "$luarocks unpack ./lxsh-${verrev_lxsh}.src.rock" | ||
232 | and cd_run("lxsh-${verrev_lxsh}/lxsh-${version_lxsh}-1", "$luarocks make --deps-mode=none --pack-binary-rock") | ||
233 | and exists "lxsh-${verrev_lxsh}/lxsh-${version_lxsh}-1/lxsh-${verrev_lxsh}.all.rock" | ||
234 | and rm_rf "./lxsh-${verrev_lxsh}" | ||
235 | end, | ||
236 | fail_make_which_rockspec = function() | ||
237 | rm_rf "./luasocket-${verrev_luasocket}" | ||
238 | run "$luarocks download --source luasocket" | ||
239 | run "$luarocks unpack ./luasocket-${verrev_luasocket}.src.rock" | ||
240 | local ok = cd_run("luasocket-${verrev_luasocket}/${srcdir_luasocket}", "$luarocks make") | ||
241 | rm_rf "./luasocket-${verrev_luasocket}" | ||
242 | return ok | ||
243 | end, | ||
244 | test_new_version = function() | ||
245 | return run "$luarocks download --rockspec luacov ${version_luacov}" | ||
246 | and run "$luarocks new_version ./luacov-${version_luacov}-1.rockspec 0.2" | ||
247 | and rm(glob("./luacov-0.*")) | ||
248 | end, | ||
249 | test_new_version_url = function() | ||
250 | return run "$luarocks download --rockspec abelhas 1.0" | ||
251 | and run "$luarocks new_version ./abelhas-1.0-1.rockspec 1.1 https://github.com/downloads/ittner/abelhas/abelhas-1.1.tar.gz" | ||
252 | and rm(glob("./abelhas-*")) | ||
253 | end, | ||
254 | test_pack = function() | ||
255 | return run "$luarocks list" | ||
256 | and run "$luarocks pack luacov" | ||
257 | and rm(glob("./luacov-*.rock")) | ||
258 | end, | ||
259 | test_pack_src = function() | ||
260 | return run "$luarocks install luasec" | ||
261 | and run "$luarocks download --rockspec luasocket" | ||
262 | and run "$luarocks pack ./luasocket-${verrev_luasocket}.rockspec" | ||
263 | and rm(glob("./luasocket-${version_luasocket}-*.rock")) | ||
264 | end, | ||
265 | test_path = function() return run "$luarocks path --bin" end, | ||
266 | test_path_lr_path = function() return run "$luarocks path --lr-path" end, | ||
267 | test_path_lr_cpath = function() return run "$luarocks path --lr-cpath" end, | ||
268 | test_path_lr_bin = function() return run "$luarocks path --lr-bin" end, | ||
269 | test_path_with_tree = function() return run "$luarocks path --tree=lua_modules" end, | ||
270 | fail_purge_missing_tree = function() return run '$luarocks purge --tree="$testing_tree"' end, | ||
271 | test_purge = function() return run '$luarocks purge --tree="$testing_sys_tree"' end, | ||
272 | test_remove = function() | ||
273 | return run "$luarocks build abelhas ${version_abelhas}" | ||
274 | and run "$luarocks remove abelhas ${version_abelhas}" | ||
275 | end, | ||
276 | test_remove_force = function() | ||
277 | need_luasocket() | ||
278 | return run "$luarocks build lualogging" | ||
279 | and run "$luarocks remove --force luasocket" | ||
280 | end, | ||
281 | fail_remove_deps = function() | ||
282 | need_luasocket() | ||
283 | return run "$luarocks build lualogging" | ||
284 | and run "$luarocks remove luasocket" | ||
285 | end, | ||
286 | fail_remove_missing = function() return run "$luarocks remove missing_rock" end, | ||
287 | fail_remove_invalid_name = function() return run "$luarocks remove invalid.rock" end, | ||
288 | test_search_found = function() return run "$luarocks search zlib" end, | ||
289 | test_search_missing = function() return run "$luarocks search missing_rock" end, | ||
290 | test_show = function() return run "$luarocks show luacov" end, | ||
291 | test_show_modules = function() return run "$luarocks show --modules luacov" end, | ||
292 | test_show_home = function() return run "$luarocks show --home luacov" end, | ||
293 | test_show_depends = function() | ||
294 | need_luasocket() | ||
295 | return run "$luarocks install luasec" | ||
296 | and run "$luarocks show luasec" | ||
297 | end, | ||
298 | test_show_oldversion = function() | ||
299 | return run "$luarocks install luacov ${version_luacov}" | ||
300 | and run "$luarocks show luacov ${version_luacov}" | ||
301 | end, | ||
302 | test_unpack_download = function() | ||
303 | return rm_rf "./cprint-${verrev_cprint}" | ||
304 | and run "$luarocks unpack cprint" | ||
305 | and rm_rf "./cprint-${verrev_cprint}" | ||
306 | end, | ||
307 | test_unpack_src = function() | ||
308 | return rm_rf "./cprint-${verrev_cprint}" | ||
309 | and run "$luarocks download --source cprint" | ||
310 | and run "$luarocks unpack ./cprint-${verrev_cprint}.src.rock" | ||
311 | and rm_rf "./cprint-${verrev_cprint}" | ||
312 | end, | ||
313 | test_unpack_rockspec = function() | ||
314 | return rm_rf "./cprint-${verrev_cprint}" | ||
315 | and run "$luarocks download --rockspec cprint" | ||
316 | and run "$luarocks unpack ./cprint-${verrev_cprint}.rockspec" | ||
317 | and rm_rf "./cprint-${verrev_cprint}" | ||
318 | end, | ||
319 | test_unpack_binary = function() | ||
320 | return rm_rf "./cprint-${verrev_cprint}" | ||
321 | and run "$luarocks build cprint" | ||
322 | and run "$luarocks pack cprint" | ||
323 | and run "$luarocks unpack ./cprint-${verrev_cprint}.${platform}.rock" | ||
324 | and rm_rf "./cprint-${verrev_cprint}" | ||
325 | end, | ||
326 | fail_unpack_invalidpatch = function() | ||
327 | need_luasocket() | ||
328 | return run '$luarocks unpack "$testing_dir/testfiles/invalid_patch-0.1-1.rockspec"' | ||
329 | end, | ||
330 | fail_unpack_invalidrockspec = function() | ||
331 | need_luasocket() | ||
332 | return run '$luarocks unpack "invalid.rockspec"' | ||
333 | end, | ||
334 | fail_upload_invalidrockspec = function() return run '$luarocks upload "invalid.rockspec"' end, | ||
335 | fail_upload_invalidkey = function() return run '$luarocks upload --api-key="invalid" "invalid.rockspec"' end, | ||
336 | test_admin_help = function() return run "$luarocks_admin help" end, | ||
337 | test_admin_make_manifest = function() return run "$luarocks_admin make_manifest" end, | ||
338 | test_admin_add_rsync = function() return run '$luarocks_admin --server=testing add "$testing_server/luasocket-${verrev_luasocket}.src.rock"' end, | ||
339 | test_admin_add_sftp = function() | ||
340 | return run("$luarocks_admin --server=testing add ./luasocket-${verrev_luasocket}.src.rock", { LUAROCKS_CONFIG="$testing_dir/testing_config_sftp.lua" }) | ||
341 | end, | ||
342 | fail_admin_add_missing = function() return run "$luarocks_admin --server=testing add" end, | ||
343 | fail_admin_invalidserver = function() return run '$luarocks_admin --server=invalid add "$testing_server/luasocket-${verrev_luasocket}.src.rock"' end, | ||
344 | fail_admin_invalidrock = function() return run "$luarocks_admin --server=testing add invalid" end, | ||
345 | test_admin_refresh_cache = function() return run "$luarocks_admin --server=testing refresh_cache" end, | ||
346 | test_admin_remove = function() return run "$luarocks_admin --server=testing remove luasocket-${verrev_luasocket}.src.rock" end, | ||
347 | fail_admin_remove_missing = function() return run "$luarocks_admin --server=testing remove" end, | ||
348 | fail_deps_mode_invalid_arg = function() return run "$luarocks remove luacov --deps-mode" end, | ||
349 | |||
350 | test_deps_mode_one = function() | ||
351 | return run '$luarocks build --tree="system" lpeg' | ||
352 | and run '$luarocks list' | ||
353 | and run '$luarocks build --deps-mode=one --tree="$testing_tree" lxsh' | ||
354 | and run_get_contents '$luarocks_noecho list --tree="$testing_tree" --porcelain lpeg' ~= "" | ||
355 | end, | ||
356 | test_deps_mode_order = function() | ||
357 | return run '$luarocks build --tree="system" lpeg' | ||
358 | and run '$luarocks build --deps-mode=order --tree="$testing_tree" lxsh' | ||
359 | and run '$luarocks_noecho list --tree="$testing_tree" --porcelain lpeg' | ||
360 | and run_get_contents '$luarocks_noecho list --tree="$testing_tree" --porcelain lpeg' == "" | ||
361 | end, | ||
362 | test_deps_mode_order_sys = function() | ||
363 | return run '$luarocks build --tree="$testing_tree" lpeg' | ||
364 | and run '$luarocks build --deps-mode=order --tree="$testing_sys_tree" lxsh' | ||
365 | and run_get_contents '$luarocks_noecho list --tree="$testing_sys_tree" --porcelain lpeg' ~= "" | ||
366 | end, | ||
367 | test_deps_mode_all_sys = function() | ||
368 | return run '$luarocks build --tree="$testing_tree" lpeg' | ||
369 | and run '$luarocks build --deps-mode=all --tree="$testing_sys_tree" lxsh' | ||
370 | and run_get_contents '$luarocks_noecho list --tree="$testing_sys_tree" --porcelain lpeg' == "" | ||
371 | end, | ||
372 | |||
373 | test_deps_mode_none = function() | ||
374 | return run '$luarocks build --tree="$testing_tree" --deps-mode=none lxsh' | ||
375 | and run_get_contents '$luarocks_noecho list --tree="$testing_tree" --porcelain lpeg' == "" | ||
376 | end, | ||
377 | test_deps_mode_nodeps_alias = function() | ||
378 | return run '$luarocks build --tree="$testing_tree" --nodeps lxsh' | ||
379 | and run_get_contents '$luarocks_noecho list --tree="$testing_tree" --porcelain lpeg' == "" | ||
380 | end, | ||
381 | test_deps_mode_make_order = function() | ||
382 | local ok = run '$luarocks build --tree="$testing_sys_tree" lpeg' | ||
383 | and rm_rf "./lxsh-${verrev_lxsh}" | ||
384 | and run "$luarocks download --source lxsh ${verrev_lxsh}" | ||
385 | and run "$luarocks unpack ./lxsh-${verrev_lxsh}.src.rock" | ||
386 | and cd_run("lxsh-${verrev_lxsh}/lxsh-${version_lxsh}-1", '$luarocks make --tree="$testing_tree" --deps-mode=order') | ||
387 | if not ok then | ||
388 | return false | ||
389 | end | ||
390 | local found = run_get_contents '$luarocks_noecho list --tree="$testing_tree" --porcelain lpeg' | ||
391 | rm_rf "./lxsh-${verrev_lxsh}" | ||
392 | return found == "" | ||
393 | end, | ||
394 | test_deps_mode_make_order_sys = function() | ||
395 | local ok = run '$luarocks build --tree="$testing_tree" lpeg' | ||
396 | and rm_rf "./lxsh-${verrev_lxsh}" | ||
397 | and run "$luarocks download --source lxsh ${verrev_lxsh}" | ||
398 | and run "$luarocks unpack ./lxsh-${verrev_lxsh}.src.rock" | ||
399 | and cd_run("lxsh-${verrev_lxsh}/lxsh-${version_lxsh}-1", '$luarocks make --tree="$testing_sys_tree" --deps-mode=order') | ||
400 | if not ok then | ||
401 | return false | ||
402 | end | ||
403 | local found = run_get_contents '$luarocks_noecho list --tree="$testing_sys_tree" --porcelain lpeg' | ||
404 | rm_rf "./lxsh-${verrev_lxsh}" | ||
405 | return found ~= "" | ||
406 | end, | ||
407 | test_write_rockspec = function() return run "$luarocks write_rockspec git://github.com/keplerproject/luarocks" end, | ||
408 | 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, | ||
409 | 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, | ||
410 | 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, | ||
411 | fail_write_rockspec_args = function() return run "$luarocks write_rockspec invalid" end, | ||
412 | fail_write_rockspec_args_url = function() return run "$luarocks write_rockspec http://example.com/invalid.zip" end, | ||
413 | 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, | ||
414 | 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, | ||
415 | |||
416 | fail_config_noflags = function() return run "$luarocks config; " end, | ||
417 | test_config_lua_incdir = function() return run "$luarocks config --lua-incdir; " end, | ||
418 | test_config_lua_libdir = function() return run "$luarocks config --lua-libdir; " end, | ||
419 | test_config_lua_ver = function() return run "$luarocks config --lua-ver; " end, | ||
420 | fail_config_system_config = function() | ||
421 | return rm "$testing_lrprefix/etc/luarocks/config.lua" | ||
422 | and run "$luarocks config --system-config; " | ||
423 | end, | ||
424 | test_config_system_config = function() | ||
425 | local ok = mkdir "$testing_lrprefix/etc/luarocks" | ||
426 | and touch "$testing_lrprefix/etc/luarocks/config.lua" | ||
427 | and run "$luarocks config --system-config; " | ||
428 | rm "$testing_lrprefix/etc/luarocks/config.lua" | ||
429 | return ok | ||
430 | end, | ||
431 | fail_config_system_config_invalid = function() | ||
432 | local ok = mkdir "$testing_lrprefix/etc/luarocks" | ||
433 | and run "echo 'if if if' > '$testing_lrprefix/etc/luarocks/config.lua' ;" | ||
434 | and run "$luarocks config --system-config" | ||
435 | rm "$testing_lrprefix/etc/luarocks/config.lua" | ||
436 | return ok | ||
437 | end, | ||
438 | test_config_user_config = function() return run "$luarocks config --user-config; " end, | ||
439 | fail_config_user_config = function() return run "LUAROCKS_CONFIG='/missing_file.lua' $luarocks config --user-config; " end, | ||
440 | test_config_rock_trees = function() return run "$luarocks config --rock-trees;" end, | ||
441 | test_config_help = function() return run "$luarocks help config;" end, | ||
442 | test_doc = function() | ||
443 | return run "$luarocks install luarepl" | ||
444 | and run "$luarocks doc luarepl" | ||
445 | end, | ||
446 | test_doc_home = function() | ||
447 | return run "$luarocks install luacov" | ||
448 | and run "$luarocks doc luacov --home" | ||
449 | end, | ||
450 | fail_doc_invalid = function () return run "$luarocks doc invalid" end, | ||
451 | |||
452 | -- Tests for https://github.com/keplerproject/luarocks/issues/375 | ||
453 | test_fetch_base_dir = function() | ||
454 | local fetch = require "luarocks.fetch" | ||
455 | |||
456 | return assert("v0.3" == fetch.url_to_base_dir("https://github.com/hishamhm/lua-compat-5.2/archive/v0.3.zip")) | ||
457 | and assert("lua-compat-5.2" == fetch.url_to_base_dir("https://github.com/hishamhm/lua-compat-5.2.zip")) | ||
458 | and assert("lua-compat-5.2" == fetch.url_to_base_dir("https://github.com/hishamhm/lua-compat-5.2.tar.gz")) | ||
459 | and assert("lua-compat-5.2" == fetch.url_to_base_dir("https://github.com/hishamhm/lua-compat-5.2.tar.bz2")) | ||
460 | and assert("parser.moon" == fetch.url_to_base_dir("git://github.com/Cirru/parser.moon")) | ||
461 | and assert("v0.3" == fetch.url_to_base_dir("https://github.com/hishamhm/lua-compat-5.2/archive/v0.3")) | ||
462 | end | ||
463 | |||
464 | } | ||
diff --git a/test/testing.sh b/test/testing.sh index e3aee55f..305168c8 100755 --- a/test/testing.sh +++ b/test/testing.sh | |||
@@ -30,8 +30,11 @@ then | |||
30 | shift | 30 | shift |
31 | fi | 31 | fi |
32 | 32 | ||
33 | luashortversion=`echo $luaversion | cut -d. -f 1-2` | ||
34 | |||
33 | testing_dir="$PWD" | 35 | testing_dir="$PWD" |
34 | 36 | ||
37 | testing_lrprefix="$testing_dir/testing_lrprefix-$luaversion" | ||
35 | testing_tree="$testing_dir/testing-$luaversion" | 38 | testing_tree="$testing_dir/testing-$luaversion" |
36 | testing_sys_tree="$testing_dir/testing_sys-$luaversion" | 39 | testing_sys_tree="$testing_dir/testing_sys-$luaversion" |
37 | testing_tree_copy="$testing_dir/testing_copy-$luaversion" | 40 | testing_tree_copy="$testing_dir/testing_copy-$luaversion" |
@@ -39,7 +42,6 @@ testing_sys_tree_copy="$testing_dir/testing_sys_copy-$luaversion" | |||
39 | testing_cache="$testing_dir/testing_cache-$luaversion" | 42 | testing_cache="$testing_dir/testing_cache-$luaversion" |
40 | testing_server="$testing_dir/testing_server-$luaversion" | 43 | testing_server="$testing_dir/testing_server-$luaversion" |
41 | 44 | ||
42 | |||
43 | if [ "$1" == "--clean" ] | 45 | if [ "$1" == "--clean" ] |
44 | then | 46 | then |
45 | shift | 47 | shift |
@@ -51,6 +53,7 @@ fi | |||
51 | rm -f luacov.report.out | 53 | rm -f luacov.report.out |
52 | rm -rf /tmp/luarocks_testing | 54 | rm -rf /tmp/luarocks_testing |
53 | mkdir /tmp/luarocks_testing | 55 | mkdir /tmp/luarocks_testing |
56 | rm -rf "$testing_lrprefix" | ||
54 | rm -rf "$testing_tree" | 57 | rm -rf "$testing_tree" |
55 | rm -rf "$testing_sys_tree" | 58 | rm -rf "$testing_sys_tree" |
56 | rm -rf "$testing_tree_copy" | 59 | rm -rf "$testing_tree_copy" |
@@ -77,7 +80,7 @@ rocks_servers = { | |||
77 | } | 80 | } |
78 | local_cache = "$testing_cache" | 81 | local_cache = "$testing_cache" |
79 | upload_server = "testing" | 82 | upload_server = "testing" |
80 | upload_user = "hisham" | 83 | upload_user = "$USER" |
81 | upload_servers = { | 84 | upload_servers = { |
82 | testing = { | 85 | testing = { |
83 | rsync = "localhost/tmp/luarocks_testing", | 86 | rsync = "localhost/tmp/luarocks_testing", |
@@ -107,7 +110,7 @@ rocks_trees = { | |||
107 | } | 110 | } |
108 | local_cache = "$testing_cache" | 111 | local_cache = "$testing_cache" |
109 | upload_server = "testing" | 112 | upload_server = "testing" |
110 | upload_user = "hisham" | 113 | upload_user = "$USER" |
111 | upload_servers = { | 114 | upload_servers = { |
112 | testing = { | 115 | testing = { |
113 | sftp = "localhost/tmp/luarocks_testing", | 116 | sftp = "localhost/tmp/luarocks_testing", |
@@ -116,20 +119,15 @@ upload_servers = { | |||
116 | EOF | 119 | EOF |
117 | cat <<EOF > $testing_dir/luacov.config | 120 | cat <<EOF > $testing_dir/luacov.config |
118 | return { | 121 | return { |
119 | ["configfile"] = ".luacov", | 122 | statsfile = "$testing_dir/luacov.stats.out", |
120 | ["statsfile"] = "$testing_dir/luacov.stats.out", | 123 | reportfile = "$testing_dir/luacov.report.out", |
121 | ["reportfile"] = "$testing_dir/luacov.report.out", | 124 | modules = { |
122 | runreport = false, | 125 | ["luarocks"] = "src/bin/luarocks", |
123 | deletestats = false, | 126 | ["luarocks-admin"] = "src/bin/luarocks-admin", |
124 | ["include"] = {}, | 127 | ["luarocks.*"] = "src", |
125 | ["exclude"] = { | 128 | ["luarocks.*.*"] = "src", |
126 | "luacov$", | 129 | ["luarocks.*.*.*"] = "src" |
127 | "luacov%.reporter$", | 130 | } |
128 | "luacov%.defaults$", | ||
129 | "luacov%.runner$", | ||
130 | "luacov%.stats$", | ||
131 | "luacov%.tick$", | ||
132 | }, | ||
133 | } | 131 | } |
134 | EOF | 132 | EOF |
135 | 133 | ||
@@ -153,8 +151,16 @@ then | |||
153 | make install INSTALL_TOP="$luadir" &> /dev/null | 151 | make install INSTALL_TOP="$luadir" &> /dev/null |
154 | fi | 152 | fi |
155 | popd | 153 | popd |
154 | [ -e ~/.ssh/id_rsa.pub ] || ssh-keygen -t rsa -P "" -f ~/.ssh/id_rsa | ||
155 | cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys | ||
156 | chmod og-wx ~/.ssh/authorized_keys | ||
157 | ssh-keyscan localhost >> ~/.ssh/known_hosts | ||
156 | else | 158 | else |
157 | luadir="/Programs/Lua/Current" | 159 | luadir="/Programs/Lua/Current" |
160 | if [ ! -e "$luadir" ] | ||
161 | then | ||
162 | luadir="/usr/local" | ||
163 | fi | ||
158 | fi | 164 | fi |
159 | 165 | ||
160 | if [ `uname -m` = i686 ] | 166 | if [ `uname -m` = i686 ] |
@@ -171,19 +177,21 @@ verrev_luasocket=${version_luasocket}-1 | |||
171 | srcdir_luasocket=luasocket-3.0-rc1 | 177 | srcdir_luasocket=luasocket-3.0-rc1 |
172 | 178 | ||
173 | version_cprint=0.1 | 179 | version_cprint=0.1 |
174 | verrev_cprint=0.1-1 | 180 | verrev_cprint=0.1-2 |
175 | 181 | ||
176 | version_luacov=0.5 | 182 | version_luacov=0.11.0 |
177 | verrev_luacov=0.5-1 | 183 | verrev_luacov=${version_luacov}-1 |
178 | version_lxsh=0.8.6 | 184 | version_lxsh=0.8.6 |
179 | version_validate_args=1.5.4 | 185 | version_validate_args=1.5.4 |
180 | verrev_validate_args=1.5.4-1 | 186 | verrev_validate_args=1.5.4-1 |
181 | verrev_lxsh=${version_lxsh}-2 | 187 | verrev_lxsh=${version_lxsh}-2 |
188 | version_abelhas=1.0 | ||
189 | verrev_abelhas=${version_abelhas}-1 | ||
182 | 190 | ||
183 | luasec=luasec | 191 | luasec=luasec |
184 | 192 | ||
185 | cd .. | 193 | cd .. |
186 | ./configure --with-lua="$luadir" | 194 | ./configure --with-lua="$luadir" --prefix="$testing_lrprefix" |
187 | make clean | 195 | make clean |
188 | make src/luarocks/site_config.lua | 196 | make src/luarocks/site_config.lua |
189 | make dev | 197 | make dev |
@@ -217,8 +225,7 @@ luarocks_admin_nocov="run_lua --nocov luarocks-admin" | |||
217 | mkdir -p "$testing_server" | 225 | mkdir -p "$testing_server" |
218 | ( | 226 | ( |
219 | cd "$testing_server" | 227 | cd "$testing_server" |
220 | luarocks_repo="http://luarocks.org/repositories/rocks" | 228 | luarocks_repo="https://luarocks.org" |
221 | luarocks_scm_repo="http://luarocks.org/repositories/rocks-scm" | ||
222 | get() { [ -e `basename "$1"` ] || wget -c "$1"; } | 229 | get() { [ -e `basename "$1"` ] || wget -c "$1"; } |
223 | get "$luarocks_repo/luacov-${verrev_luacov}.src.rock" | 230 | get "$luarocks_repo/luacov-${verrev_luacov}.src.rock" |
224 | get "$luarocks_repo/luacov-${verrev_luacov}.rockspec" | 231 | get "$luarocks_repo/luacov-${verrev_luacov}.rockspec" |
@@ -226,26 +233,33 @@ mkdir -p "$testing_server" | |||
226 | get "$luarocks_repo/lualogging-1.3.0-1.src.rock" | 233 | get "$luarocks_repo/lualogging-1.3.0-1.src.rock" |
227 | get "$luarocks_repo/luasocket-${verrev_luasocket}.src.rock" | 234 | get "$luarocks_repo/luasocket-${verrev_luasocket}.src.rock" |
228 | get "$luarocks_repo/luasocket-${verrev_luasocket}.rockspec" | 235 | get "$luarocks_repo/luasocket-${verrev_luasocket}.rockspec" |
229 | get "$luarocks_repo/luafilesystem-1.6.2-1.src.rock" | 236 | get "$luarocks_repo/luafilesystem-1.6.3-1.src.rock" |
230 | get "$luarocks_repo/stdlib-35-1.src.rock" | 237 | get "$luarocks_repo/stdlib-41.0.0-1.src.rock" |
231 | get "$luarocks_repo/luarepl-0.4-1.src.rock" | 238 | get "$luarocks_repo/luarepl-0.4-1.src.rock" |
232 | get "$luarocks_repo/validate-args-1.5.4-1.rockspec" | 239 | get "$luarocks_repo/validate-args-1.5.4-1.rockspec" |
233 | get "$luarocks_scm_repo/luasec-scm-1.rockspec" | 240 | get "$luarocks_repo/luasec-0.6-1.rockspec" |
234 | get "$luarocks_repo/luabitop-1.0.2-1.rockspec" | 241 | get "$luarocks_repo/luabitop-1.0.2-1.rockspec" |
242 | get "$luarocks_repo/luabitop-1.0.2-1.src.rock" | ||
235 | get "$luarocks_repo/lpty-1.0.1-1.src.rock" | 243 | get "$luarocks_repo/lpty-1.0.1-1.src.rock" |
236 | get "$luarocks_repo/cprint-${verrev_cprint}.src.rock" | 244 | get "$luarocks_repo/cprint-${verrev_cprint}.src.rock" |
237 | get "$luarocks_repo/cprint-${verrev_cprint}.rockspec" | 245 | get "$luarocks_repo/cprint-${verrev_cprint}.rockspec" |
238 | get "$luarocks_repo/wsapi-1.6-1.src.rock" | 246 | get "$luarocks_repo/wsapi-1.6-1.src.rock" |
239 | get "$luarocks_repo/lxsh-${verrev_lxsh}.src.rock" | 247 | get "$luarocks_repo/lxsh-${verrev_lxsh}.src.rock" |
240 | get "$luarocks_repo/abelhas-1.0-1.rockspec" | 248 | get "$luarocks_repo/lxsh-${verrev_lxsh}.rockspec" |
241 | get "$luarocks_repo/lzlib-0.4.work3-1.src.rock" | 249 | get "$luarocks_repo/abelhas-${verrev_abelhas}.rockspec" |
250 | get "$luarocks_repo/lzlib-0.4.1.53-1.src.rock" | ||
242 | get "$luarocks_repo/lpeg-0.12-1.src.rock" | 251 | get "$luarocks_repo/lpeg-0.12-1.src.rock" |
243 | get "$luarocks_repo/luaposix-31-1.src.rock" | 252 | get "$luarocks_repo/luaposix-33.2.1-1.src.rock" |
244 | get "$luarocks_repo/md5-1.2-1.src.rock" | 253 | get "$luarocks_repo/md5-1.2-1.src.rock" |
245 | get "$luarocks_repo/lrandom-20120430.51-1.src.rock" | 254 | get "$luarocks_repo/lmathx-20120430.51-1.src.rock" |
246 | get "$luarocks_repo/lrandom-20120430.52-1.src.rock" | 255 | get "$luarocks_repo/lmathx-20120430.51-1.rockspec" |
247 | get "$luarocks_repo/lrandom-20120430.51-1.rockspec" | 256 | get "$luarocks_repo/lmathx-20120430.52-1.src.rock" |
248 | get "$luarocks_repo/lrandom-20120430.52-1.rockspec" | 257 | get "$luarocks_repo/lmathx-20120430.52-1.rockspec" |
258 | get "$luarocks_repo/lmathx-20150505-1.src.rock" | ||
259 | get "$luarocks_repo/lmathx-20150505-1.rockspec" | ||
260 | get "$luarocks_repo/lua-path-0.2.3-1.src.rock" | ||
261 | get "$luarocks_repo/lua-cjson-2.1.0-1.src.rock" | ||
262 | get "$luarocks_repo/luacov-coveralls-0.1.1-1.src.rock" | ||
249 | ) | 263 | ) |
250 | $luarocks_admin_nocov make_manifest "$testing_server" | 264 | $luarocks_admin_nocov make_manifest "$testing_server" |
251 | 265 | ||
@@ -270,6 +284,8 @@ build_environment() { | |||
270 | $luarocks_nocov pack --tree="$testing_sys_tree" $package; mv $package-*.rock "$testing_cache" | 284 | $luarocks_nocov pack --tree="$testing_sys_tree" $package; mv $package-*.rock "$testing_cache" |
271 | } | 285 | } |
272 | done | 286 | done |
287 | export LUA_PATH= | ||
288 | export LUA_CPATH= | ||
273 | eval `$luarocks_noecho_nocov path --bin` | 289 | eval `$luarocks_noecho_nocov path --bin` |
274 | cp -a "$testing_tree" "$testing_tree_copy" | 290 | cp -a "$testing_tree" "$testing_tree_copy" |
275 | cp -a "$testing_sys_tree" "$testing_sys_tree_copy" | 291 | cp -a "$testing_sys_tree" "$testing_sys_tree_copy" |
@@ -313,14 +329,23 @@ need() { | |||
313 | need_luasocket() { need luasocket $verrev_luasocket; } | 329 | need_luasocket() { need luasocket $verrev_luasocket; } |
314 | 330 | ||
315 | # Tests ######################################### | 331 | # Tests ######################################### |
316 | |||
317 | test_version() { $luarocks --version; } | 332 | test_version() { $luarocks --version; } |
318 | 333 | ||
319 | fail_arg_server() { $luarocks --server; } | ||
320 | fail_arg_only_server() { $luarocks --only-server; } | ||
321 | fail_unknown_command() { $luarocks unknown_command; } | 334 | fail_unknown_command() { $luarocks unknown_command; } |
322 | 335 | ||
336 | fail_arg_boolean_parameter() { $luarocks --porcelain=invalid; } | ||
337 | fail_arg_boolean_unknown() { $luarocks --invalid-flag; } | ||
338 | fail_arg_string_no_parameter() { $luarocks --server; } | ||
339 | fail_arg_string_followed_by_flag() { $luarocks --server --porcelain; } | ||
340 | fail_arg_string_unknown() { $luarocks --invalid-flag=abc; } | ||
341 | |||
342 | fail_invalid_assignment() { $luarocks invalid=5; } | ||
343 | |||
323 | test_empty_list() { $luarocks list; } | 344 | test_empty_list() { $luarocks list; } |
345 | test_list_outdated() { $luarocks list --outdated; } | ||
346 | |||
347 | 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"; } | ||
348 | 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"; } | ||
324 | 349 | ||
325 | fail_build_noarg() { $luarocks build; } | 350 | fail_build_noarg() { $luarocks build; } |
326 | fail_download_noarg() { $luarocks download; } | 351 | fail_download_noarg() { $luarocks download; } |
@@ -329,6 +354,7 @@ fail_lint_noarg() { $luarocks lint; } | |||
329 | fail_search_noarg() { $luarocks search; } | 354 | fail_search_noarg() { $luarocks search; } |
330 | fail_show_noarg() { $luarocks show; } | 355 | fail_show_noarg() { $luarocks show; } |
331 | fail_unpack_noarg() { $luarocks unpack; } | 356 | fail_unpack_noarg() { $luarocks unpack; } |
357 | fail_upload_noarg() { $luarocks upload; } | ||
332 | fail_remove_noarg() { $luarocks remove; } | 358 | fail_remove_noarg() { $luarocks remove; } |
333 | fail_doc_noarg() { $luarocks doc; } | 359 | fail_doc_noarg() { $luarocks doc; } |
334 | fail_new_version_noarg() { $luarocks new_version; } | 360 | fail_new_version_noarg() { $luarocks new_version; } |
@@ -341,45 +367,80 @@ fail_lint_invalid() { $luarocks lint invalid; } | |||
341 | fail_show_invalid() { $luarocks show invalid; } | 367 | fail_show_invalid() { $luarocks show invalid; } |
342 | fail_new_version_invalid() { $luarocks new_version invalid; } | 368 | fail_new_version_invalid() { $luarocks new_version invalid; } |
343 | 369 | ||
370 | test_list_invalidtree() { $luarocks --tree=/some/invalid/tree list; } | ||
371 | |||
372 | fail_inexistent_dir() { mkdir idontexist; cd idontexist; rmdir ../idontexist; $luarocks; err=$?; cd ..; return $err; } | ||
373 | |||
344 | fail_make_norockspec() { $luarocks make; } | 374 | fail_make_norockspec() { $luarocks make; } |
345 | 375 | ||
376 | fail_build_permissions() { $luarocks build --tree=/usr lpeg; } | ||
377 | fail_build_permissions_parent() { $luarocks build --tree=/usr/invalid lpeg; } | ||
378 | |||
379 | test_build_verbose() { $luarocks build --verbose lpeg; } | ||
380 | test_build_timeout() { $luarocks --timeout=10; } | ||
381 | fail_build_timeout_invalid() { $luarocks --timeout=abc; } | ||
382 | test_build_branch() { $luarocks build --branch=master lpeg; } | ||
383 | fail_build_invalid_entry_deps_mode() { $luarocks build --deps-mode=123 lpeg; } | ||
384 | test_build_only_server() { $luarocks --only-server=testing; } | ||
385 | test_build_only_sources() { $luarocks build --only-sources="http://example.com" lpeg; } | ||
346 | fail_build_blank_arg() { $luarocks build --tree="" lpeg; } | 386 | fail_build_blank_arg() { $luarocks build --tree="" lpeg; } |
347 | test_build_withpatch() { need_luasocket; $luarocks build luadoc; } | 387 | test_build_withpatch() { need_luasocket; $luarocks build luadoc; } |
348 | test_build_diffversion() { $luarocks build luacov ${version_luacov}; } | 388 | test_build_diffversion() { $luarocks build luacov ${version_luacov}; } |
349 | test_build_command() { $luarocks build stdlib; } | 389 | test_build_command() { $luarocks build stdlib; } |
350 | test_build_install_bin() { $luarocks build luarepl; } | 390 | test_build_install_bin() { $luarocks build luarepl; } |
351 | fail_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; } | 391 | 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; } |
352 | 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; } | 392 | 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; } |
353 | test_build_supported_platforms() { $luarocks build lpty; } | 393 | test_build_supported_platforms() { $luarocks build lpty; } |
394 | test_build_only_deps_rockspec() { $luarocks download --rockspec lxsh ${verrev_lxsh} && $luarocks build ./lxsh-${verrev_lxsh}.rockspec --only-deps && { $luarocks show lxsh; [ $? -ne 0 ]; }; } | ||
395 | 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 ]; }; } | ||
396 | test_build_only_deps() { $luarocks build luasec --only-deps && { $luarocks show luasec; [ $? -ne 0 ]; }; } | ||
397 | test_install_only_deps() { $luarocks install lxsh ${verrev_lxsh} --only-deps && { $luarocks show lxsh; [ $? -ne 0 ]; }; } | ||
398 | test_build_no_deps() { $luarocks build luasec --nodeps; } | ||
399 | test_install_no_deps() { $luarocks install luasec --nodeps; } | ||
354 | fail_build_missing_external() { $luarocks build "$testing_dir/testfiles/missing_external-0.1-1.rockspec" INEXISTENT_INCDIR="/invalid/dir"; } | 400 | fail_build_missing_external() { $luarocks build "$testing_dir/testfiles/missing_external-0.1-1.rockspec" INEXISTENT_INCDIR="/invalid/dir"; } |
401 | fail_build_invalidpatch() { need_luasocket; $luarocks build "$testing_dir/testfiles/invalid_patch-0.1-1.rockspec"; } | ||
355 | 402 | ||
356 | test_build_deps_partial_match() { $luarocks build lrandom; } | 403 | test_build_deps_partial_match() { $luarocks build lmathx; } |
357 | 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"; } | 404 | 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"; } |
358 | 405 | ||
359 | test_download_all() { $luarocks download --all validate-args && rm validate-args-*; } | 406 | test_download_all() { $luarocks download --all validate-args && rm validate-args-*; } |
360 | test_download_rockspecversion() { $luarocks download --rockspec validate-args ${verrev_validate_args} && rm validate-args-*; } | 407 | test_download_rockspecversion() { $luarocks download --rockspec validate-args ${verrev_validate_args} && rm validate-args-*; } |
361 | 408 | ||
362 | test_help() { $luarocks help; } | 409 | test_help() { $luarocks help; } |
410 | fail_help_invalid() { $luarocks help invalid; } | ||
363 | 411 | ||
412 | test_install_only_deps() { $luarocks install --only-deps "$testing_cache/luasocket-$verrev_luasocket.$platform.rock"; } | ||
364 | test_install_binaryrock() { $luarocks build --pack-binary-rock cprint && $luarocks install ./cprint-${verrev_cprint}.${platform}.rock && rm ./cprint-${verrev_cprint}.${platform}.rock; } | 413 | test_install_binaryrock() { $luarocks build --pack-binary-rock cprint && $luarocks install ./cprint-${verrev_cprint}.${platform}.rock && rm ./cprint-${verrev_cprint}.${platform}.rock; } |
365 | test_install_with_bin() { $luarocks install wsapi; } | 414 | test_install_with_bin() { $luarocks install wsapi; } |
366 | fail_install_notazipfile() { $luarocks install "$testing_dir/testfiles/not_a_zipfile-1.0-1.src.rock"; } | 415 | fail_install_notazipfile() { $luarocks install "$testing_dir/testfiles/not_a_zipfile-1.0-1.src.rock"; } |
416 | fail_install_invalidpatch() { need_luasocket; $luarocks install "$testing_dir/testfiles/invalid_patch-0.1-1.rockspec"; } | ||
417 | fail_install_invalid_filename() { $luarocks install "invalid.rock"; } | ||
418 | fail_install_invalid_arch() { $luarocks install "foo-1.0-1.impossible-x86.rock"; } | ||
419 | test_install_reinstall() { $luarocks install "$testing_cache/luasocket-$verrev_luasocket.$platform.rock"; $luarocks install --deps-mode=none "$testing_cache/luasocket-$verrev_luasocket.$platform.rock"; } | ||
420 | |||
421 | fail_local_root() { USER=root $luarocks install --local luasocket; } | ||
422 | |||
423 | 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; } | ||
367 | 424 | ||
368 | 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; } | 425 | 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; } |
369 | fail_lint_type_mismatch_string() { $luarocks lint "$testing_dir/testfiles/type_mismatch_string-1.0-1.rockspec"; } | 426 | fail_lint_type_mismatch_string() { $luarocks lint "$testing_dir/testfiles/type_mismatch_string-1.0-1.rockspec"; } |
370 | fail_lint_type_mismatch_version() { $luarocks lint "$testing_dir/testfiles/type_mismatch_version-1.0-1.rockspec"; } | 427 | fail_lint_type_mismatch_version() { $luarocks lint "$testing_dir/testfiles/type_mismatch_version-1.0-1.rockspec"; } |
371 | fail_lint_type_mismatch_table() { $luarocks lint "$testing_dir/testfiles/type_mismatch_table-1.0-1.rockspec"; } | 428 | fail_lint_type_mismatch_table() { $luarocks lint "$testing_dir/testfiles/type_mismatch_table-1.0-1.rockspec"; } |
429 | fail_lint_no_build_table() { $luarocks lint "$testing_dir/testfiles/no_build_table-0.1-1.rockspec"; } | ||
372 | 430 | ||
373 | test_list() { $luarocks list; } | 431 | test_list() { $luarocks list; } |
374 | test_list_porcelain() { $luarocks list --porcelain; } | 432 | test_list_porcelain() { $luarocks list --porcelain; } |
375 | 433 | ||
376 | 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}; } | 434 | 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}; } |
377 | 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}; } | 435 | 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 new_version lxsh-${verrev_lxsh}.rockspec && $luarocks make && cd ../.. && rm -rf ./lxsh-${verrev_lxsh}; } |
378 | 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}; } | 436 | test_make_unnamed_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 && cp lxsh-${verrev_lxsh}.rockspec rockspec && $luarocks make && cd ../.. && rm -rf ./lxsh-${verrev_lxsh}; } |
379 | 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}; } | 437 | fail_make_ambiguous_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 && cp lxsh-${verrev_lxsh}.rockspec lxsh2-${verrev_lxsh}.rockspec && $luarocks make && cd ../.. && rm -rf ./lxsh-${verrev_lxsh}; } |
438 | fail_make_ambiguous_unnamed_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 && mv lxsh-${verrev_lxsh}.rockspec 1_rockspec && cp 1_rockspec 2_rockspec && $luarocks make && cd ../.. && rm -rf ./lxsh-${verrev_lxsh}; } | ||
439 | 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}; } | ||
380 | 440 | ||
381 | test_new_version() { $luarocks download --rockspec luacov ${version_luacov} && $luarocks new_version ./luacov-${version_luacov}-1.rockspec 0.2 && rm ./luacov-0.*; } | 441 | test_new_version() { $luarocks download --rockspec luacov ${version_luacov} && $luarocks new_version ./luacov-${version_luacov}-1.rockspec 0.2 && rm ./luacov-0.*; } |
382 | 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-*; } | 442 | 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-*; } |
443 | test_new_version_tag() { $luarocks download --rockspec luacov ${version_luacov} && $luarocks new_version ./luacov-${version_luacov}-1.rockspec --tag v0.3 && rm ./luacov-0.3-1.rockspec; } | ||
383 | 444 | ||
384 | test_pack() { $luarocks list && $luarocks pack luacov && rm ./luacov-*.rock; } | 445 | test_pack() { $luarocks list && $luarocks pack luacov && rm ./luacov-*.rock; } |
385 | test_pack_src() { $luarocks install $luasec && $luarocks download --rockspec luasocket && $luarocks pack ./luasocket-${verrev_luasocket}.rockspec && rm ./luasocket-${version_luasocket}-*.rock; } | 446 | test_pack_src() { $luarocks install $luasec && $luarocks download --rockspec luasocket && $luarocks pack ./luasocket-${verrev_luasocket}.rockspec && rm ./luasocket-${version_luasocket}-*.rock; } |
@@ -388,39 +449,61 @@ test_path() { $luarocks path --bin; } | |||
388 | test_path_lr_path() { $luarocks path --lr-path; } | 449 | test_path_lr_path() { $luarocks path --lr-path; } |
389 | test_path_lr_cpath() { $luarocks path --lr-cpath; } | 450 | test_path_lr_cpath() { $luarocks path --lr-cpath; } |
390 | test_path_lr_bin() { $luarocks path --lr-bin; } | 451 | test_path_lr_bin() { $luarocks path --lr-bin; } |
452 | test_path_with_tree() { $luarocks path --tree=lua_modules; } | ||
391 | 453 | ||
392 | fail_purge_missing_tree() { $luarocks purge --tree="$testing_tree"; } | 454 | fail_purge_missing_tree() { $luarocks purge --tree="$testing_tree"; } |
455 | fail_purge_tree_notstring() { $luarocks purge --tree=1; } | ||
393 | test_purge() { $luarocks purge --tree="$testing_sys_tree"; } | 456 | test_purge() { $luarocks purge --tree="$testing_sys_tree"; } |
457 | test_purge_oldversions() { $luarocks purge --old-versions --tree="$testing_sys_tree"; } | ||
394 | 458 | ||
395 | test_remove() { $luarocks build luacov ${version_luacov} && $luarocks remove luacov ${version_luacov}; } | 459 | test_remove() { $luarocks build abelhas ${version_abelhas} && $luarocks remove abelhas ${version_abelhas}; } |
396 | test_remove_force() { need_luasocket; $luarocks build lualogging && $luarocks remove --force luasocket; } | 460 | test_remove_force() { need_luasocket; $luarocks build lualogging && $luarocks remove --force luasocket; } |
397 | fail_remove_deps() { need_luasocket; $luarocks build lualogging && $luarocks remove luasocket; } | 461 | fail_remove_deps() { need_luasocket; $luarocks build lualogging && $luarocks remove luasocket; } |
462 | fail_remove_missing() { $luarocks remove missing_rock; } | ||
398 | fail_remove_invalid_name() { $luarocks remove invalid.rock; } | 463 | fail_remove_invalid_name() { $luarocks remove invalid.rock; } |
399 | 464 | ||
400 | test_search_found() { $luarocks search zlib; } | 465 | test_search_found() { $luarocks search zlib; } |
401 | test_search_missing() { $luarocks search missing_rock; } | 466 | test_search_missing() { $luarocks search missing_rock; } |
467 | test_search_version() { $luarocks search zlib 1.1; } | ||
468 | test_search_all() { $luarocks search --all; } | ||
469 | fail_search_nostring() { $var=123; $luarocks search $var; } | ||
402 | 470 | ||
403 | test_show() { $luarocks show luacov; } | 471 | test_show() { $luarocks show luacov; } |
404 | test_show_modules() { $luarocks show --modules luacov; } | 472 | test_show_modules() { $luarocks show --modules luacov; } |
473 | test_show_home() { $luarocks show --home luacov; } | ||
474 | test_show_deps() { $luarocks show --deps luacov; } | ||
475 | test_show_rockspec() { $luarocks show --rockspec luacov; } | ||
476 | test_show_mversion() { $luarocks show --mversion luacov; } | ||
477 | test_show_rocktree() { $luarocks show --rock-tree luacov; } | ||
478 | test_show_rockdir() { $luarocks show --rock-dir luacov; } | ||
405 | test_show_depends() { need_luasocket; $luarocks install $luasec && $luarocks show luasec; } | 479 | test_show_depends() { need_luasocket; $luarocks install $luasec && $luarocks show luasec; } |
406 | test_show_oldversion() { $luarocks install luacov ${version_luacov} && $luarocks show luacov ${version_luacov}; } | 480 | test_show_oldversion() { $luarocks install luacov ${version_luacov} && $luarocks show luacov ${version_luacov}; } |
407 | 481 | ||
408 | test_unpack_download() { rm -rf ./cprint-${verrev_cprint} && $luarocks unpack cprint && rm -rf ./cprint-${verrev_cprint}; } | 482 | test_unpack_download() { rm -rf ./cprint-${verrev_cprint} && $luarocks unpack cprint && rm -rf ./cprint-${verrev_cprint}; } |
409 | test_unpack_src() { rm -rf ./cprint-${verrev_cprint} && $luarocks download --src cprint && $luarocks unpack ./cprint-${verrev_cprint}.src.rock && rm -rf ./cprint-${verrev_cprint}; } | 483 | test_unpack_src() { rm -rf ./cprint-${verrev_cprint} && $luarocks download --source cprint && $luarocks unpack ./cprint-${verrev_cprint}.src.rock && rm -rf ./cprint-${verrev_cprint}; } |
410 | test_unpack_rockspec() { rm -rf ./cprint-${verrev_cprint} && $luarocks download --rockspec cprint && $luarocks unpack ./cprint-${verrev_cprint}.rockspec && rm -rf ./cprint-${verrev_cprint}; } | 484 | test_unpack_rockspec() { rm -rf ./cprint-${verrev_cprint} && $luarocks download --rockspec cprint && $luarocks unpack ./cprint-${verrev_cprint}.rockspec && rm -rf ./cprint-${verrev_cprint}; } |
411 | 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}; } | 485 | 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}; } |
486 | fail_unpack_invalidpatch() { need_luasocket; $luarocks unpack "$testing_dir/testfiles/invalid_patch-0.1-1.rockspec"; } | ||
487 | fail_unpack_invalidrockspec() { need_luasocket; $luarocks unpack "invalid.rockspec"; } | ||
488 | |||
489 | fail_upload_invalidrockspec() { $luarocks upload "invalid.rockspec"; } | ||
490 | fail_upload_invalidkey() { $luarocks upload --api-key="invalid" "invalid.rockspec"; } | ||
491 | fail_upload_skippack() { $luarocks upload --api-key="invalid" --skip-pack "luacov-${verrev_luacov}.rockspec"; } | ||
492 | fail_upload_force() { $luarocks install lua-cjson && $luarocks upload --api-key="invalid" --force "luacov-${verrev_luacov}.rockspec" && $luarocks remove lua-cjson; } | ||
493 | |||
412 | 494 | ||
413 | test_admin_help() { $luarocks_admin help; } | 495 | test_admin_help() { $luarocks_admin help; } |
414 | 496 | ||
415 | test_admin_make_manifest() { $luarocks_admin make_manifest; } | 497 | test_admin_make_manifest() { $luarocks_admin make_manifest; } |
416 | test_admin_add_rsync() { if [ "$travis" ]; then return; fi; $luarocks_admin --server=testing add "$testing_server/luasocket-${verrev_luasocket}.src.rock"; } | 498 | test_admin_add_rsync() { $luarocks_admin --server=testing add "$testing_server/luasocket-${verrev_luasocket}.src.rock"; } |
417 | 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"; } | 499 | 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"; } |
418 | fail_admin_add_missing() { $luarocks_admin --server=testing add; } | 500 | fail_admin_add_missing() { $luarocks_admin --server=testing add; } |
419 | fail_admin_invalidserver() { $luarocks_admin --server=invalid add "$testing_server/luasocket-${verrev_luasocket}.src.rock"; } | 501 | fail_admin_invalidserver() { $luarocks_admin --server=invalid add "$testing_server/luasocket-${verrev_luasocket}.src.rock"; } |
420 | fail_admin_invalidrock() { if [ "$travis" ]; then return 1; fi; $luarocks_admin --server=testing add invalid; } | 502 | fail_admin_invalidrock() { $luarocks_admin --server=testing add invalid; } |
421 | test_admin_refresh_cache() { if [ "$travis" ]; then return; fi; $luarocks_admin --server=testing refresh_cache; } | 503 | test_admin_refresh_cache() { $luarocks_admin --server=testing refresh_cache; } |
422 | test_admin_remove() { if [ "$travis" ]; then return; fi; $luarocks_admin --server=testing remove luasocket-${verrev_luasocket}.src.rock; } | 504 | test_admin_remove() { $luarocks_admin --server=testing remove luasocket-${verrev_luasocket}.src.rock; } |
423 | fail_admin_remove_missing() { $luarocks_admin --server=testing remove; } | 505 | fail_admin_remove_missing() { $luarocks_admin --server=testing remove; } |
506 | fail_admin_split_server_url() { $luarocks_admin --server="localhost@/tmp/luarocks_testing" add "$testing_server/luasocket-${verrev_luasocket}.src.rock"; } | ||
424 | 507 | ||
425 | fail_deps_mode_invalid_arg() { $luarocks remove luacov --deps-mode; } | 508 | fail_deps_mode_invalid_arg() { $luarocks remove luacov --deps-mode; } |
426 | test_deps_mode_one() { $luarocks build --tree="system" lpeg && $luarocks list && $luarocks build --deps-mode=one --tree="$testing_tree" lxsh && [ `$luarocks_noecho list --tree="$testing_tree" --porcelain lpeg | wc -l` = 1 ]; } | 509 | test_deps_mode_one() { $luarocks build --tree="system" lpeg && $luarocks list && $luarocks build --deps-mode=one --tree="$testing_tree" lxsh && [ `$luarocks_noecho list --tree="$testing_tree" --porcelain lpeg | wc -l` = 1 ]; } |
@@ -429,18 +512,50 @@ test_deps_mode_order_sys() { $luarocks build --tree="$testing_tree" lpeg && $lua | |||
429 | 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 ]; } | 512 | 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 ]; } |
430 | test_deps_mode_none() { $luarocks build --tree="$testing_tree" --deps-mode=none lxsh; [ `$luarocks_noecho list --tree="$testing_tree" --porcelain lpeg | wc -l` = 0 ]; } | 513 | test_deps_mode_none() { $luarocks build --tree="$testing_tree" --deps-mode=none lxsh; [ `$luarocks_noecho list --tree="$testing_tree" --porcelain lpeg | wc -l` = 0 ]; } |
431 | test_deps_mode_nodeps_alias() { $luarocks build --tree="$testing_tree" --nodeps lxsh; [ `$luarocks_noecho list --tree="$testing_tree" --porcelain lpeg | wc -l` = 0 ]; } | 514 | test_deps_mode_nodeps_alias() { $luarocks build --tree="$testing_tree" --nodeps lxsh; [ `$luarocks_noecho list --tree="$testing_tree" --porcelain lpeg | wc -l` = 0 ]; } |
432 | 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}; } | 515 | 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}; } |
433 | 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}; } | 516 | 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}; } |
434 | 517 | ||
435 | test_write_rockspec() { $luarocks write_rockspec git://github.com/keplerproject/luarocks; } | 518 | test_write_rockspec() { $luarocks write_rockspec git://github.com/keplerproject/luarocks; } |
519 | test_write_rockspec_tag() { $luarocks write_rockspec git://github.com/keplerproject/luarocks --tag=v2.3.0; } | ||
436 | test_write_rockspec_lib() { $luarocks write_rockspec git://github.com/mbalmer/luafcgi --lib=fcgi --license="3-clause BSD" --lua-version=5.1,5.2; } | 520 | test_write_rockspec_lib() { $luarocks write_rockspec git://github.com/mbalmer/luafcgi --lib=fcgi --license="3-clause BSD" --lua-version=5.1,5.2; } |
521 | test_write_rockspec_format() { $luarocks write_rockspec git://github.com/keplerproject/luarocks --rockspec-format=1.1 --lua-version=5.1,5.2; } | ||
437 | 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"; } | 522 | 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"; } |
438 | fail_write_rockspec_args() { $luarocks write_rockspec invalid; } | 523 | fail_write_rockspec_args() { $luarocks write_rockspec invalid; } |
439 | fail_write_rockspec_args_url() { $luarocks write_rockspec http://example.com/invalid.zip; } | 524 | fail_write_rockspec_args_url() { $luarocks write_rockspec http://example.com/invalid.zip; } |
440 | test_write_rockspec_http() { $luarocks write_rockspec http://luarocks.org/releases/luarocks-2.1.0.tar.gz --lua-version=5.1; } | 525 | test_write_rockspec_http() { $luarocks write_rockspec http://luarocks.org/releases/luarocks-2.1.0.tar.gz --lua-version=5.1; } |
441 | test_write_rockspec_basedir() { $luarocks write_rockspec https://github.com/downloads/Olivine-Labs/luassert/luassert-1.2.tar.gz --lua-version=5.1; } | 526 | test_write_rockspec_basedir() { $luarocks write_rockspec https://github.com/downloads/Olivine-Labs/luassert/luassert-1.2.tar.gz --lua-version=5.1; } |
442 | 527 | ||
528 | fail_config_noflags() { $luarocks config; } | ||
529 | test_config_lua_incdir() { $luarocks config --lua-incdir; } | ||
530 | test_config_lua_libdir() { $luarocks config --lua-libdir; } | ||
531 | test_config_lua_ver() { $luarocks config --lua-ver; } | ||
532 | fail_config_system_config() { rm -f "$testing_lrprefix/etc/luarocks/config.lua"; $luarocks config --system-config; } | ||
533 | 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; } | ||
534 | 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; } | ||
535 | test_config_user_config() { $luarocks config --user-config; } | ||
536 | fail_config_user_config() { LUAROCKS_CONFIG="/missing_file.lua" $luarocks config --user-config; } | ||
537 | test_config_rock_trees() { $luarocks config --rock-trees; } | ||
538 | test_config_help() { $luarocks help config; } | ||
539 | |||
540 | # Tests for https://github.com/keplerproject/luarocks/issues/375 | ||
541 | test_fetch_base_dir() { $lua <<EOF | ||
542 | local fetch = require "luarocks.fetch" | ||
543 | |||
544 | assert("v0.3" == fetch.url_to_base_dir("https://github.com/hishamhm/lua-compat-5.2/archive/v0.3.zip")) | ||
545 | assert("lua-compat-5.2" == fetch.url_to_base_dir("https://github.com/hishamhm/lua-compat-5.2.zip")) | ||
546 | assert("lua-compat-5.2" == fetch.url_to_base_dir("https://github.com/hishamhm/lua-compat-5.2.tar.gz")) | ||
547 | assert("lua-compat-5.2" == fetch.url_to_base_dir("https://github.com/hishamhm/lua-compat-5.2.tar.bz2")) | ||
548 | assert("parser.moon" == fetch.url_to_base_dir("git://github.com/Cirru/parser.moon")) | ||
549 | assert("v0.3" == fetch.url_to_base_dir("https://github.com/hishamhm/lua-compat-5.2/archive/v0.3")) | ||
550 | EOF | ||
551 | } | ||
552 | |||
443 | test_doc() { $luarocks install luarepl; $luarocks doc luarepl; } | 553 | test_doc() { $luarocks install luarepl; $luarocks doc luarepl; } |
554 | test_doc_home() { $luarocks install luacov; $luarocks doc luacov --home; } | ||
555 | fail_doc_invalid() { $luarocks doc invalid; } | ||
556 | test_doc_list() { $luarocks install luacov; $luarocks doc luacov --list; } | ||
557 | test_doc_local() { $luarocks install luacov; $luarocks doc luacov --local; } | ||
558 | test_doc_porcelain() { $luarocks install luacov; $luarocks doc luacov --porcelain; } | ||
444 | 559 | ||
445 | # Driver ######################################### | 560 | # Driver ######################################### |
446 | 561 | ||
@@ -452,8 +567,13 @@ run_tests() { | |||
452 | echo "-------------------------------------------" | 567 | echo "-------------------------------------------" |
453 | reset_environment | 568 | reset_environment |
454 | if $test | 569 | if $test |
455 | then echo "OK: Expected success." | 570 | then |
456 | else echo "FAIL: Unexpected failure."; exit 1 | 571 | echo "OK: Expected success." |
572 | else | ||
573 | if [ $? = 99 ] | ||
574 | then echo "FAIL: Unexpected crash!"; exit 99 | ||
575 | fi | ||
576 | echo "FAIL: Unexpected failure."; exit 1 | ||
457 | fi | 577 | fi |
458 | done | 578 | done |
459 | grep "^fail_$1.*(" < $testing_dir/testing.sh | cut -d'(' -f1 | while read test | 579 | grep "^fail_$1.*(" < $testing_dir/testing.sh | cut -d'(' -f1 | while read test |
@@ -464,7 +584,11 @@ run_tests() { | |||
464 | reset_environment | 584 | reset_environment |
465 | if $test | 585 | if $test |
466 | then echo "FAIL: Unexpected success."; exit 1 | 586 | then echo "FAIL: Unexpected success."; exit 1 |
467 | else echo "OK: Expected failure." | 587 | else |
588 | if [ $? = 99 ] | ||
589 | then echo "FAIL: Unexpected crash!"; exit 99 | ||
590 | fi | ||
591 | echo "OK: Expected failure." | ||
468 | fi | 592 | fi |
469 | done | 593 | done |
470 | } | 594 | } |
@@ -481,7 +605,11 @@ run_with_full_environment() { | |||
481 | echo "===========================================" | 605 | echo "===========================================" |
482 | echo "Running with full environment" | 606 | echo "Running with full environment" |
483 | echo "===========================================" | 607 | echo "===========================================" |
484 | build_environment luacov luafilesystem luasocket luabitop luaposix md5 lzlib | 608 | |
609 | local bitop= | ||
610 | [ "$luaversion" = "5.1.5" ] && bitop=luabitop | ||
611 | |||
612 | build_environment luacov luafilesystem luasocket $bitop luaposix md5 lzlib | ||
485 | run_tests $1 | 613 | run_tests $1 |
486 | } | 614 | } |
487 | 615 | ||
@@ -493,12 +621,18 @@ run_all_tests() { | |||
493 | run_all_tests $1 | 621 | run_all_tests $1 |
494 | #run_with_minimal_environment $1 | 622 | #run_with_minimal_environment $1 |
495 | 623 | ||
496 | $testing_sys_tree/bin/luacov -c $testing_dir/luacov.config src/luarocks src/bin | 624 | cd "$testing_dir/.." |
497 | 625 | ||
498 | if [ "$travis" ] | 626 | if [ "$travis" ] |
499 | then | 627 | then |
500 | grep "Summary" -B1 -A1000 $testing_dir/luacov.report.out | 628 | if [ "$TRAVIS" ] |
629 | then | ||
630 | build_environment luacov luafilesystem luacov-coveralls | ||
631 | $testing_sys_tree/bin/luacov-coveralls -c "$testing_dir/luacov.config" || echo "ok" | ||
632 | fi | ||
633 | $testing_sys_tree/bin/luacov -c "$testing_dir/luacov.config" | ||
634 | grep "Summary" -B1 -A1000 "$testing_dir/luacov.report.out" | ||
501 | else | 635 | else |
636 | $testing_sys_tree/bin/luacov -c "$testing_dir/luacov.config" | ||
502 | cat "$testing_dir/luacov.report.out" | 637 | cat "$testing_dir/luacov.report.out" |
503 | fi | 638 | fi |
504 | |||
diff --git a/win32/pe-parser.lua b/win32/pe-parser.lua index 30bb8390..9cd36ffc 100644 --- a/win32/pe-parser.lua +++ b/win32/pe-parser.lua | |||
@@ -1,7 +1,11 @@ | |||
1 | --------------------------------------------------------------------------------------- | 1 | --------------------------------------------------------------------------------------- |
2 | -- Lua module to parse a Portable Executable (.exe , .dll, etc.) file and extract metadata. | 2 | -- Lua module to parse a Portable Executable (.exe , .dll, etc.) file and extract metadata. |
3 | -- | 3 | -- |
4 | -- Version 0.1, [copyright (c) 2013 - Thijs Schreijer](http://www.thijsschreijer.nl) | 4 | -- NOTE: numerical information is extracted as strings (hex) to prevent numerical overflows in |
5 | -- case of 64 bit fields (bit/flag fields). Pointer arithmetic is still done numerically, so for | ||
6 | -- very large files this could lead to undefined results. Use with care! | ||
7 | -- | ||
8 | -- Version 0.4, [copyright (c) 2013-2015 Thijs Schreijer](http://www.thijsschreijer.nl) | ||
5 | -- @name pe-parser | 9 | -- @name pe-parser |
6 | -- @class module | 10 | -- @class module |
7 | 11 | ||
@@ -238,7 +242,7 @@ local function readstring(f) | |||
238 | end | 242 | end |
239 | 243 | ||
240 | --- Parses a file and extracts the information. | 244 | --- Parses a file and extracts the information. |
241 | -- All numbers are delivered as "string" types containing hex values, see `toHex` and `toDec` conversion functions. | 245 | -- 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. |
242 | -- @return table with data, or nil + error | 246 | -- @return table with data, or nil + error |
243 | -- @usage local pe = require("pe-parser") | 247 | -- @usage local pe = require("pe-parser") |
244 | -- local obj = pe.parse("c:\lua\lua.exe") | 248 | -- local obj = pe.parse("c:\lua\lua.exe") |
@@ -524,9 +528,12 @@ function M.msvcrt(infile) | |||
524 | 528 | ||
525 | for i, dll in ipairs(obj.DataDirectory.ImportTable) do | 529 | for i, dll in ipairs(obj.DataDirectory.ImportTable) do |
526 | dll = dll.Name:upper() | 530 | dll = dll.Name:upper() |
527 | local result = dll:match('(MSVCR%d*)%.DLL') | 531 | local result = dll:match('(MSVCR%d*D?)%.DLL') |
532 | if not result then | ||
533 | result = dll:match('(MSVCRTD?)%.DLL') | ||
534 | end | ||
528 | if not result then | 535 | if not result then |
529 | result = dll:match('(MSVCRT)%.DLL') | 536 | result = dll:match('(VCRUNTIME%d*D?)%.DLL') |
530 | end | 537 | end |
531 | -- success, found it return name + binary where it was found | 538 | -- success, found it return name + binary where it was found |
532 | if result then return result, infile end | 539 | if result then return result, infile end |