Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/torch/luajit-rocks.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRonan Collobert <locronan@fb.com>2014-09-11 01:51:39 +0400
committerRonan Collobert <locronan@fb.com>2014-09-11 01:51:39 +0400
commitd4d49fd9fbdd07a5e4b4fca85544e99cd17d63d4 (patch)
treee49da758e42936f6d9408d75e0faddd686f6f811
parent6819e2edda2db910b9e82fb302448f7d45eacac7 (diff)
parent31690a82a01bf8a336699e6a278f85d5a420561f (diff)
Merge commit '31690a82a01bf8a336699e6a278f85d5a420561f' into vanilla
Conflicts: luarocks/install.bat luarocks/src/luarocks/cfg.lua
-rw-r--r--luarocks/.travis.yml10
-rw-r--r--luarocks/COPYING29
-rw-r--r--luarocks/COPYING_win16
-rw-r--r--luarocks/Makefile83
-rw-r--r--luarocks/README.md9
-rwxr-xr-xluarocks/configure73
-rw-r--r--luarocks/install.bat681
-rwxr-xr-xluarocks/makedist5
-rw-r--r--luarocks/rockspec2
-rwxr-xr-xluarocks/src/bin/luarocks40
-rwxr-xr-xluarocks/src/bin/luarocks-admin15
-rw-r--r--luarocks/src/luarocks/add.lua32
-rw-r--r--luarocks/src/luarocks/admin_remove.lua28
-rw-r--r--luarocks/src/luarocks/build.lua154
-rw-r--r--luarocks/src/luarocks/build/builtin.lua70
-rw-r--r--luarocks/src/luarocks/build/cmake.lua15
-rw-r--r--luarocks/src/luarocks/build/command.lua7
-rw-r--r--luarocks/src/luarocks/build/make.lua9
-rw-r--r--luarocks/src/luarocks/cache.lua29
-rw-r--r--luarocks/src/luarocks/cfg.lua254
-rw-r--r--luarocks/src/luarocks/command_line.lua76
-rw-r--r--luarocks/src/luarocks/deps.lua141
-rw-r--r--luarocks/src/luarocks/dir.lua49
-rw-r--r--luarocks/src/luarocks/doc.lua156
-rw-r--r--luarocks/src/luarocks/download.lua39
-rw-r--r--luarocks/src/luarocks/fetch.lua150
-rw-r--r--luarocks/src/luarocks/fetch/cvs.lua12
-rw-r--r--luarocks/src/luarocks/fetch/git.lua27
-rw-r--r--luarocks/src/luarocks/fetch/git_file.lua7
-rw-r--r--luarocks/src/luarocks/fetch/git_http.lua27
-rw-r--r--luarocks/src/luarocks/fetch/hg.lua15
-rw-r--r--luarocks/src/luarocks/fetch/sscm.lua7
-rw-r--r--luarocks/src/luarocks/fetch/svn.lua15
-rw-r--r--luarocks/src/luarocks/fs.lua39
-rw-r--r--luarocks/src/luarocks/fs/lua.lua340
-rw-r--r--luarocks/src/luarocks/fs/unix.lua35
-rw-r--r--luarocks/src/luarocks/fs/unix/tools.lua161
-rw-r--r--luarocks/src/luarocks/fs/win32.lua130
-rw-r--r--luarocks/src/luarocks/fs/win32/tools.lua213
-rw-r--r--luarocks/src/luarocks/help.lua57
-rw-r--r--luarocks/src/luarocks/index.lua47
-rw-r--r--luarocks/src/luarocks/install.lua35
-rw-r--r--luarocks/src/luarocks/lint.lua28
-rw-r--r--luarocks/src/luarocks/list.lua14
-rw-r--r--luarocks/src/luarocks/loader.lua84
-rw-r--r--luarocks/src/luarocks/make.lua27
-rw-r--r--luarocks/src/luarocks/make_manifest.lua23
-rw-r--r--luarocks/src/luarocks/manif.lua200
-rw-r--r--luarocks/src/luarocks/manif_core.lua27
-rw-r--r--luarocks/src/luarocks/new_version.lua43
-rw-r--r--luarocks/src/luarocks/pack.lua42
-rw-r--r--luarocks/src/luarocks/path.lua152
-rw-r--r--luarocks/src/luarocks/path_cmd.lua73
-rw-r--r--luarocks/src/luarocks/persist.lua28
-rw-r--r--luarocks/src/luarocks/purge.lua21
-rw-r--r--luarocks/src/luarocks/refresh_cache.lua14
-rw-r--r--luarocks/src/luarocks/remove.lua87
-rw-r--r--luarocks/src/luarocks/repos.lua98
-rw-r--r--luarocks/src/luarocks/require.lua6
-rw-r--r--luarocks/src/luarocks/search.lua98
-rw-r--r--luarocks/src/luarocks/show.lua59
-rw-r--r--luarocks/src/luarocks/tools/patch.lua40
-rw-r--r--luarocks/src/luarocks/tools/tar.lua13
-rw-r--r--luarocks/src/luarocks/tools/zip.lua11
-rw-r--r--luarocks/src/luarocks/type_check.lua57
-rw-r--r--luarocks/src/luarocks/unpack.lua43
-rw-r--r--luarocks/src/luarocks/upload.lua92
-rw-r--r--luarocks/src/luarocks/upload/api.lua270
-rw-r--r--luarocks/src/luarocks/upload/multipart.lua112
-rw-r--r--luarocks/src/luarocks/util.lua117
-rw-r--r--luarocks/src/luarocks/validate.lua26
-rw-r--r--luarocks/src/luarocks/write_rockspec.lua340
-rw-r--r--luarocks/test/testfiles/missing_external-0.1-1.rockspec24
-rwxr-xr-xluarocks/test/testing.sh353
-rw-r--r--luarocks/win32/LuaRocks.reg.lua (renamed from luarocks/win32/bin/create_reg_file.lua)0
-rw-r--r--luarocks/win32/LuaRocks.reg.template (renamed from luarocks/win32/bin/LuaRocks.reg.template)0
-rw-r--r--luarocks/win32/bin/chmod.exebin81920 -> 0 bytes
-rw-r--r--luarocks/win32/bin/objdump.exebin2247694 -> 0 bytes
-rwxr-xr-xluarocks/win32/bin/rm.exebin109056 -> 0 bytes
-rw-r--r--luarocks/win32/lua.ico (renamed from luarocks/win32/bin/lua.ico)bin22486 -> 22486 bytes
-rw-r--r--luarocks/win32/luarocksw.bat (renamed from luarocks/win32/bin/luarocksw.bat)4
-rw-r--r--luarocks/win32/pe-parser.lua546
-rw-r--r--luarocks/win32/rclauncher.c (renamed from luarocks/win32/bin/rclauncher.c)0
-rw-r--r--luarocks/win32/tools/7z.dll (renamed from luarocks/win32/bin/7z.dll)bin858624 -> 858624 bytes
-rw-r--r--luarocks/win32/tools/7z.exe (renamed from luarocks/win32/bin/7z.exe)bin161792 -> 161792 bytes
-rw-r--r--[-rwxr-xr-x]luarocks/win32/tools/cp.exe (renamed from luarocks/win32/bin/cp.exe)bin130048 -> 130048 bytes
-rw-r--r--[-rwxr-xr-x]luarocks/win32/tools/find.exe (renamed from luarocks/win32/bin/find.exe)bin160256 -> 160256 bytes
-rw-r--r--luarocks/win32/tools/libeay32.dll (renamed from luarocks/win32/bin/libeay32.dll)bin1177600 -> 1177600 bytes
-rw-r--r--luarocks/win32/tools/libiconv2.dll (renamed from luarocks/win32/bin/libiconv2.dll)bin1008128 -> 1008128 bytes
-rw-r--r--luarocks/win32/tools/libintl3.dll (renamed from luarocks/win32/bin/libintl3.dll)bin103424 -> 103424 bytes
-rw-r--r--luarocks/win32/tools/libssl32.dll (renamed from luarocks/win32/bin/libssl32.dll)bin232960 -> 232960 bytes
-rw-r--r--[-rwxr-xr-x]luarocks/win32/tools/ls.exe (renamed from luarocks/win32/bin/ls.exe)bin180736 -> 180736 bytes
-rw-r--r--luarocks/win32/tools/md5sum.exe (renamed from luarocks/win32/bin/md5sum.exe)bin41984 -> 41984 bytes
-rw-r--r--[-rwxr-xr-x]luarocks/win32/tools/mkdir.exe (renamed from luarocks/win32/bin/mkdir.exe)bin32768 -> 32768 bytes
-rw-r--r--[-rwxr-xr-x]luarocks/win32/tools/mv.exe (renamed from luarocks/win32/bin/mv.exe)bin138752 -> 138752 bytes
-rw-r--r--[-rwxr-xr-x]luarocks/win32/tools/pwd.exe (renamed from luarocks/win32/bin/pwd.exe)bin61440 -> 61440 bytes
-rw-r--r--[-rwxr-xr-x]luarocks/win32/tools/rmdir.exe (renamed from luarocks/win32/bin/rmdir.exe)bin25088 -> 25088 bytes
-rw-r--r--[-rwxr-xr-x]luarocks/win32/tools/test.exe (renamed from luarocks/win32/bin/test.exe)bin62976 -> 62976 bytes
-rw-r--r--[-rwxr-xr-x]luarocks/win32/tools/uname.exe (renamed from luarocks/win32/bin/uname.exe)bin33792 -> 33792 bytes
-rw-r--r--luarocks/win32/tools/wget.exe (renamed from luarocks/win32/bin/wget.exe)bin449024 -> 449024 bytes
100 files changed, 4877 insertions, 1634 deletions
diff --git a/luarocks/.travis.yml b/luarocks/.travis.yml
new file mode 100644
index 0000000..cf2b1e6
--- /dev/null
+++ b/luarocks/.travis.yml
@@ -0,0 +1,10 @@
+language: c
+
+compiler: gcc
+
+env:
+ matrix:
+ - LUA_VER=5.1.5
+ - LUA_VER=5.2.3
+
+script: cd test && ./testing.sh --travis --lua $LUA_VER
diff --git a/luarocks/COPYING b/luarocks/COPYING
index 4311883..34a3de3 100644
--- a/luarocks/COPYING
+++ b/luarocks/COPYING
@@ -1,31 +1,4 @@
-LuaRocks is free software: it can be used for both academic and commercial
-purposes at absolutely no cost. There are no royalties or GNU-like "copyleft"
-restrictions. LuaRocks qualifies as Open Source software. Its licenses are
-compatible with the GPL. LuaRocks is not in the public domain and the Kepler
-Project keeps its copyright. The legal details are below.
-
-The spirit of the license is that you are free to use LuaRocks for any purpose
-at no cost without having to ask us. The only requirement is that if you do
-use LuaRocks, then you should give us credit by including the appropriate
-copyright notice somewhere in your product or its documentation.
-
-7z.exe and 7z.dll are covered by another license, please see COPYING.7z for
-details.
-
-find.exe, mv.exe, rm.exe, wget.exe, ls.exe, pwd.exe, rmdir.exe, chmod.exe,
-md5sum.exe, test.exe, cp.exe, mkdir.exe, and uname.exe are part of UnxUtils,
-check http://unxutils.sourceforge.net/ for license information.
-
-Files under win32/lua5.1, except for Microsoft.VC80.CRT.manifest and msv*.*,
-are covered by another license, please see COPYING.lua for details.
-
-Microsoft.VC80.CRT.manifest, msvcm80.dll, msvcp80.dll, msvcr80.dll are part
-of the Microsoft Visual C++ 2005 SP1 Redistributable Package (x86) and
-are Copyright Microsoft, Inc. 2007.
-
-------------------------------------------------------------------------------
-
-Copyright 2007-2010 Kepler Project.
+Copyright 2007-2014 Kepler Project.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/luarocks/COPYING_win b/luarocks/COPYING_win
new file mode 100644
index 0000000..3413b8c
--- /dev/null
+++ b/luarocks/COPYING_win
@@ -0,0 +1,16 @@
+
+This package includes additional Windows components which are under the
+following licenses:
+
+* For 7z.exe and 7z.dll, please see COPYING_7z for details.
+
+* find.exe, mv.exe, wget.exe, ls.exe, pwd.exe, rmdir.exe, md5sum.exe,
+ test.exe, cp.exe, mkdir.exe, and uname.exe are part of UnxUtils, check
+ http://unxutils.sourceforge.net/ for license information.
+
+* Files under win32/lua5.1, except for Microsoft.VC80.CRT.manifest and msv*.*,
+ are covered by another license, please see COPYING_lua for details.
+
+* Microsoft.VC80.CRT.manifest, msvcm80.dll, msvcp80.dll, msvcr80.dll are part
+ of the Microsoft Visual C++ 2005 SP1 Redistributable Package (x86) and are
+ Copyright Microsoft, Inc. 2007.
diff --git a/luarocks/Makefile b/luarocks/Makefile
index be83c01..1f9d0e2 100644
--- a/luarocks/Makefile
+++ b/luarocks/Makefile
@@ -1,7 +1,10 @@
-# $Id: Makefile,v 1.30 2008/08/18 14:07:35 hisham Exp $
include config.unix
+.PHONY: all build dev build_bins luadoc check_makefile cleanup_bins clean \
+ install_bins install_luas install_site_config write_sysconfig \
+ install bootstrap install_rock
+
DESTDIR =
PREFIX ?= /usr/local
ROCKS_TREE ?= $(PREFIX)
@@ -16,14 +19,18 @@ LUAROCKS_FILES = fs/unix/tools.lua fs/unix.lua fs/win32/tools.lua fs/win32.lua \
fs/lua.lua persist.lua list.lua require.lua repos.lua dir.lua make_manifest.lua \
command_line.lua install.lua build/command.lua build/cmake.lua build/make.lua \
build/builtin.lua fetch/cvs.lua fetch/git.lua fetch/sscm.lua tools/patch.lua \
-fetch/svn.lua tools/zip.lua tools/tar.lua pack.lua type_check.lua make.lua path.lua \
+fetch/svn.lua tools/zip.lua tools/tar.lua pack.lua type_check.lua make.lua \
remove.lua fs.lua manif.lua add.lua deps.lua build.lua search.lua show.lua \
manif_core.lua fetch.lua unpack.lua validate.lua cfg.lua download.lua \
help.lua util.lua index.lua cache.lua refresh_cache.lua loader.lua \
-admin_remove.lua fetch/hg.lua fetch/git_file.lua new_version.lua lint.lua purge.lua
+admin_remove.lua fetch/hg.lua fetch/git_file.lua new_version.lua lint.lua \
+purge.lua path.lua path_cmd.lua write_rockspec.lua doc.lua upload.lua \
+upload/api.lua upload/multipart.lua fetch/git_http.lua
CONFIG_FILE = $(SYSCONFDIR)/config-$(LUA_VERSION).lua
+SAFEPWD=`echo "$$PWD" | sed -e 's/\([][]\)\1/]]..'\''\1\1'\''..[[/g'`
+
all:
@echo "- Type 'make build' and 'make install':"
@echo " to install to $(PREFIX) as usual."
@@ -31,55 +38,64 @@ all:
@echo " to install LuaRocks in $(PREFIX) as a rock."
@echo
-build: built
+build: src/luarocks/site_config.lua build_bins
+ @echo
+ @echo "Done. Type 'make install' to install into $(PREFIX)."
+ @echo
src/luarocks/site_config.lua: config.unix
rm -f src/luarocks/site_config.lua
- echo 'module("luarocks.site_config")' >> src/luarocks/site_config.lua
+ echo 'local site_config = {}' >> src/luarocks/site_config.lua
if [ -n "$(PREFIX)" ] ;\
then \
- echo "LUAROCKS_PREFIX=[[$(PREFIX)]]" >> src/luarocks/site_config.lua ;\
+ echo "site_config.LUAROCKS_PREFIX=[[$(PREFIX)]]" >> src/luarocks/site_config.lua ;\
fi
if [ -n "$(LUA_INCDIR)" ] ;\
then \
- echo "LUA_INCDIR=[[$(LUA_INCDIR)]]" >> src/luarocks/site_config.lua ;\
+ echo "site_config.LUA_INCDIR=[[$(LUA_INCDIR)]]" >> src/luarocks/site_config.lua ;\
fi
if [ -n "$(LUA_LIBDIR)" ] ;\
then \
- echo "LUA_LIBDIR=[[$(LUA_LIBDIR)]]" >> src/luarocks/site_config.lua ;\
+ echo "site_config.LUA_LIBDIR=[[$(LUA_LIBDIR)]]" >> src/luarocks/site_config.lua ;\
fi
if [ -n "$(LUA_BINDIR)" ] ;\
then \
- echo "LUA_BINDIR=[[$(LUA_BINDIR)]]" >> src/luarocks/site_config.lua ;\
+ echo "site_config.LUA_BINDIR=[[$(LUA_BINDIR)]]" >> src/luarocks/site_config.lua ;\
fi
if [ -n "$(LUA_SUFFIX)" ] ;\
then \
- echo "LUA_INTERPRETER=[[lua$(LUA_SUFFIX)]]" >> src/luarocks/site_config.lua ;\
+ echo "site_config.LUA_INTERPRETER=[[lua$(LUA_SUFFIX)]]" >> src/luarocks/site_config.lua ;\
fi
if [ -n "$(SYSCONFDIR)" ] ;\
then \
- echo "LUAROCKS_SYSCONFDIR=[[$(SYSCONFDIR)]]" >> src/luarocks/site_config.lua ;\
+ echo "site_config.LUAROCKS_SYSCONFDIR=[[$(SYSCONFDIR)]]" >> src/luarocks/site_config.lua ;\
fi
if [ -n "$(ROCKS_TREE)" ] ;\
then \
- echo "LUAROCKS_ROCKS_TREE=[[$(ROCKS_TREE)]]" >> src/luarocks/site_config.lua ;\
+ echo "site_config.LUAROCKS_ROCKS_TREE=[[$(ROCKS_TREE)]]" >> src/luarocks/site_config.lua ;\
fi
if [ -n "$(FORCE_CONFIG)" ] ;\
then \
- echo "LUAROCKS_FORCE_CONFIG=true" >> src/luarocks/site_config.lua ;\
+ echo "site_config.LUAROCKS_FORCE_CONFIG=true" >> src/luarocks/site_config.lua ;\
fi
if [ -n "$(LUAROCKS_ROCKS_SUBDIR)" ] ;\
then \
- echo "LUAROCKS_ROCKS_SUBDIR=[[$(LUAROCKS_ROCKS_SUBDIR)]]" >> src/luarocks/site_config.lua ;\
+ echo "site_config.LUAROCKS_ROCKS_SUBDIR=[[$(LUAROCKS_ROCKS_SUBDIR)]]" >> src/luarocks/site_config.lua ;\
fi
if [ "$(LUA_DIR_SET)" = "yes" ] ;\
then \
- echo "LUA_DIR_SET=true" >> src/luarocks/site_config.lua ;\
+ echo "site_config.LUA_DIR_SET=true" >> src/luarocks/site_config.lua ;\
fi
- echo "LUAROCKS_UNAME_S=[[$(LUAROCKS_UNAME_S)]]" >> src/luarocks/site_config.lua
- echo "LUAROCKS_UNAME_M=[[$(LUAROCKS_UNAME_M)]]" >> src/luarocks/site_config.lua
- echo "LUAROCKS_DOWNLOADER=[[$(LUAROCKS_DOWNLOADER)]]" >> src/luarocks/site_config.lua
- echo "LUAROCKS_MD5CHECKER=[[$(LUAROCKS_MD5CHECKER)]]" >> src/luarocks/site_config.lua
+ echo "site_config.LUAROCKS_UNAME_S=[[$(LUAROCKS_UNAME_S)]]" >> src/luarocks/site_config.lua
+ echo "site_config.LUAROCKS_UNAME_M=[[$(LUAROCKS_UNAME_M)]]" >> src/luarocks/site_config.lua
+ echo "site_config.LUAROCKS_DOWNLOADER=[[$(LUAROCKS_DOWNLOADER)]]" >> src/luarocks/site_config.lua
+ echo "site_config.LUAROCKS_MD5CHECKER=[[$(LUAROCKS_MD5CHECKER)]]" >> src/luarocks/site_config.lua
+ if [ -n "$(MULTIARCH_SUBDIR)" ] ;\
+ then \
+ echo 'site_config.LUAROCKS_EXTERNAL_DEPS_SUBDIRS={ bin="bin", lib={ "lib", [[$(MULTIARCH_SUBDIR)]] }, include="include" }' >> src/luarocks/site_config.lua ;\
+ echo 'site_config.LUAROCKS_RUNTIME_EXTERNAL_DEPS_SUBDIRS={ bin="bin", lib={ "lib", [[$(MULTIARCH_SUBDIR)]] }, include="include" }' >> src/luarocks/site_config.lua ;\
+ fi
+ echo "return site_config" >> src/luarocks/site_config.lua
dev:
$(MAKE) build_bins LUADIR=$(PWD)/src
@@ -89,18 +105,12 @@ build_bins: cleanup_bins
do \
sed "1d" src/bin/$$f > src/bin/$$f.bak ;\
echo "#!$(LUA_BINDIR)/lua$(LUA_SUFFIX)" > src/bin/$$f ;\
- echo "package.path = [[$(LUADIR)/?.lua;$(LUADIR)/?/init.lua;]]..package.path" >> src/bin/$$f ;\
+ echo "package.path = [[$(LUADIR)/?.lua;]]..package.path" | sed "s,//,/,g" >> src/bin/$$f ;\
cat src/bin/$$f.bak >> src/bin/$$f ;\
chmod +x src/bin/$$f ;\
rm -f src/bin/$$f.bak ;\
done
-built: src/luarocks/site_config.lua build_bins
- touch built
- @echo
- @echo "Done. Type 'make install' to install into $(PREFIX)."
- @echo
-
luadoc:
rm -rf doc/luadoc
mkdir -p doc/luadoc
@@ -128,17 +138,16 @@ cleanup_bins:
clean: cleanup_bins
rm -f src/luarocks/site_config.lua
- rm -f built
-install_bins: built
+install_bins:
mkdir -p "$(DESTDIR)$(BINDIR)"
cd src/bin && for f in $(BIN_FILES); \
do \
cp "$$f" "$(DESTDIR)$(BINDIR)/$$f-$(LUA_VERSION)"; \
- ln -nfs "$(DESTDIR)$(BINDIR)/$$f-$(LUA_VERSION)" "$(DESTDIR)$(BINDIR)/$$f"; \
+ ln -nfs "$$f-$(LUA_VERSION)" "$(DESTDIR)$(BINDIR)/$$f"; \
done
-install_luas: built
+install_luas:
mkdir -p "$(DESTDIR)$(LUADIR)/luarocks"
cd src/luarocks && for f in $(LUAROCKS_FILES); \
do \
@@ -147,11 +156,11 @@ install_luas: built
cp "$$f" "$$d" || exit 1; \
done
-install_site_config: built
+install_site_config: src/luarocks/site_config.lua
mkdir -p "$(DESTDIR)$(LUADIR)/luarocks"
- cd src/luarocks && cp site_config.lua "$(DESTDIR)$(LUADIR)/luarocks"
+ cp src/luarocks/site_config.lua "$(DESTDIR)$(LUADIR)/luarocks"
-write_sysconfig: built
+write_sysconfig:
mkdir -p "$(DESTDIR)$(ROCKS_TREE)"
if [ ! -f "$(DESTDIR)$(CONFIG_FILE)" ] ;\
then \
@@ -159,15 +168,15 @@ write_sysconfig: built
echo 'rocks_trees = {' >> "$(DESTDIR)$(CONFIG_FILE)" ;\
if [ ! -n "$(FORCE_CONFIG)" ] ;\
then \
- echo ' home..[[/.luarocks]],' >> "$(DESTDIR)$(CONFIG_FILE)" ;\
+ echo ' { name = [[user]], root = home..[[/.luarocks]] },' >> "$(DESTDIR)$(CONFIG_FILE)" ;\
fi ;\
- echo ' [[$(ROCKS_TREE)]]' >> "$(DESTDIR)$(CONFIG_FILE)" ;\
+ echo ' { name = [[system]], root = [[$(ROCKS_TREE)]] }' >> "$(DESTDIR)$(CONFIG_FILE)" ;\
echo '}' >> "$(DESTDIR)$(CONFIG_FILE)" ;\
fi
install: install_bins install_luas install_site_config write_sysconfig
-bootstrap: src/luarocks/site_config.lua install_site_config write_sysconfig
- LUA_PATH="$$PWD/src/?.lua;$$LUA_PATH" src/bin/luarocks make rockspec --tree="$(PREFIX)"
+bootstrap: src/luarocks/site_config.lua install_site_config write_sysconfig cleanup_bins
+ '$(LUA_BINDIR)/lua$(LUA_SUFFIX)' -e "package.path=[[$(SAFEPWD)/src/?.lua;]]..package.path" src/bin/luarocks make rockspec --tree="$(PREFIX)"
install_rock: install_bins install_luas
diff --git a/luarocks/README.md b/luarocks/README.md
index 87345a2..c779c3d 100644
--- a/luarocks/README.md
+++ b/luarocks/README.md
@@ -1,8 +1,13 @@
-This is LuaRocks, a deployment and management system for Lua modules.
+LuaRocks
+========
+
+A package manager for Lua modules.
+
+[![Build Status](https://travis-ci.org/keplerproject/luarocks.png?branch=master)](https://travis-ci.org/keplerproject/luarocks)
Main website: [luarocks.org](http://www.luarocks.org)
-LuaRocks allows you to install Lua modules as self-contained packages called
+It allows you to install Lua modules as self-contained packages called
[*rocks*][1], which also contain version [dependency][2] information. This
information is used both during installation, so that when one rock is
requested all rocks it depends on are installed as well, and at run time, so
diff --git a/luarocks/configure b/luarocks/configure
index a5aa1f4..a7b8529 100755
--- a/luarocks/configure
+++ b/luarocks/configure
@@ -14,6 +14,7 @@ LUA_BINDIR="/usr/bin"
LUA_INCDIR="/usr/include"
LUA_LIBDIR="/usr/lib"
LUA_VERSION="5.1"
+MULTIARCH_SUBDIR=""
# ----------------------------------------------------------------------------
# FUNCTION DEFINITIONS
@@ -35,21 +36,24 @@ Where to install files installed by rocks, to make the accessible to Lua and
your \$PATH. Beware of clashes between files installed by LuaRocks and by your
system's package manager.
---rocks-tree=FILE Root of the local tree of installed rocks.
+--rocks-tree=DIR Root of the local tree of installed rocks.
Default is \$PREFIX
---lua-version=VERSION Use specific Lua version: 5.1 or 5.2
+--lua-version=VERSION Use specific Lua version: 5.1, 5.2, or 5.3
Default is "$LUA_VERSION"
--lua-suffix=SUFFIX Versioning suffix to use in Lua filenames.
Default is "$LUA_SUFFIX" (lua$LUA_SUFFIX...)
--with-lua=PREFIX Use Lua from given prefix.
- Default is $LUA_DIR
+ Default is auto-detected (the parent directory of \$LUA_BINDIR).
+--with-lua-bin=DIR You can also specify Lua's bin dir.
+ Default is the directory of the auto-detected Lua interpreter,
+ or \$LUA_DIR/bin if --with-lua is used.
--with-lua-include=DIR You can also specify Lua's includes dir.
Default is \$LUA_DIR/include
--with-lua-lib=DIR You can also specify Lua's libraries dir.
Default is \$LUA_DIR/lib
--with-downloader=TOOL Which tool to use as a downloader.
- Valid options are: wget, curl.
+ Valid options are: curl, wget.
Default is to auto-detect.
--with-md5-checker=TOOL Which tool to use as a downloader.
Valid options are: md5sum, openssl
@@ -176,7 +180,7 @@ do
--lua-version)
[ -n "$value" ] || die "Missing value in flag $key."
LUA_VERSION="$value"
- [ "$LUA_VERSION" = "5.1" -o "$LUA_VERSION" = "5.2" ] || die "Invalid Lua version in flag $key."
+ [ "$LUA_VERSION" = "5.1" -o "$LUA_VERSION" = "5.2" -o "$LUA_VERSION" = "5.3" ] || die "Invalid Lua version in flag $key."
LUA_VERSION_SET=yes
;;
--with-lua)
@@ -184,6 +188,11 @@ do
LUA_DIR="$value"
LUA_DIR_SET=yes
;;
+ --with-lua-bin)
+ [ -n "$value" ] || die "Missing value in flag $key."
+ LUA_BINDIR="$value"
+ LUA_BINDIR_SET=yes
+ ;;
--with-lua-include)
[ -n "$value" ] || die "Missing value in flag $key."
LUA_INCDIR="$value"
@@ -233,7 +242,7 @@ fi
detect_lua_version() {
detected_lua=`$1 -e 'print(_VERSION:sub(5))' 2> /dev/null`
- if [ "$detected_lua" = "5.1" -o "$detected_lua" = "5.2" ]
+ if [ "$detected_lua" = "5.1" -o "$detected_lua" = "5.2" -o "$detected_lua" = "5.3" ]
then
echo "Lua version detected: $detected_lua"
if [ "$LUA_VERSION_SET" != "yes" ]
@@ -248,7 +257,10 @@ detect_lua_version() {
search_interpreter() {
LUA_SUFFIX="$1"
- if [ "$LUA_DIR_SET" = "yes" ]
+ if [ "$LUA_BINDIR_SET" = "yes" ]
+ then
+ find_lua="$LUA_BINDIR"
+ elif [ "$LUA_DIR_SET" = "yes" ]
then
if [ -f "$LUA_DIR/bin/lua$suffix" ]
then
@@ -259,7 +271,7 @@ search_interpreter() {
fi
if [ -n "$find_lua" ]
then
- echo "Lua interpreter found: $find_lua/lua$suffix..."
+ echo "Lua interpreter: $find_lua/lua$suffix..."
detect_lua_version "$find_lua/lua$suffix"
return 0
fi
@@ -270,14 +282,17 @@ if [ "$LUA_SUFFIX_SET" != "yes" ]
then
if [ "$LUA_VERSION_SET" = "yes" -a "$LUA_VERSION" = "5.1" ]
then
- suffixes="5.1 51"
+ suffixes="5.1 51 -5.1 -51"
elif [ "$LUA_VERSION_SET" = "yes" -a "$LUA_VERSION" = "5.2" ]
then
- suffixes="5.2 52"
+ suffixes="5.2 52 -5.2 -52"
+ elif [ "$LUA_VERSION_SET" = "yes" -a "$LUA_VERSION" = "5.3" ]
+ then
+ suffixes="5.3 53 -5.3 -53"
else
- suffixes="5.2 52 5.1 51"
+ suffixes="5.3 53 -5.3 -53 5.2 52 -5.2 -52 5.1 51 -5.1 -51"
fi
- for suffix in "" `echo $suffixes` ""
+ for suffix in `echo $suffixes` ""
do
search_interpreter "$suffix" && break
done
@@ -285,9 +300,9 @@ fi
if [ "$LUA_DIR_SET" != "yes" ]
then
- echo_n "Looking for Lua... "
- if [ ! -n "$find_lua" ]
+ if [ -z "$find_lua" ]
then
+ echo_n "Looking for Lua... "
find_lua=`find_program lua$LUA_SUFFIX`
fi
@@ -312,7 +327,7 @@ then
LUA_LIBDIR="$LUA_DIR/lib"
fi
-if [ "$LUA_DIR_SET" = "yes" ]
+if [ "$LUA_DIR_SET" = "yes" -a "$LUA_BINDIR_SET" != "yes" ]
then
LUA_BINDIR="$LUA_DIR/bin"
fi
@@ -345,7 +360,7 @@ fi
if [ "$LUAROCKS_DOWNLOADER_SET" != "yes" ]
then
- find_helper "downloader helper program" wget curl fetch
+ find_helper "downloader helper program" curl wget fetch
LUAROCKS_DOWNLOADER=$HELPER
fi
@@ -370,12 +385,14 @@ else
die "Could not determine processor architecture. 'uname -m' failed."
fi
-if [ "$LUA_VERSION" = "5.2" ]
-then
- LUA_OTHER_VERSION=5.1
-else
- LUA_OTHER_VERSION=5.2
-fi
+for v in 5.1 5.2 5.3; do
+ if [ "$v" != "$LUA_VERSION" ]; then
+ if [ -e "$PREFIX/share/lua/$v/luarocks/site_config.lua" ]; then
+ LUA_OTHER_VERSION="$v"
+ break
+ fi
+ fi
+done
LUAROCKS_ROCKS_SUBDIR=/lib/luarocks/rocks
if [ "$VERSIONED_ROCKS_DIR" = "yes" ]
@@ -387,7 +404,7 @@ then
echo "Existing installation detected."
LUAROCKS_ROCKS_SUBDIR=`grep "LUAROCKS_ROCKS_SUBDIR" "$PREFIX/share/lua/$LUA_VERSION/luarocks/site_config.lua" | sed 's,.*=\[\[\(.*\)\]\],\1,'`
echo "Using previously configured rocks dir: $PREFIX$LUAROCKS_ROCKS_SUBDIR"
-elif [ -e "$PREFIX/share/lua/$LUA_OTHER_VERSION/luarocks/site_config.lua" ]
+elif [ -n "$LUA_OTHER_VERSION" ]
then
echo "Existing installation detected for other Lua version ($LUA_OTHER_VERSION)."
LUAROCKS_ROCKS_SUBDIR=$LUAROCKS_ROCKS_SUBDIR-$LUA_VERSION
@@ -396,6 +413,15 @@ else
echo "Using unversioned rocks dir: $PREFIX$LUAROCKS_ROCKS_SUBDIR"
fi
+if [ "$LUAROCKS_UNAME_S" = Linux ]
+then
+ GCC_ARCH=`gcc -print-multiarch 2>/dev/null`
+ if [ -n "$GCC_ARCH" -a -d "/usr/lib/$GCC_ARCH" ]
+ then
+ MULTIARCH_SUBDIR="lib/$GCC_ARCH"
+ fi
+fi
+
if [ -f config.unix ]; then
rm -f config.unix
fi
@@ -426,6 +452,7 @@ LUAROCKS_UNAME_S=$LUAROCKS_UNAME_S
LUAROCKS_DOWNLOADER=$LUAROCKS_DOWNLOADER
LUAROCKS_MD5CHECKER=$LUAROCKS_MD5CHECKER
LUAROCKS_ROCKS_SUBDIR=$LUAROCKS_ROCKS_SUBDIR
+MULTIARCH_SUBDIR=$MULTIARCH_SUBDIR
EOF
diff --git a/luarocks/install.bat b/luarocks/install.bat
index 417b095..ae7df63 100644
--- a/luarocks/install.bat
+++ b/luarocks/install.bat
@@ -1,14 +1,17 @@
rem=rem --[[
@setlocal& set luafile="%~f0" & if exist "%~f0.bat" set luafile="%~f0.bat"
-@lua5.1\bin\lua5.1.exe %luafile% %*& exit /b ]]
+@win32\lua5.1\bin\lua5.1.exe %luafile% %*& exit /b ]]
local vars = {}
-vars.PREFIX = [[C:\LuaRocks]]
-vars.VERSION = "2.1"
-vars.SYSCONFDIR = [[C:\LuaRocks]]
-vars.ROCKS_TREE = [[C:\LuaRocks]]
-vars.SCRIPTS_DIR = nil
+
+vars.PREFIX = nil
+vars.VERSION = "2.2"
+vars.SYSCONFDIR = nil
+vars.TREE_ROOT = nil
+vars.TREE_BIN = nil
+vars.TREE_LMODULE = nil
+vars.TREE_CMODULE = nil
vars.LUA_INTERPRETER = nil
vars.LUA_PREFIX = nil
vars.LUA_BINDIR = nil
@@ -16,20 +19,29 @@ vars.LUA_INCDIR = nil
vars.LUA_LIBDIR = nil
vars.LUA_LIBNAME = nil
vars.LUA_VERSION = "5.1"
-vars.LUA_SHORTV = nil
-vars.LUA_LIB_NAMES = "lua5.1.lib lua51.dll liblua.dll.a"
+vars.LUA_SHORTV = nil -- "51"
+-- MinGW does not generate .lib, nor needs it to link, but MSVC does
+-- so .lib must be listed first to ensure they are found first if present.
+-- To prevent MSVC trying to link to a .dll, which won't work.
+vars.LUA_LIB_NAMES = "lua5.1.lib lua51.lib lua5.1.dll lua51.dll liblua.dll.a"
vars.LUA_RUNTIME = nil
+vars.UNAME_M = nil
-local P_SET = false
local FORCE = false
local FORCE_CONFIG = false
local INSTALL_LUA = false
local USE_MINGW = false
-local REGISTRY = false
+local REGISTRY = true
+local NOADMIN = false
+local PROMPT = true
+local SELFCONTAINED = false
---
-- Some helpers
--
+
+local pe = assert(loadfile(".\\win32\\pe-parser.lua"))()
+
local function die(message)
if message then print(message) end
print()
@@ -37,19 +49,64 @@ local function die(message)
os.exit(1)
end
+function split_string(str, delim, maxNb)
+ -- Eliminate bad cases...
+ if string.find(str, delim) == nil then
+ return { str }
+ end
+ if maxNb == nil or maxNb < 1 then
+ maxNb = 0 -- No limit
+ end
+ local result = {}
+ local pat = "(.-)" .. delim .. "()"
+ local nb = 0
+ local lastPos
+ for part, pos in string.gmatch(str, pat) do
+ nb = nb + 1
+ result[nb] = part
+ lastPos = pos
+ if nb == maxNb then break end
+ end
+ -- Handle the last field
+ if nb ~= maxNb then
+ result[nb + 1] = string.sub(str, lastPos)
+ end
+ return result
+end
+
+
local function exec(cmd)
--print(cmd)
local status = os.execute(cmd)
- return status == 0
+ return (status == 0 or status == true) -- compat 5.1/5.2
end
local function exists(filename)
- local cmd = [[.\bin\test -e "]]..filename..[["]]
+ local cmd = [[.\win32\tools\test -e "]]..filename..[["]]
return exec(cmd)
end
local function mkdir (dir)
- return exec([[.\bin\mkdir -p "]]..dir..[[" >NUL]])
+ return exec([[.\win32\tools\mkdir -p "]]..dir..[[" >NUL]])
+end
+
+-- does the current user have admin priviledges ( = elevated)
+local function permission()
+ return exec("net session >NUL 2>&1") -- fails if not admin
+end
+
+-- rename file (full path) to backup (name only), appending number if required
+-- returns the new name (name only)
+local function backup(filename, backupname)
+ local path = filename:match("(.+)%\\.-$").."\\"
+ local nname = backupname
+ local i = 0
+ while exists(path..nname) do
+ i = i + 1
+ nname = backupname..tostring(i)
+ end
+ exec([[REN "]]..filename..[[" "]]..nname..[[" > NUL]])
+ return nname
end
-- interpolate string with values from 'vars' table
@@ -61,44 +118,69 @@ local function print_help()
print(S[[
Installs LuaRocks.
-/P [dir] (REQUIRED) Where to install.
- Note that version; $VERSION, will be
- appended to this path.
-/CONFIG [dir] Location where the config file should be installed.
- Default is same place of installation
-/TREE [dir] Root of the local tree of installed rocks.
- Default is same place of installation
-/SCRIPTS [dir] Where to install scripts installed by rocks.
- Default is TREE/bin.
+/P [dir] Where to install LuaRocks.
+ Note that version; $VERSION, will be appended to this
+ path, so "/P c:\luarocks\" will install in
+ "c:\luarocks\$VERSION\"
+ Default is %PROGRAMFILES%\LuaRocks
-/LV [version] Lua version to use; either 5.1 or 5.2.
+Configuring the destinations:
+/TREE [dir] Root of the local tree of installed rocks.
+ Default is %PROGRAMFILES%\LuaRocks\systree
+/SCRIPTS [dir] Where to install commandline scripts installed by
+ rocks. Default is {TREE}\bin.
+/LUAMOD [dir] Where to install Lua modules installed by rocks.
+ Default is {TREE}\share\lua\{LV}.
+/CMOD [dir] Where to install c modules installed by rocks.
+ Default is {TREE}\lib\lua\{LV}.
+/CONFIG [dir] Location where the config file should be installed.
+ Default is to follow /P option
+/SELFCONTAINED Creates a self contained installation in a single
+ directory given by /P.
+ Sets the /TREE and /CONFIG options to the same
+ location as /P. And does not load registry info
+ with option /NOREG. The only option NOT self
+ contained is the user rock tree, so don't use that
+ if you create a self contained installation.
+
+Configuring the Lua interpreter:
+/LV [version] Lua version to use; either 5.1, 5.2, or 5.3.
Default is 5.1
-/L Install LuaRocks' own copy of Lua even if detected,
- this will always be a 5.1 installation.
- (/LUA, /INC, /LIB, /BIN cannot be used with /L)
/LUA [dir] Location where Lua is installed - e.g. c:\lua\5.1\
+ If not provided, the installer will search the system
+ path and some default locations for a valid Lua
+ installation.
This is the base directory, the installer will look
for subdirectories bin, lib, include. Alternatively
these can be specified explicitly using the /INC,
/LIB, and /BIN options.
/INC [dir] Location of Lua includes - e.g. c:\lua\5.1\include
If provided overrides sub directory found using /LUA.
-/LIB [dir] Location of Lua libraries -e.g. c:\lua\5.1\lib
+/LIB [dir] Location of Lua libraries (.dll/.lib) - e.g. c:\lua\5.1\lib
If provided overrides sub directory found using /LUA.
/BIN [dir] Location of Lua executables - e.g. c:\lua\5.1\bin
If provided overrides sub directory found using /LUA.
+/L Install LuaRocks' own copy of Lua even if detected,
+ this will always be a 5.1 installation.
+ (/LUA, /INC, /LIB, /BIN cannot be used with /L)
+Compiler configuration:
/MW Use mingw as build system instead of MSVC
+Other options:
/FORCECONFIG Use a single config location. Do not use the
LUAROCKS_CONFIG variable or the user's home directory.
Useful to avoid conflicts when LuaRocks
is embedded within an application.
-
/F Remove installation directory if it already exists.
-
-/R Load registry information to register '.rockspec'
+/NOREG Do not load registry info to register '.rockspec'
extension with LuaRocks commands (right-click).
+/NOADMIN The installer requires admin priviledges. If not
+ available it will elevate a new process. Use this
+ switch to prevent elevation, but make sure the
+ destination paths are all accessible for the current
+ user.
+/Q Do not prompt for confirmation of settings
]])
end
@@ -114,15 +196,16 @@ local function parse_options(args)
os.exit(0)
elseif name == "/P" then
vars.PREFIX = option.value
- vars.SYSCONFDIR = option.value
- vars.ROCKS_TREE = option.value
- P_SET = true
elseif name == "/CONFIG" then
vars.SYSCONFDIR = option.value
elseif name == "/TREE" then
- vars.ROCKS_TREE = option.value
+ vars.TREE_ROOT = option.value
elseif name == "/SCRIPTS" then
- vars.SCRIPTS_DIR = option.value
+ vars.TREE_BIN = option.value
+ elseif name == "/LUAMOD" then
+ vars.TREE_LMODULE = option.value
+ elseif name == "/CMOD" then
+ vars.TREE_CMODULE = option.value
elseif name == "/LV" then
vars.LUA_VERSION = option.value
elseif name == "/L" then
@@ -141,8 +224,14 @@ local function parse_options(args)
FORCE_CONFIG = true
elseif name == "/F" then
FORCE = true
- elseif name == "/R" then
- REGISTRY = true
+ elseif name == "/SELFCONTAINED" then
+ SELFCONTAINED = true
+ elseif name == "/NOREG" then
+ REGISTRY = false
+ elseif name == "/NOADMIN" then
+ NOADMIN = true
+ elseif name == "/Q" then
+ PROMPT = false
else
die("Unrecognized option: " .. name)
end
@@ -151,8 +240,13 @@ end
-- check for combination/required flags
local function check_flags()
- if not P_SET then
- die("Missing required parameter /P")
+ if SELFCONTAINED then
+ if not vars.PREFIX then
+ die("Option /P is required when using /SELFCONTAINED")
+ end
+ if vars.SYSCONFDIR or vars.TREE_ROOT or vars.TREE_BIN or vars.TREE_LMODULE or vars.TREE_CMODULE then
+ die("Cannot combine /TREE, /SCRIPTS, /LUAMOD, /CMOD, or /CONFIG with /SELFCONTAINED")
+ end
end
if INSTALL_LUA then
if vars.LUA_INCDIR or vars.LUA_BINDIR or vars.LUA_LIBDIR or vars.LUA_PREFIX then
@@ -165,8 +259,10 @@ local function check_flags()
if vars.LUA_VERSION ~= "5.1" then
if vars.LUA_VERSION == "5.2" then
vars.LUA_LIB_NAMES = vars.LUA_LIB_NAMES:gsub("5([%.]?)1", "5%12")
+ elseif vars.LUA_VERSION == "5.3" then
+ vars.LUA_LIB_NAMES = vars.LUA_LIB_NAMES:gsub("5([%.]?)1", "5%13")
else
- die("Bad argument: /LV must either be 5.1 or 5.2")
+ die("Bad argument: /LV must either be 5.1, 5.2, or 5.3")
end
end
end
@@ -176,10 +272,15 @@ end
-- ***********************************************************
local function look_for_interpreter (directory)
if vars.LUA_BINDIR then
+ -- if LUA_BINDIR is specified, it must be there, otherwise we fail
if exists( S"$LUA_BINDIR\\lua$LUA_VERSION.exe" ) then
vars.LUA_INTERPRETER = S"lua$LUA_VERSION.exe"
print(S" Found $LUA_BINDIR\\$LUA_INTERPRETER")
return true
+ elseif exists( S"$LUA_BINDIR\\lua$LUA_SHORTV.exe" ) then
+ vars.LUA_INTERPRETER = S"lua$LUA_SHORTV.exe"
+ print(S" Found $LUA_BINDIR\\$LUA_INTERPRETER")
+ return true
elseif exists(S"$LUA_BINDIR\\lua.exe") then
vars.LUA_INTERPRETER = "lua.exe"
print(S" Found $LUA_BINDIR\\$LUA_INTERPRETER")
@@ -189,7 +290,7 @@ local function look_for_interpreter (directory)
print(S" Found $LUA_BINDIR\\$LUA_INTERPRETER")
return true
end
- die(S"Lua executable lua.exe, luajit.exe or lua$LUA_VERSION.exe not found in $LUA_BINDIR")
+ die(S"Lua executable lua.exe, luajit.exe, lua$LUA_SHORTV.exe or lua$LUA_VERSION.exe not found in $LUA_BINDIR")
end
for _, e in ipairs{ [[\]], [[\bin\]] } do
@@ -199,6 +300,12 @@ local function look_for_interpreter (directory)
print(" Found ."..e..vars.LUA_INTERPRETER)
return true
+ elseif exists(directory..e.."\\lua"..vars.LUA_SHORTV..".exe") then
+ vars.LUA_INTERPRETER = S"lua$LUA_SHORTV.exe"
+ vars.LUA_BINDIR = directory .. e
+ print(" Found ."..e..vars.LUA_INTERPRETER)
+ return true
+
elseif exists(directory..e.."\\lua.exe") then
vars.LUA_INTERPRETER = "lua.exe"
vars.LUA_BINDIR = directory..e
@@ -264,76 +371,62 @@ local function look_for_headers (directory)
return false
end
--- Checks a binary file for the runtime dll used by it. If nu runtime is found, it returns an
--- array of dll's is depends upon.
--- result: string = runtime used, table = list of dll's depended upon, nil = nothing found.
-local function get_file_runtime(p,f) -- path, filename
- local infile = p.."\\"..f
- local outfile = "output.txt"
- local content
- -- analyze binary
- if exec([[.\bin\objdump -x "]]..infile..[[" > ]]..outfile..[[ 2<&1]]) then
- -- read temp file
- local fh = io.open(outfile)
- content = fh:read("*a")
- fh:close()
- end
- -- delete temp file
- os.remove(outfile)
- if not content then
- print(" Failed to analyze "..infile.." for the runtime used")
- return nil
- end
-
- -- lookup
- content = content:upper()
- local result = content:match('DLL NAME%: (MSVCR%d*)%.DLL')
- if not result then
- result = content:match('DLL NAME%: (MSVCRT)%.DLL')
- end
-
- if result then
- print(" "..f.." uses "..tostring(result)..".DLL as runtime")
- else
- print(" No runtime found for "..f)
- -- so; create a list of dll's this file is depending upon, next level of the tree
- result = {}
- for name in content:gmatch("DLL NAME%: (.-%.DLL)") do
- --print("found dll:", name)
- table.insert(result, name)
- end
- end
- return result
-end
local function get_runtime()
- -- first check interpreter
- vars.LUA_RUNTIME = get_file_runtime(vars.LUA_BINDIR, vars.LUA_INTERPRETER)
- if type(vars.LUA_RUNTIME) == "table" then
- -- a table with dll's depended upon was returned, check this list
- -- note: we only check 1 level deep
- for _,dll in ipairs(vars.LUA_RUNTIME) do
- local t = get_file_runtime(vars.LUA_BINDIR, dll)
- if type(t) == "string" then
- -- found it
- vars.LUA_RUNTIME = t
- break
- end
- end
- end
+ local f
+ vars.LUA_RUNTIME, f = pe.msvcrt(vars.LUA_BINDIR.."\\"..vars.LUA_INTERPRETER)
if type(vars.LUA_RUNTIME) ~= "string" then
-- analysis failed, issue a warning
vars.LUA_RUNTIME = "MSVCR80"
print("*** WARNING ***: could not analyse the runtime used, defaulting to "..vars.LUA_RUNTIME)
+ else
+ print(" "..f.." uses "..vars.LUA_RUNTIME..".DLL as runtime")
end
return true
end
+local function get_architecture()
+ -- detect processor arch interpreter was compiled for
+ local proc = (pe.parse(vars.LUA_BINDIR.."\\"..vars.LUA_INTERPRETER) or {}).Machine
+ if not proc then
+ die("Could not detect processor architecture used in "..vars.LUA_INTERPRETER)
+ end
+ proc = pe.const.Machine[proc] -- collect name from constant value
+ if proc == "IMAGE_FILE_MACHINE_I386" then
+ proc = "x86"
+ else
+ proc = "x86_64"
+ end
+ return proc
+end
+
local function look_for_lua_install ()
print("Looking for Lua interpreter")
- local directories = { [[c:\lua5.1.2]], [[c:\lua]], [[c:\kepler\1.1]] }
+ local directories
if vars.LUA_PREFIX then
- table.insert(directories, 1, vars.LUA_PREFIX)
+ directories = { vars.LUA_PREFIX }
+ else
+ -- no prefix given, so use path
+ directories = (os.getenv("PATH",";") or "")
+ local i = 1
+ while i ~= 0 do directories, i = directories:gsub(";;",";") end --remove all doubles
+ directories = split_string(directories,";")
+ -- if a path element ends with "\bin\" then remove it, as the searcher will check there anyway
+ for i, val in ipairs(directories) do
+ -- remove trailing backslash
+ while val:sub(-1,-1) == "\\" and val:sub(-2,-1) ~= ":\\" do
+ val = val:sub(1,-2)
+ end
+ -- remove trailing 'bin'
+ if val:upper():sub(-4,-1) == "\\BIN" or val:upper():sub(-4,-1) == ":BIN" then
+ val = val:sub(1,-5)
+ end
+ directories[i] = val
+ end
+ -- finaly add some other default paths
+ table.insert(directories, [[c:\lua5.1.2]])
+ table.insert(directories, [[c:\lua]])
+ table.insert(directories, [[c:\kepler\1.1]])
end
if vars.LUA_BINDIR and vars.LUA_LIBDIR and vars.LUA_INCDIR then
if look_for_interpreter(vars.LUA_BINDIR) and
@@ -342,7 +435,7 @@ local function look_for_lua_install ()
then
if get_runtime() then
print("Runtime check completed, now testing interpreter...")
- if exec(S[[$LUA_BINDIR\$LUA_INTERPRETER -v 2>NUL]]) then
+ if exec(S[["$LUA_BINDIR\$LUA_INTERPRETER" -v 2>NUL]]) then
print(" Ok")
return true
end
@@ -363,7 +456,7 @@ local function look_for_lua_install ()
print("Headers found, checking runtime to use...")
if get_runtime() then
print("Runtime check completed, now testing interpreter...")
- if exec(S[[$LUA_BINDIR\$LUA_INTERPRETER -v 2>NUL]]) then
+ if exec(S[["$LUA_BINDIR\$LUA_INTERPRETER" -v 2>NUL]]) then
print(" Ok")
return true
end
@@ -377,7 +470,11 @@ local function look_for_lua_install ()
return false
end
----
+
+-- ***********************************************************
+-- Installer script start
+-- ***********************************************************
+
-- Poor man's command-line parsing
local config = {}
local with_arg = { -- options followed by an argument, others are flags
@@ -385,16 +482,46 @@ local with_arg = { -- options followed by an argument, others are flags
["/CONFIG"] = true,
["/TREE"] = true,
["/SCRIPTS"] = true,
+ ["/LUAMOD"] = true,
+ ["/CMOD"] = true,
["/LV"] = true,
["/LUA"] = true,
["/INC"] = true,
["/BIN"] = true,
["/LIB"] = true,
}
+-- reconstruct argument values with spaces and double quotes
+-- this will be damaged by the batch construction at the start of this file
+local oarg = arg -- retain old table
+if #arg > 0 then
+ farg = table.concat(arg, " ") .. " "
+ arg = {}
+ farg = farg:gsub('%"', "")
+ local i = 0
+ while #farg>0 do
+ i = i + 1
+ if (farg:sub(1,1) ~= "/") and ((arg[i-1] or ""):sub(1,1) ~= "/") then
+ i = i - 1 -- continued previous arg
+ if i == 0 then i = 1 end
+ end
+ if arg[i] then
+ arg[i] = arg[i] .. " "
+ else
+ arg[i] = ""
+ end
+ local v,r = farg:match("^(.-)%s(.*)$")
+ arg[i], farg = arg[i]..v, r
+ while farg:sub(1,1) == " " do farg = farg:sub(2,-1) end -- remove prefix spaces
+ end
+end
+for k,v in pairs(oarg) do if k < 1 then arg[k] = v end end -- copy 0 and negative indexes
+oarg = nil
+
+-- build config option table with name and value elements
local i = 1
while i <= #arg do
local opt = arg[i]
- if with_arg[opt] then
+ if with_arg[opt:upper()] then
local value = arg[i + 1]
if not value then
die("Missing value for option "..opt)
@@ -410,8 +537,46 @@ end
print(S"LuaRocks $VERSION.x installer.\n")
parse_options(config)
+
+print([[
+
+========================
+== Checking system... ==
+========================
+
+]])
+
check_flags()
+if not permission() then
+ if not NOADMIN then
+ -- must elevate the process with admin priviledges
+ if not exec("PowerShell /? >NUL 2>&1") then
+ -- powershell is not available, so error out
+ die("No administrative priviledges detected and cannot auto-elevate. Please run with admin priviledges or use the /NOADMIN switch")
+ end
+ print("Need admin priviledges, now elevating a new process to continue installing...")
+ local runner = os.getenv("TEMP").."\\".."LuaRocks_Installer.bat"
+ local f = io.open(runner, "w")
+ f:write("@echo off\n")
+ f:write("CHDIR /D "..arg[0]:match("(.+)%\\.-$").."\n") -- return to current dir, elevation changes current path
+ f:write('"'..arg[-1]..'" "'..table.concat(arg, '" "', 0)..'"\n')
+ f:write("ECHO Press any key to close this window...\n")
+ f:write("PAUSE > NUL\n")
+ f:write('DEL "'..runner..'"') -- temp batch file deletes itself
+ f:close()
+ -- run the created temp batch file in elevated mode
+ exec("PowerShell -Command (New-Object -com 'Shell.Application').ShellExecute('"..runner.."', '', '', 'runas')\n")
+ print("Now exiting unpriviledged installer")
+ os.exit() -- exit here, the newly created elevated process will do the installing
+ else
+ print("Attempting to install without admin priviledges...")
+ end
+else
+ print("Admin priviledges available for installing")
+end
+
+vars.PREFIX = vars.PREFIX or os.getenv("PROGRAMFILES")..[[\LuaRocks]]
vars.FULL_PREFIX = S"$PREFIX\\$VERSION"
vars.BINDIR = vars.FULL_PREFIX
vars.LIBDIR = vars.FULL_PREFIX
@@ -419,33 +584,72 @@ vars.LUADIR = S"$FULL_PREFIX\\lua"
vars.INCDIR = S"$FULL_PREFIX\\include"
vars.LUA_SHORTV = vars.LUA_VERSION:gsub("%.", "")
-if not look_for_lua_install() then
- print("Could not find Lua. Will install its own copy.")
- print("See /? for options for specifying the location of Lua.")
+if INSTALL_LUA then
if vars.LUA_VERSION ~= "5.1" then
- die("Cannot install own copy because no 5.2 version is bundled")
+ die("Cannot install own copy of Lua because only 5.1 is bundled")
end
- INSTALL_LUA = true
vars.LUA_INTERPRETER = "lua5.1"
vars.LUA_BINDIR = vars.BINDIR
vars.LUA_LIBDIR = vars.LIBDIR
vars.LUA_INCDIR = vars.INCDIR
vars.LUA_LIBNAME = "lua5.1.lib"
- vars.LUA_RUNTIME = "MSVCR80"
+ vars.LUA_RUNTIME = "MSVCR80"
+ vars.UNAME_M = "x86"
else
- print(S[[
+ if not look_for_lua_install() then
+ die("Could not find Lua. See /? for options for specifying the location of Lua, or installing a bundled copy of Lua 5.1.")
+ end
+ vars.UNAME_M = get_architecture() -- can only do when installation was found
+end
+
+local datapath
+if vars.UNAME_M == "x86" then
+ datapath = os.getenv("PROGRAMFILES") .. [[\LuaRocks]]
+else
+ -- our target interpreter is 64bit, so the tree (with binaries) should go into 64bit program files
+ datapath = os.getenv("ProgramW6432") .. [[\LuaRocks]]
+end
+vars.SYSCONFDIR = vars.SYSCONFDIR or vars.PREFIX
+vars.TREE_ROOT = vars.TREE_ROOT or datapath..[[\systree]]
+if SELFCONTAINED then
+ vars.SYSCONFDIR = vars.PREFIX
+ vars.TREE_ROOT = vars.PREFIX..[[\systree]]
+ REGISTRY = false
+end
+
+print(S[[
+
+==========================
+== System check results ==
+==========================
Will configure LuaRocks with the following paths:
-LuaRocks : $FULL_PREFIX
-Lua interpreter: $LUA_BINDIR\$LUA_INTERPRETER
-Lua binaries : $LUA_BINDIR
-Lua libraries : $LUA_LIBDIR
-Lua includes : $LUA_INCDIR
-Binaries will be linked against: $LUA_LIBNAME with runtime $LUA_RUNTIME
+LuaRocks : $FULL_PREFIX
+Config file : $SYSCONFDIR\config.lua
+Rocktree : $TREE_ROOT
+
+Lua interpreter : $LUA_BINDIR\$LUA_INTERPRETER
+ binaries : $LUA_BINDIR
+ libraries : $LUA_LIBDIR
+ includes : $LUA_INCDIR
+ architecture: $UNAME_M
+ binary link : $LUA_LIBNAME with runtime $LUA_RUNTIME.dll
]])
+
+if PROMPT then
+ print("Press <ENTER> to start installing, or press <CTRL>+<C> to abort. Use install /? for installation options.")
+ io.read()
end
+print([[
+
+============================
+== Installing LuaRocks... ==
+============================
+
+]])
+
-- ***********************************************************
-- Install LuaRocks files
-- ***********************************************************
@@ -474,13 +678,22 @@ if INSTALL_LUA then
if not exists(vars.LUA_INCDIR) then
mkdir(vars.LUA_INCDIR)
end
- exec(S[[COPY lua5.1\bin\*.* "$LUA_BINDIR" >NUL]])
- exec(S[[COPY lua5.1\include\*.* "$LUA_INCDIR" >NUL]])
+ exec(S[[COPY win32\lua5.1\bin\*.* "$LUA_BINDIR" >NUL]])
+ exec(S[[COPY win32\lua5.1\include\*.* "$LUA_INCDIR" >NUL]])
print(S"Installed the LuaRocks bundled Lua interpreter in $LUA_BINDIR")
end
-- Copy the LuaRocks binaries
-if not exec(S[[COPY bin\*.* "$BINDIR" >NUL]]) then
+if not exists(S[[$BINDIR\tools]]) then
+ if not mkdir(S[[$BINDIR\tools]]) then
+ die()
+ end
+end
+if not exec(S[[COPY win32\tools\*.* "$BINDIR\tools" >NUL]]) then
+ die()
+end
+-- Copy LR bin helper files
+if not exec(S[[COPY win32\*.* "$BINDIR" >NUL]]) then
die()
end
-- Copy the LuaRocks lua source files
@@ -507,61 +720,104 @@ for _, c in ipairs{"luarocks", "luarocks-admin"} do
f:write(S[[
@ECHO OFF
SETLOCAL
-SET LUA_PATH=$LUADIR\?.lua;$LUADIR\?\init.lua;%LUA_PATH%
-SET PATH=$BINDIR\;%PATH%
-"$LUA_INTERPRETER" "$BINDIR\]]..c..[[.lua" %*
+SET "LUA_PATH=$LUADIR\?.lua;$LUADIR\?\init.lua;%LUA_PATH%"
+IF NOT "%LUA_PATH_5_2%"=="" (
+ SET "LUA_PATH_5_2=$LUADIR\?.lua;$LUADIR\?\init.lua;%LUA_PATH_5_2%"
+)
+IF NOT "%LUA_PATH_5_3%"=="" (
+ SET "LUA_PATH_5_3=$LUADIR\?.lua;$LUADIR\?\init.lua;%LUA_PATH_5_3%"
+)
+SET "PATH=$BINDIR;%PATH%"
+"$LUA_BINDIR\$LUA_INTERPRETER" "$BINDIR\]]..c..[[.lua" %*
+IF NOT "%ERRORLEVEL%"=="2" GOTO EXITLR
+
+REM Permission denied error, try and auto elevate...
+REM already an admin? (checking to prevent loops)
+NET SESSION >NUL 2>&1
+IF "%ERRORLEVEL%"=="0" GOTO EXITLR
+
+REM Do we have PowerShell available?
+PowerShell /? >NUL 2>&1
+IF NOT "%ERRORLEVEL%"=="0" GOTO EXITLR
+
+:GETTEMPNAME
+SET TMPFILE=%TEMP%\LuaRocks-Elevator-%RANDOM%.bat
+IF EXIST "%TMPFILE%" GOTO :GETTEMPNAME
+
+ECHO @ECHO OFF > "%TMPFILE%"
+ECHO CHDIR /D %CD% >> "%TMPFILE%"
+ECHO ECHO %0 %* >> "%TMPFILE%"
+ECHO ECHO. >> "%TMPFILE%"
+ECHO CALL %0 %* >> "%TMPFILE%"
+ECHO ECHO. >> "%TMPFILE%"
+ECHO ECHO Press any key to close this window... >> "%TMPFILE%"
+ECHO PAUSE ^> NUL >> "%TMPFILE%"
+ECHO DEL "%TMPFILE%" >> "%TMPFILE%"
+
+ECHO Now retrying as a priviledged user...
+PowerShell -Command (New-Object -com 'Shell.Application').ShellExecute('%TMPFILE%', '', '', 'runas')
+
+:EXITLR
ENDLOCAL
]])
f:close()
print(S"Created LuaRocks command: $BINDIR\\"..c..".bat")
end
+
+-- part below was commented out as its purpose was unclear
+-- see https://github.com/keplerproject/luarocks/pull/197#issuecomment-30176548
+
-- configure 'scripts' directory
-if vars.SCRIPTS_DIR then
- mkdir(vars.SCRIPTS_DIR)
- if not USE_MINGW then
- -- definitly not for MinGW because of conflicting runtimes
- -- but is it ok to do it for others???
- exec(S[[COPY lua5.1\bin\*.dll "$SCRIPTS_DIR" >NUL]])
- end
-else
- if not USE_MINGW then
- mkdir(S[[$ROCKS_TREE\bin]])
- -- definitly not for MinGW because of conflicting runtimes
- -- but is it ok to do it for others???
- exec(S[[COPY lua5.1\bin\*.dll "$ROCKS_TREE"\bin >NUL]])
- end
-end
+-- if vars.TREE_BIN then
+-- mkdir(vars.TREE_BIN)
+-- if not USE_MINGW then
+-- -- definitly not for MinGW because of conflicting runtimes
+-- -- but is it ok to do it for others???
+-- exec(S[[COPY lua5.1\bin\*.dll "$TREE_BIN" >NUL]])
+-- end
+-- else
+-- if not USE_MINGW then
+-- mkdir(S[[$TREE_ROOT\bin]])
+-- -- definitly not for MinGW because of conflicting runtimes
+-- -- but is it ok to do it for others???
+-- exec(S[[COPY lua5.1\bin\*.dll "$TREE_ROOT"\bin >NUL]])
+-- end
+-- end
+-- ***********************************************************
+-- Configure LuaRocks
+-- ***********************************************************
print()
print("Configuring LuaRocks...")
+
-- Create a site-config file
if exists(S[[$LUADIR\luarocks\site_config.lua]]) then
exec(S[[RENAME "$LUADIR\luarocks\site_config.lua" site_config.lua.bak]])
end
local f = io.open(vars.LUADIR.."\\luarocks\\site_config.lua", "w")
f:write(S[=[
-module("luarocks.site_config")
-LUA_INCDIR=[[$LUA_INCDIR]]
-LUA_LIBDIR=[[$LUA_LIBDIR]]
-LUA_BINDIR=[[$LUA_BINDIR]]
-LUA_INTERPRETER=[[$LUA_INTERPRETER]]
+local site_config = {}
+site_config.LUA_INCDIR=[[$LUA_INCDIR]]
+site_config.LUA_LIBDIR=[[$LUA_LIBDIR]]
+site_config.LUA_BINDIR=[[$LUA_BINDIR]]
+site_config.LUA_INTERPRETER=[[$LUA_INTERPRETER]]
]=])
if USE_MINGW then
- f:write("LUAROCKS_UNAME_S=[[MINGW]]\n")
+ f:write("site_config.LUAROCKS_UNAME_S=[[MINGW]]\n")
else
- f:write("LUAROCKS_UNAME_S=[[WindowsNT]]\n")
+ f:write("site_config.LUAROCKS_UNAME_S=[[WindowsNT]]\n")
end
f:write(S[=[
-LUAROCKS_UNAME_M=[[x86]]
-LUAROCKS_SYSCONFIG=[[$SYSCONFDIR\config.lua]]
-LUAROCKS_ROCKS_TREE=[[$ROCKS_TREE]]
-LUAROCKS_PREFIX=[[$PREFIX]]
-LUAROCKS_DOWNLOADER=[[wget]]
-LUAROCKS_MD5CHECKER=[[md5sum]]
+site_config.LUAROCKS_UNAME_M=[[$UNAME_M]]
+site_config.LUAROCKS_SYSCONFIG=[[$SYSCONFDIR\config.lua]]
+site_config.LUAROCKS_ROCKS_TREE=[[$TREE_ROOT]]
+site_config.LUAROCKS_PREFIX=[[$PREFIX]]
+site_config.LUAROCKS_DOWNLOADER=[[wget]]
+site_config.LUAROCKS_MD5CHECKER=[[md5sum]]
]=])
if FORCE_CONFIG then
- f:write("local LUAROCKS_FORCE_CONFIG=true\n")
+ f:write("site_config.LUAROCKS_FORCE_CONFIG=true\n")
end
if exists(vars.LUADIR.."\\luarocks\\site_config.lua.bak") then
for line in io.lines(vars.LUADIR.."\\luarocks\\site_config.lua.bak", "r") do
@@ -570,6 +826,7 @@ if exists(vars.LUADIR.."\\luarocks\\site_config.lua.bak") then
end
exec(S[[DEL /F /Q "$LUADIR\luarocks\site_config.lua.bak"]])
end
+f:write("return site_config\n")
f:close()
print(S[[Created LuaRocks site-config file: $LUADIR\luarocks\site_config.lua]])
@@ -578,51 +835,69 @@ vars.CONFIG_FILE = vars.SYSCONFDIR.."\\config.lua"
if not exists(vars.SYSCONFDIR) then
mkdir(vars.SYSCONFDIR)
end
-if not exists(vars.CONFIG_FILE) then
- local f = io.open(vars.CONFIG_FILE, "w")
- f:write([=[
+if exists(vars.CONFIG_FILE) then
+ local nname = backup(vars.CONFIG_FILE, "config.bak")
+ print("***************")
+ print(S"*** WARNING *** LuaRocks config file already exists: '$CONFIG_FILE'. The old file has been renamed to '"..nname.."'")
+ print("***************")
+end
+local f = io.open(vars.CONFIG_FILE, "w")
+f:write([=[
rocks_servers = {
[[https://raw.githubusercontent.com/torch/rocks/master]],
[[https://raw.githubusercontent.com/torch/luarocks-mirror/master/rocks]]
}
rocks_trees = {
]=])
- if FORCE_CONFIG then
- f:write(" home..[[/luarocks]],\n")
- end
- f:write(S" [[$ROCKS_TREE]]\n")
- f:write("}\n")
- if vars.SCRIPTS_DIR then
- f:write(S"scripts_dir=[[$SCRIPTS_DIR]]\n")
- end
- f:write("variables = {\n")
- if USE_MINGW and vars.LUA_RUNTIME == "MSVCRT" then
- f:write(" MSVCRT = 'm', -- make MinGW use MSVCRT.DLL as runtime\n")
- else
- f:write(" MSVCRT = '"..vars.LUA_RUNTIME.."',\n")
- end
- f:write(S" LUALIB = '$LUA_LIBNAME'\n")
- f:write("}\n")
- f:close()
- print(S"Created LuaRocks config file: $CONFIG_FILE")
+if FORCE_CONFIG then
+ f:write(" home..[[/luarocks]],\n")
+end
+f:write(S" { name = [[user]],\n")
+f:write(S" root = home..[[/luarocks]],\n")
+f:write(S" },\n")
+f:write(S" { name = [[system]],\n")
+f:write(S" root = [[$TREE_ROOT]],\n")
+if vars.TREE_BIN then
+ f:write(S" bin_dir = [[$TREE_BIN]],\n")
+end
+if vars.TREE_CMODULE then
+ f:write(S" lib_dir = [[$TREE_CMODULE]],\n")
+end
+if vars.TREE_LMODULE then
+ f:write(S" lua_dir = [[$TREE_LMODULE]],\n")
+end
+f:write(S" },\n")
+f:write("}\n")
+f:write("variables = {\n")
+if USE_MINGW and vars.LUA_RUNTIME == "MSVCRT" then
+ f:write(" MSVCRT = 'm', -- make MinGW use MSVCRT.DLL as runtime\n")
else
- print(S"LuaRocks config file already exists: $CONFIG_FILE")
+ f:write(" MSVCRT = '"..vars.LUA_RUNTIME.."',\n")
end
+f:write(S" LUALIB = '$LUA_LIBNAME'\n")
+f:write("}\n")
+f:write("verbose = false -- set to 'true' to enable verbose output\n")
+f:close()
+
+print(S"Created LuaRocks config file: $CONFIG_FILE")
+
print()
print("Creating rocktrees...")
-if not exists(vars.ROCKS_TREE) then
- mkdir(vars.ROCKS_TREE)
- print(S[[Created rocktree: "$ROCKS_TREE"]])
+if not exists(vars.TREE_ROOT) then
+ mkdir(vars.TREE_ROOT)
+ print(S[[Created system rocktree : "$TREE_ROOT"]])
else
- print(S[[Rocktree exists: "$ROCKS_TREE"]])
+ print(S[[System rocktree exists : "$TREE_ROOT"]])
end
-local APPDATA = os.getenv("APPDATA")
-if not exists(APPDATA.."\\luarocks") then
- mkdir(APPDATA.."\\luarocks")
- print([[Created rocktree: "]]..APPDATA..[[\luarocks"]])
+
+vars.APPDATA = os.getenv("APPDATA")
+vars.LOCAL_TREE = vars.APPDATA..[[\LuaRocks]]
+if not exists(vars.LOCAL_TREE) then
+ mkdir(vars.LOCAL_TREE)
+ print(S[[Created local user rocktree: "$LOCAL_TREE"]])
else
- print([[Rocktree exists: "]]..APPDATA..[[\luarocks"]])
+ print(S[[Local user rocktree exists : "$LOCAL_TREE"]])
end
-- Load registry information
@@ -630,21 +905,49 @@ if REGISTRY then
-- expand template with correct path information
print()
print([[Loading registry information for ".rockspec" files]])
- exec( S[[lua5.1\bin\lua5.1.exe "$FULL_PREFIX\create_reg_file.lua" "$FULL_PREFIX\LuaRocks.reg.template"]] )
- exec( S"$FULL_PREFIX\\LuaRocks.reg" )
+ exec( S[[win32\lua5.1\bin\lua5.1.exe "$FULL_PREFIX\LuaRocks.reg.lua" "$FULL_PREFIX\LuaRocks.reg.template"]] )
+ exec( S[[regedit /S "$FULL_PREFIX\\LuaRocks.reg"]] )
end
-- ***********************************************************
--- Exit handlers
+-- Cleanup
-- ***********************************************************
+-- remove regsitry related files, no longer needed
+exec( S[[del "$FULL_PREFIX\LuaRocks.reg.*" >NUL]] )
+-- remove pe-parser module
+exec( S[[del "$FULL_PREFIX\pe-parser.lua" >NUL]] )
+-- ***********************************************************
+-- Exit handlers
+-- ***********************************************************
+vars.TREE_BIN = vars.TREE_BIN or vars.TREE_ROOT..[[\bin]]
+vars.TREE_LMODULE = vars.TREE_LMODULE or vars.TREE_ROOT..[[\share\lua\]]..vars.LUA_VERSION
+vars.TREE_CMODULE = vars.TREE_CMODULE or vars.TREE_ROOT..[[\lib\lua\]]..vars.LUA_VERSION
print(S[[
-*** LuaRocks is installed! ***
- You may want to add the following elements to your paths;
-PATH : $LUA_BINDIR;$FULL_PREFIX
-LUA_PATH : $ROCKS_TREE\share\lua\$LUA_VERSION\?.lua;$ROCKS_TREE\share\lua\$LUA_VERSION\?\init.lua
-LUA_CPATH: $LUA_LIBDIR\lua\$LUA_VERSION\?.dll
+============================
+== LuaRocks is installed! ==
+============================
+
+
+You may want to add the following elements to your paths;
+Lua interpreter;
+ PATH : $LUA_BINDIR
+ PATHEXT : .LUA
+LuaRocks;
+ PATH : $FULL_PREFIX
+ LUA_PATH : $FULL_PREFIX\lua\?.lua;$FULL_PREFIX\lua\?\init.lua
+Local user rocktree (Note: %APPDATA% is user dependent);
+ PATH : %APPDATA%\LuaRocks\bin
+ LUA_PATH : %APPDATA%\LuaRocks\share\lua\$LUA_VERSION\?.lua;%APPDATA%\LuaRocks\share\lua\$LUA_VERSION\?\init.lua
+ LUA_CPATH: %APPDATA%\LuaRocks\lib\lua\$LUA_VERSION\?.dll
+System rocktree
+ PATH : $TREE_BIN
+ LUA_PATH : $TREE_LMODULE\?.lua;$TREE_LMODULE\?\init.lua
+ LUA_CPATH: $TREE_CMODULE\?.dll
+
+Note that the %APPDATA% element in the paths above is user specific and it MUST be replaced by its actual value.
+For the current user that value is: $APPDATA.
]])
os.exit(0)
diff --git a/luarocks/makedist b/luarocks/makedist
index 9b3308e..141f670 100755
--- a/luarocks/makedist
+++ b/luarocks/makedist
@@ -61,15 +61,14 @@ mkdir "release-windows"
mv "$out" "release-windows/$out-win32"
cd "release-unix/$out"
-rm -rf makedist install.bat COPYING.lua COPYING.7z win32 lfw
+rm -rf makedist install.bat COPYING_lua COPYING_7z COPYING_win win32 lfw .travis.yml .gitignore
cd ..
tar czvpf ../"$out.tar.gz" "$out"
cd ..
rm -rf "release-unix"
cd "release-windows/$out-win32"
-cp -va win32/* .
-rm -rf makedist Makefile configure lfw win32
+rm -rf makedist Makefile configure lfw .travis.yml .gitignore
cd ..
zip -r ../"$out-win32.zip" "$out-win32"
cd ..
diff --git a/luarocks/rockspec b/luarocks/rockspec
index 69f253b..16ac635 100644
--- a/luarocks/rockspec
+++ b/luarocks/rockspec
@@ -1,5 +1,5 @@
package = "LuaRocks"
-local VER = "2.1.0"
+local VER = "2.2.0beta1"
local REV = "1"
version = VER.."-"..REV
diff --git a/luarocks/src/bin/luarocks b/luarocks/src/bin/luarocks
index 05f5df6..426542c 100755
--- a/luarocks/src/bin/luarocks
+++ b/luarocks/src/bin/luarocks
@@ -1,25 +1,33 @@
#!/Users/ronan/usr72/bin/luajit
package.path = [[/Users/ronan/usr72/share/lua/5.1//?.lua;/Users/ronan/usr72/share/lua/5.1//?/init.lua;]]..package.path
+-- this should be loaded first.
+local cfg = require("luarocks.cfg")
+
+local loader = require("luarocks.loader")
local command_line = require("luarocks.command_line")
program_description = "LuaRocks main command-line interface"
-commands = {}
-commands.help = require("luarocks.help")
-commands.pack = require("luarocks.pack")
-commands.unpack = require("luarocks.unpack")
-commands.build = require("luarocks.build")
-commands.install = require("luarocks.install")
-commands.search = require("luarocks.search")
-commands.list = require("luarocks.list")
-commands.remove = require("luarocks.remove")
-commands.make = require("luarocks.make")
-commands.download = require("luarocks.download")
-commands.path = require("luarocks.path")
-commands.show = require("luarocks.show")
-commands.new_version = require("luarocks.new_version")
-commands.lint = require("luarocks.lint")
-commands.purge = require("luarocks.purge")
+commands = {
+ help = "luarocks.help",
+ pack = "luarocks.pack",
+ unpack = "luarocks.unpack",
+ build = "luarocks.build",
+ install = "luarocks.install",
+ search = "luarocks.search",
+ list = "luarocks.list",
+ remove = "luarocks.remove",
+ make = "luarocks.make",
+ download = "luarocks.download",
+ path = "luarocks.path_cmd",
+ show = "luarocks.show",
+ new_version = "luarocks.new_version",
+ lint = "luarocks.lint",
+ write_rockspec = "luarocks.write_rockspec",
+ purge = "luarocks.purge",
+ doc = "luarocks.doc",
+ upload = "luarocks.upload",
+}
command_line.run_command(...)
diff --git a/luarocks/src/bin/luarocks-admin b/luarocks/src/bin/luarocks-admin
index 419485f..4b44dbc 100755
--- a/luarocks/src/bin/luarocks-admin
+++ b/luarocks/src/bin/luarocks-admin
@@ -1,17 +1,20 @@
#!/Users/ronan/usr72/bin/luajit
package.path = [[/Users/ronan/usr72/share/lua/5.1//?.lua;/Users/ronan/usr72/share/lua/5.1//?/init.lua;]]..package.path
+-- this should be loaded first.
+local cfg = require("luarocks.cfg")
+
+local loader = require("luarocks.loader")
local command_line = require("luarocks.command_line")
program_description = "LuaRocks repository administration interface"
commands = {
+ help = "luarocks.help",
+ make_manifest = "luarocks.make_manifest",
+ add = "luarocks.add",
+ remove = "luarocks.admin_remove",
+ refresh_cache = "luarocks.refresh_cache",
}
-commands.help = require("luarocks.help")
-commands.make_manifest = require("luarocks.make_manifest")
-commands.add = require("luarocks.add")
-commands.remove = require("luarocks.admin_remove")
-commands.refresh_cache = require("luarocks.refresh_cache")
-
command_line.run_command(...)
diff --git a/luarocks/src/luarocks/add.lua b/luarocks/src/luarocks/add.lua
index d7c293e..fc913c9 100644
--- a/luarocks/src/luarocks/add.lua
+++ b/luarocks/src/luarocks/add.lua
@@ -1,20 +1,21 @@
--- Module implementing the luarocks-admin "add" command.
-- Adds a rock or rockspec to a rocks server.
-module("luarocks.add", package.seeall)
+--module("luarocks.add", package.seeall)
+local add = {}
+package.loaded["luarocks.add"] = add
local cfg = require("luarocks.cfg")
local util = require("luarocks.util")
-local fetch = require("luarocks.fetch")
local dir = require("luarocks.dir")
local manif = require("luarocks.manif")
local index = require("luarocks.index")
local fs = require("luarocks.fs")
local cache = require("luarocks.cache")
-help_summary = "Add a rock or rockspec to a rocks server."
-help_arguments = "[--server=<server>] [--no-refresh] {<rockspec>|<rock>...}"
-help = [[
+add.help_summary = "Add a rock or rockspec to a rocks server."
+add.help_arguments = "[--server=<server>] [--no-refresh] {<rockspec>|<rock>...}"
+add.help = [[
Arguments are local files, which may be rockspecs or rocks.
The flag --server indicates which server to use.
If not given, the default server set in the upload_server variable
@@ -45,7 +46,8 @@ local function add_files_to_server(refresh, rockfiles, server, upload_server)
login_url = protocol.."://"..server_path
end
- fs.change_dir(at)
+ local ok, err = fs.change_dir(at)
+ if not ok then return nil, err end
local files = {}
for i, rockfile in ipairs(rockfiles) do
@@ -62,10 +64,14 @@ local function add_files_to_server(refresh, rockfiles, server, upload_server)
return nil, "No files found"
end
- fs.change_dir(local_cache)
+ local ok, err = fs.change_dir(local_cache)
+ if not ok then return nil, err end
util.printout("Updating manifest...")
manif.make_manifest(local_cache, "one", true)
+
+ manif.zip_manifests()
+
util.printout("Updating index.html...")
index.make_index(local_cache)
@@ -78,15 +84,17 @@ local function add_files_to_server(refresh, rockfiles, server, upload_server)
table.insert(files, "index.html")
table.insert(files, "manifest")
- table.insert(files, "manifest-5.1")
- table.insert(files, "manifest-5.2")
+ for ver in util.lua_versions() do
+ table.insert(files, "manifest-"..ver)
+ table.insert(files, "manifest-"..ver..".zip")
+ end
-- TODO abstract away explicit 'curl' call
local cmd
if protocol == "rsync" then
local srv, path = server_path:match("([^/]+)(/.+)")
- cmd = cfg.variables.RSYNC.." --exclude=.git -Oavz -e ssh "..local_cache.."/ "..user.."@"..srv..":"..path.."/"
+ cmd = cfg.variables.RSYNC.." "..cfg.variables.RSYNCFLAGS.." -e ssh "..local_cache.."/ "..user.."@"..srv..":"..path.."/"
elseif upload_server and upload_server.sftp then
local part1, part2 = upload_server.sftp:match("^([^/]*)/(.*)$")
cmd = cfg.variables.SCP.." "..table.concat(files, " ").." "..user.."@"..part1..":/"..part2
@@ -100,7 +108,7 @@ local function add_files_to_server(refresh, rockfiles, server, upload_server)
return true
end
-function run(...)
+function add.run(...)
local files = { util.parse_flags(...) }
local flags = table.remove(files, 1)
if #files < 1 then
@@ -111,3 +119,5 @@ function run(...)
return add_files_to_server(not flags["no-refresh"], files, server, server_table)
end
+
+return add
diff --git a/luarocks/src/luarocks/admin_remove.lua b/luarocks/src/luarocks/admin_remove.lua
index 83b57fc..839121d 100644
--- a/luarocks/src/luarocks/admin_remove.lua
+++ b/luarocks/src/luarocks/admin_remove.lua
@@ -1,22 +1,23 @@
--- Module implementing the luarocks-admin "remove" command.
-- Removes a rock or rockspec from a rocks server.
-module("luarocks.admin_remove", package.seeall)
+--module("luarocks.admin_remove", package.seeall)
+local admin_remove = {}
+package.loaded["luarocks.admin_remove"] = admin_remove
local cfg = require("luarocks.cfg")
local util = require("luarocks.util")
-local fetch = require("luarocks.fetch")
local dir = require("luarocks.dir")
local manif = require("luarocks.manif")
local index = require("luarocks.index")
local fs = require("luarocks.fs")
local cache = require("luarocks.cache")
-help_summary = "Remove a rock or rockspec from a rocks server."
-help_arguments = "[--from=<server>] [--no-refresh] {<rockspec>|<rock>...}"
-help = [[
+admin_remove.help_summary = "Remove a rock or rockspec from a rocks server."
+admin_remove.help_arguments = "[--server=<server>] [--no-refresh] {<rockspec>|<rock>...}"
+admin_remove.help = [[
Arguments are local files, which may be rockspecs or rocks.
-The flag --from indicates which server to use.
+The flag --server indicates which server to use.
If not given, the default server set in the upload_server variable
from the configuration file is used instead.
The flag --no-refresh indicates the local cache should not be refreshed
@@ -41,14 +42,16 @@ local function remove_files_from_server(refresh, rockfiles, server, upload_serve
return nil, "This command requires 'rsync', check your configuration."
end
- fs.change_dir(at)
+ local ok, err = fs.change_dir(at)
+ if not ok then return nil, err end
local nr_files = 0
for i, rockfile in ipairs(rockfiles) do
local basename = dir.base_name(rockfile)
local file = dir.path(local_cache, basename)
util.printout("Removing file "..file.."...")
- if fs.delete(file) then
+ fs.delete(file)
+ if not fs.exists(file) then
nr_files = nr_files + 1
else
util.printerr("Failed removing "..file)
@@ -58,7 +61,8 @@ local function remove_files_from_server(refresh, rockfiles, server, upload_serve
return nil, "No files removed."
end
- fs.change_dir(local_cache)
+ local ok, err = fs.change_dir(local_cache)
+ if not ok then return nil, err end
util.printout("Updating manifest...")
manif.make_manifest(local_cache, "one", true)
@@ -66,7 +70,7 @@ local function remove_files_from_server(refresh, rockfiles, server, upload_serve
index.make_index(local_cache)
local srv, path = server_path:match("([^/]+)(/.+)")
- local cmd = "rsync -Oavz --delete -e ssh "..local_cache.."/ "..user.."@"..srv..":"..path.."/"
+ local cmd = cfg.variables.RSYNC.." "..cfg.variables.RSYNCFLAGS.." --delete -e ssh "..local_cache.."/ "..user.."@"..srv..":"..path.."/"
util.printout(cmd)
fs.execute(cmd)
@@ -74,7 +78,7 @@ local function remove_files_from_server(refresh, rockfiles, server, upload_serve
return true
end
-function run(...)
+function admin_remove.run(...)
local files = { util.parse_flags(...) }
local flags = table.remove(files, 1)
if #files < 1 then
@@ -85,3 +89,5 @@ function run(...)
return remove_files_from_server(not flags["no-refresh"], files, server, server_table)
end
+
+return admin_remove
diff --git a/luarocks/src/luarocks/build.lua b/luarocks/src/luarocks/build.lua
index dbe450a..01bfa9d 100644
--- a/luarocks/src/luarocks/build.lua
+++ b/luarocks/src/luarocks/build.lua
@@ -1,7 +1,9 @@
--- Module implementing the LuaRocks "build" command.
-- Builds a rock, compiling its C parts if any.
-module("luarocks.build", package.seeall)
+--module("luarocks.build", package.seeall)
+local build = {}
+package.loaded["luarocks.build"] = build
local pack = require("luarocks.pack")
local path = require("luarocks.path")
@@ -12,13 +14,12 @@ local fs = require("luarocks.fs")
local dir = require("luarocks.dir")
local deps = require("luarocks.deps")
local manif = require("luarocks.manif")
-local search = require("luarocks.search")
local remove = require("luarocks.remove")
local cfg = require("luarocks.cfg")
-help_summary = "Build/compile a rock."
-help_arguments = "[--pack-binary-rock] [--keep] {<rockspec>|<rock>|<name> [<version>]}"
-help = [[
+build.help_summary = "Build/compile a rock."
+build.help_arguments = "[--pack-binary-rock] [--keep] {<rockspec>|<rock>|<name> [<version>]}"
+build.help = [[
Build and install a rock, compiling its C parts if any.
Argument may be a rockspec file, a source rock file
or the name of a rock to be fetched from a repository.
@@ -31,7 +32,12 @@ or the name of a rock to be fetched from a repository.
rock after building a new one. This behavior can
be made permanent by setting keep_other_versions=true
in the configuration file.
-]]
+
+--branch=<name> Override the `source.branch` field in the loaded
+ rockspec. Allows to specify a different branch to
+ fetch. Particularly for SCM rocks.
+
+]]..util.deps_mode_help()
--- Install files to a given location.
-- Takes a table where the array part is a list of filenames to be copied.
@@ -53,19 +59,31 @@ local function install_files(files, location, is_module_path)
if files then
for k, file in pairs(files) do
local dest = location
+ local filename = dir.base_name(file)
if type(k) == "string" then
+ local modname = k
if is_module_path then
- dest = dir.path(location, path.module_to_path(k))
- fs.make_dir(dest)
+ dest = dir.path(location, path.module_to_path(modname))
+ local ok, err = fs.make_dir(dest)
+ if not ok then return nil, err end
+ if filename:match("%.lua$") then
+ local basename = modname:match("([^.]+)$")
+ local baseinfo = filename:gsub("%.lua$", "")
+ if basename ~= baseinfo then
+ filename = basename..".lua"
+ end
+ end
else
- dest = dir.path(location, dir.dir_name(k))
- fs.make_dir(dest)
- dest = dir.path(dest, dir.base_name(k))
+ dest = dir.path(location, dir.dir_name(modname))
+ local ok, err = fs.make_dir(dest)
+ if not ok then return nil, err end
+ filename = dir.base_name(modname)
end
else
- fs.make_dir(dest)
+ local ok, err = fs.make_dir(dest)
+ if not ok then return nil, err end
end
- local ok = fs.copy(dir.path(file), dest)
+ local ok = fs.copy(dir.path(file), dir.path(dest, filename))
if not ok then
return nil, "Failed copying "..file
end
@@ -91,16 +109,16 @@ end
-- @param rockspec table: A rockspec table.
-- @return boolean or (nil, string): True if succeeded or
-- nil and an error message.
-function apply_patches(rockspec)
+function build.apply_patches(rockspec)
assert(type(rockspec) == "table")
- local build = rockspec.build
- if build.extra_files then
- extract_from_rockspec(build.extra_files)
+ local build_spec = rockspec.build
+ if build_spec.extra_files then
+ extract_from_rockspec(build_spec.extra_files)
end
- if build.patches then
- extract_from_rockspec(build.patches)
- for patch, patchdata in util.sortedpairs(build.patches) do
+ if build_spec.patches then
+ extract_from_rockspec(build_spec.patches)
+ for patch, patchdata in util.sortedpairs(build_spec.patches) do
util.printout("Applying patch "..patch.."...")
local ok, err = fs.apply_patch(tostring(patch), patchdata)
if not ok then
@@ -111,6 +129,24 @@ function apply_patches(rockspec)
return true
end
+local function install_default_docs(name, version)
+ local patterns = { "readme", "license", "copying" }
+ local dest = dir.path(path.install_dir(name, version), "doc")
+ local has_dir = false
+ for name in fs.dir() do
+ for _, pattern in ipairs(patterns) do
+ if name:lower():match("^"..pattern) then
+ if not has_dir then
+ fs.make_dir(dest)
+ has_dir = true
+ end
+ fs.copy(name, dest)
+ break
+ end
+ end
+ end
+end
+
--- Build and install a rock given a rockspec.
-- @param rockspec_file string: local or remote filename of a rockspec.
-- @param need_to_fetch boolean: true if sources need to be fetched,
@@ -123,7 +159,7 @@ end
-- "none" for no trees.
-- @return (string, string) or (nil, string, [string]): Name and version of
-- installed rock if succeeded or nil and an error message followed by an error code.
-function build_rockspec(rockspec_file, need_to_fetch, minimal_mode, deps_mode)
+function build.build_rockspec(rockspec_file, need_to_fetch, minimal_mode, deps_mode)
assert(type(rockspec_file) == "string")
assert(type(need_to_fetch) == "boolean")
@@ -145,7 +181,7 @@ function build_rockspec(rockspec_file, need_to_fetch, minimal_mode, deps_mode)
end
end
- ok, err, errcode = deps.check_external_deps(rockspec, "build")
+ local ok, err, errcode = deps.check_external_deps(rockspec, "build")
if err then
return nil, err, errcode
end
@@ -162,7 +198,8 @@ function build_rockspec(rockspec_file, need_to_fetch, minimal_mode, deps_mode)
if not ok then
return nil, source_dir, errcode
end
- fs.change_dir(source_dir)
+ local ok, err = fs.change_dir(source_dir)
+ if not ok then return nil, err end
elseif rockspec.source.file then
local ok, err = fs.unpack_archive(rockspec.source.file)
if not ok then
@@ -180,38 +217,39 @@ function build_rockspec(rockspec_file, need_to_fetch, minimal_mode, deps_mode)
}
for _, d in pairs(dirs) do
- fs.make_dir(d.name)
+ local ok, err = fs.make_dir(d.name)
+ if not ok then return nil, err end
end
local rollback = util.schedule_function(function()
fs.delete(path.install_dir(name, version))
fs.remove_dir_if_empty(path.versions_dir(name))
end)
- local build = rockspec.build
+ local build_spec = rockspec.build
if not minimal_mode then
- ok, err = apply_patches(rockspec)
+ ok, err = build.apply_patches(rockspec)
if err then
return nil, err
end
end
- if build.type ~= "none" then
+ if build_spec.type ~= "none" then
-- Temporary compatibility
- if build.type == "module" then
+ if build_spec.type == "module" then
util.printout("Do not use 'module' as a build type. Use 'builtin' instead.")
- build.type = "builtin"
+ build_spec.type = "builtin"
end
- if cfg.accepted_build_types and util.array_contains(cfg.accepted_build_types, build.type) then
- return nil, "This rockspec uses the '"..build.type.."' build type, which is blocked by the 'accepted_build_types' setting in your LuaRocks configuration."
+ if cfg.accepted_build_types and util.array_contains(cfg.accepted_build_types, build_spec.type) then
+ return nil, "This rockspec uses the '"..build_spec.type.."' build type, which is blocked by the 'accepted_build_types' setting in your LuaRocks configuration."
end
local build_type
- ok, build_type = pcall(require, "luarocks.build." .. build.type)
+ ok, build_type = pcall(require, "luarocks.build." .. build_spec.type)
if not ok or not type(build_type) == "table" then
- return nil, "Failed initializing build back-end for build type '"..build.type.."': "..build_type
+ return nil, "Failed initializing build back-end for build type '"..build_spec.type.."': "..build_type
end
ok, err = build_type.run(rockspec)
@@ -220,27 +258,40 @@ function build_rockspec(rockspec_file, need_to_fetch, minimal_mode, deps_mode)
end
end
- if build.install then
+ if build_spec.install then
for id, install_dir in pairs(dirs) do
- ok, err = install_files(build.install[id], install_dir.name, install_dir.is_module_path)
+ ok, err = install_files(build_spec.install[id], install_dir.name, install_dir.is_module_path)
if not ok then
return nil, err
end
end
end
- local copy_directories = build.copy_directories or {"doc"}
+ local copy_directories = build_spec.copy_directories
+ local copying_default = false
+ if not copy_directories then
+ copy_directories = {"doc"}
+ copying_default = true
+ end
+ local any_docs = false
for _, copy_dir in pairs(copy_directories) do
if fs.is_dir(copy_dir) then
local dest = dir.path(path.install_dir(name, version), copy_dir)
fs.make_dir(dest)
fs.copy_contents(copy_dir, dest)
+ any_docs = true
else
- util.warning("Directory '"..copy_dir.."' not found")
+ if not copying_default then
+ return nil, "Directory '"..copy_dir.."' not found"
+ end
end
end
-
+
+ if not any_docs then
+ install_default_docs(name, version)
+ end
+
for _, d in pairs(dirs) do
fs.remove_dir_if_empty(d.name)
end
@@ -275,8 +326,8 @@ function build_rockspec(rockspec_file, need_to_fetch, minimal_mode, deps_mode)
end
local root_dir = path.root_dir(cfg.rocks_dir)
- util.printout()
util.printout(name.." "..version.." is now built and installed in "..root_dir.." "..license)
+ util.printout()
util.remove_scheduled_function(rollback)
return name, version
@@ -291,7 +342,7 @@ end
-- "order" for all trees with priority >= the current default, "none" for no trees.
-- @return boolean or (nil, string, [string]): True if build was successful,
-- or false and an error message and an optional error code.
-function build_rock(rock_file, need_to_fetch, deps_mode)
+function build.build_rock(rock_file, need_to_fetch, deps_mode)
assert(type(rock_file) == "string")
assert(type(need_to_fetch) == "boolean")
@@ -300,25 +351,26 @@ function build_rock(rock_file, need_to_fetch, deps_mode)
return nil, err, errcode
end
local rockspec_file = path.rockspec_name_from_rock(rock_file)
- fs.change_dir(unpack_dir)
- local ok, err, errcode = build_rockspec(rockspec_file, need_to_fetch, false, deps_mode)
+ local ok, err = fs.change_dir(unpack_dir)
+ if not ok then return nil, err end
+ local ok, err, errcode = build.build_rockspec(rockspec_file, need_to_fetch, false, deps_mode)
fs.pop_dir()
return ok, err, errcode
end
local function do_build(name, version, deps_mode)
if name:match("%.rockspec$") then
- return build_rockspec(name, true, false, deps_mode)
+ return build.build_rockspec(name, true, false, deps_mode)
elseif name:match("%.src%.rock$") then
- return build_rock(name, false, deps_mode)
+ return build.build_rock(name, false, deps_mode)
elseif name:match("%.all%.rock$") then
local install = require("luarocks.install")
return install.install_binary_rock(name, deps_mode)
elseif name:match("%.rock$") then
- return build_rock(name, true, deps_mode)
+ return build.build_rock(name, true, deps_mode)
elseif not name:match(dir.separator) then
local search = require("luarocks.search")
- return search.act_on_src_or_rockspec(run, name:lower(), version, deps.deps_mode_to_flag(deps_mode))
+ return search.act_on_src_or_rockspec(build.run, name:lower(), version, deps.deps_mode_to_flag(deps_mode))
end
return nil, "Don't know what to do with "..name
end
@@ -329,9 +381,9 @@ end
-- if returned a result, installs the matching rock.
-- @param version string: When passing a package name, a version number may
-- also be given.
--- @return boolean or (nil, string): True if build was successful; nil and an
--- error message otherwise.
-function run(...)
+-- @return boolean or (nil, string, exitcode): True if build was successful; nil and an
+-- error message otherwise. exitcode is optionally returned.
+function build.run(...)
local flags, name, version = util.parse_flags(...)
if type(name) ~= "string" then
return nil, "Argument missing. "..util.see_help("build")
@@ -342,7 +394,7 @@ function run(...)
return pack.pack_binary_rock(name, version, do_build, name, version, deps.get_deps_mode(flags))
else
local ok, err = fs.check_command_permissions(flags)
- if not ok then return nil, err end
+ if not ok then return nil, err, cfg.errorcodes.PERMISSIONDENIED end
ok, err = do_build(name, version, deps.get_deps_mode(flags))
if not ok then return nil, err end
local name, version = ok, err
@@ -353,3 +405,5 @@ function run(...)
return name, version
end
end
+
+return build
diff --git a/luarocks/src/luarocks/build/builtin.lua b/luarocks/src/luarocks/build/builtin.lua
index 9d97d58..47aa71f 100644
--- a/luarocks/src/luarocks/build/builtin.lua
+++ b/luarocks/src/luarocks/build/builtin.lua
@@ -1,6 +1,9 @@
--- A builtin build system: back-end to provide a portable way of building C-based Lua modules.
-module("luarocks.build.builtin", package.seeall)
+--module("luarocks.build.builtin", package.seeall)
+local builtin = {}
+
+local unpack = unpack or table.unpack
local fs = require("luarocks.fs")
local path = require("luarocks.path")
@@ -19,6 +22,7 @@ end
--- Makes an RC file with an embedded Lua script, for building .exes on Windows
-- @return nil if could open files, error otherwise
local function make_rc(luafilename, rcfilename)
+ --TODO EXEWRAPPER
local rcfile = io.open(rcfilename, "w")
if not rcfile then
error("Could not open "..rcfilename.." for writing.")
@@ -44,9 +48,9 @@ end
-- @param rockspec table: the loaded rockspec.
-- @return boolean or (nil, string): true if no errors ocurred,
-- nil and an error message otherwise.
-function run(rockspec)
+function builtin.run(rockspec)
assert(type(rockspec) == "table")
- local compile_object, compile_library, compile_wrapper_binary
+ local compile_object, compile_library, compile_wrapper_binary --TODO EXEWRAPPER
local build = rockspec.build
local variables = rockspec.variables
@@ -80,6 +84,7 @@ function run(rockspec)
return ok
end
compile_wrapper_binary = function(fullname, name)
+ --TODO EXEWRAPPER
local fullbasename = fullname:gsub("%.lua$", ""):gsub("/", "\\")
local basename = name:gsub("%.lua$", ""):gsub("/", "\\")
local rcname = basename..".rc"
@@ -112,13 +117,20 @@ function run(rockspec)
def:write("luaopen_"..name:gsub("%.", "_").."\n")
def:close()
local ok = execute(variables.LD, "-dll", "-def:"..deffile, "-out:"..library, dir.path(variables.LUA_LIBDIR, variables.LUALIB), unpack(extras))
- local manifestfile = basename..".dll.manifest"
+ local basedir = ""
+ if name:find("%.") ~= nil then
+ basedir = name:gsub("%.%w+$", "\\")
+ basedir = basedir:gsub("%.", "\\")
+ end
+ local manifestfile = basedir .. basename..".dll.manifest"
+
if ok and fs.exists(manifestfile) then
- ok = execute(variables.MT, "-manifest", manifestfile, "-outputresource:"..basename..".dll;2")
+ ok = execute(variables.MT, "-manifest", manifestfile, "-outputresource:"..basedir..basename..".dll;2")
end
return ok
end
compile_wrapper_binary = function(fullname, name)
+ --TODO EXEWRAPPER
local fullbasename = fullname:gsub("%.lua$", ""):gsub("/", "\\")
local basename = name:gsub("%.lua$", ""):gsub("/", "\\")
local object = basename..".obj"
@@ -159,47 +171,48 @@ function run(rockspec)
return execute(variables.LD.." "..variables.LIBFLAG, "-o", library, "-L"..variables.LUA_LIBDIR, unpack(extras))
end
compile_wrapper_binary = function(fullname, name) return true, name end
+ --TODO EXEWRAPPER
end
local ok = true
- local err = "Build error"
local built_modules = {}
local luadir = path.lua_dir(rockspec.name, rockspec.version)
local libdir = path.lib_dir(rockspec.name, rockspec.version)
- local docdir = path.doc_dir(rockspec.name, rockspec.version)
+ --TODO EXEWRAPPER
-- On Windows, compiles an .exe for each Lua file in build.install.bin, and
-- replaces the filename with the .exe name. Strips the .lua extension if it exists,
- -- otherwise just appends .exe to the name
+ -- otherwise just appends .exe to the name. Only if `cfg.exewrapper = true`
if build.install and build.install.bin then
- for i, name in ipairs(build.install.bin) do
+ for key, name in pairs(build.install.bin) do
local fullname = dir.path(fs.current_dir(), name)
- local match = name:match("%.lua$")
- local basename = name:gsub("%.lua$", "")
- local file
- if not match then
- file = io.open(fullname)
- end
- if match or (file and file:read():match("#!.*lua.*")) then
+ if cfg.exewrapper and fs.is_lua(fullname) then
ok, name = compile_wrapper_binary(fullname, name)
if ok then
- build.install.bin[i] = name
+ build.install.bin[key] = name
else
- if file then file:close() end
return nil, "Build error in wrapper binaries"
end
end
- if file then file:close() end
end
end
+
+
for name, info in pairs(build.modules) do
local moddir = path.module_to_path(name)
if type(info) == "string" then
local ext = info:match(".([^.]+)$")
if ext == "lua" then
+ local filename = dir.base_name(info)
if info:match("init%.lua$") and not name:match("%.init$") then
moddir = path.module_to_path(name..".init")
+ else
+ local basename = name:match("([^.]+)$")
+ local baseinfo = filename:gsub("%.lua$", "")
+ if basename ~= baseinfo then
+ filename = basename..".lua"
+ end
end
- local dest = dir.path(luadir, moddir)
+ local dest = dir.path(luadir, moddir, filename)
built_modules[info] = dest
else
info = {info}
@@ -222,12 +235,13 @@ function run(rockspec)
table.insert(objects, object)
end
if not ok then break end
- local module_name = dir.path(moddir, name:match("([^.]*)$").."."..util.matchquote(cfg.lib_extension)):gsub("//", "/")
+ local module_name = name:match("([^.]*)$").."."..util.matchquote(cfg.lib_extension)
if moddir ~= "" then
- fs.make_dir(moddir)
+ module_name = dir.path(moddir, module_name)
+ local ok, err = fs.make_dir(moddir)
+ if not ok then return nil, err end
end
- local dest = dir.path(libdir, moddir)
- built_modules[module_name] = dest
+ built_modules[module_name] = dir.path(libdir, module_name)
ok = compile_library(module_name, objects, info.libraries, info.libdirs, name)
if not ok then
return nil, "Failed compiling module "..module_name
@@ -235,17 +249,19 @@ function run(rockspec)
end
end
for name, dest in pairs(built_modules) do
- fs.make_dir(dest)
+ fs.make_dir(dir.dir_name(dest))
ok = fs.copy(name, dest)
if not ok then
return nil, "Failed installing "..name.." in "..dest
end
end
if fs.is_dir("lua") then
- ok, err = fs.copy_contents("lua", luadir)
- if not ok then
+ local ok, err = fs.copy_contents("lua", luadir)
+ if not ok then
return nil, "Failed copying contents of 'lua' directory: "..err
end
end
return true
end
+
+return builtin
diff --git a/luarocks/src/luarocks/build/cmake.lua b/luarocks/src/luarocks/build/cmake.lua
index 82f4ff5..ed2af3f 100644
--- a/luarocks/src/luarocks/build/cmake.lua
+++ b/luarocks/src/luarocks/build/cmake.lua
@@ -1,6 +1,7 @@
--- Build back-end for CMake-based modules.
-module("luarocks.build.cmake", package.seeall)
+--module("luarocks.build.cmake", package.seeall)
+local cmake = {}
local fs = require("luarocks.fs")
local util = require("luarocks.util")
@@ -10,7 +11,7 @@ local cfg = require("luarocks.cfg")
-- @param rockspec table: the loaded rockspec.
-- @return boolean or (nil, string): true if no errors ocurred,
-- nil and an error message otherwise.
-function run(rockspec)
+function cmake.run(rockspec)
assert(type(rockspec) == "table")
local build = rockspec.build
local variables = build.variables or {}
@@ -22,15 +23,15 @@ function run(rockspec)
util.variable_substitutions(variables, rockspec.variables)
- if not fs.execute_string(fs.quiet(rockspec.variables.CMAKE.." --help")) then
+ if not fs.execute_quiet(rockspec.variables.CMAKE, "--help") then
return nil, "'"..rockspec.variables.CMAKE.."' program not found. Is cmake installed? You may want to edit variables.CMAKE"
end
-- If inline cmake is present create CMakeLists.txt from it.
if type(build.cmake) == "string" then
- local cmake = assert(io.open(fs.current_dir().."/CMakeLists.txt", "w"))
- cmake:write(build.cmake)
- cmake:close()
+ local cmake_handler = assert(io.open(fs.current_dir().."/CMakeLists.txt", "w"))
+ cmake_handler:write(build.cmake)
+ cmake_handler:close()
end
@@ -56,3 +57,5 @@ function run(rockspec)
end
return true
end
+
+return cmake
diff --git a/luarocks/src/luarocks/build/command.lua b/luarocks/src/luarocks/build/command.lua
index aeec0da..650e323 100644
--- a/luarocks/src/luarocks/build/command.lua
+++ b/luarocks/src/luarocks/build/command.lua
@@ -1,6 +1,7 @@
--- Build back-end for raw listing of commands in rockspec files.
-module("luarocks.build.command", package.seeall)
+--module("luarocks.build.command", package.seeall)
+local command = {}
local fs = require("luarocks.fs")
local util = require("luarocks.util")
@@ -9,7 +10,7 @@ local util = require("luarocks.util")
-- @param rockspec table: the loaded rockspec.
-- @return boolean or (nil, string): true if no errors ocurred,
-- nil and an error message otherwise.
-function run(rockspec)
+function command.run(rockspec)
assert(type(rockspec) == "table")
local build = rockspec.build
@@ -30,3 +31,5 @@ function run(rockspec)
end
return true
end
+
+return command
diff --git a/luarocks/src/luarocks/build/make.lua b/luarocks/src/luarocks/build/make.lua
index c4b2157..0da183e 100644
--- a/luarocks/src/luarocks/build/make.lua
+++ b/luarocks/src/luarocks/build/make.lua
@@ -1,6 +1,9 @@
--- Build back-end for using Makefile-based packages.
-module("luarocks.build.make", package.seeall)
+--module("luarocks.build.make", package.seeall)
+local make = {}
+
+local unpack = unpack or table.unpack
local fs = require("luarocks.fs")
local util = require("luarocks.util")
@@ -36,7 +39,7 @@ end
-- @param rockspec table: the loaded rockspec.
-- @return boolean or (nil, string): true if no errors ocurred,
-- nil and an error message otherwise.
-function run(rockspec)
+function make.run(rockspec)
assert(type(rockspec) == "table")
local build = rockspec.build
@@ -90,3 +93,5 @@ function run(rockspec)
end
return true
end
+
+return make
diff --git a/luarocks/src/luarocks/cache.lua b/luarocks/src/luarocks/cache.lua
index 21185c1..dbea840 100644
--- a/luarocks/src/luarocks/cache.lua
+++ b/luarocks/src/luarocks/cache.lua
@@ -1,14 +1,16 @@
--- Module handling the LuaRocks local cache.
-- Adds a rock or rockspec to a rocks server.
-module("luarocks.cache", package.seeall)
+--module("luarocks.cache", package.seeall)
+local cache = {}
+package.loaded["luarocks.cache"] = cache
local fs = require("luarocks.fs")
local cfg = require("luarocks.cfg")
local dir = require("luarocks.dir")
local util = require("luarocks.util")
-function get_upload_server(server)
+function cache.get_upload_server(server)
if not server then server = cfg.upload_server end
if not server then
return nil, "No server specified and no default configured with upload_server."
@@ -16,7 +18,7 @@ function get_upload_server(server)
return server, cfg.upload_servers and cfg.upload_servers[server]
end
-function get_server_urls(server, upload_server)
+function cache.get_server_urls(server, upload_server)
local download_url = server
local login_url = nil
if upload_server then
@@ -32,7 +34,7 @@ function get_server_urls(server, upload_server)
return download_url, login_url
end
-function split_server_url(server, url, user, password)
+function cache.split_server_url(server, url, user, password)
local protocol, server_path = dir.split_url(url)
if server_path:match("@") then
local credentials
@@ -50,28 +52,31 @@ function split_server_url(server, url, user, password)
return local_cache, protocol, server_path, user, password
end
-function refresh_local_cache(server, url, user, password)
- local local_cache, protocol, server_path, user, password = split_server_url(server, url, user, password)
+function cache.refresh_local_cache(server, url, user, password)
+ local local_cache, protocol, server_path, user, password = cache.split_server_url(server, url, user, password)
- fs.make_dir(cfg.local_cache)
+ local ok, err = fs.make_dir(cfg.local_cache)
+ if not ok then return nil, err end
local tmp_cache = false
if not local_cache then
- local_cache = fs.make_temp_dir("local_cache")
+ local err
+ local_cache, err = fs.make_temp_dir("local_cache")
tmp_cache = true
end
- local ok = fs.make_dir(local_cache)
+ local ok, err = fs.make_dir(local_cache)
if not ok then
- return nil, "Failed creating local cache dir."
+ return nil, "Failed creating local cache dir: "..err
end
fs.change_dir(local_cache)
+ if not ok then return nil, err end
util.printout("Refreshing cache "..local_cache.."...")
-- TODO abstract away explicit 'wget' call
local ok = false
if protocol == "rsync" then
local srv, path = server_path:match("([^/]+)(/.+)")
- ok = fs.execute(cfg.variables.RSYNC.." -avz -e ssh "..user.."@"..srv..":"..path.."/ "..local_cache.."/")
+ ok = fs.execute(cfg.variables.RSYNC.." "..cfg.variables.RSYNCFLAGS.." -e ssh "..user.."@"..srv..":"..path.."/ "..local_cache.."/")
else
local login_info = ""
if user then login_info = " --user="..user end
@@ -83,3 +88,5 @@ function refresh_local_cache(server, url, user, password)
end
return local_cache, protocol, server_path, user, password
end
+
+return cache
diff --git a/luarocks/src/luarocks/cfg.lua b/luarocks/src/luarocks/cfg.lua
index a1345db..a08c7c8 100644
--- a/luarocks/src/luarocks/cfg.lua
+++ b/luarocks/src/luarocks/cfg.lua
@@ -13,10 +13,14 @@
local rawset, next, table, pairs, require, io, os, setmetatable, pcall, ipairs, package, tonumber, type, assert, _VERSION =
rawset, next, table, pairs, require, io, os, setmetatable, pcall, ipairs, package, tonumber, type, assert, _VERSION
-module("luarocks.cfg")
+--module("luarocks.cfg")
+local cfg = {}
+package.loaded["luarocks.cfg"] = cfg
-lua_version = _VERSION:sub(5)
-local version_suffix = lua_version:gsub("%.", "_")
+local util = require("luarocks.util")
+
+cfg.lua_version = _VERSION:sub(5)
+local version_suffix = cfg.lua_version:gsub("%.", "_")
-- Load site-local global configurations
local ok, site_config = pcall(require, "luarocks.site_config_"..version_suffix)
@@ -28,12 +32,28 @@ if not ok then
site_config = {}
end
-_M.site_config = site_config
+cfg.site_config = site_config
-program_version = "2.1.0"
+cfg.program_version = "2.2.0beta1"
+cfg.major_version = cfg.program_version:match("([^.]%.[^.])")
local persist = require("luarocks.persist")
+cfg.errorcodes = setmetatable({
+ OK = 0,
+ UNSPECIFIED = 1,
+ PERMISSIONDENIED = 2,
+},{
+ __index = function(t, key)
+ local val = rawget(t, key)
+ if not val then
+ error("'"..tostring(key).."' is not a valid errorcode", 2)
+ end
+ return val
+ end
+})
+
+
local popen_ok, popen_result = pcall(io.popen, "")
if popen_ok then
if popen_result then
@@ -42,7 +62,7 @@ if popen_ok then
else
io.stderr:write("Your version of Lua does not support io.popen,\n")
io.stderr:write("which is required by LuaRocks. Please check your Lua installation.\n")
- os.exit(1)
+ os.exit(cfg.errorcodes.UNSPECIFIED)
end
-- System detection:
@@ -105,31 +125,32 @@ end
local sys_config_file, home_config_file
local sys_config_dir, home_config_dir
local sys_config_ok, home_config_ok = false, false
+local extra_luarocks_module_dir
sys_config_dir = site_config.LUAROCKS_SYSCONFDIR
if detected.windows then
- home = os.getenv("APPDATA") or "c:"
+ cfg.home = os.getenv("APPDATA") or "c:"
sys_config_dir = sys_config_dir or "c:/luarocks"
- home_config_dir = home.."/luarocks"
- home_tree = home.."/luarocks/"
+ home_config_dir = cfg.home.."/luarocks"
+ cfg.home_tree = cfg.home.."/luarocks/"
else
- home = os.getenv("HOME") or ""
+ cfg.home = os.getenv("HOME") or ""
sys_config_dir = sys_config_dir or "/etc/luarocks"
- home_config_dir = home.."/.luarocks"
- home_tree = home.."/.luarocks/"
+ home_config_dir = cfg.home.."/.luarocks"
+ cfg.home_tree = cfg.home.."/.luarocks/"
end
-variables = {}
-rocks_trees = {}
+cfg.variables = {}
+cfg.rocks_trees = {}
-sys_config_file = site_config.LUAROCKS_SYSCONFIG or sys_config_dir.."/config-"..lua_version..".lua"
+sys_config_file = site_config.LUAROCKS_SYSCONFIG or sys_config_dir.."/config-"..cfg.lua_version..".lua"
local err
-sys_config_ok, err = persist.load_into_table(sys_config_file, _M)
+sys_config_ok, err = persist.load_into_table(sys_config_file, cfg)
if not sys_config_ok then
sys_config_file = sys_config_dir.."/config.lua"
- sys_config_ok, err = persist.load_into_table(sys_config_file, _M)
+ sys_config_ok, err = persist.load_into_table(sys_config_file, cfg)
end
-if err and ok == nil then
+if err and sys_config_ok == nil then
io.stderr:write(err.."\n")
end
@@ -137,25 +158,24 @@ if not site_config.LUAROCKS_FORCE_CONFIG then
local home_overrides, err
home_config_file = os.getenv("LUAROCKS_CONFIG_" .. version_suffix) or os.getenv("LUAROCKS_CONFIG")
if home_config_file then
- home_overrides, err = persist.load_into_table(home_config_file, { home = home, lua_version = lua_version })
+ home_overrides, err = persist.load_into_table(home_config_file, { home = cfg.home, lua_version = cfg.lua_version })
else
- home_config_file = home_config_dir.."/config-"..lua_version..".lua"
- home_overrides, err = persist.load_into_table(home_config_file, { home = home, lua_version = lua_version })
+ home_config_file = home_config_dir.."/config-"..cfg.lua_version..".lua"
+ home_overrides, err = persist.load_into_table(home_config_file, { home = cfg.home, lua_version = cfg.lua_version })
if not home_overrides then
home_config_file = home_config_dir.."/config.lua"
- home_overrides, err = persist.load_into_table(home_config_file, { home = home, lua_version = lua_version })
+ home_overrides, err = persist.load_into_table(home_config_file, { home = cfg.home, lua_version = cfg.lua_version })
end
end
if home_overrides then
home_config_ok = true
- local util = require("luarocks.util")
if home_overrides.rocks_trees then
- _M.rocks_trees = nil
+ cfg.rocks_trees = nil
end
if home_overrides.rocks_servers then
- _M.rocks_servers = nil
+ cfg.rocks_servers = nil
end
- util.deep_merge(_M, home_overrides)
+ util.deep_merge(cfg, home_overrides)
else -- nil or false
home_config_ok = home_overrides
if err and home_config_ok == nil then
@@ -164,18 +184,18 @@ if not site_config.LUAROCKS_FORCE_CONFIG then
end
end
-if not next(rocks_trees) then
- if home_tree then
- table.insert(rocks_trees, home_tree)
+if not next(cfg.rocks_trees) then
+ if cfg.home_tree then
+ table.insert(cfg.rocks_trees, { name = "user", root = cfg.home_tree } )
end
if site_config.LUAROCKS_ROCKS_TREE then
- table.insert(rocks_trees, site_config.LUAROCKS_ROCKS_TREE)
+ table.insert(cfg.rocks_trees, { name = "system", root = site_config.LUAROCKS_ROCKS_TREE } )
end
end
-- Configure defaults:
-local root = rocks_trees[#rocks_trees]
+local root = cfg.rocks_trees[#cfg.rocks_trees]
local defaults = {
local_by_default = false,
@@ -185,8 +205,8 @@ local defaults = {
hooks_enabled = true,
deps_mode = "one",
- lua_modules_path = "/share/lua/"..lua_version,
- lib_modules_path = "/lib/lua/"..lua_version,
+ lua_modules_path = "/share/lua/"..cfg.lua_version,
+ lib_modules_path = "/lib/lua/"..cfg.lua_version,
rocks_subdir = site_config.LUAROCKS_ROCKS_SUBDIR or "/lib/luarocks/rocks",
arch = "unknown",
@@ -199,11 +219,19 @@ local defaults = {
"https://raw.githubusercontent.com/torch/luarocks-mirror/master/rocks/"
}
},
+ disabled_servers = {},
+
+ upload = {
+ server = "https://rocks.moonscript.org",
+ tool_version = "0.0.1",
+ api_version = "1",
+ },
lua_extension = "lua",
lua_interpreter = site_config.LUA_INTERPRETER or "lua",
downloader = site_config.LUAROCKS_DOWNLOADER or "wget",
md5checker = site_config.LUAROCKS_MD5CHECKER or "md5sum",
+ connection_timeout = 30, -- 0 = no timeout
variables = {
MAKE = "make",
@@ -246,22 +274,28 @@ local defaults = {
CMAKE = "cmake",
SEVENZ = "7z",
+ RSYNCFLAGS = "--exclude=.git -Oavz",
STATFLAG = "-c '%a'",
},
- external_deps_subdirs = {
+ external_deps_subdirs = site_config.LUAROCKS_EXTERNAL_DEPS_SUBDIRS or {
bin = "bin",
lib = "lib",
include = "include"
},
- runtime_external_deps_subdirs = {
+ runtime_external_deps_subdirs = site_config.LUAROCKS_RUNTIME_EXTERNAL_DEPS_SUBDIRS or {
bin = "bin",
lib = "lib",
include = "include"
},
+
+ rocks_provided = {}
}
if detected.windows then
+ local full_prefix = site_config.LUAROCKS_PREFIX.."\\"..cfg.major_version
+ extra_luarocks_module_dir = full_prefix.."\\lua\\?.lua"
+
home_config_file = home_config_file and home_config_file:gsub("\\","/")
defaults.fs_use_modules = false
defaults.arch = "win32-"..proc
@@ -270,21 +304,29 @@ if detected.windows then
defaults.external_lib_extension = "dll"
defaults.obj_extension = "obj"
defaults.external_deps_dirs = { "c:/external/" }
- defaults.variables.LUA_BINDIR = site_config.LUA_BINDIR and site_config.LUA_BINDIR:gsub("\\", "/") or "c:/lua"..lua_version.."/bin"
- defaults.variables.LUA_INCDIR = site_config.LUA_INCDIR and site_config.LUA_INCDIR:gsub("\\", "/") or "c:/lua"..lua_version.."/include"
- defaults.variables.LUA_LIBDIR = site_config.LUA_LIBDIR and site_config.LUA_LIBDIR:gsub("\\", "/") or "c:/lua"..lua_version.."/lib"
+ defaults.variables.LUA_BINDIR = site_config.LUA_BINDIR and site_config.LUA_BINDIR:gsub("\\", "/") or "c:/lua"..cfg.lua_version.."/bin"
+ defaults.variables.LUA_INCDIR = site_config.LUA_INCDIR and site_config.LUA_INCDIR:gsub("\\", "/") or "c:/lua"..cfg.lua_version.."/include"
+ defaults.variables.LUA_LIBDIR = site_config.LUA_LIBDIR and site_config.LUA_LIBDIR:gsub("\\", "/") or "c:/lua"..cfg.lua_version.."/lib"
defaults.cmake_generator = "MinGW Makefiles"
defaults.makefile = "Makefile.win"
defaults.variables.MAKE = "nmake"
defaults.variables.CC = "cl"
defaults.variables.RC = "rc"
- defaults.variables.WRAPPER = site_config.LUAROCKS_PREFIX .. "\\2.0\\rclauncher.c"
+ defaults.variables.WRAPPER = full_prefix.."\\rclauncher.c"
defaults.variables.LD = "link"
defaults.variables.MT = "mt"
- defaults.variables.LUALIB = "lua"..lua_version..".lib"
+ defaults.variables.LUALIB = "lua"..cfg.lua_version..".lib"
defaults.variables.CFLAGS = "/MD /O2"
defaults.variables.LIBFLAG = "/dll"
- defaults.variables.LUALIB = "lua"..lua_version..".lib"
+
+ local bins = { "SEVENZ", "CP", "FIND", "LS", "MD5SUM",
+ "MKDIR", "MV", "PWD", "RMDIR", "TEST", "UNAME", "WGET" }
+ for _, var in ipairs(bins) do
+ if defaults.variables[var] then
+ defaults.variables[var] = full_prefix.."\\tools\\"..defaults.variables[var]
+ end
+ end
+
defaults.external_deps_patterns = {
bin = { "?.exe", "?.bat" },
lib = { "?.lib", "?.dll", "lib?.dll" },
@@ -299,7 +341,15 @@ if detected.windows then
defaults.export_path_separator = ";"
defaults.export_lua_path = "SET LUA_PATH=%s"
defaults.export_lua_cpath = "SET LUA_CPATH=%s"
- defaults.local_cache = home.."/cache/luarocks"
+ defaults.wrapper_suffix = ".bat"
+
+ local localappdata = os.getenv("LOCALAPPDATA")
+ if not localappdata then
+ -- for Windows versions below Vista
+ localappdata = os.getenv("USERPROFILE").."/Local Settings/Application Data"
+ end
+ defaults.local_cache = localappdata.."/LuaRocks/Cache"
+ defaults.web_browser = "start"
end
if detected.mingw32 then
@@ -309,10 +359,22 @@ if detected.mingw32 then
defaults.variables.MAKE = "mingw32-make"
defaults.variables.CC = "mingw32-gcc"
defaults.variables.RC = "windres"
- defaults.variables.WRAPPER = site_config.LUAROCKS_PREFIX .. "\\2.0\\rclauncher.c"
defaults.variables.LD = "mingw32-gcc"
defaults.variables.CFLAGS = "-O2"
defaults.variables.LIBFLAG = "-shared"
+ defaults.external_deps_patterns = {
+ bin = { "?.exe", "?.bat" },
+ -- mingw lookup list from http://stackoverflow.com/a/15853231/1793220
+ -- ...should we keep ?.lib at the end? It's not in the above list.
+ lib = { "lib?.dll.a", "?.dll.a", "lib?.a", "cyg?.dll", "lib?.dll", "?.dll", "?.lib" },
+ include = { "?.h" }
+ }
+ defaults.runtime_external_deps_patterns = {
+ bin = { "?.exe", "?.bat" },
+ lib = { "cyg?.dll", "?.dll", "lib?.dll" },
+ include = { "?.h" }
+ }
+
end
if detected.unix then
@@ -344,10 +406,12 @@ if detected.unix then
defaults.export_path_separator = ":"
defaults.export_lua_path = "export LUA_PATH='%s'"
defaults.export_lua_cpath = "export LUA_CPATH='%s'"
- defaults.local_cache = home.."/.cache/luarocks"
+ defaults.wrapper_suffix = ""
+ defaults.local_cache = cfg.home.."/.cache/luarocks"
if not defaults.variables.CFLAGS:match("-fPIC") then
defaults.variables.CFLAGS = defaults.variables.CFLAGS.." -fPIC"
end
+ defaults.web_browser = "xdg-open"
end
if detected.cygwin then
@@ -381,6 +445,7 @@ if detected.macosx then
end
defaults.variables.CC = "export MACOSX_DEPLOYMENT_TARGET=10."..version.."; gcc"
defaults.variables.LD = "export MACOSX_DEPLOYMENT_TARGET=10."..version.."; gcc"
+ defaults.web_browser = "open"
end
if detected.linux then
@@ -391,6 +456,9 @@ end
if detected.freebsd then
defaults.arch = "freebsd-"..proc
defaults.platforms = {"unix", "bsd", "freebsd"}
+ defaults.gcc_rpath = false
+ defaults.variables.CC = "cc"
+ defaults.variables.LD = "cc"
end
if detected.openbsd then
@@ -415,16 +483,38 @@ defaults.variables.OBJ_EXTENSION = defaults.obj_extension
defaults.variables.LUAROCKS_PREFIX = site_config.LUAROCKS_PREFIX
defaults.variables.LUA = site_config.LUA_DIR_SET and (defaults.variables.LUA_BINDIR.."/"..defaults.lua_interpreter) or defaults.lua_interpreter
--- Use defaults:
+-- Add built-in modules to rocks_provided
+defaults.rocks_provided["lua"] = cfg.lua_version.."-1"
+
+if cfg.lua_version >= "5.2" then
+ -- Lua 5.2+
+ defaults.rocks_provided["bit32"] = cfg.lua_version.."-1"
+end
+
+if cfg.lua_version >= "5.3" then
+ -- Lua 5.3+
+ defaults.rocks_provided["utf8"] = cfg.lua_version.."-1"
+end
--- Populate values from 'defaults.variables' in 'variables' if they were not
--- already set by user.
-if not _M.variables then
- _M.variables = {}
+if package.loaded.jit then
+ -- LuaJIT
+ local lj_version = package.loaded.jit.version:match("LuaJIT (.*)"):gsub("%-","")
+ --defaults.rocks_provided["luajit"] = lj_version.."-1"
+ defaults.rocks_provided["luabitop"] = lj_version.."-1"
end
-for k,v in pairs(defaults.variables) do
- if not _M.variables[k] then
- _M.variables[k] = v
+
+-- Use defaults:
+
+-- Populate some arrays with values from their 'defaults' counterparts
+-- if they were not already set by user.
+for _, entry in ipairs({"variables", "rocks_provided"}) do
+ if not cfg[entry] then
+ cfg[entry] = {}
+ end
+ for k,v in pairs(defaults[entry]) do
+ if not cfg[entry][k] then
+ cfg[entry][k] = v
+ end
end
end
@@ -438,44 +528,60 @@ local cfg_mt = {
return default
end
}
-setmetatable(_M, cfg_mt)
-
-function package_paths()
- local new_path, new_cpath = {}, {}
- for _,tree in ipairs(rocks_trees) do
- if type(tree) == "string" then
- table.insert(new_path, 1, tree..lua_modules_path.."/?.lua;"..tree..lua_modules_path.."/?/init.lua")
- table.insert(new_cpath, 1, tree..lib_modules_path.."/?."..lib_extension)
- else
- table.insert(new_path, 1, (tree.lua_dir or tree.root..lua_modules_path).."/?.lua;"..
- (tree.lua_dir or tree.root..lua_modules_path).."/?/init.lua")
- table.insert(new_cpath, 1, (tree.lib_dir or tree.root..lib_modules_path).."/?."..lib_extension)
- end
+setmetatable(cfg, cfg_mt)
+
+function cfg.make_paths_from_tree(tree)
+ local lua_path, lib_path, bin_path
+ if type(tree) == "string" then
+ lua_path = tree..cfg.lua_modules_path
+ lib_path = tree..cfg.lib_modules_path
+ bin_path = tree.."/bin"
+ else
+ lua_path = tree.lua_dir or tree.root..cfg.lua_modules_path
+ lib_path = tree.lib_dir or tree.root..cfg.lib_modules_path
+ bin_path = tree.bin_dir or tree.root.."/bin"
end
- return table.concat(new_path, ";"), table.concat(new_cpath, ";")
+ return lua_path, lib_path, bin_path
end
-do
- local new_path, new_cpath = package_paths()
- package.path = new_path..";"..package.path
- package.cpath = new_cpath..";"..package.cpath
+function cfg.package_paths()
+ local new_path, new_cpath, new_bin = {}, {}, {}
+ for _,tree in ipairs(cfg.rocks_trees) do
+ local lua_path, lib_path, bin_path = cfg.make_paths_from_tree(tree)
+ table.insert(new_path, lua_path.."/?.lua")
+ table.insert(new_path, lua_path.."/?/init.lua")
+ table.insert(new_cpath, lib_path.."/?."..cfg.lib_extension)
+ table.insert(new_bin, bin_path)
+ end
+ if extra_luarocks_module_dir then
+ table.insert(new_path, extra_luarocks_module_dir)
+ end
+ return table.concat(new_path, ";"), table.concat(new_cpath, ";"), table.concat(new_bin, cfg.export_path_separator)
+end
+
+function cfg.init_package_paths()
+ local lr_path, lr_cpath, lr_bin = cfg.package_paths()
+ package.path = util.remove_path_dupes(package.path .. ";" .. lr_path, ";")
+ package.cpath = util.remove_path_dupes(package.cpath .. ";" .. lr_cpath, ";")
end
-function which_config()
+function cfg.which_config()
return sys_config_file, sys_config_ok, home_config_file, home_config_ok
end
-user_agent = "LuaRocks/"..program_version.." "..arch
+cfg.user_agent = "LuaRocks/"..cfg.program_version.." "..cfg.arch
--- Check if platform was detected
-- @param query string: The platform name to check.
-- @return boolean: true if LuaRocks is currently running on queried platform.
-function is_platform(query)
+function cfg.is_platform(query)
assert(type(query) == "string")
- for _, platform in ipairs(platforms) do
+ for _, platform in ipairs(cfg.platforms) do
if platform == query then
return true
end
end
end
+
+return cfg
diff --git a/luarocks/src/luarocks/command_line.lua b/luarocks/src/luarocks/command_line.lua
index d16ef8e..cc2e168 100644
--- a/luarocks/src/luarocks/command_line.lua
+++ b/luarocks/src/luarocks/command_line.lua
@@ -1,6 +1,9 @@
--- Functions for command-line scripts.
-module("luarocks.command_line", package.seeall)
+--module("luarocks.command_line", package.seeall)
+local command_line = {}
+
+local unpack = unpack or table.unpack
local util = require("luarocks.util")
local cfg = require("luarocks.cfg")
@@ -12,7 +15,8 @@ local program = util.this_program("luarocks")
--- Display an error message and exit.
-- @param message string: The error message.
-local function die(message)
+-- @param exitcode number: the exitcode to use
+local function die(message, exitcode)
assert(type(message) == "string")
local ok, err = pcall(util.run_scheduled_functions)
@@ -20,7 +24,19 @@ local function die(message)
util.printerr("\nLuaRocks "..cfg.program_version.." internal bug (please report at luarocks-developers@lists.sourceforge.net):\n"..err)
end
util.printerr("\nError: "..message)
- os.exit(1)
+ os.exit(exitcode or cfg.errorcodes.UNSPECIFIED)
+end
+
+local function replace_tree(flags, args, tree)
+ tree = dir.normalize(tree)
+ flags["tree"] = tree
+ for i = 1, #args do
+ if args[i]:match("%-%-tree=") then
+ args[i] = "--tree="..tree
+ break
+ end
+ end
+ path.use_tree(tree)
end
--- Main command-line processor.
@@ -30,7 +46,7 @@ end
-- Uses the global table "commands", which contains
-- the loaded modules representing commands.
-- @param ... string: Arguments given on the command-line.
-function run_command(...)
+function command_line.run_command(...)
local args = {...}
local cmdline_vars = {}
for i = #args, 1, -1 do
@@ -61,11 +77,26 @@ function run_command(...)
local command
+ if flags["verbose"] then -- setting it in the config file will kick-in earlier in the process
+ cfg.verbose = true
+ local fs = require("luarocks.fs")
+ fs.verbose()
+ end
+
+ if flags["timeout"] then -- setting it in the config file will kick-in earlier in the process
+ local timeout = tonumber(flags["timeout"])
+ if timeout then
+ cfg.connection_timeout = timeout
+ else
+ die "Argument error: --timeout expects a numeric argument."
+ end
+ end
+
if flags["version"] then
util.printout(program.." "..cfg.program_version)
util.printout(program_description)
util.printout()
- os.exit(0)
+ os.exit(cfg.errorcodes.OK)
elseif flags["help"] or #nonflags == 0 then
command = "help"
args = nonflags
@@ -94,15 +125,35 @@ function run_command(...)
die("Invalid entry for --deps-mode.")
end
+ if flags["branch"] then
+ if flags["branch"] == true or flags["branch"] == "" then
+ die("Argument error: use --branch=<branch-name>")
+ end
+ cfg.branch = flags["branch"]
+ end
+
if flags["tree"] then
if flags["tree"] == true or flags["tree"] == "" then
die("Argument error: use --tree=<path>")
end
- local fs = require("luarocks.fs")
- local root_dir = fs.absolute_name(flags["tree"])
- path.use_tree(root_dir)
+ local named = false
+ for _, tree in ipairs(cfg.rocks_trees) do
+ if type(tree) == "table" and flags["tree"] == tree.name then
+ if not tree.root then
+ die("Configuration error: tree '"..tree.name.."' has no 'root' field.")
+ end
+ replace_tree(flags, args, tree.root)
+ named = true
+ break
+ end
+ end
+ if not named then
+ local fs = require("luarocks.fs")
+ local root_dir = fs.absolute_name(flags["tree"])
+ replace_tree(flags, args, root_dir)
+ end
elseif flags["local"] then
- path.use_tree(cfg.home_tree)
+ replace_tree(flags, args, cfg.home_tree)
else
local trees = cfg.rocks_trees
path.use_tree(trees[#trees])
@@ -153,16 +204,19 @@ function run_command(...)
-- I'm not changing this now to avoid messing with the run()
-- interface, which I know some people use (even though
-- I never published it as a public API...)
- local xp, ok, err = xpcall(function() return commands[command].run(unpack(args)) end, function(err)
+ local cmd = require(commands[command])
+ local xp, ok, err, exitcode = xpcall(function() return cmd.run(unpack(args)) end, function(err)
die(debug.traceback("LuaRocks "..cfg.program_version
.." bug (please report at luarocks-developers@lists.sourceforge.net).\n"
..err, 2))
end)
if xp and (not ok) then
- die(err)
+ die(err, exitcode)
end
else
die("Unknown command: "..command)
end
util.run_scheduled_functions()
end
+
+return command_line
diff --git a/luarocks/src/luarocks/deps.lua b/luarocks/src/luarocks/deps.lua
index 5ac822c..3f75f9b 100644
--- a/luarocks/src/luarocks/deps.lua
+++ b/luarocks/src/luarocks/deps.lua
@@ -11,7 +11,9 @@
-- comparison criteria is the source code of this module, but the
-- test/test_deps.lua file included with LuaRocks provides some
-- insights on what these criteria are.
-module("luarocks.deps", package.seeall)
+--module("luarocks.deps", package.seeall)
+local deps = {}
+package.loaded["luarocks.deps"] = deps
local cfg = require("luarocks.cfg")
local manif_core = require("luarocks.manif_core")
@@ -34,7 +36,7 @@ local operators = {
}
local deltas = {
- scm = 1000,
+ scm = 1100,
cvs = 1000,
rc = -1000,
pre = -10000,
@@ -101,7 +103,7 @@ setmetatable(version_cache, {
-- @param vstring string: A version number in string format.
-- @return table or nil: A version table or nil
-- if the input string contains invalid characters.
-function parse_version(vstring)
+function deps.parse_version(vstring)
if not vstring then return nil end
assert(type(vstring) == "string")
@@ -140,7 +142,6 @@ function parse_version(vstring)
version[i] = 0
break
end
- local last = #version
version[i] = deltas[token] or (token:byte() / 1000)
end
vstring = rest
@@ -154,8 +155,8 @@ end
-- @param a string: one version.
-- @param b string: another version.
-- @return boolean: True if a > b.
-function compare_versions(a, b)
- return parse_version(a) > parse_version(b)
+function deps.compare_versions(a, b)
+ return deps.parse_version(a) > deps.parse_version(b)
end
--- Consumes a constraint from a string, converting it to table format.
@@ -171,7 +172,7 @@ local function parse_constraint(input)
local no_upgrade, op, version, rest = input:match("^(@?)([<>=~!]*)%s*([%w%.%_%-]+)[%s,]*(.*)")
local _op = operators[op]
- version = parse_version(version)
+ version = deps.parse_version(version)
if not _op then
return nil, "Encountered bad constraint operator: '"..tostring(op).."' in '"..input.."'"
end
@@ -189,7 +190,7 @@ end
-- @param input string: A list of constraints in string format.
-- @return table or nil: A table representing the same constraints,
-- or nil if the input string is invalid.
-function parse_constraints(input)
+function deps.parse_constraints(input)
assert(type(input) == "string")
local constraints, constraint, oinput = {}, nil, input
@@ -214,12 +215,12 @@ end
-- as entered in rockspec files.
-- @return table or nil: A table representing the same dependency relation,
-- or nil if the input string is invalid.
-function parse_dep(dep)
+function deps.parse_dep(dep)
assert(type(dep) == "string")
- local name, rest = dep:match("^%s*([a-zA-Z][a-zA-Z0-9%.%-%_]*)%s*(.*)")
+ local name, rest = dep:match("^%s*([a-zA-Z0-9][a-zA-Z0-9%.%-%_]*)%s*(.*)")
if not name then return nil, "failed to extract dependency name from '"..tostring(dep).."'" end
- local constraints, err = parse_constraints(rest)
+ local constraints, err = deps.parse_constraints(rest)
if not constraints then return nil, err end
return { name = name, constraints = constraints }
end
@@ -229,7 +230,7 @@ end
-- @param internal boolean or nil: Whether to display versions in their
-- internal representation format or how they were specified.
-- @return string: The dependency information pretty-printed as a string.
-function show_version(v, internal)
+function deps.show_version(v, internal)
assert(type(v) == "table")
assert(type(internal) == "boolean" or not internal)
@@ -243,13 +244,13 @@ end
-- @param internal boolean or nil: Whether to display versions in their
-- internal representation format or how they were specified.
-- @return string: The dependency information pretty-printed as a string.
-function show_dep(dep, internal)
+function deps.show_dep(dep, internal)
assert(type(dep) == "table")
assert(type(internal) == "boolean" or not internal)
local pretty = {}
for _, c in ipairs(dep.constraints) do
- table.insert(pretty, c.op .. " " .. show_version(c.version, internal))
+ table.insert(pretty, c.op .. " " .. deps.show_version(c.version, internal))
end
return dep.name.." "..table.concat(pretty, ", ")
end
@@ -270,8 +271,8 @@ local function partial_match(version, requested)
assert(type(version) == "string" or type(version) == "table")
assert(type(requested) == "string" or type(version) == "table")
- if type(version) ~= "table" then version = parse_version(version) end
- if type(requested) ~= "table" then requested = parse_version(requested) end
+ if type(version) ~= "table" then version = deps.parse_version(version) end
+ if type(requested) ~= "table" then requested = deps.parse_version(requested) end
if not version or not requested then return false end
for i, ri in ipairs(requested) do
@@ -289,14 +290,14 @@ end
-- @param constraints table: An array of constraints in table format.
-- @return boolean: True if version satisfies all constraints,
-- false otherwise.
-function match_constraints(version, constraints)
+function deps.match_constraints(version, constraints)
assert(type(version) == "table")
assert(type(constraints) == "table")
local ok = true
setmetatable(version, version_mt)
for _, constr in pairs(constraints) do
if type(constr.version) == "string" then
- constr.version = parse_version(constr.version)
+ constr.version = deps.parse_version(constr.version)
end
local constr_version, constr_op = constr.version, constr.op
setmetatable(constr_version, version_mt)
@@ -323,9 +324,10 @@ end
local function match_dep(dep, blacklist, deps_mode)
assert(type(dep) == "table")
- local versions
- if dep.name == "lua" then
- versions = { cfg.lua_version }
+ local versions = cfg.rocks_provided[dep.name]
+ if cfg.rocks_provided[dep.name] then
+ -- provided rocks have higher priority than manifest's rocks
+ versions = { cfg.rocks_provided[dep.name] }
else
versions = manif_core.get_versions(dep.name, deps_mode)
end
@@ -344,8 +346,8 @@ local function match_dep(dep, blacklist, deps_mode)
end
local candidates = {}
for _, vstring in ipairs(versions) do
- local version = parse_version(vstring)
- if match_constraints(version, dep.constraints) then
+ local version = deps.parse_version(vstring)
+ if deps.match_constraints(version, dep.constraints) then
table.insert(candidates, version)
end
end
@@ -365,19 +367,21 @@ end
-- @param blacklist table or nil: Program versions to not use as valid matches.
-- Table where keys are program names and values are tables where keys
-- are program versions and values are 'true'.
--- @return table, table: A table where keys are dependencies parsed
+-- @return table, table, table: A table where keys are dependencies parsed
-- in table format and values are tables containing fields 'name' and
--- version' representing matches, and a table of missing dependencies
--- parsed as tables.
-function match_deps(rockspec, blacklist, deps_mode)
+-- version' representing matches; a table of missing dependencies
+-- parsed as tables; and a table of "no-upgrade" missing dependencies
+-- (to be used in plugin modules so that a plugin does not force upgrade of
+-- its parent application).
+function deps.match_deps(rockspec, blacklist, deps_mode)
assert(type(rockspec) == "table")
assert(type(blacklist) == "table" or not blacklist)
local matched, missing, no_upgrade = {}, {}, {}
-
+
for _, dep in ipairs(rockspec.dependencies) do
local found = match_dep(dep, blacklist and blacklist[dep.name] or nil, deps_mode)
if found then
- if dep.name ~= "lua" then
+ if not cfg.rocks_provided[dep.name] then
matched[dep] = found
end
else
@@ -409,24 +413,24 @@ end
-- @return boolean or (nil, string, [string]): True if no errors occurred, or
-- nil and an error message if any test failed, followed by an optional
-- error code.
-function fulfill_dependencies(rockspec, deps_mode)
+function deps.fulfill_dependencies(rockspec, deps_mode)
local search = require("luarocks.search")
local install = require("luarocks.install")
if rockspec.supported_platforms then
- if not platforms_set then
- platforms_set = values_set(cfg.platforms)
+ if not deps.platforms_set then
+ deps.platforms_set = values_set(cfg.platforms)
end
local supported = nil
for _, plat in pairs(rockspec.supported_platforms) do
local neg, plat = plat:match("^(!?)(.*)")
if neg == "!" then
- if platforms_set[plat] then
+ if deps.platforms_set[plat] then
return nil, "This rockspec for "..rockspec.package.." does not support "..plat.." platforms."
end
else
- if platforms_set[plat] then
+ if deps.platforms_set[plat] then
supported = true
else
if supported == nil then
@@ -441,22 +445,22 @@ function fulfill_dependencies(rockspec, deps_mode)
end
end
- local matched, missing, no_upgrade = match_deps(rockspec, nil, deps_mode)
+ local _, missing, no_upgrade = deps.match_deps(rockspec, nil, deps_mode)
if next(no_upgrade) then
util.printerr("Missing dependencies for "..rockspec.name.." "..rockspec.version..":")
for _, dep in pairs(no_upgrade) do
- util.printerr(show_dep(dep))
+ util.printerr(deps.show_dep(dep))
end
if next(missing) then
for _, dep in pairs(missing) do
- util.printerr(show_dep(dep))
+ util.printerr(deps.show_dep(dep))
end
end
util.printerr()
for _, dep in pairs(no_upgrade) do
util.printerr("This version of "..rockspec.name.." is designed for use with")
- util.printerr(show_dep(dep)..", but is configured to avoid upgrading it")
+ util.printerr(deps.show_dep(dep)..", but is configured to avoid upgrading it")
util.printerr("automatically. Please upgrade "..dep.name.." with")
util.printerr(" luarocks install "..dep.name)
util.printerr("or choose an older version of "..rockspec.name.." with")
@@ -469,7 +473,7 @@ function fulfill_dependencies(rockspec, deps_mode)
util.printerr()
util.printerr("Missing dependencies for "..rockspec.name..":")
for _, dep in pairs(missing) do
- util.printerr(show_dep(dep))
+ util.printerr(deps.show_dep(dep))
end
util.printerr()
@@ -478,7 +482,7 @@ function fulfill_dependencies(rockspec, deps_mode)
if not match_dep(dep, nil, deps_mode) then
local rock = search.find_suitable_rock(dep)
if not rock then
- return nil, "Could not satisfy dependency: "..show_dep(dep)
+ return nil, "Could not satisfy dependency: "..deps.show_dep(dep)
end
local ok, err, errcode = install.run(rock)
if not ok then
@@ -528,7 +532,7 @@ end
-- if "install" is given, do not scan for headers.
-- @return boolean or (nil, string): True if no errors occurred, or
-- nil and an error message if any test failed.
-function check_external_deps(rockspec, mode)
+function deps.check_external_deps(rockspec, mode)
assert(type(rockspec) == "table")
local fs = require("luarocks.fs")
@@ -574,7 +578,19 @@ function check_external_deps(rockspec, mode)
prefix = prefix.prefix
end
for dirname, dirdata in pairs(dirs) do
- dirdata.dir = vars[name.."_"..dirname] or dir.path(prefix, dirdata.subdir)
+ local paths
+ local path_var_value = vars[name.."_"..dirname]
+ if path_var_value then
+ paths = { path_var_value }
+ elseif type(dirdata.subdir) == "table" then
+ paths = {}
+ for i,v in ipairs(dirdata.subdir) do
+ paths[i] = dir.path(prefix, v)
+ end
+ else
+ paths = { dir.path(prefix, dirdata.subdir) }
+ end
+ dirdata.dir = paths[1]
local file = files[dirdata.testfile]
if file then
local files = {}
@@ -596,16 +612,22 @@ function check_external_deps(rockspec, mode)
if f:match("%.so$") or f:match("%.dylib$") or f:match("%.dll$") then
f = f:gsub("%.[^.]+$", "."..cfg.external_lib_extension)
end
- if f:match("%*") then
- local replaced = f:gsub("%.", "%%."):gsub("%*", ".*")
- for _, entry in ipairs(fs.list_dir(dirdata.dir)) do
- if entry:match(replaced) then
- found = true
- break
+ for _, d in ipairs(paths) do
+ if f:match("%*") then
+ local replaced = f:gsub("%.", "%%."):gsub("%*", ".*")
+ for entry in fs.dir(d) do
+ if entry:match(replaced) then
+ found = true
+ break
+ end
end
+ else
+ found = fs.is_file(dir.path(d, f))
+ end
+ if found then
+ dirdata.dir = d
+ break
end
- else
- found = fs.is_file(dir.path(dirdata.dir, f))
end
if found then
break
@@ -648,7 +670,7 @@ end
-- @param name string: Package name.
-- @param version string: Package version.
-- @return (table, table): The results and a table of missing dependencies.
-function scan_deps(results, missing, manifest, name, version, deps_mode)
+function deps.scan_deps(results, missing, manifest, name, version, deps_mode)
assert(type(results) == "table")
assert(type(missing) == "table")
assert(type(manifest) == "table")
@@ -668,7 +690,7 @@ function scan_deps(results, missing, manifest, name, version, deps_mode)
local deplist = dependencies_name[version]
local rockspec, err
if not deplist then
- rockspec, err = fetch.load_local_rockspec(path.rockspec_file(name, version))
+ rockspec, err = fetch.load_local_rockspec(path.rockspec_file(name, version), false)
if err then
missing[name.." "..version] = err
return results, missing
@@ -677,13 +699,14 @@ function scan_deps(results, missing, manifest, name, version, deps_mode)
else
rockspec = { dependencies = deplist }
end
- local matched, failures = match_deps(rockspec, nil, deps_mode)
+ local matched, failures = deps.match_deps(rockspec, nil, deps_mode)
+ results[name] = results
for _, match in pairs(matched) do
- results, missing = scan_deps(results, missing, manifest, match.name, match.version, deps_mode)
+ results, missing = deps.scan_deps(results, missing, manifest, match.name, match.version, deps_mode)
end
if next(failures) then
for _, failure in pairs(failures) do
- missing[show_dep(failure)] = "failed"
+ missing[deps.show_dep(failure)] = "failed"
end
end
results[name] = version
@@ -697,11 +720,11 @@ local valid_deps_modes = {
none = true,
}
-function check_deps_mode_flag(flag)
+function deps.check_deps_mode_flag(flag)
return valid_deps_modes[flag]
end
-function get_deps_mode(flags)
+function deps.get_deps_mode(flags)
if flags["deps-mode"] then
return flags["deps-mode"]
else
@@ -709,6 +732,8 @@ function get_deps_mode(flags)
end
end
-function deps_mode_to_flag(deps_mode)
+function deps.deps_mode_to_flag(deps_mode)
return "--deps-mode="..deps_mode
end
+
+return deps
diff --git a/luarocks/src/luarocks/dir.lua b/luarocks/src/luarocks/dir.lua
index b496c96..2ef9881 100644
--- a/luarocks/src/luarocks/dir.lua
+++ b/luarocks/src/luarocks/dir.lua
@@ -1,14 +1,16 @@
--- Generic utilities for handling pathnames.
-module("luarocks.dir", package.seeall)
+--module("luarocks.dir", package.seeall)
+local dir = {}
+package.loaded["luarocks.dir"] = dir
-separator = "/"
+dir.separator = "/"
--- Strip the path off a path+filename.
-- @param pathname string: A path+name, such as "/a/b/c"
-- or "\a\b\c".
-- @return string: The filename without its path, such as "c".
-function base_name(pathname)
+function dir.base_name(pathname)
assert(type(pathname) == "string")
local base = pathname:gsub("[/\\]*$", ""):match(".*[/\\]([^/\\]*)")
@@ -17,13 +19,12 @@ end
--- Strip the name off a path+filename.
-- @param pathname string: A path+name, such as "/a/b/c".
--- @return string: The filename without its path, such as "/a/b/".
--- For entries such as "/a/b/", "/a/" is returned. If there are
+-- @return string: The filename without its path, such as "/a/b".
+-- For entries such as "/a/b/", "/a" is returned. If there are
-- no directory separators in input, "" is returned.
-function dir_name(pathname)
+function dir.dir_name(pathname)
assert(type(pathname) == "string")
-
- return (pathname:gsub("/*$", ""):match("(.*/)[^/]*")) or ""
+ return (pathname:gsub("/*$", ""):match("(.*)[/]+[^/]*")) or ""
end
--- Describe a path in a cross-platform way.
@@ -35,18 +36,12 @@ end
-- @param ... strings representing directories
-- @return string: a string with a platform-specific representation
-- of the path.
-function path(...)
- local items = {...}
- local i = 1
- while items[i] do
- items[i] = items[i]:gsub("(.+)/+$", "%1")
- if items[i] == "" then
- table.remove(items, i)
- else
- i = i + 1
- end
+function dir.path(...)
+ local t = {...}
+ while t[1] == "" do
+ table.remove(t, 1)
end
- return (table.concat(items, "/"):gsub("(.+)/+$", "%1"))
+ return (table.concat(t, "/"):gsub("([^:])/+", "%1/"):gsub("^/+", "/"):gsub("/*$", ""))
end
--- Split protocol and path from an URL or local pathname.
@@ -54,7 +49,7 @@ end
-- For local pathnames, "file" is returned as the protocol.
-- @param url string: an URL or a local pathname.
-- @return string, string: the protocol, and the pathname without the protocol.
-function split_url(url)
+function dir.split_url(url)
assert(type(url) == "string")
local protocol, pathname = url:match("^([^:]*)://(.*)")
@@ -65,6 +60,16 @@ function split_url(url)
return protocol, pathname
end
-function normalize(name)
- return name:gsub("\\", "/"):gsub("(.)/*$", "%1")
+--- Normalize a url or local path.
+-- URLs should be in the "protocol://path" format. System independent
+-- forward slashes are used, removing trailing and double slashes
+-- @param url string: an URL or a local pathname.
+-- @return string: Normalized result.
+function dir.normalize(name)
+ local protocol, pathname = dir.split_url(name)
+ pathname = pathname:gsub("\\", "/"):gsub("(.)/*$", "%1"):gsub("//", "/")
+ if protocol ~= "file" then pathname = protocol .."://"..pathname end
+ return pathname
end
+
+return dir
diff --git a/luarocks/src/luarocks/doc.lua b/luarocks/src/luarocks/doc.lua
new file mode 100644
index 0000000..6dee106
--- /dev/null
+++ b/luarocks/src/luarocks/doc.lua
@@ -0,0 +1,156 @@
+
+--- Module implementing the LuaRocks "doc" command.
+-- Shows documentation for an installed rock.
+--module("luarocks.doc", package.seeall)
+local doc = {}
+package.loaded["luarocks.doc"] = doc
+
+local util = require("luarocks.util")
+local show = require("luarocks.show")
+local path = require("luarocks.path")
+local dir = require("luarocks.dir")
+local fetch = require("luarocks.fetch")
+local fs = require("luarocks.fs")
+local download = require("luarocks.download")
+
+doc.help_summary = "Shows documentation for an installed rock."
+
+doc.help = [[
+<argument> is an existing package name.
+Without any flags, tries to load the documentation
+using a series of heuristics.
+With these flags, return only the desired information:
+
+--homepage Open the home page of project.
+--list List documentation files only.
+
+For more information about a rock, see the 'show' command.
+]]
+
+local function show_homepage(homepage, name, version)
+ if not homepage then
+ return nil, "No 'homepage' field in rockspec for "..name.." "..version
+ end
+ util.printout("Opening "..homepage.." ...")
+ fs.browser(homepage)
+ return true
+end
+
+local function try_to_open_homepage(name, version)
+ local temp_dir, err = fs.make_temp_dir("doc-"..name.."-"..(version or ""))
+ if not temp_dir then
+ return nil, "Failed creating temporary directory: "..err
+ end
+ util.schedule_function(fs.delete, temp_dir)
+ local ok, err = fs.change_dir(temp_dir)
+ if not ok then return nil, err end
+ local filename, err = download.download("rockspec", name, version)
+ if not filename then return nil, err end
+ local rockspec, err = fetch.load_local_rockspec(filename)
+ if not rockspec then return nil, err end
+ fs.pop_dir()
+ local descript = rockspec.description or {}
+ if not descript.homepage then return nil, "No homepage defined for "..name end
+ return show_homepage(descript.homepage, name, version)
+end
+
+--- Driver function for "doc" command.
+-- @param name or nil: an existing package name.
+-- @param version string or nil: a version may also be passed.
+-- @return boolean: True if succeeded, nil on errors.
+function doc.run(...)
+ local flags, name, version = util.parse_flags(...)
+ if not name then
+ return nil, "Argument missing. "..util.see_help("doc")
+ end
+
+ local iname, iversion, repo = show.pick_installed_rock(name, version, flags["tree"])
+ if not iname then
+ util.printout(name..(version and " "..version or "").." is not installed. Looking for it in the rocks servers...")
+ return try_to_open_homepage(name, version)
+ end
+ name, version = iname, iversion
+
+ local rockspec, err = fetch.load_local_rockspec(path.rockspec_file(name, version, repo))
+ if not rockspec then return nil,err end
+ local descript = rockspec.description or {}
+
+ if flags["homepage"] then
+ return show_homepage(descript.homepage, name, version)
+ end
+
+ local directory = path.install_dir(name,version,repo)
+
+ local docdir
+ local directories = { "doc", "docs" }
+ for _, d in ipairs(directories) do
+ local dirname = dir.path(directory, d)
+ if fs.is_dir(dirname) then
+ docdir = dirname
+ break
+ end
+ end
+ if not docdir then
+ if descript.homepage and not flags["list"] then
+ util.printout("Local documentation directory not found -- opening "..descript.homepage.." ...")
+ fs.browser(descript.homepage)
+ return true
+ end
+ return nil, "Documentation directory not found for "..name.." "..version
+ end
+
+ docdir = dir.normalize(docdir):gsub("/+", "/")
+ local files = fs.find(docdir)
+ local htmlpatt = "%.html?$"
+ local extensions = { htmlpatt, "%.md$", "%.txt$", "%.textile$", "" }
+ local basenames = { "index", "readme", "manual" }
+
+ local porcelain = flags["porcelain"]
+ if #files > 0 then
+ util.title("Documentation files for "..name.." "..version, porcelain)
+ if porcelain then
+ for _, file in ipairs(files) do
+ util.printout(docdir.."/"..file)
+ end
+ else
+ util.printout(docdir.."/")
+ for _, file in ipairs(files) do
+ util.printout("\t"..file)
+ end
+ end
+ end
+
+ if flags["list"] then
+ return true
+ end
+
+ for _, extension in ipairs(extensions) do
+ for _, basename in ipairs(basenames) do
+ local filename = basename..extension
+ local found
+ for _, file in ipairs(files) do
+ if file:lower():match(filename) and ((not found) or #file < #found) then
+ found = file
+ end
+ end
+ if found then
+ local pathname = dir.path(docdir, found)
+ util.printout()
+ util.printout("Opening "..pathname.." ...")
+ util.printout()
+ local ok = fs.browser(pathname)
+ if not ok and not pathname:match(htmlpatt) then
+ local fd = io.open(pathname, "r")
+ util.printout(fd:read("*a"))
+ fd:close()
+ end
+ return true
+ end
+ end
+ end
+
+ return true
+end
+
+
+return doc
diff --git a/luarocks/src/luarocks/download.lua b/luarocks/src/luarocks/download.lua
index 0012cb1..74ed40e 100644
--- a/luarocks/src/luarocks/download.lua
+++ b/luarocks/src/luarocks/download.lua
@@ -1,24 +1,42 @@
--- Module implementing the luarocks "download" command.
-- Download a rock from the repository.
-module("luarocks.download", package.seeall)
+--module("luarocks.download", package.seeall)
+local download = {}
+package.loaded["luarocks.download"] = download
local util = require("luarocks.util")
local path = require("luarocks.path")
local fetch = require("luarocks.fetch")
local search = require("luarocks.search")
+local fs = require("luarocks.fs")
+local dir = require("luarocks.dir")
-help_summary = "Download a specific rock file from a rocks server."
-help_arguments = "[--all] [--arch=<arch> | --source | --rockspec] [<name> [<version>]]"
+download.help_summary = "Download a specific rock file from a rocks server."
+download.help_arguments = "[--all] [--arch=<arch> | --source | --rockspec] [<name> [<version>]]"
-help = [[
+download.help = [[
--all Download all files if there are multiple matches.
--source Download .src.rock if available.
--rockspec Download .rockspec if available.
--arch=<arch> Download rock for a specific architecture.
]]
-function download(arch, name, version, all)
+local function get_file(filename)
+ local protocol, pathname = dir.split_url(filename)
+ if protocol == "file" then
+ local ok, err = fs.copy(pathname, fs.current_dir())
+ if ok then
+ return pathname
+ else
+ return nil, err
+ end
+ else
+ return fetch.fetch_url(filename)
+ end
+end
+
+function download.download(arch, name, version, all)
local results, err
local query = search.make_query(name, version)
if arch then query.arch = arch end
@@ -29,8 +47,7 @@ function download(arch, name, version, all)
results, err = search.find_suitable_rock(query)
end
if type(results) == "string" then
- local file = fetch.fetch_url(results)
- return file
+ return get_file(results)
elseif type(results) == "table" and next(results) then
if all then
local all_ok = true
@@ -39,7 +56,7 @@ function download(arch, name, version, all)
for version, versions in pairs(result) do
for _,items in pairs(versions) do
local filename = path.make_url(items.repo, name, version, items.arch)
- local ok, err = fetch.fetch_url(filename)
+ local ok, err = get_file(filename)
if not ok then
all_ok = false
any_err = any_err .. "\n" .. err
@@ -64,7 +81,7 @@ end
-- version may also be passed.
-- @return boolean or (nil, string): true if successful or nil followed
-- by an error message.
-function run(...)
+function download.run(...)
local flags, name, version = util.parse_flags(...)
assert(type(version) == "string" or not version)
@@ -83,6 +100,8 @@ function run(...)
arch = flags["arch"]
end
- local dl, err = download(arch, name, version, flags["all"])
+ local dl, err = download.download(arch, name, version, flags["all"])
return dl and true, err
end
+
+return download
diff --git a/luarocks/src/luarocks/fetch.lua b/luarocks/src/luarocks/fetch.lua
index bfdbace..980c8fe 100644
--- a/luarocks/src/luarocks/fetch.lua
+++ b/luarocks/src/luarocks/fetch.lua
@@ -1,6 +1,8 @@
--- Functions related to fetching and loading local and remote files.
-module("luarocks.fetch", package.seeall)
+--module("luarocks.fetch", package.seeall)
+local fetch = {}
+package.loaded["luarocks.fetch"] = fetch
local fs = require("luarocks.fs")
local dir = require("luarocks.dir")
@@ -11,6 +13,10 @@ local persist = require("luarocks.persist")
local util = require("luarocks.util")
local cfg = require("luarocks.cfg")
+function fetch.is_basic_protocol(protocol, remote)
+ return protocol == "http" or protocol == "https" or protocol == "ftp" or (not remote and protocol == "file")
+end
+
--- Fetch a local or remote file.
-- Make a remote or local URL/pathname local, fetching the file if necessary.
-- Other "fetch" and "load" functions use this function to obtain files.
@@ -23,19 +29,19 @@ local cfg = require("luarocks.cfg")
-- @return string or (nil, string, [string]): the absolute local pathname for the
-- fetched file, or nil and a message in case of errors, followed by
-- an optional error code.
-function fetch_url(url, filename)
+function fetch.fetch_url(url, filename, cache)
assert(type(url) == "string")
assert(type(filename) == "string" or not filename)
local protocol, pathname = dir.split_url(url)
if protocol == "file" then
return fs.absolute_name(pathname)
- elseif protocol == "http" or protocol == "ftp" or protocol == "https" then
- local ok, err = fs.download(url, filename)
+ elseif fetch.is_basic_protocol(protocol, true) then
+ local ok, filename = fs.download(url, filename, cache)
if not ok then
- return nil, "Failed downloading "..url..(err and " - "..err or ""), "network"
+ return nil, "Failed downloading "..url..(filename and " - "..filename or ""), "network"
end
- return dir.path(fs.current_dir(), filename or dir.base_name(url))
+ return filename
else
return nil, "Unsupported protocol "..protocol
end
@@ -52,7 +58,7 @@ end
-- @return (string, string) or (nil, string, [string]): absolute local pathname of
-- the fetched file and temporary directory name; or nil and an error message
-- followed by an optional error code
-function fetch_url_at_temp_dir(url, tmpname, filename)
+function fetch.fetch_url_at_temp_dir(url, tmpname, filename)
assert(type(url) == "string")
assert(type(tmpname) == "string")
assert(type(filename) == "string" or not filename)
@@ -66,13 +72,14 @@ function fetch_url_at_temp_dir(url, tmpname, filename)
return nil, "File not found: "..pathname
end
else
- local temp_dir = fs.make_temp_dir(tmpname)
+ local temp_dir, err = fs.make_temp_dir(tmpname)
if not temp_dir then
- return nil, "Failed creating temporary directory."
+ return nil, "Failed creating temporary directory "..tmpname..": "..err
end
util.schedule_function(fs.delete, temp_dir)
- fs.change_dir(temp_dir)
- local file, err, errcode = fetch_url(url, filename)
+ local ok, err = fs.change_dir(temp_dir)
+ if not ok then return nil, err end
+ local file, err, errcode = fetch.fetch_url(url, filename)
fs.pop_dir()
if not file then
return nil, "Error fetching file: "..err, errcode
@@ -81,6 +88,44 @@ function fetch_url_at_temp_dir(url, tmpname, filename)
end
end
+-- Determine base directory of a fetched URL by extracting its
+-- archive and looking for a directory in the root.
+-- @param file string: absolute local pathname of the fetched file
+-- @param temp_dir string: temporary directory in which URL was fetched.
+-- @param src_url string: URL to use when inferring base directory.
+-- @param src_dir string or nil: expected base directory (inferred
+-- from src_url if not given).
+-- @return (string, string) or (string, nil) or (nil, string):
+-- The inferred base directory and the one actually found (which may
+-- be nil if not found), or nil followed by an error message.
+-- The inferred dir is returned first to avoid confusion with errors,
+-- because it is never nil.
+function fetch.find_base_dir(file, temp_dir, src_url, src_dir)
+ local ok, err = fs.change_dir(temp_dir)
+ if not ok then return nil, err end
+ fs.unpack_archive(file)
+ local inferred_dir = src_dir or fetch.url_to_base_dir(src_url)
+ local found_dir = nil
+ if fs.exists(inferred_dir) then
+ found_dir = inferred_dir
+ else
+ util.printerr("Directory "..inferred_dir.." not found")
+ local files = fs.list_dir()
+ if files then
+ table.sort(files)
+ for i,filename in ipairs(files) do
+ if fs.is_dir(filename) then
+ util.printerr("Found "..filename)
+ found_dir = filename
+ break
+ end
+ end
+ end
+ end
+ fs.pop_dir()
+ return inferred_dir, found_dir
+end
+
--- Obtain a rock and unpack it.
-- If a directory is not given, a temporary directory will be created,
-- which will be deleted on program termination.
@@ -89,13 +134,13 @@ end
-- a permanent destination.
-- @return string or (nil, string, [string]): the directory containing the contents
-- of the unpacked rock.
-function fetch_and_unpack_rock(rock_file, dest)
+function fetch.fetch_and_unpack_rock(rock_file, dest)
assert(type(rock_file) == "string")
assert(type(dest) == "string" or not dest)
local name = dir.base_name(rock_file):match("(.*)%.[^.]*%.rock")
- local rock_file, err, errcode = fetch_url_at_temp_dir(rock_file,"luarocks-rock-"..name)
+ local rock_file, err, errcode = fetch.fetch_url_at_temp_dir(rock_file,"luarocks-rock-"..name)
if not rock_file then
return nil, "Could not fetch rock file: " .. err, errcode
end
@@ -104,15 +149,19 @@ function fetch_and_unpack_rock(rock_file, dest)
local unpack_dir
if dest then
unpack_dir = dest
- fs.make_dir(unpack_dir)
+ local ok, err = fs.make_dir(unpack_dir)
+ if not ok then
+ return nil, "Failed unpacking rock file: " .. err
+ end
else
unpack_dir = fs.make_temp_dir(name)
end
if not dest then
util.schedule_function(fs.delete, unpack_dir)
end
- fs.change_dir(unpack_dir)
- local ok = fs.unzip(rock_file)
+ local ok, err = fs.change_dir(unpack_dir)
+ if not ok then return nil, err end
+ ok = fs.unzip(rock_file)
if not ok then
return nil, "Failed unpacking rock file: " .. rock_file
end
@@ -120,7 +169,7 @@ function fetch_and_unpack_rock(rock_file, dest)
return unpack_dir
end
-function url_to_base_dir(url)
+function fetch.url_to_base_dir(url)
local base = dir.base_name(url)
return base:gsub("%.[^.]*$", ""):gsub("%.tar$", "")
end
@@ -128,19 +177,28 @@ end
--- Back-end function that actually loads the local rockspec.
-- Performs some validation and postprocessing of the rockspec contents.
-- @param filename string: The local filename of the rockspec file.
+-- @param quick boolean: if true, skips some steps when loading
+-- rockspec.
-- @return table or (nil, string): A table representing the rockspec
-- or nil followed by an error message.
-function load_local_rockspec(filename)
+function fetch.load_local_rockspec(filename, quick)
assert(type(filename) == "string")
filename = fs.absolute_name(filename)
local rockspec, err = persist.load_into_table(filename)
if not rockspec then
return nil, "Could not load rockspec file "..filename.." ("..err..")"
end
+ if cfg.branch and (type(rockspec.source) == "table") then
+ rockspec.source.branch = cfg.branch
+ end
+ local globals = err
- local ok, err = type_check.type_check_rockspec(rockspec)
- if not ok then
- return nil, filename..": "..err
+ local ok, err = true, nil
+ if not quick then
+ ok, err = type_check.type_check_rockspec(rockspec, globals)
+ if not ok then
+ return nil, filename..": "..err
+ end
end
if rockspec.rockspec_format then
@@ -166,7 +224,7 @@ function load_local_rockspec(filename)
end
local protocol, pathname = dir.split_url(rockspec.source.url)
- if protocol == "http" or protocol == "https" or protocol == "ftp" or protocol == "file" then
+ if fetch.is_basic_protocol(protocol) then
rockspec.source.file = rockspec.source.file or dir.base_name(rockspec.source.url)
end
rockspec.source.protocol, rockspec.source.pathname = protocol, pathname
@@ -182,10 +240,10 @@ function load_local_rockspec(filename)
rockspec.local_filename = filename
local filebase = rockspec.source.file or rockspec.source.url
- local base = url_to_base_dir(filebase)
+ local base = fetch.url_to_base_dir(filebase)
rockspec.source.dir = rockspec.source.dir
or rockspec.source.module
- or ((filebase:match(".lua$") or filebase:match(".c$")) and ".")
+ or ((filebase:match("%.lua$") or filebase:match("%.c$")) and ".")
or base
if rockspec.dependencies then
for i = 1, #rockspec.dependencies do
@@ -198,9 +256,8 @@ function load_local_rockspec(filename)
else
rockspec.dependencies = {}
end
- local ok, err = path.configure_paths(rockspec)
- if err then
- return nil, "Error verifying paths: "..err
+ if not quick then
+ path.configure_paths(rockspec)
end
return rockspec
@@ -215,7 +272,7 @@ end
-- a temporary dir is created.
-- @return table or (nil, string, [string]): A table representing the rockspec
-- or nil followed by an error message and optional error code.
-function load_rockspec(filename, location)
+function fetch.load_rockspec(filename, location)
assert(type(filename) == "string")
local name
@@ -224,35 +281,37 @@ function load_rockspec(filename, location)
name = "rockspec"
else
name = basename:match("(.*)%.rockspec")
- if not name and not basename == "rockspec" then
+ if not name then
return nil, "Filename '"..filename.."' does not look like a rockspec."
end
end
local err, errcode
if location then
- fs.change_dir(location)
- filename, err = fetch_url(filename)
+ local ok, err = fs.change_dir(location)
+ if not ok then return nil, err end
+ filename, err = fetch.fetch_url(filename)
fs.pop_dir()
else
- filename, err, errcode = fetch_url_at_temp_dir(filename,"luarocks-rockspec-"..name)
+ filename, err, errcode = fetch.fetch_url_at_temp_dir(filename,"luarocks-rockspec-"..name)
end
if not filename then
return nil, err, errcode
end
- return load_local_rockspec(filename)
+ return fetch.load_local_rockspec(filename)
end
--- Download sources for building a rock using the basic URL downloader.
-- @param rockspec table: The rockspec table
-- @param extract boolean: Whether to extract the sources from
-- the fetched source tarball or not.
--- @param dest_dir string or nil: If set, will extract to the given directory.
+-- @param dest_dir string or nil: If set, will extract to the given directory;
+-- if not given, will extract to a temporary directory.
-- @return (string, string) or (nil, string, [string]): The absolute pathname of
-- the fetched source tarball and the temporary directory created to
-- store it; or nil and an error message and optional error code.
-function get_sources(rockspec, extract, dest_dir)
+function fetch.get_sources(rockspec, extract, dest_dir)
assert(type(rockspec) == "table")
assert(type(extract) == "boolean")
assert(type(dest_dir) == "string" or not dest_dir)
@@ -262,26 +321,28 @@ function get_sources(rockspec, extract, dest_dir)
local filename = rockspec.source.file
local source_file, store_dir, err, errcode
if dest_dir then
- fs.change_dir(dest_dir)
- source_file, err, errcode = fetch_url(url, filename)
+ local ok, err = fs.change_dir(dest_dir)
+ if not ok then return nil, err, "dest_dir" end
+ source_file, err, errcode = fetch.fetch_url(url, filename)
fs.pop_dir()
store_dir = dest_dir
else
- source_file, store_dir, errcode = fetch_url_at_temp_dir(url, "luarocks-source-"..name, filename)
+ source_file, store_dir, errcode = fetch.fetch_url_at_temp_dir(url, "luarocks-source-"..name, filename)
end
if not source_file then
return nil, err or store_dir, errcode
end
if rockspec.source.md5 then
if not fs.check_md5(source_file, rockspec.source.md5) then
- return nil, "MD5 check for "..filename.." has failed."
+ return nil, "MD5 check for "..filename.." has failed.", "md5"
end
end
if extract then
- fs.change_dir(store_dir)
+ local ok, err = fs.change_dir(store_dir)
+ if not ok then return nil, err end
fs.unpack_archive(rockspec.source.file)
if not fs.exists(rockspec.source.dir) then
- return nil, "Directory "..rockspec.source.dir.." not found inside archive "..rockspec.source.file
+ return nil, "Directory "..rockspec.source.dir.." not found inside archive "..rockspec.source.file, "source.dir", source_file, store_dir
end
fs.pop_dir()
end
@@ -293,17 +354,18 @@ end
-- @param extract boolean: When downloading compressed formats, whether to extract
-- the sources from the fetched archive or not.
-- @param dest_dir string or nil: If set, will extract to the given directory.
+-- if not given, will extract to a temporary directory.
-- @return (string, string) or (nil, string): The absolute pathname of
-- the fetched source tarball and the temporary directory created to
-- store it; or nil and an error message.
-function fetch_sources(rockspec, extract, dest_dir)
+function fetch.fetch_sources(rockspec, extract, dest_dir)
assert(type(rockspec) == "table")
assert(type(extract) == "boolean")
assert(type(dest_dir) == "string" or not dest_dir)
local protocol = rockspec.source.protocol
local ok, proto
- if protocol == "http" or protocol == "https" or protocol == "ftp" or protocol == "file" then
+ if fetch.is_basic_protocol(protocol) then
proto = require("luarocks.fetch")
else
ok, proto = pcall(require, "luarocks.fetch."..protocol:gsub("[+-]", "_"))
@@ -323,3 +385,5 @@ function fetch_sources(rockspec, extract, dest_dir)
end
return proto.get_sources(rockspec, extract, dest_dir)
end
+
+return fetch
diff --git a/luarocks/src/luarocks/fetch/cvs.lua b/luarocks/src/luarocks/fetch/cvs.lua
index a622cdc..cc9fd65 100644
--- a/luarocks/src/luarocks/fetch/cvs.lua
+++ b/luarocks/src/luarocks/fetch/cvs.lua
@@ -1,6 +1,9 @@
--- Fetch back-end for retrieving sources from CVS.
-module("luarocks.fetch.cvs", package.seeall)
+--module("luarocks.fetch.cvs", package.seeall)
+local cvs = {}
+
+local unpack = unpack or table.unpack
local fs = require("luarocks.fs")
local dir = require("luarocks.dir")
@@ -13,7 +16,7 @@ local util = require("luarocks.util")
-- @return (string, string) or (nil, string): The absolute pathname of
-- the fetched source tarball and the temporary directory created to
-- store it; or nil and an error message.
-function get_sources(rockspec, extract, dest_dir)
+function cvs.get_sources(rockspec, extract, dest_dir)
assert(type(rockspec) == "table")
assert(type(dest_dir) == "string" or not dest_dir)
@@ -34,7 +37,8 @@ function get_sources(rockspec, extract, dest_dir)
else
store_dir = dest_dir
end
- fs.change_dir(store_dir)
+ local ok, err = fs.change_dir(store_dir)
+ if not ok then return nil, err end
if not fs.execute(unpack(command)) then
return nil, "Failed fetching files from CVS."
end
@@ -42,3 +46,5 @@ function get_sources(rockspec, extract, dest_dir)
return module, store_dir
end
+
+return cvs
diff --git a/luarocks/src/luarocks/fetch/git.lua b/luarocks/src/luarocks/fetch/git.lua
index e7c8943..53fd444 100644
--- a/luarocks/src/luarocks/fetch/git.lua
+++ b/luarocks/src/luarocks/fetch/git.lua
@@ -1,6 +1,9 @@
--- Fetch back-end for retrieving sources from GIT.
-module("luarocks.fetch.git", package.seeall)
+--module("luarocks.fetch.git", package.seeall)
+local git = {}
+
+local unpack = unpack or table.unpack
local fs = require("luarocks.fs")
local dir = require("luarocks.dir")
@@ -11,13 +14,13 @@ local util = require("luarocks.util")
-- clone by tag then we'll have to issue a subsequent command to check out the
-- given tag.
-- @return boolean: Whether Git can clone by tag.
-local function git_can_clone_by_tag()
- local version_string = io.popen('git --version'):read()
+local function git_can_clone_by_tag(git_cmd)
+ local version_string = io.popen(fs.Q(git_cmd)..' --version'):read()
local major, minor, tiny = version_string:match('(%d-)%.(%d+)%.?(%d*)')
major, minor, tiny = tonumber(major), tonumber(minor), tonumber(tiny) or 0
local value = major > 1 or (major == 1 and (minor > 7 or (minor == 7 and tiny >= 10)))
git_can_clone_by_tag = function() return value end
- return git_can_clone_by_tag()
+ return value
end
--- Download sources for building a rock, using git.
@@ -27,7 +30,7 @@ end
-- @return (string, string) or (nil, string): The absolute pathname of
-- the fetched source tarball and the temporary directory created to
-- store it; or nil and an error message.
-function get_sources(rockspec, extract, dest_dir)
+function git.get_sources(rockspec, extract, dest_dir, depth)
assert(type(rockspec) == "table")
assert(type(dest_dir) == "string" or not dest_dir)
@@ -48,15 +51,16 @@ function get_sources(rockspec, extract, dest_dir)
store_dir = dest_dir
end
store_dir = fs.absolute_name(store_dir)
- fs.change_dir(store_dir)
+ local ok, err = fs.change_dir(store_dir)
+ if not ok then return nil, err end
- local command = {git_cmd, "clone", "--depth=1", rockspec.source.url, module}
+ local command = {fs.Q(git_cmd), "clone", depth or "--depth=1", rockspec.source.url, module}
local tag_or_branch = rockspec.source.tag or rockspec.source.branch
-- If the tag or branch is explicitly set to "master" in the rockspec, then
-- we can avoid passing it to Git since it's the default.
if tag_or_branch == "master" then tag_or_branch = nil end
if tag_or_branch then
- if git_can_clone_by_tag() then
+ if git_can_clone_by_tag(git_cmd) then
-- The argument to `--branch` can actually be a branch or a tag as of
-- Git 1.7.10.
table.insert(command, 4, "--branch=" .. tag_or_branch)
@@ -65,9 +69,10 @@ function get_sources(rockspec, extract, dest_dir)
if not fs.execute(unpack(command)) then
return nil, "Failed cloning git repository."
end
- fs.change_dir(module)
+ ok, err = fs.change_dir(module)
+ if not ok then return nil, err end
if tag_or_branch and not git_can_clone_by_tag() then
- local checkout_command = {git_cmd, "checkout", tag_or_branch}
+ local checkout_command = {fs.Q(git_cmd), "checkout", tag_or_branch}
if not fs.execute(unpack(checkout_command)) then
return nil, 'Failed to check out the "' .. tag_or_branch ..'" tag or branch.'
end
@@ -79,3 +84,5 @@ function get_sources(rockspec, extract, dest_dir)
fs.pop_dir()
return module, store_dir
end
+
+return git
diff --git a/luarocks/src/luarocks/fetch/git_file.lua b/luarocks/src/luarocks/fetch/git_file.lua
index 1b18d0f..0144bc2 100644
--- a/luarocks/src/luarocks/fetch/git_file.lua
+++ b/luarocks/src/luarocks/fetch/git_file.lua
@@ -1,6 +1,7 @@
--- Fetch back-end for retrieving sources from local Git repositories.
-module("luarocks.fetch.git_file", package.seeall)
+--module("luarocks.fetch.git_file", package.seeall)
+local git_file = {}
local git = require("luarocks.fetch.git")
@@ -11,7 +12,9 @@ local git = require("luarocks.fetch.git")
-- @return (string, string) or (nil, string): The absolute pathname of
-- the fetched source tarball and the temporary directory created to
-- store it; or nil and an error message.
-function get_sources(rockspec, extract, dest_dir)
+function git_file.get_sources(rockspec, extract, dest_dir)
rockspec.source.url = rockspec.source.url:gsub("^git.file://", "")
return git.get_sources(rockspec, extract, dest_dir)
end
+
+return git_file
diff --git a/luarocks/src/luarocks/fetch/git_http.lua b/luarocks/src/luarocks/fetch/git_http.lua
new file mode 100644
index 0000000..4ecd481
--- /dev/null
+++ b/luarocks/src/luarocks/fetch/git_http.lua
@@ -0,0 +1,27 @@
+
+--- Fetch back-end for retrieving sources from Git repositories
+-- that use http:// transport. For example, for fetching a repository
+-- that requires the following command line:
+-- `git clone http://example.com/foo.git`
+-- you can use this in the rockspec:
+-- source = { url = "git+http://example.com/foo.git" }
+-- Prefer using the normal git:// fetch mode as it is more widely
+-- available in older versions of LuaRocks.
+--module("luarocks.fetch.git_http", package.seeall)
+local git_http = {}
+
+local git = require("luarocks.fetch.git")
+
+--- Fetch sources for building a rock from a local Git repository.
+-- @param rockspec table: The rockspec table
+-- @param extract boolean: Unused in this module (required for API purposes.)
+-- @param dest_dir string or nil: If set, will extract to the given directory.
+-- @return (string, string) or (nil, string): The absolute pathname of
+-- the fetched source tarball and the temporary directory created to
+-- store it; or nil and an error message.
+function git_http.get_sources(rockspec, extract, dest_dir)
+ rockspec.source.url = rockspec.source.url:gsub("^git.", "")
+ return git.get_sources(rockspec, extract, dest_dir, "--")
+end
+
+return git_http
diff --git a/luarocks/src/luarocks/fetch/hg.lua b/luarocks/src/luarocks/fetch/hg.lua
index a08520a..b2ba56e 100644
--- a/luarocks/src/luarocks/fetch/hg.lua
+++ b/luarocks/src/luarocks/fetch/hg.lua
@@ -1,6 +1,9 @@
--- Fetch back-end for retrieving sources from HG.
-module("luarocks.fetch.hg", package.seeall)
+--module("luarocks.fetch.hg", package.seeall)
+local hg = {}
+
+local unpack = unpack or table.unpack
local fs = require("luarocks.fs")
local dir = require("luarocks.dir")
@@ -13,7 +16,7 @@ local util = require("luarocks.util")
-- @return (string, string) or (nil, string): The absolute pathname of
-- the fetched source tarball and the temporary directory created to
-- store it; or nil and an error message.
-function get_sources(rockspec, extract, dest_dir)
+function hg.get_sources(rockspec, extract, dest_dir)
assert(type(rockspec) == "table")
assert(type(dest_dir) == "string" or not dest_dir)
@@ -39,11 +42,13 @@ function get_sources(rockspec, extract, dest_dir)
else
store_dir = dest_dir
end
- fs.change_dir(store_dir)
+ local ok, err = fs.change_dir(store_dir)
+ if not ok then return nil, err end
if not fs.execute(unpack(command)) then
return nil, "Failed cloning hg repository."
end
- fs.change_dir(module)
+ ok, err = fs.change_dir(module)
+ if not ok then return nil, err end
fs.delete(dir.path(store_dir, module, ".hg"))
fs.delete(dir.path(store_dir, module, ".hgignore"))
@@ -52,3 +57,5 @@ function get_sources(rockspec, extract, dest_dir)
return module, store_dir
end
+
+return hg
diff --git a/luarocks/src/luarocks/fetch/sscm.lua b/luarocks/src/luarocks/fetch/sscm.lua
index e52e801..53ae86a 100644
--- a/luarocks/src/luarocks/fetch/sscm.lua
+++ b/luarocks/src/luarocks/fetch/sscm.lua
@@ -1,6 +1,7 @@
--- Fetch back-end for retrieving sources from Surround SCM Server
-module("luarocks.fetch.sscm", package.seeall)
+--module("luarocks.fetch.sscm", package.seeall)
+local sscm = {}
local fs = require("luarocks.fs")
local dir = require("luarocks.dir")
@@ -12,7 +13,7 @@ local dir = require("luarocks.dir")
-- @return (string, string) or (nil, string): The absolute pathname of
-- the fetched source tarball and the temporary directory created to
-- store it; or nil and an error message.
-function get_sources(rockspec, extract, dest_dir)
+function sscm.get_sources(rockspec, extract, dest_dir)
assert(type(rockspec) == "table")
assert(type(dest_dir) == "string" or not dest_dir)
@@ -40,3 +41,5 @@ function get_sources(rockspec, extract, dest_dir)
-- FIXME: This function does not honor the dest_dir parameter.
return module, working_dir
end
+
+return sscm
diff --git a/luarocks/src/luarocks/fetch/svn.lua b/luarocks/src/luarocks/fetch/svn.lua
index a4e952d..abeacf9 100644
--- a/luarocks/src/luarocks/fetch/svn.lua
+++ b/luarocks/src/luarocks/fetch/svn.lua
@@ -1,6 +1,9 @@
--- Fetch back-end for retrieving sources from Subversion.
-module("luarocks.fetch.svn", package.seeall)
+--module("luarocks.fetch.svn", package.seeall)
+local svn = {}
+
+local unpack = unpack or table.unpack
local fs = require("luarocks.fs")
local dir = require("luarocks.dir")
@@ -13,7 +16,7 @@ local util = require("luarocks.util")
-- @return (string, string) or (nil, string): The absolute pathname of
-- the fetched source tarball and the temporary directory created to
-- store it; or nil and an error message.
-function get_sources(rockspec, extract, dest_dir)
+function svn.get_sources(rockspec, extract, dest_dir)
assert(type(rockspec) == "table")
assert(type(dest_dir) == "string" or not dest_dir)
@@ -36,11 +39,13 @@ function get_sources(rockspec, extract, dest_dir)
else
store_dir = dest_dir
end
- fs.change_dir(store_dir)
+ local ok, err = fs.change_dir(store_dir)
+ if not ok then return nil, err end
if not fs.execute(unpack(command)) then
return nil, "Failed fetching files from Subversion."
end
- fs.change_dir(module)
+ ok, err = fs.change_dir(module)
+ if not ok then return nil, err end
for _, d in ipairs(fs.find(".")) do
if dir.base_name(d) == ".svn" then
fs.delete(dir.path(store_dir, module, d))
@@ -51,3 +56,5 @@ function get_sources(rockspec, extract, dest_dir)
return module, store_dir
end
+
+return svn
diff --git a/luarocks/src/luarocks/fs.lua b/luarocks/src/luarocks/fs.lua
index 467b194..72e11c0 100644
--- a/luarocks/src/luarocks/fs.lua
+++ b/luarocks/src/luarocks/fs.lua
@@ -7,14 +7,45 @@
local pairs = pairs
-module("luarocks.fs", package.seeall)
+--module("luarocks.fs", package.seeall)
+local fs = {}
+package.loaded["luarocks.fs"] = fs
local cfg = require("luarocks.cfg")
+local pack = table.pack or function(...) return { n = select("#", ...), ... } end
+local unpack = table.unpack or unpack
+
+local old_popen, old_exec
+fs.verbose = function() -- patch io.popen and os.execute to display commands in verbose mode
+ if old_popen or old_exec then return end
+ old_popen = io.popen
+ io.popen = function(one, two)
+ if two == nil then
+ print("\nio.popen: ", one)
+ else
+ print("\nio.popen: ", one, "Mode:", two)
+ end
+ return old_popen(one, two)
+ end
+
+ old_exec = os.execute
+ os.execute = function(cmd)
+ print("\nos.execute: ", cmd)
+ local code = pack(old_exec(cmd))
+ print("Results: "..tostring(code.n))
+ for i = 1,code.n do
+ print(" "..tostring(i).." ("..type(code[i]).."): "..tostring(code[i]))
+ end
+ return unpack(code, 1, code.n)
+ end
+end
+if cfg.verbose then fs.verbose() end
+
local function load_fns(fs_table)
for name, fn in pairs(fs_table) do
- if not _M[name] then
- _M[name] = fn
+ if not fs[name] then
+ fs[name] = fn
end
end
end
@@ -38,3 +69,5 @@ load_fns(fs_lua)
local ok, fs_plat_tools = pcall(require, "luarocks.fs."..loaded_platform..".tools")
if ok and fs_plat_tools then load_fns(fs_plat_tools) end
+
+return fs
diff --git a/luarocks/src/luarocks/fs/lua.lua b/luarocks/src/luarocks/fs/lua.lua
index 36b3369..b261905 100644
--- a/luarocks/src/luarocks/fs/lua.lua
+++ b/luarocks/src/luarocks/fs/lua.lua
@@ -1,7 +1,8 @@
--- Native Lua implementation of filesystem and platform abstractions,
-- using LuaFileSystem, LZLib, MD5 and LuaCurl.
-module("luarocks.fs.lua", package.seeall)
+-- module("luarocks.fs.lua")
+local fs_lua = {}
local fs = require("luarocks.fs")
@@ -29,17 +30,17 @@ local dir_stack = {}
math.randomseed(os.time())
-dir_separator = "/"
+local dir_separator = "/"
--- Quote argument for shell processing.
-- Adds single quotes and escapes.
-- @param arg string: Unquoted argument.
-- @return string: Quoted argument.
-function Q(arg)
+function fs_lua.Q(arg)
assert(type(arg) == "string")
-- FIXME Unix-specific
- return "'" .. arg:gsub("\\", "\\\\"):gsub("'", "'\\''") .. "'"
+ return "'" .. arg:gsub("'", "'\\''") .. "'"
end
--- Test is file/dir is writable.
@@ -48,7 +49,7 @@ end
-- for checking the result of subsequent operations.
-- @param file string: filename to test
-- @return boolean: true if file exists, false otherwise.
-function is_writable(file)
+function fs_lua.is_writable(file)
assert(file)
file = dir.normalize(file)
local result
@@ -69,17 +70,27 @@ end
--- Create a temporary directory.
-- @param name string: name pattern to use for avoiding conflicts
-- when creating temporary directory.
--- @return string or nil: name of temporary directory or nil on failure.
-function make_temp_dir(name)
+-- @return string or (nil, string): name of temporary directory or (nil, error message) on failure.
+function fs_lua.make_temp_dir(name)
assert(type(name) == "string")
name = dir.normalize(name)
local temp_dir = (os.getenv("TMP") or "/tmp") .. "/luarocks_" .. name:gsub(dir.separator, "_") .. "-" .. tostring(math.floor(math.random() * 10000))
- if fs.make_dir(temp_dir) then
+ local ok, err = fs.make_dir(temp_dir)
+ if ok then
return temp_dir
else
- return nil
+ return nil, err
+ end
+end
+
+local function quote_args(command, ...)
+ local out = { command }
+ for _, arg in ipairs({...}) do
+ assert(type(arg) == "string")
+ out[#out+1] = fs.Q(arg)
end
+ return table.concat(out, " ")
end
--- Run the given command, quoting its arguments.
@@ -89,34 +100,75 @@ end
-- @param ... Strings containing additional arguments, which are quoted.
-- @return boolean: true if command succeeds (status code 0), false
-- otherwise.
-function execute(command, ...)
+function fs_lua.execute(command, ...)
assert(type(command) == "string")
+ return fs.execute_string(quote_args(command, ...))
+end
- for _, arg in ipairs({...}) do
- assert(type(arg) == "string")
- command = command .. " " .. fs.Q(arg)
+--- Run the given command, quoting its arguments, silencing its output.
+-- The command is executed in the current directory in the dir stack.
+-- Silencing is omitted if 'verbose' mode is enabled.
+-- @param command string: The command to be executed. No quoting/escaping
+-- is applied.
+-- @param ... Strings containing additional arguments, which will be quoted.
+-- @return boolean: true if command succeeds (status code 0), false
+-- otherwise.
+function fs_lua.execute_quiet(command, ...)
+ assert(type(command) == "string")
+ if cfg.verbose then -- omit silencing output
+ return fs.execute_string(quote_args(command, ...))
+ else
+ return fs.execute_string(fs.quiet(quote_args(command, ...)))
end
- return fs.execute_string(command)
end
--- Check the MD5 checksum for a file.
-- @param file string: The file to be checked.
-- @param md5sum string: The string with the expected MD5 checksum.
--- @return boolean: true if the MD5 checksum for 'file' equals 'md5sum', false if not
+-- @return boolean: true if the MD5 checksum for 'file' equals 'md5sum', false + msg if not
-- or if it could not perform the check for any reason.
-function check_md5(file, md5sum)
+function fs_lua.check_md5(file, md5sum)
file = dir.normalize(file)
- local computed = fs.get_md5(file)
+ local computed, msg = fs.get_md5(file)
if not computed then
- return false
+ return false, msg
end
if computed:match("^"..md5sum) then
return true
else
- return false
+ return false, "Mismatch MD5 hash for file "..file
end
end
+--- List the contents of a directory.
+-- @param at string or nil: directory to list (will be the current
+-- directory if none is given).
+-- @return table: an array of strings with the filenames representing
+-- the contents of a directory.
+function fs_lua.list_dir(at)
+ local result = {}
+ for file in fs.dir(at) do
+ result[#result+1] = file
+ end
+ return result
+end
+
+--- Iterate over the contents of a directory.
+-- @param at string or nil: directory to list (will be the current
+-- directory if none is given).
+-- @return function: an iterator function suitable for use with
+-- the for statement.
+function fs_lua.dir(at)
+ if not at then
+ at = fs.current_dir()
+ end
+ at = dir.normalize(at)
+ if not fs.is_dir(at) then
+ return function() end
+ end
+ return coroutine.wrap(function() fs.dir_iterator(at) end)
+end
+
---------------------------------------------------------------------
-- LuaFileSystem functions
---------------------------------------------------------------------
@@ -128,20 +180,15 @@ if lfs_ok then
-- @param cmd string: No quoting/escaping is applied to the command.
-- @return boolean: true if command succeeds (status code 0), false
-- otherwise.
-function execute_string(cmd)
- if cfg.verbose then print("Executing: "..cmd) end
+function fs_lua.execute_string(cmd)
local code = os.execute(cmd)
- if code == 0 or code == true then
- return true
- else
- return false
- end
+ return (code == 0 or code == true)
end
--- Obtain current directory.
-- Uses the module's internal dir stack.
-- @return string: the absolute pathname of the current directory.
-function current_dir()
+function fs_lua.current_dir()
return lfs.currentdir()
end
@@ -150,23 +197,23 @@ end
-- semantics of chdir, as it does not handle errors the same way,
-- but works well for our purposes for now.
-- @param d string: The directory to switch to.
-function change_dir(d)
+function fs_lua.change_dir(d)
table.insert(dir_stack, lfs.currentdir())
d = dir.normalize(d)
- lfs.chdir(d)
+ return lfs.chdir(d)
end
--- Change directory to root.
-- Allows leaving a directory (e.g. for deleting it) in
-- a crossplatform way.
-function change_dir_to_root()
+function fs_lua.change_dir_to_root()
table.insert(dir_stack, lfs.currentdir())
lfs.chdir("/") -- works on Windows too
end
--- Change working directory to the previous in the dir stack.
-- @return true if a pop ocurred, false if the stack was empty.
-function pop_dir()
+function fs_lua.pop_dir()
local d = table.remove(dir_stack)
if d then
lfs.chdir(d)
@@ -177,11 +224,11 @@ function pop_dir()
end
--- Create a directory if it does not already exist.
--- If any of the higher levels in the path name does not exist
+-- If any of the higher levels in the path name do not exist
-- too, they are created as well.
-- @param directory string: pathname of directory to create.
--- @return boolean: true on success, false on failure.
-function make_dir(directory)
+-- @return boolean or (boolean, string): true on success or (false, error message) on failure.
+function fs_lua.make_dir(directory)
assert(type(directory) == "string")
directory = dir.normalize(directory)
local path = nil
@@ -197,11 +244,12 @@ function make_dir(directory)
path = path and path .. dir.separator .. d or d
local mode = lfs.attributes(path, "mode")
if not mode then
- if not lfs.mkdir(path) then
- return false
+ local ok, err = lfs.mkdir(path)
+ if not ok then
+ return false, err
end
elseif mode ~= "directory" then
- return false
+ return false, path.." is not a directory"
end
end
return true
@@ -211,7 +259,7 @@ end
-- Does not return errors (for example, if directory is not empty or
-- if already does not exist)
-- @param d string: pathname of directory to remove.
-function remove_dir_if_empty(d)
+function fs_lua.remove_dir_if_empty(d)
assert(d)
d = dir.normalize(d)
lfs.rmdir(d)
@@ -221,7 +269,7 @@ end
-- Does not return errors (for example, if directory is not empty or
-- if already does not exist)
-- @param d string: pathname of directory to remove.
-function remove_dir_tree_if_empty(d)
+function fs_lua.remove_dir_tree_if_empty(d)
assert(d)
d = dir.normalize(d)
for i=1,10 do
@@ -237,7 +285,7 @@ end
-- or nil to use the source filename permissions
-- @return boolean or (boolean, string): true on success, false on failure,
-- plus an error message.
-function copy(src, dest, perms)
+function fs_lua.copy(src, dest, perms)
assert(src and dest)
src = dir.normalize(src)
dest = dir.normalize(dest)
@@ -274,7 +322,8 @@ local function recursive_copy(src, dest)
if not ok then return false end
elseif srcmode == "directory" then
local subdir = dir.path(dest, dir.base_name(src))
- fs.make_dir(subdir)
+ local ok, err = fs.make_dir(subdir)
+ if not ok then return nil, err end
for file in lfs.dir(src) do
if file ~= "." and file ~= ".." then
local ok = recursive_copy(dir.path(src, file), subdir)
@@ -290,7 +339,7 @@ end
-- @param dest string: Pathname of destination
-- @return boolean or (boolean, string): true on success, false on failure,
-- plus an error message.
-function copy_contents(src, dest)
+function fs_lua.copy_contents(src, dest)
assert(src and dest)
src = dir.normalize(src)
dest = dir.normalize(dest)
@@ -313,11 +362,9 @@ end
-- @return boolean or (boolean, string): true on success,
-- or nil and an error message on failure.
local function recursive_delete(name)
- local mode = lfs.attributes(name, "mode")
-
- if mode == "file" then
- return os.remove(name)
- elseif mode == "directory" then
+ local ok = os.remove(name)
+ if ok then return true end
+ local pok, ok, err = pcall(function()
for file in lfs.dir(name) do
if file ~= "." and file ~= ".." then
local ok, err = recursive_delete(dir.path(name, file))
@@ -325,40 +372,33 @@ local function recursive_delete(name)
end
end
local ok, err = lfs.rmdir(name)
- if not ok then return nil, err end
+ return ok, (not ok) and err
+ end)
+ if pok then
+ return ok, err
+ else
+ return pok, ok
end
- return true
end
--- Delete a file or a directory and all its contents.
-- @param name string: Pathname of source
--- @return boolean: true on success, false on failure.
-function delete(name)
+-- @return nil
+function fs_lua.delete(name)
name = dir.normalize(name)
- return recursive_delete(name) or false
+ recursive_delete(name)
end
---- List the contents of a directory.
--- @param at string or nil: directory to list (will be the current
--- directory if none is given).
--- @return table: an array of strings with the filenames representing
--- the contents of a directory.
-function list_dir(at)
- assert(type(at) == "string" or not at)
- if not at then
- at = fs.current_dir()
- end
- at = dir.normalize(at)
- if not fs.is_dir(at) then
- return {}
- end
- local result = {}
+--- Internal implementation function for fs.dir.
+-- Yields a filename on each iteration.
+-- @param at string: directory to list
+-- @return nil
+function fs_lua.dir_iterator(at)
for file in lfs.dir(at) do
if file ~= "." and file ~= ".." then
- table.insert(result, file)
+ coroutine.yield(file)
end
end
- return result
end
--- Implementation function for recursive find.
@@ -384,7 +424,7 @@ end
-- directory if none is given).
-- @return table: an array of strings with the filenames representing
-- the contents of a directory.
-function find(at)
+function fs_lua.find(at)
assert(type(at) == "string" or not at)
if not at then
at = fs.current_dir()
@@ -401,7 +441,7 @@ end
--- Test for existance of a file.
-- @param file string: filename to test
-- @return boolean: true if file exists, false otherwise.
-function exists(file)
+function fs_lua.exists(file)
assert(file)
file = dir.normalize(file)
return type(lfs.attributes(file)) == "table"
@@ -410,7 +450,7 @@ end
--- Test is pathname is a directory.
-- @param file string: pathname to test
-- @return boolean: true if it is a directory, false otherwise.
-function is_dir(file)
+function fs_lua.is_dir(file)
assert(file)
file = dir.normalize(file)
return lfs.attributes(file, "mode") == "directory"
@@ -419,13 +459,13 @@ end
--- Test is pathname is a regular file.
-- @param file string: pathname to test
-- @return boolean: true if it is a file, false otherwise.
-function is_file(file)
+function fs_lua.is_file(file)
assert(file)
file = dir.normalize(file)
return lfs.attributes(file, "mode") == "file"
end
-function set_time(file, time)
+function fs_lua.set_time(file, time)
file = dir.normalize(file)
return lfs.touch(file, time)
end
@@ -438,7 +478,7 @@ end
if zip_ok then
-function zip(zipfile, ...)
+function fs_lua.zip(zipfile, ...)
return lrzip.zip(zipfile, ...)
end
@@ -448,15 +488,24 @@ if unzip_ok then
--- Uncompress files from a .zip archive.
-- @param zipfile string: pathname of .zip archive to be extracted.
-- @return boolean: true on success, false on failure.
-function unzip(zipfile)
+function fs_lua.unzip(zipfile)
local zipfile, err = luazip.open(zipfile)
if not zipfile then return nil, err end
local files = zipfile:files()
local file = files()
repeat
if file.filename:sub(#file.filename) == "/" then
- fs.make_dir(dir.path(fs.current_dir(), file.filename))
+ local ok, err = fs.make_dir(dir.path(fs.current_dir(), file.filename))
+ if not ok then return nil, err end
else
+ local base = dir.dir_name(file.filename)
+ if base ~= "" then
+ base = dir.path(fs.current_dir(), base)
+ if not fs.is_dir(base) then
+ local ok, err = fs.make_dir(base)
+ if not ok then return nil, err end
+ end
+ end
local rf, err = zipfile:open(file.filename)
if not rf then zipfile:close(); return nil, err end
local contents = rf:read("*a")
@@ -482,12 +531,13 @@ if socket_ok then
local ltn12 = require("ltn12")
local luasec_ok, https = pcall(require, "ssl.https")
+
local redirect_protocols = {
http = http,
https = luasec_ok and https,
}
-local function http_request(url, http, loop_control)
+local function request(url, method, http, loop_control)
local result = {}
local proxy = cfg.proxy
@@ -497,15 +547,36 @@ local function http_request(url, http, loop_control)
proxy = "http://" .. proxy
end
+ if cfg.show_downloads then
+ io.write(method.." "..url.." ...\n")
+ end
+ local dots = 0
+ if cfg.connection_timeout and cfg.connection_timeout > 0 then
+ http.TIMEOUT = cfg.connection_timeout
+ end
local res, status, headers, err = http.request {
url = url,
proxy = proxy,
+ method = method,
redirect = false,
sink = ltn12.sink.table(result),
+ step = cfg.show_downloads and function(...)
+ io.write(".")
+ io.flush()
+ dots = dots + 1
+ if dots == 70 then
+ io.write("\n")
+ dots = 0
+ end
+ return ltn12.pump.step(...)
+ end,
headers = {
["user-agent"] = cfg.user_agent.." via LuaSocket"
},
}
+ if cfg.show_downloads then
+ io.write("\n")
+ end
if not res then
return nil, status
elseif status == 301 or status == 302 then
@@ -519,46 +590,89 @@ local function http_request(url, http, loop_control)
return nil, "Redirection loop -- broken URL?"
end
loop_control[url] = true
- return http_request(location, redirect_protocols[protocol], loop_control)
+ return request(location, method, redirect_protocols[protocol], loop_control)
else
- return nil, "URL redirected to unsupported protocol - install luasec to get HTTPS support."
+ return nil, "URL redirected to unsupported protocol - install luasec to get HTTPS support.", "https"
end
end
return nil, err
elseif status ~= 200 then
return nil, err
else
+ return result, status, headers, err
+ end
+end
+
+local function http_request(url, http, cached)
+ if cached then
+ local tsfd = io.open(cached..".timestamp", "r")
+ if tsfd then
+ local timestamp = tsfd:read("*a")
+ tsfd:close()
+ local result, status, headers, err = request(url, "HEAD", http)
+ if status == 200 and headers["last-modified"] == timestamp then
+ return true
+ end
+ if not result then
+ return nil, status, headers
+ end
+ end
+ end
+ local result, status, headers, err = request(url, "GET", http)
+ if result then
+ if cached and headers["last-modified"] then
+ local tsfd = io.open(cached..".timestamp", "w")
+ if tsfd then
+ tsfd:write(headers["last-modified"])
+ tsfd:close()
+ end
+ end
return table.concat(result)
+ else
+ return nil, status, headers
end
end
+local downloader_warning = false
+
--- Download a remote file.
-- @param url string: URL to be fetched.
-- @param filename string or nil: this function attempts to detect the
-- resulting local filename of the remote file as the basename of the URL;
-- if that is not correct (due to a redirection, for example), the local
-- filename can be given explicitly as this second argument.
--- @return boolean: true on success, false on failure.
-function download(url, filename)
+-- @return (boolean, string): true and the filename on success,
+-- false and the error message on failure.
+function fs_lua.download(url, filename, cache)
assert(type(url) == "string")
assert(type(filename) == "string" or not filename)
- filename = dir.path(fs.current_dir(), filename or dir.base_name(url))
+ filename = fs.absolute_name(filename or dir.base_name(url))
- local content, err
+ local content, err, https_err
if util.starts_with(url, "http:") then
- content, err = http_request(url, http)
+ content, err, https_err = http_request(url, http, cache and filename)
elseif util.starts_with(url, "ftp:") then
content, err = ftp.get(url)
elseif util.starts_with(url, "https:") then
if luasec_ok then
- content, err = http_request(url, https)
+ content, err = http_request(url, https, cache and filename)
else
- err = "Unsupported protocol - install luasec to get HTTPS support."
+ https_err = true
end
else
err = "Unsupported protocol"
end
+ if https_err then
+ if not downloader_warning then
+ util.printerr("Warning: falling back to "..cfg.downloader.." - install luasec to get native HTTPS support")
+ downloader_warning = true
+ end
+ return fs.use_downloader(url, filename, cache)
+ end
+ if cache and content == true then
+ return true, filename
+ end
if not content then
return false, tostring(err)
end
@@ -566,7 +680,13 @@ function download(url, filename)
if not file then return false end
file:write(content)
file:close()
- return true
+ return true, filename
+end
+
+else --...if socket_ok == false then
+
+function fs_lua.download(url, filename, cache)
+ return fs.use_downloader(url, filename, cache)
end
end
@@ -578,14 +698,15 @@ if md5_ok then
--- Get the MD5 checksum for a file.
-- @param file string: The file to be computed.
--- @return string: The MD5 checksum
-function get_md5(file)
+-- @return string: The MD5 checksum or nil + error
+function fs_lua.get_md5(file)
file = fs.absolute_name(file)
- local file = io.open(file, "rb")
- if not file then return false end
- local computed = md5.sumhexa(file:read("*a"))
- file:close()
- return computed
+ local file_handler = io.open(file, "rb")
+ if not file_handler then return nil, "Failed to open file for reading: "..file end
+ local computed = md5.sumhexa(file_handler:read("*a"))
+ file_handler:close()
+ if computed then return computed end
+ return nil, "Failed to compute MD5 hash for file "..file
end
end
@@ -607,7 +728,7 @@ local octal_to_rwx = {
["7"] = "rwx",
}
-function chmod(file, mode)
+function fs_lua.chmod(file, mode)
-- LuaPosix (as of 5.1.15) does not support octal notation...
if mode:sub(1,1) == "0" then
local new_mode = {}
@@ -620,7 +741,7 @@ function chmod(file, mode)
return err == 0
end
-function get_permissions(file)
+function fs_lua.get_permissions(file)
return posix.stat(file, "mode")
end
@@ -633,7 +754,7 @@ end
--- Apply a patch.
-- @param patchname string: The filename of the patch.
-- @param patchdata string or nil: The actual patch as a string.
-function apply_patch(patchname, patchdata)
+function fs_lua.apply_patch(patchname, patchdata)
local p, all_ok = patch.read_patch(patchname, patchdata)
if not all_ok then
return nil, "Failed reading patch "..patchname
@@ -648,7 +769,7 @@ end
-- @param dest string: Pathname of destination
-- @return boolean or (boolean, string): true on success, false on failure,
-- plus an error message.
-function move(src, dest)
+function fs_lua.move(src, dest)
assert(src and dest)
if fs.exists(dest) and not fs.is_dir(dest) then
return false, "File already exists: "..dest
@@ -657,8 +778,8 @@ function move(src, dest)
if not ok then
return false, err
end
- ok = fs.delete(src)
- if not ok then
+ fs.delete(src)
+ if fs.exists(src) then
return false, "Failed move: could not delete "..src.." after copy."
end
return true
@@ -669,7 +790,7 @@ end
-- @param flags table: the flags table passed to run() drivers.
-- @return boolean or (boolean, string): true on success, false on failure,
-- plus an error message.
-function check_command_permissions(flags)
+function fs_lua.check_command_permissions(flags)
local root_dir = path.root_dir(cfg.rocks_dir)
local ok = true
local err = ""
@@ -696,3 +817,18 @@ function check_command_permissions(flags)
return nil, err
end
end
+
+--- Check whether a file is a Lua script
+-- When the file can be succesfully compiled by the configured
+-- Lua interpreter, it's considered to be a valid Lua file.
+-- @param name filename of file to check
+-- @return boolean true, if it is a Lua script, false otherwise
+function fs_lua.is_lua(name)
+ name = name:gsub([[%\]],"/") -- normalize on fw slash to prevent escaping issues
+ local lua = fs.Q(dir.path(cfg.variables["LUA_BINDIR"], cfg.lua_interpreter)) -- get lua interpreter configured
+ -- execute on configured interpreter, might not be the same as the interpreter LR is run on
+ local result = fs.execute_string(lua..[[ -e "if loadfile(']]..name..[[') then os.exit() else os.exit(1) end"]])
+ return (result == true)
+end
+
+return fs_lua
diff --git a/luarocks/src/luarocks/fs/unix.lua b/luarocks/src/luarocks/fs/unix.lua
index cccbbd3..6ad5a67 100644
--- a/luarocks/src/luarocks/fs/unix.lua
+++ b/luarocks/src/luarocks/fs/unix.lua
@@ -1,16 +1,12 @@
--- Unix implementation of filesystem and platform abstractions.
-
-local assert, type, table, io, package, math, os, ipairs =
- assert, type, table, io, package, math, os, ipairs
-
-module("luarocks.fs.unix", package.seeall)
+--module("luarocks.fs.unix", package.seeall)
+local unix = {}
local fs = require("luarocks.fs")
local cfg = require("luarocks.cfg")
local dir = require("luarocks.dir")
-local fs = require("luarocks.fs")
local util = require("luarocks.util")
math.randomseed(os.time())
@@ -18,7 +14,7 @@ math.randomseed(os.time())
--- Annotate command string for quiet execution.
-- @param cmd string: A command-line string.
-- @return string: The command-line, with silencing annotation.
-function quiet(cmd)
+function unix.quiet(cmd)
return cmd.." 1> /dev/null 2> /dev/null"
end
@@ -28,7 +24,7 @@ end
-- pathname absolute, or the current dir in the dir stack if
-- not given.
-- @return string: The pathname converted to absolute.
-function absolute_name(pathname, relative_to)
+function unix.absolute_name(pathname, relative_to)
assert(type(pathname) == "string")
assert(type(relative_to) == "string" or not relative_to)
@@ -47,21 +43,22 @@ end
-- @param version string: rock version to be used in loader context.
-- @return boolean or (nil, string): True if succeeded, or nil and
-- an error message.
-function wrap_script(file, dest, name, version)
+function unix.wrap_script(file, dest, name, version)
assert(type(file) == "string")
assert(type(dest) == "string")
local base = dir.base_name(file)
local wrapname = fs.is_dir(dest) and dest.."/"..base or dest
+ local lpath, lcpath = cfg.package_paths()
local wrapper = io.open(wrapname, "w")
if not wrapper then
return nil, "Could not open "..wrapname.." for writing."
end
wrapper:write("#!/bin/sh\n\n")
- wrapper:write('LUA_PATH="'..package.path..';$LUA_PATH"\n')
- wrapper:write('LUA_CPATH="'..package.cpath..';$LUA_CPATH"\n')
- wrapper:write('export LUA_PATH LUA_CPATH\n')
- wrapper:write('exec "'..dir.path(cfg.variables["LUA_BINDIR"], cfg.lua_interpreter)..'" -lluarocks.loader -e\'luarocks.loader.add_context([['..name..']],[['..version..']])\' "'..file..'" "$@"\n')
+ local lua = dir.path(cfg.variables["LUA_BINDIR"], cfg.lua_interpreter)
+ local ppaths = "package.path="..util.LQ(lpath..";").."..package.path; package.cpath="..util.LQ(lcpath..";").."..package.cpath"
+ local addctx = "local k,l,_=pcall(require,"..util.LQ("luarocks.loader")..") _=k and l.add_context("..util.LQ(name)..","..util.LQ(version)..")"
+ wrapper:write('exec '..fs.Q(lua)..' -e '..fs.Q(ppaths)..' -e '..fs.Q(addctx)..' '..fs.Q(file)..' "$@"\n')
wrapper:close()
if fs.chmod(wrapname, "0755") then
return true
@@ -75,7 +72,7 @@ end
-- @param filename string: the file name with full path.
-- @return boolean: returns true if file is an actual binary
-- (or if it couldn't check) or false if it is a Lua wrapper.
-function is_actual_binary(filename)
+function unix.is_actual_binary(filename)
if filename:match("%.lua$") then
return false
end
@@ -92,7 +89,7 @@ function is_actual_binary(filename)
return first ~= "#!"
end
-function copy_binary(filename, dest)
+function unix.copy_binary(filename, dest)
return fs.copy(filename, dest, "0755")
end
@@ -106,6 +103,12 @@ end
-- which will replace old_file.
-- @return boolean or (nil, string): True if succeeded, or nil and
-- an error message.
-function replace_file(old_file, new_file)
+function unix.replace_file(old_file, new_file)
return os.rename(new_file, old_file)
end
+
+function unix.tmpname()
+ return os.tmpname()
+end
+
+return unix
diff --git a/luarocks/src/luarocks/fs/unix/tools.lua b/luarocks/src/luarocks/fs/unix/tools.lua
index 3b853be..f36e815 100644
--- a/luarocks/src/luarocks/fs/unix/tools.lua
+++ b/luarocks/src/luarocks/fs/unix/tools.lua
@@ -1,6 +1,7 @@
--- fs operations implemented with third-party tools for Unix platform abstractions.
-module("luarocks.fs.unix.tools", package.seeall)
+--module("luarocks.fs.unix.tools", package.seeall)
+local tools = {}
local fs = require("luarocks.fs")
local dir = require("luarocks.dir")
@@ -17,10 +18,14 @@ end
--- Obtain current directory.
-- Uses the module's internal directory stack.
-- @return string: the absolute pathname of the current directory.
-function current_dir()
- local pipe = io.popen(vars.PWD)
- local current = pipe:read("*l")
- pipe:close()
+function tools.current_dir()
+ local current = cfg.cache_pwd
+ if not current then
+ local pipe = io.popen(fs.Q(vars.PWD))
+ current = pipe:read("*l")
+ pipe:close()
+ cfg.cache_pwd = current
+ end
for _, directory in ipairs(dir_stack) do
current = fs.absolute_name(directory, current)
end
@@ -32,8 +37,8 @@ end
-- @param cmd string: No quoting/escaping is applied to the command.
-- @return boolean: true if command succeeds (status code 0), false
-- otherwise.
-function execute_string(cmd)
- local code = os.execute(command_at(fs.current_dir(), cmd))
+function tools.execute_string(cmd)
+ local code, err = os.execute(command_at(fs.current_dir(), cmd))
if code == 0 or code == true then
return true
else
@@ -46,20 +51,24 @@ end
-- semantics of chdir, as it does not handle errors the same way,
-- but works well for our purposes for now.
-- @param directory string: The directory to switch to.
-function change_dir(directory)
+function tools.change_dir(directory)
assert(type(directory) == "string")
- table.insert(dir_stack, directory)
+ if fs.is_dir(directory) then
+ table.insert(dir_stack, directory)
+ return true
+ end
+ return nil, "directory not found: "..directory
end
--- Change directory to root.
-- Allows leaving a directory (e.g. for deleting it) in
-- a crossplatform way.
-function change_dir_to_root()
+function tools.change_dir_to_root()
table.insert(dir_stack, "/")
end
--- Change working directory to the previous in the directory stack.
-function pop_dir()
+function tools.pop_dir()
local directory = table.remove(dir_stack)
return directory ~= nil
end
@@ -69,27 +78,31 @@ end
-- too, they are created as well.
-- @param directory string: pathname of directory to create.
-- @return boolean: true on success, false on failure.
-function make_dir(directory)
+function tools.make_dir(directory)
assert(directory)
- return fs.execute(vars.MKDIR.." -p", directory)
+ local ok, err = fs.execute(vars.MKDIR.." -p", directory)
+ if not ok then
+ err = "failed making directory "..directory
+ end
+ return ok, err
end
--- Remove a directory if it is empty.
-- Does not return errors (for example, if directory is not empty or
-- if already does not exist)
-- @param directory string: pathname of directory to remove.
-function remove_dir_if_empty(directory)
+function tools.remove_dir_if_empty(directory)
assert(directory)
- fs.execute_string(fs.quiet(vars.RMDIR.." "..fs.Q(directory)))
+ fs.execute_quiet(vars.RMDIR, directory)
end
--- Remove a directory if it is empty.
-- Does not return errors (for example, if directory is not empty or
-- if already does not exist)
-- @param directory string: pathname of directory to remove.
-function remove_dir_tree_if_empty(directory)
+function tools.remove_dir_tree_if_empty(directory)
assert(directory)
- fs.execute_string(fs.quiet(vars.RMDIR.." -p "..fs.Q(directory)))
+ fs.execute_quiet(vars.RMDIR, "-p", directory)
end
--- Copy a file.
@@ -98,7 +111,7 @@ end
-- @param perm string or nil: Permissions for destination file,
-- @return boolean or (boolean, string): true on success, false on failure,
-- plus an error message.
-function copy(src, dest, perm)
+function tools.copy(src, dest, perm)
assert(src and dest)
if fs.execute(vars.CP, src, dest) then
if perm then
@@ -122,9 +135,9 @@ end
-- @param dest string: Pathname of destination
-- @return boolean or (boolean, string): true on success, false on failure,
-- plus an error message.
-function copy_contents(src, dest)
+function tools.copy_contents(src, dest)
assert(src and dest)
- if fs.execute_string(fs.quiet(vars.CP.." -pPR "..fs.Q(src).."/* "..fs.Q(dest))) then
+ if fs.execute_quiet(vars.CP.." -pPR "..fs.Q(src).."/* "..fs.Q(dest)) then
return true
else
return false, "Failed copying "..src.." to "..dest
@@ -133,33 +146,25 @@ end
--- Delete a file or a directory and all its contents.
-- For safety, this only accepts absolute paths.
-- @param arg string: Pathname of source
--- @return boolean: true on success, false on failure.
-function delete(arg)
+-- @return nil
+function tools.delete(arg)
assert(arg)
assert(arg:sub(1,1) == "/")
- return fs.execute_string(fs.quiet(vars.RM.." -rf " .. fs.Q(arg)))
+ fs.execute_quiet(vars.RM, "-rf", arg)
end
---- List the contents of a directory.
--- @param at string or nil: directory to list (will be the current
--- directory if none is given).
--- @return table: an array of strings with the filenames representing
--- the contents of a directory.
-function list_dir(at)
- assert(type(at) == "string" or not at)
- if not at then
- at = fs.current_dir()
- end
- if not fs.is_dir(at) then
- return {}
- end
- local result = {}
+--- Internal implementation function for fs.dir.
+-- Yields a filename on each iteration.
+-- @param at string: directory to list
+-- @return nil
+function tools.dir_iterator(at)
local pipe = io.popen(command_at(at, vars.LS))
for file in pipe:lines() do
- table.insert(result, file)
+ if file ~= "." and file ~= ".." then
+ coroutine.yield(file)
+ end
end
pipe:close()
- return result
end
--- Recursively scan the contents of a directory.
@@ -167,7 +172,7 @@ end
-- directory if none is given).
-- @return table: an array of strings with the filenames representing
-- the contents of a directory.
-function find(at)
+function tools.find(at)
assert(type(at) == "string" or not at)
if not at then
at = fs.current_dir()
@@ -189,22 +194,22 @@ end
-- @param ... Filenames to be stored in the archive are given as
-- additional arguments.
-- @return boolean: true on success, false on failure.
-function zip(zipfile, ...)
+function tools.zip(zipfile, ...)
return fs.execute(vars.ZIP.." -r", zipfile, ...)
end
--- Uncompress files from a .zip archive.
-- @param zipfile string: pathname of .zip archive to be extracted.
-- @return boolean: true on success, false on failure.
-function unzip(zipfile)
+function tools.unzip(zipfile)
assert(zipfile)
- return fs.execute(vars.UNZIP, zipfile)
+ return fs.execute_quiet(vars.UNZIP, zipfile)
end
--- Test is file/directory exists
-- @param file string: filename to test
-- @return boolean: true if file exists, false otherwise.
-function exists(file)
+function tools.exists(file)
assert(file)
return fs.execute(vars.TEST, "-e", file)
end
@@ -212,7 +217,7 @@ end
--- Test is pathname is a directory.
-- @param file string: pathname to test
-- @return boolean: true if it is a directory, false otherwise.
-function is_dir(file)
+function tools.is_dir(file)
assert(file)
return fs.execute(vars.TEST, "-d", file)
end
@@ -220,7 +225,7 @@ end
--- Test is pathname is a regular file.
-- @param file string: pathname to test
-- @return boolean: true if it is a regular file, false otherwise.
-function is_file(file)
+function tools.is_file(file)
assert(file)
return fs.execute(vars.TEST, "-f", file)
end
@@ -231,25 +236,46 @@ end
-- resulting local filename of the remote file as the basename of the URL;
-- if that is not correct (due to a redirection, for example), the local
-- filename can be given explicitly as this second argument.
--- @return boolean: true on success, false on failure.
-function download(url, filename)
+-- @return (boolean, string): true and the filename on success,
+-- false and the error message on failure.
+function tools.use_downloader(url, filename, cache)
assert(type(url) == "string")
assert(type(filename) == "string" or not filename)
+ filename = fs.absolute_name(filename or dir.base_name(url))
+
+ local ok
if cfg.downloader == "wget" then
- local wget_cmd = vars.WGET.." --no-check-certificate --no-cache --user-agent='"..cfg.user_agent.." via wget' --quiet --continue "
- if filename then
- return fs.execute(wget_cmd.." --output-document ", filename, url)
+ local wget_cmd = fs.Q(vars.WGET).." --no-check-certificate --no-cache --user-agent='"..cfg.user_agent.." via wget' --quiet "
+ if cfg.connection_timeout and cfg.connection_timeout > 0 then
+ wget_cmd = wget_cmd .. "--timeout="..tonumber(cfg.connection_timeout).." --tries=1 "
+ end
+ if cache then
+ -- --timestamping is incompatible with --output-document,
+ -- but that's not a problem for our use cases.
+ fs.change_dir(dir.dir_name(filename))
+ ok = fs.execute_quiet(wget_cmd.." --timestamping ", url)
+ fs.pop_dir()
+ elseif filename then
+ ok = fs.execute_quiet(wget_cmd.." --output-document ", filename, url)
else
- return fs.execute(wget_cmd, url)
+ ok = fs.execute_quiet(wget_cmd, url)
end
elseif cfg.downloader == "curl" then
- filename = filename or dir.base_name(url)
- return fs.execute_string(vars.CURL.." -L --user-agent '"..cfg.user_agent.." via curl' "..fs.Q(url).." 2> /dev/null 1> "..fs.Q(filename))
+ local curl_cmd = fs.Q(vars.CURL).." -f -k -L --user-agent '"..cfg.user_agent.." via curl' "
+ if cfg.connection_timeout and cfg.connection_timeout > 0 then
+ curl_cmd = curl_cmd .. "--connect-timeout "..tonumber(cfg.connection_timeout).." "
+ end
+ ok = fs.execute_string(curl_cmd..fs.Q(url).." 2> /dev/null 1> "..fs.Q(filename))
+ end
+ if ok then
+ return true, filename
+ else
+ return false
end
end
-function chmod(pathname, mode)
+function tools.chmod(pathname, mode)
if mode then
return fs.execute(vars.CHMOD, mode, pathname)
else
@@ -259,7 +285,7 @@ end
--- Apply a patch.
-- @param patchname string: The filename of the patch.
-function apply_patch(patchname)
+function tools.apply_patch(patchname)
return fs.execute(vars.PATCH.." -p1 -f -i ", patchname)
end
@@ -268,7 +294,7 @@ end
-- filename extension.
-- @param archive string: Filename of archive.
-- @return boolean or (boolean, string): true on success, false and an error message on failure.
-function unpack_archive(archive)
+function tools.unpack_archive(archive)
assert(type(archive) == "string")
local ok
@@ -300,19 +326,28 @@ local md5_cmd = {
--- Get the MD5 checksum for a file.
-- @param file string: The file to be computed.
-- @return string: The MD5 checksum
-function get_md5(file)
+function tools.get_md5(file)
local cmd = md5_cmd[cfg.md5checker]
- if not cmd then return nil end
- local pipe = io.popen(cmd.." "..fs.absolute_name(file))
+ if not cmd then return nil, "no MD5 checker command configured" end
+ local pipe = io.popen(cmd.." "..fs.Q(fs.absolute_name(file)))
local computed = pipe:read("*a")
pipe:close()
- if not computed then return nil end
- return computed:match("("..("%x"):rep(32)..")")
+ if computed then
+ computed = computed:match("("..("%x"):rep(32)..")")
+ end
+ if computed then return computed end
+ return nil, "Failed to compute MD5 hash for file "..tostring(fs.absolute_name(file))
end
-function get_permissions(filename)
+function tools.get_permissions(filename)
local pipe = io.popen(vars.STAT.." "..vars.STATFLAG.." "..fs.Q(filename))
local ret = pipe:read("*l")
pipe:close()
return ret
end
+
+function tools.browser(url)
+ return fs.execute(cfg.web_browser, url)
+end
+
+return tools
diff --git a/luarocks/src/luarocks/fs/win32.lua b/luarocks/src/luarocks/fs/win32.lua
index 2b5bb95..12d86d1 100644
--- a/luarocks/src/luarocks/fs/win32.lua
+++ b/luarocks/src/luarocks/fs/win32.lua
@@ -1,32 +1,84 @@
--- Windows implementation of filesystem and platform abstractions.
-- Download http://unxutils.sourceforge.net/ for Windows GNU utilities
-- used by this module.
-module("luarocks.fs.win32", package.seeall)
+--module("luarocks.fs.win32", package.seeall)
+local win32 = {}
local fs = require("luarocks.fs")
local cfg = require("luarocks.cfg")
local dir = require("luarocks.dir")
+local util = require("luarocks.util")
+
+-- Monkey patch io.popen and os.execute to make sure quoting
+-- works as expected.
+-- See http://lua-users.org/lists/lua-l/2013-11/msg00367.html
+local _prefix = "type NUL && "
+local _popen, _execute = io.popen, os.execute
+io.popen = function(cmd, ...) return _popen(_prefix..cmd, ...) end
+os.execute = function(cmd, ...) return _execute(_prefix..cmd, ...) end
+
--- Annotate command string for quiet execution.
-- @param cmd string: A command-line string.
-- @return string: The command-line, with silencing annotation.
-function quiet(cmd)
+function win32.quiet(cmd)
return cmd.." 2> NUL 1> NUL"
end
+
+local win_escape_chars = {
+ ["%"] = "%%",
+ ['"'] = '\\"',
+}
+
+local function q_escaper(bs, q)
+ return ("\\"):rep(2*#bs-1) .. (q or "\\")
+end
+
+local function p_escaper(bs)
+ return bs .. bs .. '"%"'
+end
+
--- Quote argument for shell processing. Fixes paths on Windows.
--- Adds single quotes and escapes.
+-- Adds double quotes and escapes.
-- @param arg string: Unquoted argument.
-- @return string: Quoted argument.
-function Q(arg)
+function win32.Q(arg)
assert(type(arg) == "string")
-- Quote DIR for Windows
- if arg:match("^[%.a-zA-Z]?:?[\\/]") then
- return '"' .. arg:gsub("/", "\\"):gsub('"', '\\"') .. '"'
- end
+ if arg:match("^[%.a-zA-Z]?:?[\\/]") then
+ arg = arg:gsub("/", "\\")
+ end
+ if arg == "\\" then
+ return '\\' -- CHDIR needs special handling for root dir
+ end
-- URLs and anything else
- return '"' .. arg:gsub('"', '\\"') .. '"'
+ arg = arg:gsub('(\\+)(")', q_escaper)
+ arg = arg:gsub('(\\+)$', q_escaper)
+ arg = arg:gsub('"', win_escape_chars)
+ arg = arg:gsub('(\\*)%%', p_escaper)
+ return '"' .. arg .. '"'
+end
+
+--- Quote argument for shell processing in batch files.
+-- Adds double quotes and escapes.
+-- @param arg string: Unquoted argument.
+-- @return string: Quoted argument.
+function win32.Qb(arg)
+ assert(type(arg) == "string")
+ -- Quote DIR for Windows
+ if arg:match("^[%.a-zA-Z]?:?[\\/]") then
+ arg = arg:gsub("/", "\\")
+ end
+ if arg == "\\" then
+ return '\\' -- CHDIR needs special handling for root dir
+ end
+ -- URLs and anything else
+ arg = arg:gsub('(\\+)(")', q_escaper)
+ arg = arg:gsub('(\\+)$', q_escaper)
+ arg = arg:gsub('[%%"]', win_escape_chars)
+ return '"' .. arg .. '"'
end
--- Return an absolute pathname from a potentially relative one.
@@ -35,7 +87,7 @@ end
-- pathname absolute, or the current dir in the dir stack if
-- not given.
-- @return string: The pathname converted to absolute.
-function absolute_name(pathname, relative_to)
+function win32.absolute_name(pathname, relative_to)
assert(type(pathname) == "string")
assert(type(relative_to) == "string" or not relative_to)
@@ -56,28 +108,28 @@ end
-- @param version string: rock version to be used in loader context.
-- @return boolean or (nil, string): True if succeeded, or nil and
-- an error message.
-function wrap_script(file, dest, name, version)
+function win32.wrap_script(file, dest, name, version)
assert(type(file) == "string")
assert(type(dest) == "string")
local base = dir.base_name(file)
local wrapname = fs.is_dir(dest) and dest.."/"..base or dest
wrapname = wrapname..".bat"
+ local lpath, lcpath = cfg.package_paths()
local wrapper = io.open(wrapname, "w")
if not wrapper then
return nil, "Could not open "..wrapname.." for writing."
end
wrapper:write("@echo off\n")
- wrapper:write("setlocal\n")
- wrapper:write('set LUA_PATH='..package.path..";%LUA_PATH%\n")
- wrapper:write('set LUA_CPATH='..package.cpath..";%LUA_CPATH%\n")
- wrapper:write('"'..dir.path(cfg.variables["LUA_BINDIR"], cfg.lua_interpreter)..'" -lluarocks.loader -e\'luarocks.loader.add_context([['..name..']],[['..version..']])\' "'..file..'" %*\n')
- wrapper:write("endlocal\n")
+ local lua = dir.path(cfg.variables["LUA_BINDIR"], cfg.lua_interpreter)
+ local ppaths = "package.path="..util.LQ(lpath..";").."..package.path; package.cpath="..util.LQ(lcpath..";").."..package.cpath"
+ local addctx = "local k,l,_=pcall(require,"..util.LQ("luarocks.loader")..") _=k and l.add_context("..util.LQ(name)..","..util.LQ(version)..")"
+ wrapper:write(fs.Qb(lua)..' -e '..fs.Qb(ppaths)..' -e '..fs.Qb(addctx)..' '..fs.Qb(file)..' %*\n')
wrapper:close()
return true
end
-function is_actual_binary(name)
+function win32.is_actual_binary(name)
name = name:lower()
if name:match("%.bat$") or name:match("%.exe$") then
return true
@@ -85,14 +137,14 @@ function is_actual_binary(name)
return false
end
-function copy_binary(filename, dest)
+function win32.copy_binary(filename, dest)
local ok, err = fs.copy(filename, dest)
if not ok then
return nil, err
end
local exe_pattern = "%.[Ee][Xx][Ee]$"
local base = dir.base_name(filename)
- local dest = dir.dir_name(dest)
+ dest = dir.dir_name(dest)
if base:match(exe_pattern) then
base = base:gsub(exe_pattern, ".lua")
local helpname = dest.."/"..base
@@ -107,11 +159,11 @@ function copy_binary(filename, dest)
return true
end
-function chmod(filename, mode)
+function win32.chmod(filename, mode)
return true
end
-function get_permissions(filename)
+function win32.get_permissions(filename)
return ""
end
@@ -126,8 +178,44 @@ end
-- which will replace old_file.
-- @return boolean or (nil, string): True if succeeded, or nil and
-- an error message.
-function replace_file(old_file, new_file)
+function win32.replace_file(old_file, new_file)
os.remove(old_file)
return os.rename(new_file, old_file)
end
+--- Test is file/dir is writable.
+-- Warning: testing if a file/dir is writable does not guarantee
+-- that it will remain writable and therefore it is no replacement
+-- for checking the result of subsequent operations.
+-- @param file string: filename to test
+-- @return boolean: true if file exists, false otherwise.
+function win32.is_writable(file)
+ assert(file)
+ file = dir.normalize(file)
+ local result
+ local tmpname = 'tmpluarockstestwritable.deleteme'
+ if fs.is_dir(file) then
+ local file2 = dir.path(file, tmpname)
+ local fh = io.open(file2, 'wb')
+ result = fh ~= nil
+ if fh then fh:close() end
+ if result then
+ -- the above test might give a false positive when writing to
+ -- c:\program files\ because of VirtualStore redirection on Vista and up
+ -- So check whether it's really there
+ result = fs.exists(file2)
+ end
+ os.remove(file2)
+ else
+ local fh = io.open(file, 'r+b')
+ result = fh ~= nil
+ if fh then fh:close() end
+ end
+ return result
+end
+
+function win32.tmpname()
+ return os.getenv("TMP")..os.tmpname()
+end
+
+return win32
diff --git a/luarocks/src/luarocks/fs/win32/tools.lua b/luarocks/src/luarocks/fs/win32/tools.lua
index 1af1dd9..f970f36 100644
--- a/luarocks/src/luarocks/fs/win32/tools.lua
+++ b/luarocks/src/luarocks/fs/win32/tools.lua
@@ -2,7 +2,8 @@
--- fs operations implemented with third-party tools for Windows platform abstractions.
-- Download http://unxutils.sourceforge.net/ for Windows GNU utilities
-- used by this module.
-module("luarocks.fs.win32.tools", package.seeall)
+--module("luarocks.fs.win32.tools", package.seeall)
+local tools = {}
local fs = require("luarocks.fs")
local dir = require("luarocks.dir")
@@ -12,10 +13,6 @@ local dir_stack = {}
local vars = cfg.variables
-local function pack(...)
- return { n = select("#", ...), ... }
-end
-
--- Strip the last extension of a filename.
-- Example: "foo.tar.gz" becomes "foo.tar".
-- If filename has no dots, returns it unchanged.
@@ -39,10 +36,14 @@ end
--- Obtain current directory.
-- Uses the module's internal directory stack.
-- @return string: the absolute pathname of the current directory.
-function current_dir()
- local pipe = io.popen(vars.PWD)
- local current = pipe:read("*l")
- pipe:close()
+function tools.current_dir()
+ local current = cfg.cache_pwd
+ if not current then
+ local pipe = io.popen(fs.Q(vars.PWD))
+ current = pipe:read("*l")
+ pipe:close()
+ cfg.cache_pwd = current
+ end
for _, directory in ipairs(dir_stack) do
current = fs.absolute_name(directory, current)
end
@@ -54,18 +55,10 @@ end
-- @param cmd string: No quoting/escaping is applied to the command.
-- @return boolean: true if command succeeds (status code 0), false
-- otherwise.
-function execute_string(cmd)
+function tools.execute_string(cmd)
cmd = command_at(fs.current_dir(), cmd)
- if cfg.verbose then print("Executing: "..tostring(cmd)) end
- local code = pack(os.execute(cmd))
- if cfg.verbose then
- print("Results: "..tostring(code.n))
- for i = 1,code.n do
- print(" "..tostring(i).." ("..type(code[i]).."): "..tostring(code[i]))
- end
- print()
- end
- if code[1] == 0 or code[1] == true then
+ local code = os.execute(cmd)
+ if code == 0 or code == true then
return true
else
return false
@@ -77,20 +70,25 @@ end
-- semantics of chdir, as it does not handle errors the same way,
-- but works well for our purposes for now.
-- @param directory string: The directory to switch to.
-function change_dir(directory)
+-- @return boolean or (nil, string): true if successful, (nil, error message) if failed.
+function tools.change_dir(directory)
assert(type(directory) == "string")
- table.insert(dir_stack, directory)
+ if fs.is_dir(directory) then
+ table.insert(dir_stack, directory)
+ return true
+ end
+ return nil, "directory not found: "..directory
end
--- Change directory to root.
-- Allows leaving a directory (e.g. for deleting it) in
-- a crossplatform way.
-function change_dir_to_root()
+function tools.change_dir_to_root()
table.insert(dir_stack, "/")
end
--- Change working directory to the previous in the directory stack.
-function pop_dir()
+function tools.pop_dir()
local directory = table.remove(dir_stack)
return directory ~= nil
end
@@ -100,28 +98,32 @@ end
-- too, they are created as well.
-- @param directory string: pathname of directory to create.
-- @return boolean: true on success, false on failure.
-function make_dir(directory)
+function tools.make_dir(directory)
assert(directory)
- fs.execute(fs.quiet(vars.MKDIR.." "..fs.Q(directory)))
- return 1
+ directory = dir.normalize(directory)
+ fs.execute_quiet(fs.Q(vars.MKDIR).." -p ", directory)
+ if not fs.is_dir(directory) then
+ return false, "failed making directory "..directory
+ end
+ return true
end
--- Remove a directory if it is empty.
-- Does not return errors (for example, if directory is not empty or
-- if already does not exist)
-- @param directory string: pathname of directory to remove.
-function remove_dir_if_empty(directory)
+function tools.remove_dir_if_empty(directory)
assert(directory)
- fs.execute_string(fs.quiet(vars.RMDIR.." "..fs.Q(directory)))
+ fs.execute_quiet(fs.Q(vars.RMDIR), directory)
end
--- Remove a directory if it is empty.
-- Does not return errors (for example, if directory is not empty or
-- if already does not exist)
-- @param directory string: pathname of directory to remove.
-function remove_dir_tree_if_empty(directory)
+function tools.remove_dir_tree_if_empty(directory)
assert(directory)
- fs.execute_string(fs.quiet(vars.RMDIR.." "..fs.Q(directory)))
+ fs.execute_quiet(fs.Q(vars.RMDIR), directory)
end
--- Copy a file.
@@ -129,10 +131,11 @@ end
-- @param dest string: Pathname of destination
-- @return boolean or (boolean, string): true on success, false on failure,
-- plus an error message.
-function copy(src, dest)
+function tools.copy(src, dest)
assert(src and dest)
if dest:match("[/\\]$") then dest = dest:sub(1, -2) end
- if fs.execute(vars.CP, src, dest) then
+ local ok = fs.execute(fs.Q(vars.CP), src, dest)
+ if ok then
return true
else
return false, "Failed copying "..src.." to "..dest
@@ -144,9 +147,9 @@ end
-- @param dest string: Pathname of destination
-- @return boolean or (boolean, string): true on success, false on failure,
-- plus an error message.
-function copy_contents(src, dest)
+function tools.copy_contents(src, dest)
assert(src and dest)
- if fs.execute_string(fs.quiet(vars.CP.." -dR "..src.."\\*.* "..fs.Q(dest))) then
+ if fs.execute_quiet(fs.Q(vars.CP).." -dR "..src.."\\*.* "..fs.Q(dest)) then
return true
else
return false, "Failed copying "..src.." to "..dest
@@ -156,35 +159,25 @@ end
--- Delete a file or a directory and all its contents.
-- For safety, this only accepts absolute paths.
-- @param arg string: Pathname of source
--- @return boolean: true on success, false on failure.
-function delete(arg)
+-- @return nil
+function tools.delete(arg)
assert(arg)
- assert(arg:match("^[\a-zA-Z]?:?[\\/]"))
- fs.execute(vars.CHMOD.." a+rw -R ", arg)
- return fs.execute_string(fs.quiet(vars.RM.." -rf " .. fs.Q(arg)))
+ assert(arg:match("^[a-zA-Z]?:?[\\/]"))
+ fs.execute_quiet("if exist "..fs.Q(arg.."\\").." ( RMDIR /S /Q "..fs.Q(arg).." ) else ( DEL /Q /F "..fs.Q(arg).." )")
end
---- List the contents of a directory.
--- @param at string or nil: directory to list (will be the current
--- directory if none is given).
--- @return table: an array of strings with the filenames representing
--- the contents of a directory.
-function list_dir(at)
- assert(type(at) == "string" or not at)
- if not at then
- at = fs.current_dir()
- end
- if not fs.is_dir(at) then
- return {}
- end
- local result = {}
- local pipe = io.popen(command_at(at, vars.LS))
+--- Internal implementation function for fs.dir.
+-- Yields a filename on each iteration.
+-- @param at string: directory to list
+-- @return nil
+function tools.dir_iterator(at)
+ local pipe = io.popen(command_at(at, fs.Q(vars.LS)))
for file in pipe:lines() do
- table.insert(result, file)
+ if file ~= "." and file ~= ".." then
+ coroutine.yield(file)
+ end
end
pipe:close()
-
- return result
end
--- Recursively scan the contents of a directory.
@@ -192,7 +185,7 @@ end
-- directory if none is given).
-- @return table: an array of strings with the filenames representing
-- the contents of a directory. Paths are returned with forward slashes.
-function find(at)
+function tools.find(at)
assert(type(at) == "string" or not at)
if not at then
at = fs.current_dir()
@@ -201,7 +194,7 @@ function find(at)
return {}
end
local result = {}
- local pipe = io.popen(command_at(at, vars.FIND.." 2> NUL"))
+ local pipe = io.popen(command_at(at, fs.Q(vars.FIND).." 2> NUL"))
for file in pipe:lines() do
-- Windows find is a bit different
local first_two = file:sub(1,2)
@@ -219,32 +212,32 @@ end
-- @param ... Filenames to be stored in the archive are given as
-- additional arguments.
-- @return boolean: true on success, false on failure.
-function zip(zipfile, ...)
- return fs.execute(vars.SEVENZ.." a -tzip", zipfile, ...)
+function tools.zip(zipfile, ...)
+ return fs.execute_quiet(fs.Q(vars.SEVENZ).." -aoa a -tzip", zipfile, ...)
end
--- Uncompress files from a .zip archive.
-- @param zipfile string: pathname of .zip archive to be extracted.
-- @return boolean: true on success, false on failure.
-function unzip(zipfile)
+function tools.unzip(zipfile)
assert(zipfile)
- return fs.execute(vars.SEVENZ.." x", zipfile)
+ return fs.execute_quiet(fs.Q(vars.SEVENZ).." -aoa x", zipfile)
end
--- Test is pathname is a directory.
-- @param file string: pathname to test
-- @return boolean: true if it is a directory, false otherwise.
-function is_dir(file)
+function tools.is_dir(file)
assert(file)
- return fs.execute(fs.quiet(vars.TEST.." -d " .. fs.Q(file)))
+ return fs.execute_quiet("if not exist " .. fs.Q(file.."\\").." invalidcommandname")
end
--- Test is pathname is a regular file.
-- @param file string: pathname to test
-- @return boolean: true if it is a regular file, false otherwise.
-function is_file(file)
+function tools.is_file(file)
assert(file)
- return fs.execute(vars.TEST.." -f", file)
+ return fs.execute(fs.Q(vars.TEST).." -f", file)
end
--- Download a remote file.
@@ -253,21 +246,42 @@ end
-- resulting local filename of the remote file as the basename of the URL;
-- if that is not correct (due to a redirection, for example), the local
-- filename can be given explicitly as this second argument.
--- @return boolean: true on success, false on failure.
-function download(url, filename)
+-- @return (boolean, string): true and the filename on success,
+-- false and the error message on failure.
+function tools.use_downloader(url, filename, cache)
assert(type(url) == "string")
assert(type(filename) == "string" or not filename)
+ filename = fs.absolute_name(filename or dir.base_name(url))
+
+ local ok
if cfg.downloader == "wget" then
- local wget_cmd = vars.WGET.." --no-check-certificate --no-cache --user-agent=\""..cfg.user_agent.." via wget\" --quiet --continue "
- if filename then
- return fs.execute(wget_cmd.." --output-document ", filename, url)
+ local wget_cmd = fs.Q(vars.WGET).." --no-check-certificate --no-cache --user-agent=\""..cfg.user_agent.." via wget\" --quiet "
+ if cfg.connection_timeout and cfg.connection_timeout > 0 then
+ wget_cmd = wget_cmd .. "--timeout="..tonumber(cfg.connection_timeout).." --tries=1 "
+ end
+ if cache then
+ -- --timestamping is incompatible with --output-document,
+ -- but that's not a problem for our use cases.
+ fs.change_dir(dir.dir_name(filename))
+ ok = fs.execute_quiet(wget_cmd.." --timestamping ", url)
+ fs.pop_dir()
+ elseif filename then
+ ok = fs.execute_quiet(wget_cmd.." --output-document ", filename, url)
else
- return fs.execute(wget_cmd, url)
+ ok = fs.execute_quiet(wget_cmd, url)
end
elseif cfg.downloader == "curl" then
- filename = filename or dir.base_name(url)
- return fs.execute_string(vars.CURL.." -L --user-agent \""..cfg.user_agent.." via curl\" "..fs.Q(url).." 2> NUL 1> "..fs.Q(filename))
+ local curl_cmd = vars.CURL.." -f -k -L --user-agent \""..cfg.user_agent.." via curl\" "
+ if cfg.connection_timeout and cfg.connection_timeout > 0 then
+ curl_cmd = curl_cmd .. "--connect-timeout "..tonumber(cfg.connection_timeout).." "
+ end
+ ok = fs.execute_string(curl_cmd..fs.Q(url).." 2> NUL 1> "..fs.Q(filename))
+ end
+ if ok then
+ return true, filename
+ else
+ return false
end
end
@@ -275,7 +289,7 @@ end
-- @param archive string: Filename of archive.
-- @return boolean : success status
local function gunzip(archive)
- return fs.execute(vars.SEVENZ.." x", archive)
+ return fs.execute_quiet(fs.Q(vars.SEVENZ).." -aoa x", archive)
end
--- Unpack an archive.
@@ -283,28 +297,28 @@ end
-- filename extension.
-- @param archive string: Filename of archive.
-- @return boolean or (boolean, string): true on success, false and an error message on failure.
-function unpack_archive(archive)
+function tools.unpack_archive(archive)
assert(type(archive) == "string")
local ok
- local sevenzx = vars.SEVENZ.." x"
+ local sevenzx = fs.Q(vars.SEVENZ).." -aoa x"
if archive:match("%.tar%.gz$") then
ok = gunzip(archive)
if ok then
- ok = fs.execute(sevenzx, strip_extension(archive))
+ ok = fs.execute_quiet(sevenzx, strip_extension(archive))
end
elseif archive:match("%.tgz$") then
ok = gunzip(archive)
if ok then
- ok = fs.execute(sevenzx, strip_extension(archive)..".tar")
+ ok = fs.execute_quiet(sevenzx, strip_extension(archive)..".tar")
end
elseif archive:match("%.tar%.bz2$") then
- ok = fs.execute(sevenzx, archive)
+ ok = fs.execute_quiet(sevenzx, archive)
if ok then
- ok = fs.execute(sevenzx, strip_extension(archive))
+ ok = fs.execute_quiet(sevenzx, strip_extension(archive))
end
elseif archive:match("%.zip$") then
- ok = fs.execute(sevenzx, archive)
+ ok = fs.execute_quiet(sevenzx, archive)
elseif archive:match("%.lua$") or archive:match("%.c$") then
-- Ignore .lua and .c files; they don't need to be extracted.
return true
@@ -319,28 +333,37 @@ function unpack_archive(archive)
end
local md5_cmd = {
- md5sum = vars.MD5SUM,
- openssl = vars.OPENSSL.." md5",
- md5 = vars.MD5,
+ md5sum = fs.Q(vars.MD5SUM),
+ openssl = fs.Q(vars.OPENSSL).." md5",
+ md5 = fs.Q(vars.MD5),
}
--- Get the MD5 checksum for a file.
-- @param file string: The file to be computed.
--- @return string: The MD5 checksum
-function get_md5(file)
+-- @return string: The MD5 checksum or nil + message
+function tools.get_md5(file)
local cmd = md5_cmd[cfg.md5checker]
- if not cmd then return nil end
- local pipe = io.popen(cmd.." "..fs.absolute_name(file))
+ if not cmd then return nil, "no MD5 checker command configured" end
+ local pipe = io.popen(cmd.." "..fs.Q(fs.absolute_name(file)))
local computed = pipe:read("*a")
pipe:close()
- if not computed then return nil end
- return computed:match("("..("%x"):rep(32)..")")
+ if computed then
+ computed = computed:match("("..("%x"):rep(32)..")")
+ end
+ if computed then return computed end
+ return nil, "Failed to compute MD5 hash for file "..tostring(fs.absolute_name(file))
end
--- Test for existance of a file.
-- @param file string: filename to test
-- @return boolean: true if file exists, false otherwise.
-function exists(file)
+function tools.exists(file)
assert(file)
- return fs.execute(fs.quiet("if not exist " .. fs.Q(file) .. " invalidcommandname"))
+ return fs.execute_quiet("if not exist " .. fs.Q(file) .. " invalidcommandname")
+end
+
+function tools.browser(url)
+ return fs.execute(cfg.web_browser..' "Starting docs..." '..fs.Q(url))
end
+
+return tools
diff --git a/luarocks/src/luarocks/help.lua b/luarocks/src/luarocks/help.lua
index 2944dfd..0a15550 100644
--- a/luarocks/src/luarocks/help.lua
+++ b/luarocks/src/luarocks/help.lua
@@ -4,17 +4,19 @@
-- uses a global table called "commands" to find commands
-- to show help for; each command should be represented by a
-- table containing "help" and "help_summary" fields.
-module("luarocks.help", package.seeall)
+--module("luarocks.help", package.seeall)
+local help = {}
local util = require("luarocks.util")
local cfg = require("luarocks.cfg")
+local dir = require("luarocks.dir")
local program = util.this_program("luarocks")
-help_summary = "Help on commands. Type '"..program.." help <command>' for more."
+help.help_summary = "Help on commands. Type '"..program.." help <command>' for more."
-help_arguments = "[<command>]"
-help = [[
+help.help_arguments = "[<command>]"
+help.help = [[
<command> is the command to show help for.
]]
@@ -41,7 +43,7 @@ end
-- given, help summaries for all commands are shown.
-- @return boolean or (nil, string): true if there were no errors
-- or nil and an error message if an invalid command was requested.
-function run(...)
+function help.run(...)
local flags, command = util.parse_flags(...)
if not command then
@@ -63,40 +65,51 @@ function run(...)
given URL.
--tree=<tree> Which tree to operate on.
--local Use the tree in the user's home directory.
- To enable it, see ']]..program..[[ help path'.]])
+ To enable it, see ']]..program..[[ help path'.
+ --verbose Display verbose output of commands executed.
+ --timeout=<seconds> Timeout on network operations, in seconds.
+ 0 means no timeout (wait forever).
+ Default is ]]..cfg.connection_timeout..[[.]])
print_section("VARIABLES")
util.printout([[
Variables from the "variables" table of the configuration file
can be overriden with VAR=VALUE assignments.]])
print_section("COMMANDS")
- local names = {}
- for name, command in pairs(commands) do
- table.insert(names, name)
- end
- table.sort(names)
- for _, name in ipairs(names) do
- local command = commands[name]
+ for name, command in util.sortedpairs(commands) do
+ local cmd = require(command)
util.printout("", name)
- util.printout("\t", command.help_summary)
+ util.printout("\t", cmd.help_summary)
end
print_section("CONFIGURATION")
- util.printout("\tSystem configuration file: ".. sys_file .. " (" .. get_status(sys_ok) ..")")
+ util.printout("\tLua version: " .. cfg.lua_version)
+ util.printout("\tConfiguration files:")
+ util.printout("\t\tSystem: ".. dir.normalize(sys_file) .. " (" .. get_status(sys_ok) ..")")
if home_file then
- util.printout("\tUser configuration file: ".. home_file .. " (" .. get_status(home_ok) ..")\n")
+ util.printout("\t\tUser : ".. dir.normalize(home_file) .. " (" .. get_status(home_ok) ..")\n")
else
- util.printout("\tUser configuration file disabled in this LuaRocks installation.\n")
+ util.printout("\t\tUser : disabled in this LuaRocks installation.\n")
+ end
+ util.printout("\tRocks trees in use: ")
+ for _, tree in ipairs(cfg.rocks_trees) do
+ if type(tree) == "string" then
+ util.printout("\t\t"..dir.normalize(tree))
+ else
+ local name = tree.name and " (\""..tree.name.."\")" or ""
+ util.printout("\t\t"..dir.normalize(tree.root)..name)
+ end
end
else
command = command:gsub("-", "_")
- if commands[command] then
- local arguments = commands[command].help_arguments or "<argument>"
+ local cmd = require(commands[command])
+ if cmd then
+ local arguments = cmd.help_arguments or "<argument>"
print_banner()
print_section("NAME")
- util.printout("\t"..program.." "..command.." - "..commands[command].help_summary)
+ util.printout("\t"..program.." "..command.." - "..cmd.help_summary)
print_section("SYNOPSIS")
util.printout("\t"..program.." "..command.." "..arguments)
print_section("DESCRIPTION")
- util.printout("",(commands[command].help:gsub("\n","\n\t"):gsub("\n\t$","")))
+ util.printout("",(cmd.help:gsub("\n","\n\t"):gsub("\n\t$","")))
print_section("SEE ALSO")
util.printout("","'"..program.." help' for general options and configuration.\n")
else
@@ -105,3 +118,5 @@ function run(...)
end
return true
end
+
+return help
diff --git a/luarocks/src/luarocks/index.lua b/luarocks/src/luarocks/index.lua
index e1391cc..116bdfd 100644
--- a/luarocks/src/luarocks/index.lua
+++ b/luarocks/src/luarocks/index.lua
@@ -1,6 +1,8 @@
--- Module which builds the index.html page to be used in rocks servers.
-module("luarocks.index", package.seeall)
+--module("luarocks.index", package.seeall)
+local index = {}
+package.loaded["luarocks.index"] = index
local util = require("luarocks.util")
local fs = require("luarocks.fs")
@@ -27,6 +29,9 @@ a {
color: #0000c0;
text-decoration: none;
}
+a.pkg {
+ color: black;
+}
a:hover {
text-decoration: underline;
}
@@ -63,9 +68,9 @@ Lua modules available from this location for use with <a href="http://www.luaroc
<table class="main">
]]
-local index_package_start = [[
+local index_package_begin = [[
<td class="package">
-<p><a name="$anchor"></a><b>$package</b> - $summary<br/>
+<p><a name="$anchor"></a><a href="#$anchor" class="pkg"><b>$package</b></a> - $summary<br/>
</p><blockquote><p>$detailed<br/>
$externaldependencies
<font size="-1"><a href="$original">latest sources</a> $homepage | License: $license</font></p>
@@ -78,16 +83,21 @@ local index_package_end = [[
<tr><td colspan="2" class="spacer"></td></tr>
]]
-local index_footer = [[
+local index_footer_begin = [[
</table>
<p class="manifest">
-<a href="manifest">manifest file</a> &bull; <a href="manifest-5.1">Lua 5.1 manifest file</a> &bull; <a href="manifest-5.2">Lua 5.2 manifest file</a>
+<a href="manifest">manifest file</a>
+]]
+local index_manifest_ver = [[
+&bull; <a href="manifest-$VER">Lua $VER manifest file</a> (<a href="manifest-$VER.zip">zip</a>)
+]]
+local index_footer_end = [[
</p>
</body>
</html>
]]
-function format_external_dependencies(rockspec)
+function index.format_external_dependencies(rockspec)
if rockspec.external_dependencies then
local deplist = {}
local listed_set = {}
@@ -115,7 +125,7 @@ function format_external_dependencies(rockspec)
end
end
-function make_index(repo)
+function index.make_index(repo)
if not fs.is_dir(repo) then
return nil, "Cannot access repository at "..repo
end
@@ -125,21 +135,20 @@ function make_index(repo)
out:write(index_header)
for package, version_list in util.sortedpairs(manifest.repository) do
local latest_rockspec = nil
- local output = index_package_start
+ local output = index_package_begin
for version, data in util.sortedpairs(version_list, deps.compare_versions) do
local versions = {}
output = output..version..':&nbsp;'
table.sort(data, function(a,b) return a.arch < b.arch end)
for _, item in ipairs(data) do
- local link = '<a href="$url">'..item.arch..'</a>'
+ local file
if item.arch == 'rockspec' then
- local rs = ("%s-%s.rockspec"):format(package, version)
- if not latest_rockspec then latest_rockspec = rs end
- link = link:gsub("$url", rs)
+ file = ("%s-%s.rockspec"):format(package, version)
+ if not latest_rockspec then latest_rockspec = file end
else
- link = link:gsub("$url", ("%s-%s.%s.rock"):format(package, version, item.arch))
+ file = ("%s-%s.%s.rock"):format(package, version, item.arch)
end
- table.insert(versions, link)
+ table.insert(versions, '<a href="'..file..'">'..item.arch..'</a>')
end
output = output .. table.concat(versions, ',&nbsp;') .. '<br/>'
end
@@ -155,7 +164,7 @@ function make_index(repo)
detailed = descript.detailed or "",
license = descript.license or "N/A",
homepage = descript.homepage and ('| <a href="'..descript.homepage..'"'..ext_url_target..'>project homepage</a>') or "",
- externaldependencies = format_external_dependencies(rockspec)
+ externaldependencies = index.format_external_dependencies(rockspec)
}
vars.detailed = vars.detailed:gsub("\n\n", "</p><p>"):gsub("%s+", " ")
vars.detailed = vars.detailed:gsub("(https?://[a-zA-Z0-9%.%%-_%+%[%]=%?&/$@;:]+)", '<a href="%1"'..ext_url_target..'>%1</a>')
@@ -167,6 +176,12 @@ function make_index(repo)
end
out:write(output)
end
- out:write(index_footer)
+ out:write(index_footer_begin)
+ for ver in util.lua_versions() do
+ out:write((index_manifest_ver:gsub("$VER", ver)))
+ end
+ out:write(index_footer_end)
out:close()
end
+
+return index
diff --git a/luarocks/src/luarocks/install.lua b/luarocks/src/luarocks/install.lua
index c181d61..7678c0c 100644
--- a/luarocks/src/luarocks/install.lua
+++ b/luarocks/src/luarocks/install.lua
@@ -1,7 +1,8 @@
-
--- Module implementing the LuaRocks "install" command.
-- Installs binary rocks.
-module("luarocks.install", package.seeall)
+--module("luarocks.install", package.seeall)
+local install = {}
+package.loaded["luarocks.install"] = install
local path = require("luarocks.path")
local repos = require("luarocks.repos")
@@ -13,11 +14,11 @@ local manif = require("luarocks.manif")
local remove = require("luarocks.remove")
local cfg = require("luarocks.cfg")
-help_summary = "Install a rock."
+install.help_summary = "Install a rock."
-help_arguments = "{<rock>|<name> [<version>]}"
+install.help_arguments = "{<rock>|<name> [<version>]}"
-help = [[
+install.help = [[
Argument may be the name of a rock to be fetched from a repository
or a filename of a locally available rock.
@@ -25,7 +26,8 @@ or a filename of a locally available rock.
rock after installing a new one. This behavior can
be made permanent by setting keep_other_versions=true
in the configuration file.
-]]
+]]..util.deps_mode_help()
+
--- Install a binary rock.
-- @param rock_file string: local or remote filename of a rock.
@@ -34,7 +36,7 @@ or a filename of a locally available rock.
-- "order" for all trees with priority >= the current default, "none" for no trees.
-- @return (string, string) or (nil, string, [string]): Name and version of
-- installed rock if succeeded or nil and an error message followed by an error code.
-function install_binary_rock(rock_file, deps_mode)
+function install.install_binary_rock(rock_file, deps_mode)
assert(type(rock_file) == "string")
local name, version, arch = path.parse_name(rock_file)
@@ -80,11 +82,6 @@ function install_binary_rock(rock_file, deps_mode)
if err then return nil, err, errcode end
end
- local wrap_bin_scripts = true
- if rockspec.deploy and rockspec.deploy.wrap_bin_scripts == false then
- wrap_bin_scripts = false
- end
-
ok, err = repos.deploy_files(name, version, repos.should_wrap_bin_scripts(rockspec))
if err then return nil, err end
@@ -120,23 +117,23 @@ end
-- if returned a result, installs the matching rock.
-- @param version string: When passing a package name, a version number
-- may also be given.
--- @return boolean or (nil, string): True if installation was
--- successful, nil and an error message otherwise.
-function run(...)
+-- @return boolean or (nil, string, exitcode): True if installation was
+-- successful, nil and an error message otherwise. exitcode is optionally returned.
+function install.run(...)
local flags, name, version = util.parse_flags(...)
if type(name) ~= "string" then
return nil, "Argument missing. "..util.see_help("install")
end
local ok, err = fs.check_command_permissions(flags)
- if not ok then return nil, err end
+ if not ok then return nil, err, cfg.errorcodes.PERMISSIONDENIED end
if name:match("%.rockspec$") or name:match("%.src%.rock$") then
util.printout("Using "..name.."... switching to 'build' mode")
local build = require("luarocks.build")
return build.run(name, util.forward_flags(flags, "local", "keep", "deps-mode"))
elseif name:match("%.rock$") then
- ok, err = install_binary_rock(name, deps.get_deps_mode(flags))
+ ok, err = install.install_binary_rock(name, deps.get_deps_mode(flags))
if not ok then return nil, err end
local name, version = ok, err
if (not flags["keep"]) and not cfg.keep_other_versions then
@@ -152,7 +149,7 @@ function run(...)
elseif type(results) == "string" then
local url = results
util.printout("Installing "..url.."...")
- return run(url, util.forward_flags(flags))
+ return install.run(url, util.forward_flags(flags))
else
util.printout()
util.printerr("Could not determine which rock to install.")
@@ -162,3 +159,5 @@ function run(...)
end
end
end
+
+return install
diff --git a/luarocks/src/luarocks/lint.lua b/luarocks/src/luarocks/lint.lua
index 62ced64..091c8de 100644
--- a/luarocks/src/luarocks/lint.lua
+++ b/luarocks/src/luarocks/lint.lua
@@ -1,22 +1,24 @@
--- Module implementing the LuaRocks "lint" command.
-- Utility function that checks syntax of the rockspec.
-module("luarocks.lint", package.seeall)
+--module("luarocks.lint", package.seeall)
+local lint = {}
+package.loaded["luarocks.lint"] = lint
local util = require("luarocks.util")
local download = require("luarocks.download")
local fetch = require("luarocks.fetch")
-help_summary = "Check syntax of a rockspec."
-help_arguments = "<rockspec>"
-help = [[
+lint.help_summary = "Check syntax of a rockspec."
+lint.help_arguments = "<rockspec>"
+lint.help = [[
This is a utility function that checks the syntax of a rockspec.
It returns success or failure if the text of a rockspec is
syntactically correct.
]]
-function run(...)
+function lint.run(...)
local flags, input = util.parse_flags(...)
if not input then
@@ -37,5 +39,19 @@ function run(...)
return nil, "Failed loading rockspec: "..err
end
- return true
+ local ok = true
+
+ -- This should have been done in the type checker,
+ -- but it would break compatibility of other commands.
+ -- Making 'lint' alone be stricter shouldn't be a problem,
+ -- because extra-strict checks is what lint-type commands
+ -- are all about.
+ if not rs.description.license then
+ util.printerr("Rockspec has no license field.")
+ ok = false
+ end
+
+ return ok, ok or filename.." failed consistency checks."
end
+
+return lint
diff --git a/luarocks/src/luarocks/list.lua b/luarocks/src/luarocks/list.lua
index 6081ed4..319909d 100644
--- a/luarocks/src/luarocks/list.lua
+++ b/luarocks/src/luarocks/list.lua
@@ -1,16 +1,18 @@
--- Module implementing the LuaRocks "list" command.
-- Lists currently installed rocks.
-module("luarocks.list", package.seeall)
+--module("luarocks.list", package.seeall)
+local list = {}
+package.loaded["luarocks.list"] = list
local search = require("luarocks.search")
local cfg = require("luarocks.cfg")
local util = require("luarocks.util")
local path = require("luarocks.path")
-help_summary = "Lists currently installed rocks."
-help_arguments = "[--porcelain] <filter>"
-help = [[
+list.help_summary = "Lists currently installed rocks."
+list.help_arguments = "[--porcelain] <filter>"
+list.help = [[
<filter> is a substring of a rock name to filter by.
--porcelain Produce machine-friendly output.
@@ -20,7 +22,7 @@ help = [[
-- @param filter string or nil: A substring of a rock name to filter by.
-- @param version string or nil: a version may also be passed.
-- @return boolean: True if succeeded, nil on errors.
-function run(...)
+function list.run(...)
local flags, filter, version = util.parse_flags(...)
local results = {}
local query = search.make_query(filter and filter:lower() or "", version)
@@ -36,3 +38,5 @@ function run(...)
search.print_results(results, flags["porcelain"])
return true
end
+
+return list
diff --git a/luarocks/src/luarocks/loader.lua b/luarocks/src/luarocks/loader.lua
index a116766..1eaa672 100644
--- a/luarocks/src/luarocks/loader.lua
+++ b/luarocks/src/luarocks/loader.lua
@@ -5,23 +5,28 @@
-- table in the environment, which records which versions of packages were
-- used to load previous modules, so that the loader chooses versions
-- that are declared to be compatible with the ones loaded earlier.
-local global_env = _G
-local package, require, ipairs, pairs, table, type, next, unpack =
- package, require, ipairs, pairs, table, type, next, unpack
+local loaders = package.loaders or package.searchers
+local package, require, ipairs, pairs, table, type, next, tostring, error =
+ package, require, ipairs, pairs, table, type, next, tostring, error
+local unpack = unpack or table.unpack
-module("luarocks.loader")
+--module("luarocks.loader")
+local loader = {}
+package.loaded["luarocks.loader"] = loader
+
+local cfg = require("luarocks.cfg")
+cfg.init_package_paths()
local path = require("luarocks.path")
local manif_core = require("luarocks.manif_core")
local deps = require("luarocks.deps")
-local cfg = require("luarocks.cfg")
-context = {}
+loader.context = {}
-- Contains a table when rocks trees are loaded,
-- or 'false' to indicate rocks trees failed to load.
-- 'nil' indicates rocks trees were not attempted to be loaded yet.
-rocks_trees = nil
+loader.rocks_trees = nil
local function load_rocks_trees()
local any_ok = false
@@ -34,10 +39,10 @@ local function load_rocks_trees()
end
end
if not any_ok then
- rocks_trees = false
+ loader.rocks_trees = false
return false
end
- rocks_trees = trees
+ loader.rocks_trees = trees
return true
end
@@ -45,21 +50,20 @@ end
-- chain for loading modules.
-- @param name string: The name of an installed rock.
-- @param version string: The version of the rock, in string format
-function add_context(name, version)
+function loader.add_context(name, version)
-- assert(type(name) == "string")
-- assert(type(version) == "string")
- if context[name] then
+ if loader.context[name] then
return
end
- context[name] = version
+ loader.context[name] = version
- if not rocks_trees and not load_rocks_trees() then
+ if not loader.rocks_trees and not load_rocks_trees() then
return nil
end
- local providers = {}
- for _, tree in ipairs(rocks_trees) do
+ for _, tree in ipairs(loader.rocks_trees) do
local manifest = tree.manifest
local pkgdeps
@@ -72,12 +76,12 @@ function add_context(name, version)
for _, dep in ipairs(pkgdeps) do
local pkg, constraints = dep.name, dep.constraints
- for _, tree in ipairs(rocks_trees) do
+ for _, tree in ipairs(loader.rocks_trees) do
local entries = tree.manifest.repository[pkg]
if entries then
for version, pkgs in pairs(entries) do
if (not constraints) or deps.match_constraints(deps.parse_version(version), constraints) then
- add_context(pkg, version)
+ loader.add_context(pkg, version)
end
end
end
@@ -108,9 +112,9 @@ end
-- @return table or (nil, string): The module table as returned by some other loader,
-- or nil followed by an error message if no other loader managed to load the module.
local function call_other_loaders(module, name, version, module_name)
- for i, loader in pairs(package.loaders) do
- if loader ~= luarocks_loader then
- local results = { loader(module_name) }
+ for i, a_loader in ipairs(loaders) do
+ if a_loader ~= loader.luarocks_loader then
+ local results = { a_loader(module_name) }
if type(results[1]) == "function" then
return unpack(results)
end
@@ -126,34 +130,35 @@ end
-- (eg "luasocket"), the version (eg "2.0.2-1"), the path of the rocks tree
-- (eg "/usr/local"), and the numeric index of the matching entry, so the
-- filter function can know if the matching module was the first entry or not.
--- @return string, string, string: name of the rock containing the module
--- (eg. "luasocket"), version of the rock (eg. "2.0.2-1"),
--- name of the module (eg. "socket.core", or "socket.core_2_0_2" if file is
--- stored versioned).
+-- @return string, string, string, (string or table):
+-- * name of the rock containing the module (eg. "luasocket")
+-- * version of the rock (eg. "2.0.2-1")
+-- * name of the module (eg. "socket.core", or "socket.core_2_0_2" if file is stored versioned).
+-- * tree of the module (string or table in `rocks_trees` format)
local function select_module(module, filter_module_name)
--assert(type(module) == "string")
--assert(type(filter_module_name) == "function")
- if not rocks_trees and not load_rocks_trees() then
+ if not loader.rocks_trees and not load_rocks_trees() then
return nil
end
local providers = {}
- for _, tree in ipairs(rocks_trees) do
+ for _, tree in ipairs(loader.rocks_trees) do
local entries = tree.manifest.modules[module]
if entries then
for i, entry in ipairs(entries) do
local name, version = entry:match("^([^/]*)/(.*)$")
local module_name = tree.manifest.repository[name][version][1].modules[module]
if type(module_name) ~= "string" then
- error("Invalid format in manifest file (invalid data for "..tostring(name).." "..tostring(version)..")")
+ error("Invalid data in manifest file for module "..tostring(module).." (invalid data for "..tostring(name).." "..tostring(version)..")")
end
module_name = filter_module_name(module_name, name, version, tree.tree, i)
- if context[name] == version then
+ if loader.context[name] == version then
return name, version, module_name
end
version = deps.parse_version(version)
- table.insert(providers, {name = name, version = version, module_name = module_name})
+ table.insert(providers, {name = name, version = version, module_name = module_name, tree = tree})
end
end
end
@@ -161,16 +166,17 @@ local function select_module(module, filter_module_name)
if next(providers) then
table.sort(providers, sort_versions)
local first = providers[1]
- return first.name, first.version.string, first.module_name
+ return first.name, first.version.string, first.module_name, first.tree
end
end
--- Search for a module
-- @param module string: module name (eg. "socket.core")
--- @return string, string, string: name of the rock containing the module
--- (eg. "luasocket"), version of the rock (eg. "2.0.2-1"),
--- name of the module (eg. "socket.core", or "socket.core_2_0_2" if file is
--- stored versioned).
+-- @return string, string, string, (string or table):
+-- * name of the rock containing the module (eg. "luasocket")
+-- * version of the rock (eg. "2.0.2-1")
+-- * name of the module (eg. "socket.core", or "socket.core_2_0_2" if file is stored versioned).
+-- * tree of the module (string or table in `rocks_trees` format)
local function pick_module(module)
return
select_module(module, function(module_name, name, version, tree, i)
@@ -185,7 +191,7 @@ end
--- Return the pathname of the file that would be loaded for a module.
-- @param module string: module name (eg. "socket.core")
-- @return string: filename of the module (eg. "/usr/local/lib/lua/5.1/socket/core.so")
-function which(module)
+function loader.which(module)
local name, version, module_name = select_module(module, path.which_i)
return module_name
end
@@ -199,14 +205,16 @@ end
-- @return table: The module table (typically), like in plain
-- require(). See <a href="http://www.lua.org/manual/5.1/manual.html#pdf-require">require()</a>
-- in the Lua reference manual for details.
-function luarocks_loader(module)
+function loader.luarocks_loader(module)
local name, version, module_name = pick_module(module)
if not name then
return "No LuaRocks module found for "..module
else
- add_context(name, version)
+ loader.add_context(name, version)
return call_other_loaders(module, name, version, module_name)
end
end
-table.insert(global_env.package.loaders, 1, luarocks_loader)
+table.insert(loaders, 1, loader.luarocks_loader)
+
+return loader
diff --git a/luarocks/src/luarocks/make.lua b/luarocks/src/luarocks/make.lua
index eef49d0..1dfe647 100644
--- a/luarocks/src/luarocks/make.lua
+++ b/luarocks/src/luarocks/make.lua
@@ -3,7 +3,9 @@
-- Builds sources in the current directory, but unlike "build",
-- it does not fetch sources, etc., assuming everything is
-- available in the current directory.
-module("luarocks.make", package.seeall)
+--module("luarocks.make", package.seeall)
+local make = {}
+package.loaded["luarocks.make"] = make
local build = require("luarocks.build")
local fs = require("luarocks.fs")
@@ -14,9 +16,9 @@ local pack = require("luarocks.pack")
local remove = require("luarocks.remove")
local deps = require("luarocks.deps")
-help_summary = "Compile package in current directory using a rockspec."
-help_arguments = "[--pack-binary-rock] [<rockspec>]"
-help = [[
+make.help_summary = "Compile package in current directory using a rockspec."
+make.help_arguments = "[--pack-binary-rock] [<rockspec>]"
+make.help = [[
Builds sources in the current directory, but unlike "build",
it does not fetch sources, etc., assuming everything is
available in the current directory. If no argument is given,
@@ -36,19 +38,22 @@ To install rocks, you'll normally want to use the "install" and
be made permanent by setting keep_other_versions=true
in the configuration file.
+--branch=<name> Override the `source.branch` field in the loaded
+ rockspec. Allows to specify a different branch to
+ fetch. Particularly for SCM rocks.
+
]]
--- Driver function for "make" command.
-- @param name string: A local rockspec.
--- @return boolean or (nil, string): True if build was successful; nil and an
--- error message otherwise.
-function run(...)
+-- @return boolean or (nil, string, exitcode): True if build was successful; nil and an
+-- error message otherwise. exitcode is optionally returned.
+function make.run(...)
local flags, rockspec = util.parse_flags(...)
assert(type(rockspec) == "string" or not rockspec)
if not rockspec then
- local files = fs.list_dir(fs.current_dir())
- for _, file in pairs(files) do
+ for file in fs.dir() do
if file:match("rockspec$") then
if rockspec then
return nil, "Please specify which rockspec file to use."
@@ -73,7 +78,7 @@ function run(...)
return pack.pack_binary_rock(rspec.name, rspec.version, build.build_rockspec, rockspec, false, true, deps.get_deps_mode(flags))
else
local ok, err = fs.check_command_permissions(flags)
- if not ok then return nil, err end
+ if not ok then return nil, err, cfg.errorcodes.PERMISSIONDENIED end
ok, err = build.build_rockspec(rockspec, false, true, deps.get_deps_mode(flags))
if not ok then return nil, err end
local name, version = ok, err
@@ -84,3 +89,5 @@ function run(...)
return name, version
end
end
+
+return make
diff --git a/luarocks/src/luarocks/make_manifest.lua b/luarocks/src/luarocks/make_manifest.lua
index a698f83..b6e65bf 100644
--- a/luarocks/src/luarocks/make_manifest.lua
+++ b/luarocks/src/luarocks/make_manifest.lua
@@ -1,17 +1,21 @@
--- Module implementing the luarocks-admin "make_manifest" command.
-- Compile a manifest file for a repository.
-module("luarocks.make_manifest", package.seeall)
+--module("luarocks.make_manifest", package.seeall)
+local make_manifest = {}
+package.loaded["luarocks.make_manifest"] = make_manifest
local manif = require("luarocks.manif")
local index = require("luarocks.index")
local cfg = require("luarocks.cfg")
local util = require("luarocks.util")
local deps = require("luarocks.deps")
+local fs = require("luarocks.fs")
+local dir = require("luarocks.dir")
-help_summary = "Compile a manifest file for a repository."
+make_manifest.help_summary = "Compile a manifest file for a repository."
-help = [[
+make_manifest.help = [[
<argument>, if given, is a local repository pathname.
--local-tree If given, do not write versioned versions of the manifest file.
@@ -23,7 +27,7 @@ help = [[
-- the default local repository configured as cfg.rocks_dir is used.
-- @return boolean or (nil, string): True if manifest was generated,
-- or nil and an error message.
-function run(...)
+function make_manifest.run(...)
local flags, repo = util.parse_flags(...)
assert(type(repo) == "string" or not repo)
@@ -31,10 +35,21 @@ function run(...)
util.printout("Making manifest for "..repo)
+ if repo:match("/lib/luarocks") and not flags["local-tree"] then
+ util.warning("This looks like a local rocks tree, but you did not pass --local-tree.")
+ end
+
local ok, err = manif.make_manifest(repo, deps.get_deps_mode(flags), not flags["local-tree"])
if ok and not flags["local-tree"] then
util.printout("Generating index.html for "..repo)
index.make_index(repo)
end
+ if flags["local-tree"] then
+ for luaver in util.lua_versions() do
+ fs.delete(dir.path(repo, "manifest-"..luaver))
+ end
+ end
return ok, err
end
+
+return make_manifest
diff --git a/luarocks/src/luarocks/manif.lua b/luarocks/src/luarocks/manif.lua
index c17da71..f53f8dc 100644
--- a/luarocks/src/luarocks/manif.lua
+++ b/luarocks/src/luarocks/manif.lua
@@ -1,9 +1,10 @@
-
--- Module for handling manifest files and tables.
-- Manifest files describe the contents of a LuaRocks tree or server.
-- They are loaded into manifest tables, which are then used for
-- performing searches, matching dependencies, etc.
-module("luarocks.manif", package.seeall)
+--module("luarocks.manif", package.seeall)
+local manif = {}
+package.loaded["luarocks.manif"] = manif
local manif_core = require("luarocks.manif_core")
local persist = require("luarocks.persist")
@@ -17,7 +18,7 @@ local path = require("luarocks.path")
local repos = require("luarocks.repos")
local deps = require("luarocks.deps")
-rock_manifest_cache = {}
+manif.rock_manifest_cache = {}
--- Commit a table to disk in given local path.
-- @param where string: The directory where the table should be saved.
@@ -38,22 +39,22 @@ local function save_table(where, name, tbl)
return ok, err
end
-function load_rock_manifest(name, version, root)
+function manif.load_rock_manifest(name, version, root)
assert(type(name) == "string")
assert(type(version) == "string")
local name_version = name.."/"..version
- if rock_manifest_cache[name_version] then
- return rock_manifest_cache[name_version].rock_manifest
+ if manif.rock_manifest_cache[name_version] then
+ return manif.rock_manifest_cache[name_version].rock_manifest
end
local pathname = path.rock_manifest_file(name, version, root)
local rock_manifest = persist.load_into_table(pathname)
if not rock_manifest then return nil end
- rock_manifest_cache[name_version] = rock_manifest
+ manif.rock_manifest_cache[name_version] = rock_manifest
return rock_manifest.rock_manifest
end
-function make_rock_manifest(name, version)
+function manif.make_rock_manifest(name, version)
local install_dir = path.install_dir(name, version)
local rock_manifest = path.rock_manifest_file(name, version)
local tree = {}
@@ -73,18 +74,27 @@ function make_rock_manifest(name, version)
walk = next
end
if fs.is_file(full_path) then
- last[last_name] = fs.get_md5(full_path)
+ local sum, err = fs.get_md5(full_path)
+ if not sum then
+ return nil, "Failed producing checksum: "..tostring(err)
+ end
+ last[last_name] = sum
end
end
- local rock_manifest = { rock_manifest=tree }
- rock_manifest_cache[name.."/"..version] = rock_manifest
+ rock_manifest = { rock_manifest=tree }
+ manif.rock_manifest_cache[name.."/"..version] = rock_manifest
save_table(install_dir, "rock_manifest", rock_manifest )
end
local function fetch_manifest_from(repo_url, filename)
local url = dir.path(repo_url, filename)
local name = repo_url:gsub("[/:]","_")
- local file, err, errcode = fetch.fetch_url_at_temp_dir(url, "luarocks-manifest-"..name)
+ local cache_dir = dir.path(cfg.local_cache, name)
+ local ok = fs.make_dir(cache_dir)
+ if not ok then
+ return nil, "Failed creating temporary cache directory "..cache_dir
+ end
+ local file, err, errcode = fetch.fetch_url(url, dir.path(cache_dir, filename), true)
if not file then
return nil, "Failed fetching manifest for "..repo_url..(err and " - "..err or ""), errcode
end
@@ -97,32 +107,54 @@ end
-- @param repo_url string: URL or pathname for the repository.
-- @return table or (nil, string, [string]): A table representing the manifest,
-- or nil followed by an error message and an optional error code.
-function load_manifest(repo_url)
+function manif.load_manifest(repo_url)
assert(type(repo_url) == "string")
if manif_core.manifest_cache[repo_url] then
return manif_core.manifest_cache[repo_url]
end
-
- local vmanifest = "manifest-"..cfg.lua_version
-
- local protocol, pathname = dir.split_url(repo_url)
+
+ local filenames = {
+ "manifest-"..cfg.lua_version..".zip",
+ "manifest-"..cfg.lua_version,
+ "manifest",
+ }
+
+ local protocol, repodir = dir.split_url(repo_url)
+ local pathname
if protocol == "file" then
- local file = dir.path(pathname, vmanifest)
- if fs.exists(file) then
- pathname = file
- else
- pathname = dir.path(pathname, "manifest")
+ for _, filename in ipairs(filenames) do
+ pathname = dir.path(repodir, filename)
+ if fs.exists(pathname) then
+ break
+ end
end
else
- local file, err = fetch_manifest_from(repo_url, vmanifest)
- if not file then
- file, err = fetch_manifest_from(repo_url, "manifest")
+ local err, errcode
+ for _, filename in ipairs(filenames) do
+ pathname, err, errcode = fetch_manifest_from(repo_url, filename)
+ if pathname then
+ break
+ end
end
- if not file then
- return nil, err
+ if not pathname then
+ return nil, err, errcode
+ end
+ end
+ if pathname:match(".*%.zip$") then
+ pathname = fs.absolute_name(pathname)
+ local dir = dir.dir_name(pathname)
+ fs.change_dir(dir)
+ local nozip = pathname:match("(.*)%.zip$")
+ fs.delete(nozip)
+ local ok = fs.unzip(pathname)
+ fs.pop_dir()
+ if not ok then
+ fs.delete(pathname)
+ fs.delete(pathname..".timestamp")
+ return nil, "Failed extracting manifest file"
end
- pathname = file
+ pathname = nozip
end
return manif_core.manifest_loader(pathname, repo_url)
end
@@ -206,18 +238,11 @@ end
-- @param deps_mode string: Dependency mode: "one" for the current default tree,
-- "all" for all trees, "order" for all trees with priority >= the current default,
-- "none" for no trees.
--- @param repodir string: directory of repository being scanned
--- @param filter_lua string or nil: filter by Lua version
--- @param cache table: temporary rockspec cache table
-local function update_dependencies(manifest, deps_mode, repodir, filter_lua, cache)
+local function update_dependencies(manifest, deps_mode)
assert(type(manifest) == "table")
assert(type(deps_mode) == "string")
- cache = cache or {}
- local lua_version = filter_lua and deps.parse_version(filter_lua)
-
for pkg, versions in pairs(manifest.repository) do
- local to_remove = {}
for version, repositories in pairs(versions) do
local current = pkg.." "..version
for _, repo in ipairs(repositories) do
@@ -229,16 +254,39 @@ local function update_dependencies(manifest, deps_mode, repodir, filter_lua, cac
for miss, err in pairs(missing) do
if miss == current then
util.printerr("Tree inconsistency detected: "..current.." has no rockspec. "..err)
- else
+ elseif deps_mode ~= "none" then
util.printerr("Missing dependency for "..pkg.." "..version..": "..miss)
end
end
end
- elseif filter_lua and repo.arch == "rockspec" then
+ end
+ end
+ end
+ end
+end
+
+--- Filter manifest table by Lua version, removing rockspecs whose Lua version
+-- does not match.
+-- @param manifest table: a manifest table.
+-- @param lua_version string or nil: filter by Lua version
+-- @param repodir string: directory of repository being scanned
+-- @param cache table: temporary rockspec cache table
+local function filter_by_lua_version(manifest, lua_version, repodir, cache)
+ assert(type(manifest) == "table")
+ assert(type(repodir) == "string")
+ assert((not cache) or type(cache) == "table")
+
+ cache = cache or {}
+ lua_version = deps.parse_version(lua_version)
+ for pkg, versions in pairs(manifest.repository) do
+ local to_remove = {}
+ for version, repositories in pairs(versions) do
+ for _, repo in ipairs(repositories) do
+ if repo.arch == "rockspec" then
local pathname = dir.path(repodir, pkg.."-"..version..".rockspec")
local rockspec, err = cache[pathname]
if not rockspec then
- rockspec, err = fetch.load_local_rockspec(pathname)
+ rockspec, err = fetch.load_local_rockspec(pathname, true)
end
if rockspec then
cache[pathname] = rockspec
@@ -258,9 +306,9 @@ local function update_dependencies(manifest, deps_mode, repodir, filter_lua, cac
end
if next(to_remove) then
for _, incompat in ipairs(to_remove) do
- manifest.repository[pkg][incompat] = nil
+ versions[incompat] = nil
end
- if not next(manifest.repository[pkg]) then
+ if not next(versions) then
manifest.repository[pkg] = nil
end
end
@@ -271,17 +319,12 @@ end
-- @param results table: The search results as returned by search.disk_search.
-- @param manifest table: A manifest table (must contain repository, modules, commands tables).
-- It will be altered to include the search results.
--- @param deps_mode string: Dependency mode: "one" for the current default tree,
--- "all" for all trees, "order" for all trees with priority >= the current default,
--- "none" for no trees.
--- @param repo string: directory of repository
--- @param filter_lua string or nil: filter by Lua version
--- @param cache table: temporary rockspec cache table
+-- @param dep_handler: dependency handler function
-- @return boolean or (nil, string): true in case of success, or nil followed by an error message.
-local function store_results(results, manifest, deps_mode, repo, filter_lua, cache)
+local function store_results(results, manifest, dep_handler)
assert(type(results) == "table")
assert(type(manifest) == "table")
- assert(type(deps_mode) == "string")
+ assert((not dep_handler) or type(dep_handler) == "function")
for name, versions in pairs(results) do
local pkgtable = manifest.repository[name] or {}
@@ -291,7 +334,7 @@ local function store_results(results, manifest, deps_mode, repo, filter_lua, cac
local entrytable = {}
entrytable.arch = entry.arch
if entry.arch == "installed" then
- local rock_manifest = load_rock_manifest(name, version)
+ local rock_manifest = manif.load_rock_manifest(name, version)
if not rock_manifest then
return nil, "rock_manifest file not found for "..name.." "..version.." - not a LuaRocks 2 tree?"
end
@@ -304,7 +347,9 @@ local function store_results(results, manifest, deps_mode, repo, filter_lua, cac
end
manifest.repository[name] = pkgtable
end
- update_dependencies(manifest, deps_mode, repo, filter_lua, cache)
+ if dep_handler then
+ dep_handler(manifest)
+ end
sort_package_matching_table(manifest.modules)
sort_package_matching_table(manifest.commands)
return true
@@ -320,7 +365,7 @@ end
-- @param versioned boolean: if versioned versions of the manifest should be created.
-- @return boolean or (nil, string): True if manifest was generated,
-- or nil and an error message.
-function make_manifest(repo, deps_mode, versioned)
+function manif.make_manifest(repo, deps_mode, remote)
assert(type(repo) == "string")
assert(type(deps_mode) == "string")
@@ -338,14 +383,23 @@ function make_manifest(repo, deps_mode, versioned)
manif_core.manifest_cache[repo] = manifest
- local cache = {}
- local ok, err = store_results(results, manifest, deps_mode, repo, nil, cache)
+ local dep_handler = nil
+ if not remote then
+ dep_handler = function(manifest)
+ update_dependencies(manifest, deps_mode)
+ end
+ end
+ local ok, err = store_results(results, manifest, dep_handler)
if not ok then return nil, err end
- if versioned then
- for _, luaver in ipairs({"5.1", "5.2"}) do
+ if remote then
+ local cache = {}
+ for luaver in util.lua_versions() do
local vmanifest = { repository = {}, modules = {}, commands = {} }
- local ok, err = store_results(results, vmanifest, deps_mode, repo, luaver, cache)
+ local dep_handler = function(manifest)
+ filter_by_lua_version(manifest, luaver, repo, cache)
+ end
+ local ok, err = store_results(results, vmanifest, dep_handler)
save_table(repo, "manifest-"..luaver, vmanifest)
end
end
@@ -360,13 +414,13 @@ end
-- @param name string: Name of a package from the repository.
-- @param version string: Version of a package from the repository.
-- @param repo string or nil: Pathname of a local repository. If not given,
--- the default local repository configured as cfg.rocks_dir is used.
+-- the default local repository is used.
-- @param deps_mode string: Dependency mode: "one" for the current default tree,
-- "all" for all trees, "order" for all trees with priority >= the current default,
-- "none" for using the default dependency mode from the configuration.
-- @return boolean or (nil, string): True if manifest was generated,
-- or nil and an error message.
-function update_manifest(name, version, repo, deps_mode)
+function manif.update_manifest(name, version, repo, deps_mode)
assert(type(name) == "string")
assert(type(version) == "string")
repo = path.rocks_dir(repo or cfg.root_dir)
@@ -376,14 +430,14 @@ function update_manifest(name, version, repo, deps_mode)
util.printout("Updating manifest for "..repo)
- local manifest, err = load_manifest(repo)
+ local manifest, err = manif.load_manifest(repo)
if not manifest then
util.printerr("No existing manifest. Attempting to rebuild...")
- local ok, err = make_manifest(repo, deps_mode)
+ local ok, err = manif.make_manifest(repo, deps_mode)
if not ok then
return nil, err
end
- manifest, err = load_manifest(repo)
+ manifest, err = manif.load_manifest(repo)
if not manifest then
return nil, err
end
@@ -391,19 +445,31 @@ function update_manifest(name, version, repo, deps_mode)
local results = {[name] = {[version] = {{arch = "installed", repo = repo}}}}
- local ok, err = store_results(results, manifest, deps_mode, repo)
+ local dep_handler = function(manifest)
+ update_dependencies(manifest, deps_mode)
+ end
+ local ok, err = store_results(results, manifest, dep_handler)
if not ok then return nil, err end
return save_table(repo, "manifest", manifest)
end
+function manif.zip_manifests()
+ for ver in util.lua_versions() do
+ local file = "manifest-"..ver
+ local zip = file..".zip"
+ fs.delete(dir.path(fs.current_dir(), zip))
+ fs.zip(zip, file)
+ end
+end
+
local function find_providers(file, root)
assert(type(file) == "string")
root = root or cfg.root_dir
local manifest, err = manif_core.load_local_manifest(path.rocks_dir(root))
if not manifest then
- return nil, err .. " -- corrupted local rocks tree?"
+ return nil, "untracked"
end
local deploy_bin = path.deploy_bin_dir(root)
local deploy_lua = path.deploy_lua_dir(root)
@@ -435,13 +501,13 @@ end
-- @param file string: The full path of a deployed file.
-- @param root string or nil: A local root dir for a rocks tree. If not given, the default is used.
-- @return string, string: name and version of the provider rock.
-function find_current_provider(file, root)
+function manif.find_current_provider(file, root)
local providers, err = find_providers(file, root)
if not providers then return nil, err end
return providers[1]:match("([^/]*)/([^/]*)")
end
-function find_next_provider(file, root)
+function manif.find_next_provider(file, root)
local providers, err = find_providers(file, root)
if not providers then return nil, err end
if providers[2] then
@@ -450,3 +516,5 @@ function find_next_provider(file, root)
return nil
end
end
+
+return manif
diff --git a/luarocks/src/luarocks/manif_core.lua b/luarocks/src/luarocks/manif_core.lua
index 6424a1e..1a2c111 100644
--- a/luarocks/src/luarocks/manif_core.lua
+++ b/luarocks/src/luarocks/manif_core.lua
@@ -1,7 +1,9 @@
--- Core functions for querying manifest files.
-- This module requires no specific 'fs' functionality.
-module("luarocks.manif_core", package.seeall)
+--module("luarocks.manif_core", package.seeall)
+local manif_core = {}
+package.loaded["luarocks.manif_core"] = manif_core
local persist = require("luarocks.persist")
local type_check = require("luarocks.type_check")
@@ -10,26 +12,27 @@ local util = require("luarocks.util")
local cfg = require("luarocks.cfg")
local path = require("luarocks.path")
-manifest_cache = {}
+manif_core.manifest_cache = {}
--- Back-end function that actually loads the manifest
-- and stores it in the manifest cache.
-- @param file string: The local filename of the manifest file.
-- @param repo_url string: The repository identifier.
-- @param quick boolean: If given, skips type checking.
-function manifest_loader(file, repo_url, quick)
+function manif_core.manifest_loader(file, repo_url, quick)
local manifest, err = persist.load_into_table(file)
if not manifest then
return nil, "Failed loading manifest for "..repo_url..": "..err
end
+ local globals = err
if not quick then
- local ok, err = type_check.type_check_manifest(manifest)
+ local ok, err = type_check.type_check_manifest(manifest, globals)
if not ok then
return nil, "Error checking manifest: "..err
end
end
- manifest_cache[repo_url] = manifest
+ manif_core.manifest_cache[repo_url] = manifest
return manifest
end
@@ -39,16 +42,16 @@ end
-- @param repo_url string: URL or pathname for the repository.
-- @return table or (nil, string): A table representing the manifest,
-- or nil followed by an error message.
-function load_local_manifest(repo_url)
+function manif_core.load_local_manifest(repo_url)
assert(type(repo_url) == "string")
- if manifest_cache[repo_url] then
- return manifest_cache[repo_url]
+ if manif_core.manifest_cache[repo_url] then
+ return manif_core.manifest_cache[repo_url]
end
local pathname = dir.path(repo_url, "manifest")
- return manifest_loader(pathname, repo_url, true)
+ return manif_core.manifest_loader(pathname, repo_url, true)
end
--- Get all versions of a package listed in a manifest file.
@@ -59,13 +62,13 @@ end
-- or "all", to use all trees.
-- @return table: An array of strings listing installed
-- versions of a package.
-function get_versions(name, deps_mode)
+function manif_core.get_versions(name, deps_mode)
assert(type(name) == "string")
assert(type(deps_mode) == "string")
local manifest = {}
path.map_trees(deps_mode, function(tree)
- local loaded = load_local_manifest(path.rocks_dir(tree))
+ local loaded = manif_core.load_local_manifest(path.rocks_dir(tree))
if loaded then
util.deep_merge(manifest, loaded)
end
@@ -77,3 +80,5 @@ function get_versions(name, deps_mode)
end
return {}
end
+
+return manif_core
diff --git a/luarocks/src/luarocks/new_version.lua b/luarocks/src/luarocks/new_version.lua
index cb17032..9ef0cfb 100644
--- a/luarocks/src/luarocks/new_version.lua
+++ b/luarocks/src/luarocks/new_version.lua
@@ -1,19 +1,20 @@
--- Module implementing the LuaRocks "new_version" command.
-- Utility function that writes a new rockspec, updating data from a previous one.
-module("luarocks.new_version", package.seeall)
+--module("luarocks.new_version", package.seeall)
+local new_version = {}
+package.loaded["luarocks.new_version"] = new_version
local util = require("luarocks.util")
-local cfg = require("luarocks.cfg")
local download = require("luarocks.download")
local fetch = require("luarocks.fetch")
local persist = require("luarocks.persist")
-local dir = require("luarocks.dir")
local fs = require("luarocks.fs")
+local type_check = require("luarocks.type_check")
-help_summary = "Auto-write a rockspec for a new version of a rock."
-help_arguments = "{<package>|<rockspec>} [<new_version>] [<new_url>]"
-help = [[
+new_version.help_summary = "Auto-write a rockspec for a new version of a rock."
+new_version.help_arguments = "{<package>|<rockspec>} [<new_version>] [<new_url>]"
+new_version.help = [[
This is a utility function that writes a new rockspec, updating data
from a previous one.
@@ -33,13 +34,6 @@ WARNING: it writes the new rockspec to the current directory,
overwriting the file if it already exists.
]]
-local order = {"rockspec_format", "package", "version",
- { "source", { "url", "tag", "branch", "md5" } },
- { "description", {"summary", "detailed", "homepage", "license" } },
- "supported_platforms", "dependencies", "external_dependencies",
- { "build", {"type", "modules", "copy_directories", "platforms"} },
- "hooks"}
-
local function try_replace(tbl, field, old, new)
if not tbl[field] then
return false
@@ -64,18 +58,13 @@ local function check_url_and_update_md5(out_rs, out_name)
end
util.printout("File successfully downloaded. Updating MD5 checksum...")
out_rs.source.md5 = fs.get_md5(file)
- fs.change_dir(temp_dir)
- fs.unpack_archive(file)
- local base_dir = out_rs.source.dir or fetch.url_to_base_dir(out_rs.source.url)
- if not fs.exists(base_dir) then
- util.printerr("Directory "..base_dir.." not found")
- local files = fs.list_dir()
- if files[1] and fs.is_dir(files[1]) then
- util.printerr("Found "..files[1])
- out_rs.source.dir = files[1]
- end
+ local inferred_dir, found_dir = fetch.find_base_dir(file, temp_dir, out_rs.source.url, out_rs.source.dir)
+ if not inferred_dir then
+ return nil, found_dir
+ end
+ if found_dir and found_dir ~= inferred_dir then
+ out_rs.source.dir = found_dir
end
- fs.pop_dir()
return out_rs.source.md5 ~= old_md5
end
@@ -115,7 +104,7 @@ local function update_source_section(out_rs, out_name, url, old_ver, new_ver)
return true
end
-function run(...)
+function new_version.run(...)
local flags, input, version, url = util.parse_flags(...)
if not input then
return nil, "Missing arguments: expected program or rockspec. "..util.see_help("new_version")
@@ -165,7 +154,7 @@ function run(...)
local out_filename = out_name.."-"..new_rockver.."-"..new_rev..".rockspec"
- persist.save_from_table(out_filename, out_rs, order)
+ persist.save_from_table(out_filename, out_rs, type_check.rockspec_order)
util.printout("Wrote "..out_filename)
@@ -176,3 +165,5 @@ function run(...)
return true
end
+
+return new_version
diff --git a/luarocks/src/luarocks/pack.lua b/luarocks/src/luarocks/pack.lua
index 583932e..c73d66a 100644
--- a/luarocks/src/luarocks/pack.lua
+++ b/luarocks/src/luarocks/pack.lua
@@ -1,7 +1,11 @@
--- Module implementing the LuaRocks "pack" command.
-- Creates a rock, packing sources or binaries.
-module("luarocks.pack", package.seeall)
+--module("luarocks.pack", package.seeall)
+local pack = {}
+package.loaded["luarocks.pack"] = pack
+
+local unpack = unpack or table.unpack
local path = require("luarocks.path")
local repos = require("luarocks.repos")
@@ -13,9 +17,9 @@ local dir = require("luarocks.dir")
local manif = require("luarocks.manif")
local search = require("luarocks.search")
-help_summary = "Create a rock, packing sources or binaries."
-help_arguments = "{<rockspec>|<name> [<version>]}"
-help = [[
+pack.help_summary = "Create a rock, packing sources or binaries."
+pack.help_arguments = "{<rockspec>|<name> [<version>]}"
+pack.help = [[
Argument may be a rockspec file, for creating a source rock,
or the name of an installed package, for creating a binary rock.
In the latter case, the app version may be given as a second
@@ -29,7 +33,7 @@ argument.
-- @param rockspec_file string: An URL or pathname for a rockspec file.
-- @return string or (nil, string): The filename of the resulting
-- .src.rock file; or nil and an error message.
-local function pack_source_rock(rockspec_file)
+function pack.pack_source_rock(rockspec_file)
assert(type(rockspec_file) == "string")
local rockspec, err = fetch.load_rockspec(rockspec_file)
@@ -45,7 +49,8 @@ local function pack_source_rock(rockspec_file)
if not source_file then
return nil, source_dir
end
- fs.change_dir(source_dir)
+ local ok, err = fs.change_dir(source_dir)
+ if not ok then return nil, err end
fs.delete(rock_file)
fs.copy(rockspec_file, source_dir)
@@ -58,12 +63,14 @@ local function pack_source_rock(rockspec_file)
end
local function copy_back_files(name, version, file_tree, deploy_dir, pack_dir)
- fs.make_dir(pack_dir)
+ local ok, err = fs.make_dir(pack_dir)
+ if not ok then return nil, err end
for file, sub in pairs(file_tree) do
local source = dir.path(deploy_dir, file)
local target = dir.path(pack_dir, file)
if type(sub) == "table" then
local ok, err = copy_back_files(name, version, sub, source, target)
+ if not ok then return nil, err end
else
local versioned = path.versioned_name(source, deploy_dir, name, version)
if fs.exists(versioned) then
@@ -128,14 +135,17 @@ local function do_pack_binary_rock(name, version)
local is_binary = false
if rock_manifest.lib then
- copy_back_files(name, version, rock_manifest.lib, path.deploy_lib_dir(root), dir.path(temp_dir, "lib"))
+ local ok, err = copy_back_files(name, version, rock_manifest.lib, path.deploy_lib_dir(root), dir.path(temp_dir, "lib"))
+ if not ok then return nil, "Failed copying back files: " .. err end
is_binary = true
end
if rock_manifest.lua then
- copy_back_files(name, version, rock_manifest.lua, path.deploy_lua_dir(root), dir.path(temp_dir, "lua"))
+ local ok, err = copy_back_files(name, version, rock_manifest.lua, path.deploy_lua_dir(root), dir.path(temp_dir, "lua"))
+ if not ok then return nil, "Failed copying back files: " .. err end
end
- fs.change_dir(temp_dir)
+ local ok, err = fs.change_dir(temp_dir)
+ if not ok then return nil, err end
if not is_binary and not repos.has_binaries(name, version) then
rock_file = rock_file:gsub("%."..cfg.arch:gsub("%-","%%-").."%.", ".all.")
end
@@ -148,7 +158,7 @@ local function do_pack_binary_rock(name, version)
return rock_file
end
-function pack_binary_rock(name, version, cmd, ...)
+function pack.pack_binary_rock(name, version, cmd, ...)
-- The --pack-binary-rock option for "luarocks build" basically performs
-- "luarocks build" on a temporary tree and then "luarocks pack". The
@@ -157,9 +167,9 @@ function pack_binary_rock(name, version, cmd, ...)
-- to shave off the final deploy steps from the build phase and the initial
-- collect steps from the pack phase.
- local temp_dir = fs.make_temp_dir("luarocks-build-pack-"..dir.base_name(name))
+ local temp_dir, err = fs.make_temp_dir("luarocks-build-pack-"..dir.base_name(name))
if not temp_dir then
- return nil, "Failed creating temporary directory."
+ return nil, "Failed creating temporary directory: "..err
end
util.schedule_function(fs.delete, temp_dir)
@@ -182,7 +192,7 @@ end
-- version may also be passed.
-- @return boolean or (nil, string): true if successful or nil followed
-- by an error message.
-function run(...)
+function pack.run(...)
local flags, arg, version = util.parse_flags(...)
assert(type(version) == "string" or not version)
if type(arg) ~= "string" then
@@ -191,7 +201,7 @@ function run(...)
local file, err
if arg:match(".*%.rockspec") then
- file, err = pack_source_rock(arg)
+ file, err = pack.pack_source_rock(arg)
else
file, err = do_pack_binary_rock(arg, version)
end
@@ -202,3 +212,5 @@ function run(...)
return true
end
end
+
+return pack
diff --git a/luarocks/src/luarocks/path.lua b/luarocks/src/luarocks/path.lua
index 7af81c0..598e51d 100644
--- a/luarocks/src/luarocks/path.lua
+++ b/luarocks/src/luarocks/path.lua
@@ -2,31 +2,23 @@
--- LuaRocks-specific path handling functions.
-- All paths are configured in this module, making it a single
-- point where the layout of the local installation is defined in LuaRocks.
-module("luarocks.path", package.seeall)
+--module("luarocks.path", package.seeall)
+local path = {}
local dir = require("luarocks.dir")
local cfg = require("luarocks.cfg")
local util = require("luarocks.util")
-local deps = require("luarocks.deps")
-
-help_summary = "Return the currently configured package path."
-help_arguments = ""
-help = [[
-Returns the package path currently configured for this installation
-of LuaRocks, formatted as shell commands to update LUA_PATH and
-LUA_CPATH. (On Unix systems, you may run: eval `luarocks path`)
-]]
--- Infer rockspec filename from a rock filename.
-- @param rock_name string: Pathname of a rock file.
-- @return string: Filename of the rockspec, without path.
-function rockspec_name_from_rock(rock_name)
+function path.rockspec_name_from_rock(rock_name)
assert(type(rock_name) == "string")
local base_name = dir.base_name(rock_name)
return base_name:match("(.*)%.[^.]*.rock") .. ".rockspec"
end
-function rocks_dir(tree)
+function path.rocks_dir(tree)
if type(tree) == "string" then
return dir.path(tree, cfg.rocks_subdir)
else
@@ -35,12 +27,12 @@ function rocks_dir(tree)
end
end
-function root_dir(rocks_dir)
+function path.root_dir(rocks_dir)
assert(type(rocks_dir) == "string")
return rocks_dir:match("(.*)" .. util.matchquote(cfg.rocks_subdir) .. ".*$")
end
-function rocks_tree_to_string(tree)
+function path.rocks_tree_to_string(tree)
if type(tree) == "string" then
return tree
else
@@ -49,7 +41,7 @@ function rocks_tree_to_string(tree)
end
end
-function deploy_bin_dir(tree)
+function path.deploy_bin_dir(tree)
if type(tree) == "string" then
return dir.path(tree, "bin")
else
@@ -58,7 +50,7 @@ function deploy_bin_dir(tree)
end
end
-function deploy_lua_dir(tree)
+function path.deploy_lua_dir(tree)
if type(tree) == "string" then
return dir.path(tree, cfg.lua_modules_path)
else
@@ -67,7 +59,7 @@ function deploy_lua_dir(tree)
end
end
-function deploy_lib_dir(tree)
+function path.deploy_lib_dir(tree)
if type(tree) == "string" then
return dir.path(tree, cfg.lib_modules_path)
else
@@ -76,7 +68,7 @@ function deploy_lib_dir(tree)
end
end
-function manifest_file(tree)
+function path.manifest_file(tree)
if type(tree) == "string" then
return dir.path(tree, cfg.rocks_subdir, "manifest")
else
@@ -90,10 +82,10 @@ end
-- @return string: The resulting path -- does not guarantee that
-- @param tree string or nil: If given, specifies the local tree to use.
-- the package (and by extension, the path) exists.
-function versions_dir(name, tree)
+function path.versions_dir(name, tree)
assert(type(name) == "string")
tree = tree or cfg.root_dir
- return dir.path(rocks_dir(tree), name)
+ return dir.path(path.rocks_dir(tree), name)
end
--- Get the local installation directory (prefix) for a package.
@@ -102,11 +94,11 @@ end
-- @param tree string or nil: If given, specifies the local tree to use.
-- @return string: The resulting path -- does not guarantee that
-- the package (and by extension, the path) exists.
-function install_dir(name, version, tree)
+function path.install_dir(name, version, tree)
assert(type(name) == "string")
assert(type(version) == "string")
tree = tree or cfg.root_dir
- return dir.path(rocks_dir(tree), name, version)
+ return dir.path(path.rocks_dir(tree), name, version)
end
--- Get the local filename of the rockspec of an installed rock.
@@ -115,11 +107,11 @@ end
-- @param tree string or nil: If given, specifies the local tree to use.
-- @return string: The resulting path -- does not guarantee that
-- the package (and by extension, the file) exists.
-function rockspec_file(name, version, tree)
+function path.rockspec_file(name, version, tree)
assert(type(name) == "string")
assert(type(version) == "string")
tree = tree or cfg.root_dir
- return dir.path(rocks_dir(tree), name, version, name.."-"..version..".rockspec")
+ return dir.path(path.rocks_dir(tree), name, version, name.."-"..version..".rockspec")
end
--- Get the local filename of the rock_manifest file of an installed rock.
@@ -128,11 +120,11 @@ end
-- @param tree string or nil: If given, specifies the local tree to use.
-- @return string: The resulting path -- does not guarantee that
-- the package (and by extension, the file) exists.
-function rock_manifest_file(name, version, tree)
+function path.rock_manifest_file(name, version, tree)
assert(type(name) == "string")
assert(type(version) == "string")
tree = tree or cfg.root_dir
- return dir.path(rocks_dir(tree), name, version, "rock_manifest")
+ return dir.path(path.rocks_dir(tree), name, version, "rock_manifest")
end
--- Get the local installation directory for C libraries of a package.
@@ -141,11 +133,11 @@ end
-- @param tree string or nil: If given, specifies the local tree to use.
-- @return string: The resulting path -- does not guarantee that
-- the package (and by extension, the path) exists.
-function lib_dir(name, version, tree)
+function path.lib_dir(name, version, tree)
assert(type(name) == "string")
assert(type(version) == "string")
tree = tree or cfg.root_dir
- return dir.path(rocks_dir(tree), name, version, "lib")
+ return dir.path(path.rocks_dir(tree), name, version, "lib")
end
--- Get the local installation directory for Lua modules of a package.
@@ -154,11 +146,11 @@ end
-- @param tree string or nil: If given, specifies the local tree to use.
-- @return string: The resulting path -- does not guarantee that
-- the package (and by extension, the path) exists.
-function lua_dir(name, version, tree)
+function path.lua_dir(name, version, tree)
assert(type(name) == "string")
assert(type(version) == "string")
tree = tree or cfg.root_dir
- return dir.path(rocks_dir(tree), name, version, "lua")
+ return dir.path(path.rocks_dir(tree), name, version, "lua")
end
--- Get the local installation directory for documentation of a package.
@@ -167,11 +159,11 @@ end
-- @param tree string or nil: If given, specifies the local tree to use.
-- @return string: The resulting path -- does not guarantee that
-- the package (and by extension, the path) exists.
-function doc_dir(name, version, tree)
+function path.doc_dir(name, version, tree)
assert(type(name) == "string")
assert(type(version) == "string")
tree = tree or cfg.root_dir
- return dir.path(rocks_dir(tree), name, version, "doc")
+ return dir.path(path.rocks_dir(tree), name, version, "doc")
end
--- Get the local installation directory for configuration files of a package.
@@ -180,11 +172,11 @@ end
-- @param tree string or nil: If given, specifies the local tree to use.
-- @return string: The resulting path -- does not guarantee that
-- the package (and by extension, the path) exists.
-function conf_dir(name, version, tree)
+function path.conf_dir(name, version, tree)
assert(type(name) == "string")
assert(type(version) == "string")
tree = tree or cfg.root_dir
- return dir.path(rocks_dir(tree), name, version, "conf")
+ return dir.path(path.rocks_dir(tree), name, version, "conf")
end
--- Get the local installation directory for command-line scripts
@@ -194,11 +186,11 @@ end
-- @param tree string or nil: If given, specifies the local tree to use.
-- @return string: The resulting path -- does not guarantee that
-- the package (and by extension, the path) exists.
-function bin_dir(name, version, tree)
+function path.bin_dir(name, version, tree)
assert(type(name) == "string")
assert(type(version) == "string")
tree = tree or cfg.root_dir
- return dir.path(rocks_dir(tree), name, version, "bin")
+ return dir.path(path.rocks_dir(tree), name, version, "bin")
end
--- Extract name, version and arch of a rock filename,
@@ -206,7 +198,7 @@ end
-- @param file_name string: pathname of a rock or rockspec
-- @return (string, string, string) or nil: name, version and arch
-- or nil if name could not be parsed
-function parse_name(file_name)
+function path.parse_name(file_name)
assert(type(file_name) == "string")
if file_name:match("%.rock$") then
return dir.base_name(file_name):match("(.*)-([^-]+-%d+)%.([^.]+)%.rock$")
@@ -221,7 +213,7 @@ end
-- @param version string: Package version.
-- @param arch string: Architecture identifier, or "rockspec" or "installed".
-- @return string: A URL or pathname following LuaRocks naming conventions.
-function make_url(pathname, name, version, arch)
+function path.make_url(pathname, name, version, arch)
assert(type(pathname) == "string")
assert(type(name) == "string")
assert(type(version) == "string")
@@ -245,7 +237,7 @@ end
-- @return string: The module identifier, or nil if given path is
-- not a conformant module path (the function does not check if the
-- path actually exists).
-function path_to_module(file)
+function path.path_to_module(file)
assert(type(file) == "string")
local name = file:match("(.*)%."..cfg.lua_extension.."$")
@@ -270,7 +262,7 @@ end
-- For example, on Unix, "foo.bar.baz" will return "foo/bar".
-- @param mod string: A module name in Lua dot-separated format.
-- @return string: A directory name using the platform's separator.
-function module_to_path(mod)
+function path.module_to_path(mod)
assert(type(mod) == "string")
return (mod:gsub("[^.]*$", ""):gsub("%.", dir.separator))
end
@@ -279,23 +271,29 @@ end
-- Create a "variables" table in the rockspec table, containing
-- adjusted variables according to the configuration file.
-- @param rockspec table: The rockspec table.
-function configure_paths(rockspec)
+function path.configure_paths(rockspec)
assert(type(rockspec) == "table")
local vars = {}
for k,v in pairs(cfg.variables) do
vars[k] = v
end
local name, version = rockspec.name, rockspec.version
- vars.PREFIX = install_dir(name, version)
- vars.LUADIR = lua_dir(name, version)
- vars.LIBDIR = lib_dir(name, version)
- vars.CONFDIR = conf_dir(name, version)
- vars.BINDIR = bin_dir(name, version)
- vars.DOCDIR = doc_dir(name, version)
+ vars.PREFIX = path.install_dir(name, version)
+ vars.LUADIR = path.lua_dir(name, version)
+ vars.LIBDIR = path.lib_dir(name, version)
+ vars.CONFDIR = path.conf_dir(name, version)
+ vars.BINDIR = path.bin_dir(name, version)
+ vars.DOCDIR = path.doc_dir(name, version)
rockspec.variables = vars
end
-function versioned_name(file, prefix, name, version)
+--- Produce a versioned version of a filename.
+-- @param file string: filename (must start with prefix)
+-- @param prefix string: Path prefix for file
+-- @param name string: Rock name
+-- @param version string: Rock version
+-- @return string: a pathname with the same directory parts and a versioned basename.
+function path.versioned_name(file, prefix, name, version)
assert(type(file) == "string")
assert(type(name) == "string")
assert(type(version) == "string")
@@ -305,12 +303,12 @@ function versioned_name(file, prefix, name, version)
return dir.path(prefix, name_version.."-"..rest)
end
-function use_tree(tree)
+function path.use_tree(tree)
cfg.root_dir = tree
- cfg.rocks_dir = rocks_dir(tree)
- cfg.deploy_bin_dir = deploy_bin_dir(tree)
- cfg.deploy_lua_dir = deploy_lua_dir(tree)
- cfg.deploy_lib_dir = deploy_lib_dir(tree)
+ cfg.rocks_dir = path.rocks_dir(tree)
+ cfg.deploy_bin_dir = path.deploy_bin_dir(tree)
+ cfg.deploy_lua_dir = path.deploy_lua_dir(tree)
+ cfg.deploy_lib_dir = path.deploy_lib_dir(tree)
end
--- Apply a given function to the active rocks trees based on chosen dependency mode.
@@ -320,7 +318,7 @@ end
-- @param fn function: function to be applied, with the tree dir (string) as the first
-- argument and the remaining varargs of map_trees as the following arguments.
-- @return a table with all results of invocations of fn collected.
-function map_trees(deps_mode, fn, ...)
+function path.map_trees(deps_mode, fn, ...)
local result = {}
if deps_mode == "one" then
table.insert(result, (fn(cfg.root_dir, ...)) or 0)
@@ -330,7 +328,7 @@ function map_trees(deps_mode, fn, ...)
use = true
end
for _, tree in ipairs(cfg.rocks_trees) do
- if dir.normalize(tree) == dir.normalize(cfg.root_dir) then
+ if dir.normalize(path.rocks_tree_to_string(tree)) == dir.normalize(path.rocks_tree_to_string(cfg.root_dir)) then
use = true
end
if use then
@@ -349,17 +347,17 @@ end
-- @param i number: the index, 1 if version is the current default, > 1 otherwise.
-- This is done this way for use by select_module in luarocks.loader.
-- @return string: filename of the module (eg. "/usr/local/lib/lua/5.1/socket/core.so")
-function which_i(module_name, name, version, tree, i)
+function path.which_i(module_name, name, version, tree, i)
local deploy_dir
if module_name:match("%.lua$") then
- deploy_dir = deploy_lua_dir(tree)
+ deploy_dir = path.deploy_lua_dir(tree)
module_name = dir.path(deploy_dir, module_name)
else
- deploy_dir = deploy_lib_dir(tree)
+ deploy_dir = path.deploy_lib_dir(tree)
module_name = dir.path(deploy_dir, module_name)
end
if i > 1 then
- module_name = versioned_name(module_name, deploy_dir, name, version)
+ module_name = path.versioned_name(module_name, deploy_dir, name, version)
end
return module_name
end
@@ -373,45 +371,15 @@ end
-- @param tree string: repository path (eg. "/usr/local")
-- @param manifest table: the manifest table for the tree.
-- @return string: filename of the module (eg. "/usr/local/lib/lua/5.1/socket/core.so")
-function which(module_name, filename, name, version, tree, manifest)
+function path.which(module_name, filename, name, version, tree, manifest)
local versions = manifest.modules[module_name]
assert(versions)
for i, name_version in ipairs(versions) do
if name_version == name.."/"..version then
- return which_i(filename, name, version, tree, i):gsub("//", "/")
+ return path.which_i(filename, name, version, tree, i):gsub("//", "/")
end
end
assert(false)
end
---- Driver function for "path" command.
--- @return boolean This function always succeeds.
-function run(...)
- local flags = util.parse_flags(...)
- local deps_mode = deps.get_deps_mode(flags)
-
- local lr_path, lr_cpath = cfg.package_paths()
- local bin_dirs = map_trees(deps_mode, deploy_bin_dir)
-
- if flags["lr-path"] then
- util.printout(util.remove_path_dupes(lr_path, ';'))
- return true
- elseif flags["lr-cpath"] then
- util.printout(util.remove_path_dupes(lr_cpath, ';'))
- return true
- elseif flags["lr-bin"] then
- local lr_bin = util.remove_path_dupes(table.concat(bin_dirs, cfg.export_path_separator), cfg.export_path_separator)
- util.printout(util.remove_path_dupes(lr_bin, ';'))
- return true
- end
-
- util.printout(cfg.export_lua_path:format(util.remove_path_dupes(package.path, ';')))
- util.printout(cfg.export_lua_cpath:format(util.remove_path_dupes(package.cpath, ';')))
- if flags["bin"] then
- table.insert(bin_dirs, 1, os.getenv("PATH"))
- local lr_bin = util.remove_path_dupes(table.concat(bin_dirs, cfg.export_path_separator), cfg.export_path_separator)
- util.printout(cfg.export_path:format(lr_bin))
- end
- return true
-end
-
+return path
diff --git a/luarocks/src/luarocks/path_cmd.lua b/luarocks/src/luarocks/path_cmd.lua
new file mode 100644
index 0000000..95532f9
--- /dev/null
+++ b/luarocks/src/luarocks/path_cmd.lua
@@ -0,0 +1,73 @@
+
+--- @module luarocks.path_cmd
+-- Driver for the `luarocks path` command.
+local path_cmd = {}
+
+local util = require("luarocks.util")
+local deps = require("luarocks.deps")
+local cfg = require("luarocks.cfg")
+local path = require("luarocks.path")
+
+path_cmd.help_summary = "Return the currently configured package path."
+path_cmd.help_arguments = ""
+path_cmd.help = [[
+Returns the package path currently configured for this installation
+of LuaRocks, formatted as shell commands to update LUA_PATH and LUA_CPATH.
+
+--bin Adds the system path to the output
+
+--append Appends the paths to the existing paths. Default is to prefix
+ the LR paths to the existing paths.
+
+--lr-path Exports the Lua path (not formatted as shell command)
+
+--lr-cpath Exports the Lua cpath (not formatted as shell command)
+
+--lr-bin Exports the system path (not formatted as shell command)
+
+
+On Unix systems, you may run:
+ eval `luarocks path`
+And on Windows:
+ luarocks path > "%temp%\_lrp.bat" && call "%temp%\_lrp.bat" && del "%temp%\_lrp.bat"
+]]
+
+--- Driver function for "path" command.
+-- @return boolean This function always succeeds.
+function path_cmd.run(...)
+ local flags = util.parse_flags(...)
+ local deps_mode = deps.get_deps_mode(flags)
+
+ local lr_path, lr_cpath, lr_bin = cfg.package_paths()
+ local path_sep = cfg.export_path_separator
+
+ if flags["lr-path"] then
+ util.printout(util.remove_path_dupes(lr_path, ';'))
+ return true
+ elseif flags["lr-cpath"] then
+ util.printout(util.remove_path_dupes(lr_cpath, ';'))
+ return true
+ elseif flags["lr-bin"] then
+ util.printout(util.remove_path_dupes(lr_bin, path_sep))
+ return true
+ end
+
+ if flags["append"] then
+ lr_path = package.path .. ";" .. lr_path
+ lr_cpath = package.cpath .. ";" .. lr_cpath
+ lr_bin = os.getenv("PATH") .. path_sep .. lr_bin
+ else
+ lr_path = lr_path.. ";" .. package.path
+ lr_cpath = lr_cpath .. ";" .. package.cpath
+ lr_bin = lr_bin .. path_sep .. os.getenv("PATH")
+ end
+
+ util.printout(cfg.export_lua_path:format(util.remove_path_dupes(lr_path, ';')))
+ util.printout(cfg.export_lua_cpath:format(util.remove_path_dupes(lr_cpath, ';')))
+ if flags["bin"] then
+ util.printout(cfg.export_path:format(util.remove_path_dupes(lr_bin, path_sep)))
+ end
+ return true
+end
+
+return path_cmd
diff --git a/luarocks/src/luarocks/persist.lua b/luarocks/src/luarocks/persist.lua
index 208aee0..9d601a4 100644
--- a/luarocks/src/luarocks/persist.lua
+++ b/luarocks/src/luarocks/persist.lua
@@ -3,7 +3,9 @@
-- saving tables into files.
-- Implemented separately to avoid interdependencies,
-- as it is used in the bootstrapping stage of the cfg module.
-module("luarocks.persist", package.seeall)
+--module("luarocks.persist", package.seeall)
+local persist = {}
+package.loaded["luarocks.persist"] = persist
local util = require("luarocks.util")
@@ -14,13 +16,22 @@ local util = require("luarocks.util")
-- loaded values.
-- @return table or (nil, string): a table with the file's assignments
-- as fields, or nil and a message in case of errors.
-function load_into_table(filename, tbl)
+function persist.load_into_table(filename, tbl)
assert(type(filename) == "string")
assert(type(tbl) == "table" or not tbl)
local result, chunk, ran, err
- local result = tbl or {}
- if setfenv then -- Lua 5.1
+ result = tbl or {}
+ local globals = {}
+ local globals_mt = {
+ __index = function(t, n)
+ globals[n] = true
+ return rawget(t, n)
+ end
+ }
+ local save_mt = getmetatable(result)
+ setmetatable(result, globals_mt)
+ if _VERSION == "Lua 5.1" then -- Lua 5.1
chunk, err = loadfile(filename)
if chunk then
setfenv(chunk, result)
@@ -32,6 +43,7 @@ function load_into_table(filename, tbl)
ran, err = pcall(chunk)
end
end
+ setmetatable(result, save_mt)
if not chunk then
if err:sub(1,5) ~= filename:sub(1,5) then
@@ -42,7 +54,7 @@ function load_into_table(filename, tbl)
if not ran then
return nil, "Error running file: "..err
end
- return result
+ return result, globals
end
local write_table
@@ -146,7 +158,7 @@ end
-- @param tbl table: the table containing the data to be written
-- @param field_order table: an optional array indicating the order of top-level fields.
-- @return string
-function save_from_table_to_string(tbl, field_order)
+function persist.save_from_table_to_string(tbl, field_order)
local out = {buffer = {}}
function out:write(data) table.insert(self.buffer, data) end
write_table(out, tbl, field_order)
@@ -162,7 +174,7 @@ end
-- @param field_order table: an optional array indicating the order of top-level fields.
-- @return boolean or (nil, string): true if successful, or nil and a
-- message in case of errors.
-function save_from_table(filename, tbl, field_order)
+function persist.save_from_table(filename, tbl, field_order)
local out = io.open(filename, "w")
if not out then
return nil, "Cannot create file at "..filename
@@ -171,3 +183,5 @@ function save_from_table(filename, tbl, field_order)
out:close()
return true
end
+
+return persist
diff --git a/luarocks/src/luarocks/purge.lua b/luarocks/src/luarocks/purge.lua
index e76a82e..ba9b870 100644
--- a/luarocks/src/luarocks/purge.lua
+++ b/luarocks/src/luarocks/purge.lua
@@ -1,7 +1,9 @@
--- Module implementing the LuaRocks "purge" command.
-- Remove all rocks from a given tree.
-module("luarocks.purge", package.seeall)
+--module("luarocks.purge", package.seeall)
+local purge = {}
+package.loaded["luarocks.purge"] = purge
local util = require("luarocks.util")
local fs = require("luarocks.fs")
@@ -13,9 +15,9 @@ local manif = require("luarocks.manif")
local cfg = require("luarocks.cfg")
local remove = require("luarocks.remove")
-help_summary = "Remove all installed rocks from a tree."
-help_arguments = "--tree=<tree> [--old-versions]"
-help = [[
+purge.help_summary = "Remove all installed rocks from a tree."
+purge.help_arguments = "--tree=<tree> [--old-versions]"
+purge.help = [[
This command removes rocks en masse from a given tree.
By default, it removes all rocks from a tree.
@@ -29,7 +31,7 @@ assume a default tree.
overridden with the flag --force.
]]
-function run(...)
+function purge.run(...)
local flags = util.parse_flags(...)
local tree = flags["tree"]
@@ -41,6 +43,13 @@ function run(...)
local results = {}
local query = search.make_query("")
query.exact_name = false
+ if not fs.is_dir(tree) then
+ return nil, "Directory not found: "..tree
+ end
+
+ local ok, err = fs.check_command_permissions(flags)
+ if not ok then return nil, err, cfg.errorcodes.PERMISSIONDENIED end
+
search.manifest_search(results, path.rocks_dir(tree), query)
local sort = function(a,b) return deps.compare_versions(b,a) end
@@ -68,3 +77,5 @@ function run(...)
end
return manif.make_manifest(cfg.rocks_dir, "one")
end
+
+return purge
diff --git a/luarocks/src/luarocks/refresh_cache.lua b/luarocks/src/luarocks/refresh_cache.lua
index 8073037..193e599 100644
--- a/luarocks/src/luarocks/refresh_cache.lua
+++ b/luarocks/src/luarocks/refresh_cache.lua
@@ -1,20 +1,22 @@
--- Module implementing the luarocks-admin "refresh_cache" command.
-module("luarocks.refresh_cache", package.seeall)
+--module("luarocks.refresh_cache", package.seeall)
+local refresh_cache = {}
+package.loaded["luarocks.refresh_cache"] = refresh_cache
local util = require("luarocks.util")
local cfg = require("luarocks.cfg")
local cache = require("luarocks.cache")
-help_summary = "Refresh local cache of a remote rocks server."
-help_arguments = "[--from=<server>]"
-help = [[
+refresh_cache.help_summary = "Refresh local cache of a remote rocks server."
+refresh_cache.help_arguments = "[--from=<server>]"
+refresh_cache.help = [[
The flag --from indicates which server to use.
If not given, the default server set in the upload_server variable
from the configuration file is used instead.
]]
-function run(...)
+function refresh_cache.run(...)
local flags = util.parse_flags(...)
local server, upload_server = cache.get_upload_server(flags["server"])
if not server then return nil, upload_server end
@@ -28,3 +30,5 @@ function run(...)
end
end
+
+return refresh_cache
diff --git a/luarocks/src/luarocks/remove.lua b/luarocks/src/luarocks/remove.lua
index 9681641..e1cd44f 100644
--- a/luarocks/src/luarocks/remove.lua
+++ b/luarocks/src/luarocks/remove.lua
@@ -1,7 +1,9 @@
--- Module implementing the LuaRocks "remove" command.
-- Uninstalls rocks.
-module("luarocks.remove", package.seeall)
+--module("luarocks.remove", package.seeall)
+local remove = {}
+package.loaded["luarocks.remove"] = remove
local search = require("luarocks.search")
local deps = require("luarocks.deps")
@@ -13,14 +15,17 @@ local cfg = require("luarocks.cfg")
local manif = require("luarocks.manif")
local fs = require("luarocks.fs")
-help_summary = "Uninstall a rock."
-help_arguments = "[--force] <name> [<version>]"
-help = [[
+remove.help_summary = "Uninstall a rock."
+remove.help_arguments = "[--force[=fast]] <name> [<version>]"
+remove.help = [[
Argument is the name of a rock to be uninstalled.
If a version is not given, try to remove all versions at once.
Will only perform the removal if it does not break dependencies.
To override this check and force the removal, use --force.
-]]
+To perform a forced removal without reporting dependency issues,
+use --force=fast.
+
+]]..util.deps_mode_help()
--- Obtain a list of packages that depend on the given set of packages
-- (where all packages of the set are versions of one program).
@@ -69,54 +74,58 @@ local function delete_versions(name, versions)
return true
end
-function remove_search_results(results, name, deps_mode, force)
+function remove.remove_search_results(results, name, deps_mode, force)
local versions = results[name]
local version = next(versions)
local second = next(versions, version)
- util.printout("Checking stability of dependencies on the absence of")
- util.printout(name.." "..table.concat(util.keys(versions), ", ").."...")
- util.printout()
-
- local dependents = check_dependents(name, versions, deps_mode)
+ local dependents = {}
+ if force ~= "fast" then
+ util.printout("Checking stability of dependencies on the absence of")
+ util.printout(name.." "..table.concat(util.keys(versions), ", ").."...")
+ util.printout()
+ dependents = check_dependents(name, versions, deps_mode)
+ end
- if #dependents == 0 or force then
- if #dependents > 0 then
+ if #dependents > 0 then
+ if force then
util.printerr("The following packages may be broken by this forced removal:")
for _, dependent in ipairs(dependents) do
util.printerr(dependent.name.." "..dependent.version)
end
util.printerr()
- end
- local ok, err = delete_versions(name, versions)
- if not ok then return nil, err end
- ok, err = manif.make_manifest(cfg.rocks_dir, deps_mode)
- if not ok then return nil, err end
- else
- if not second then
- util.printerr("Will not remove "..name.." "..version..".")
- util.printerr("Removing it would break dependencies for: ")
else
- util.printerr("Will not remove installed versions of "..name..".")
- util.printerr("Removing them would break dependencies for: ")
- end
- for _, dependent in ipairs(dependents) do
- util.printerr(dependent.name.." "..dependent.version)
+ if not second then
+ util.printerr("Will not remove "..name.." "..version..".")
+ util.printerr("Removing it would break dependencies for: ")
+ else
+ util.printerr("Will not remove installed versions of "..name..".")
+ util.printerr("Removing them would break dependencies for: ")
+ end
+ for _, dependent in ipairs(dependents) do
+ util.printerr(dependent.name.." "..dependent.version)
+ end
+ util.printerr()
+ util.printerr("Use --force to force removal (warning: this may break modules).")
+ return nil, "Failed removing."
end
- util.printerr()
- util.printerr("Use --force to force removal (warning: this may break modules).")
- return nil, "Failed removing."
end
+
+ local ok, err = delete_versions(name, versions)
+ if not ok then return nil, err end
+ ok, err = manif.make_manifest(cfg.rocks_dir, deps_mode)
+ if not ok then return nil, err end
+
util.printout("Removal successful.")
return true
end
-function remove_other_versions(name, version, force)
+function remove.remove_other_versions(name, version, force)
local results = {}
search.manifest_search(results, cfg.rocks_dir, { name = name, exact_name = true, constraints = {{ op = "~=", version = version}} })
if results[name] then
- return remove_search_results(results, name, cfg.deps_mode, force)
+ return remove.remove_search_results(results, name, cfg.deps_mode, force)
end
return true
end
@@ -126,9 +135,9 @@ end
-- a specific version; otherwise, try to remove all versions.
-- @param version string: When passing a package name, a version number
-- may also be given.
--- @return boolean or (nil, string): True if removal was
--- successful, nil and an error message otherwise.
-function run(...)
+-- @return boolean or (nil, string, exitcode): True if removal was
+-- successful, nil and an error message otherwise. exitcode is optionally returned.
+function remove.run(...)
local flags, name, version = util.parse_flags(...)
if type(name) ~= "string" then
@@ -138,7 +147,7 @@ function run(...)
local deps_mode = flags["deps-mode"] or cfg.deps_mode
local ok, err = fs.check_command_permissions(flags)
- if not ok then return nil, err end
+ if not ok then return nil, err, cfg.errorcodes.PERMISSIONDENIED end
local rock_type = name:match("%.(rock)$") or name:match("%.(rockspec)$")
local filename = name
@@ -150,8 +159,10 @@ function run(...)
local results = {}
search.manifest_search(results, cfg.rocks_dir, search.make_query(name, version))
if not results[name] then
- return nil, "Could not find rock '"..name..(version and " "..version or "").."' in local tree."
+ return nil, "Could not find rock '"..name..(version and " "..version or "").."' in "..cfg.root_dir
end
- return remove_search_results(results, name, deps_mode, flags["force"])
+ return remove.remove_search_results(results, name, deps_mode, flags["force"])
end
+
+return remove
diff --git a/luarocks/src/luarocks/repos.lua b/luarocks/src/luarocks/repos.lua
index b7e64d4..1745659 100644
--- a/luarocks/src/luarocks/repos.lua
+++ b/luarocks/src/luarocks/repos.lua
@@ -1,6 +1,8 @@
--- Functions for managing the repository on disk.
-module("luarocks.repos", package.seeall)
+--module("luarocks.repos", package.seeall)
+local repos = {}
+package.loaded["luarocks.repos"] = repos
local fs = require("luarocks.fs")
local path = require("luarocks.path")
@@ -27,7 +29,7 @@ end
-- @param version string: package version in string format
-- @return boolean: true if a package is installed,
-- false otherwise.
-function is_installed(name, version)
+function repos.is_installed(name, version)
assert(type(name) == "string")
assert(type(version) == "string")
@@ -72,7 +74,7 @@ end
-- in "foo.bar" format and values are pathnames in architecture-dependent
-- "foo/bar.so" format. If no modules are found or if package or version
-- are invalid, an empty table is returned.
-function package_modules(package, version)
+function repos.package_modules(package, version)
assert(type(package) == "string")
assert(type(version) == "string")
@@ -91,7 +93,7 @@ end
-- as strings and values are pathnames in architecture-dependent
-- ".../bin/foo" format. If no modules are found or if package or version
-- are invalid, an empty table is returned.
-function package_commands(package, version)
+function repos.package_commands(package, version)
assert(type(package) == "string")
assert(type(version) == "string")
@@ -107,7 +109,7 @@ end
-- @param version string: version of an installed rock
-- @return boolean: returns true if rock contains platform-specific
-- binary executables, or false if it is a pure-Lua rock.
-function has_binaries(name, version)
+function repos.has_binaries(name, version)
assert(type(name) == "string")
assert(type(version) == "string")
@@ -123,7 +125,7 @@ function has_binaries(name, version)
return false
end
-function run_hook(rockspec, hook_name)
+function repos.run_hook(rockspec, hook_name)
assert(type(rockspec) == "table")
assert(type(hook_name) == "string")
@@ -153,19 +155,13 @@ end
local function install_binary(source, target, name, version)
assert(type(source) == "string")
assert(type(target) == "string")
-
- local match = source:match("%.lua$")
- local file, ok, err
- if not match then
- file = io.open(source)
- end
- if match or (file and file:read():match("^#!.*lua.*")) then
- ok, err = fs.wrap_script(source, target, name, version)
+
+ if fs.is_lua(source) then
+ repos.ok, repos.err = fs.wrap_script(source, target, name, version)
else
- ok, err = fs.copy_binary(source, target)
+ repos.ok, repos.err = fs.copy_binary(source, target)
end
- if file then file:close() end
- return ok, err
+ return repos.ok, repos.err
end
local function resolve_conflict(target, deploy_dir, name, version)
@@ -175,7 +171,8 @@ local function resolve_conflict(target, deploy_dir, name, version)
end
if name ~= cname or deps.compare_versions(version, cversion) then
local versioned = path.versioned_name(target, deploy_dir, cname, cversion)
- fs.make_dir(dir.dir_name(versioned))
+ local ok, err = fs.make_dir(dir.dir_name(versioned))
+ if not ok then return nil, err end
fs.move(target, versioned)
return target
else
@@ -183,7 +180,7 @@ local function resolve_conflict(target, deploy_dir, name, version)
end
end
-function should_wrap_bin_scripts(rockspec)
+function repos.should_wrap_bin_scripts(rockspec)
assert(type(rockspec) == "table")
if cfg.wrap_bin_scripts ~= nil then
@@ -195,7 +192,7 @@ function should_wrap_bin_scripts(rockspec)
return true
end
-function deploy_files(name, version, wrap_bin_scripts)
+function repos.deploy_files(name, version, wrap_bin_scripts)
assert(type(name) == "string")
assert(type(version) == "string")
assert(type(wrap_bin_scripts) == "boolean")
@@ -213,14 +210,20 @@ function deploy_files(name, version, wrap_bin_scripts)
if fs.exists(target) then
local new_target, err = resolve_conflict(target, deploy_dir, name, version)
if err == "untracked" then
- fs.delete(target)
+ local backup = target
+ repeat
+ backup = backup.."~"
+ until not fs.exists(backup) -- slight race condition here, but shouldn't be a problem.
+ util.printerr("Warning: "..target.." is not tracked by this installation of LuaRocks. Moving it to "..backup)
+ fs.move(target, backup)
elseif err then
return nil, err.." Cannot install new version."
else
target = new_target
end
end
- fs.make_dir(dir.dir_name(target))
+ ok, err = fs.make_dir(dir.dir_name(target))
+ if not ok then return nil, err end
ok, err = move_fn(source, target, name, version)
fs.remove_dir_tree_if_empty(dir.dir_name(source))
if not ok then return nil, err end
@@ -245,6 +248,21 @@ function deploy_files(name, version, wrap_bin_scripts)
return ok, err
end
+local function delete_suffixed(filename, suffix)
+ local filenames = { filename }
+ if suffix and suffix ~= "" then filenames = { filename..suffix, filename } end
+ for _, name in ipairs(filenames) do
+ if fs.exists(name) then
+ fs.delete(name)
+ if fs.exists(name) then
+ return nil, "Failed deleting "..name, "fail"
+ end
+ return true, name
+ end
+ end
+ return false, "File not found", "not found"
+end
+
--- Delete a package from the local repository.
-- Version numbers are compared as exact string comparison.
-- @param name string: name of package
@@ -253,32 +271,32 @@ end
-- of another version that provides the same module that
-- was deleted. This is used during 'purge', as every module
-- will be eventually deleted.
-function delete_version(name, version, quick)
+function repos.delete_version(name, version, quick)
assert(type(name) == "string")
assert(type(version) == "string")
- local function delete_deployed_file_tree(file_tree, deploy_dir)
+ local function delete_deployed_file_tree(file_tree, deploy_dir, suffix)
return recurse_rock_manifest_tree(file_tree,
function(parent_path, parent_module, file)
local target = dir.path(deploy_dir, parent_path, file)
local versioned = path.versioned_name(target, deploy_dir, name, version)
- if fs.exists(versioned) then
- local ok = fs.delete(versioned)
+ local ok, name, err = delete_suffixed(versioned, suffix)
+ if ok then
fs.remove_dir_tree_if_empty(dir.dir_name(versioned))
- if not ok then return nil, "Failed deleting "..versioned end
- else
- local ok = fs.delete(target)
- if not quick then
- local next_name, next_version = manif.find_next_provider(target)
- if next_name then
- local versioned = path.versioned_name(target, deploy_dir, next_name, next_version)
- fs.move(versioned, target)
- fs.remove_dir_tree_if_empty(dir.dir_name(versioned))
- end
+ return true
+ end
+ if err == "fail" then return nil, name end
+ ok, name, err = delete_suffixed(target, suffix)
+ if err == "fail" then return nil, name end
+ if not quick then
+ local next_name, next_version = manif.find_next_provider(target)
+ if next_name then
+ local versioned = path.versioned_name(name, deploy_dir, next_name, next_version)
+ fs.move(versioned, name)
+ fs.remove_dir_tree_if_empty(dir.dir_name(versioned))
end
- fs.remove_dir_tree_if_empty(dir.dir_name(target))
- if not ok then return nil, "Failed deleting "..target end
end
+ fs.remove_dir_tree_if_empty(dir.dir_name(target))
return true
end
)
@@ -291,7 +309,7 @@ function delete_version(name, version, quick)
local ok, err = true
if rock_manifest.bin then
- ok, err = delete_deployed_file_tree(rock_manifest.bin, cfg.deploy_bin_dir)
+ ok, err = delete_deployed_file_tree(rock_manifest.bin, cfg.deploy_bin_dir, cfg.wrapper_suffix)
end
if ok and rock_manifest.lua then
ok, err = delete_deployed_file_tree(rock_manifest.lua, cfg.deploy_lua_dir)
@@ -307,3 +325,5 @@ function delete_version(name, version, quick)
end
return true
end
+
+return repos
diff --git a/luarocks/src/luarocks/require.lua b/luarocks/src/luarocks/require.lua
index 9917770..902bd1a 100644
--- a/luarocks/src/luarocks/require.lua
+++ b/luarocks/src/luarocks/require.lua
@@ -1,6 +1,2 @@
--- Retained for compatibility reasons only. Use luarocks.loader instead.
-local require, pairs = require, pairs
-module("luarocks.require")
-for k,v in pairs(require("luarocks.loader")) do
- _M[k] = v
-end
+return require("luarocks.loader")
diff --git a/luarocks/src/luarocks/search.lua b/luarocks/src/luarocks/search.lua
index 1fc1f9a..5343938 100644
--- a/luarocks/src/luarocks/search.lua
+++ b/luarocks/src/luarocks/search.lua
@@ -1,7 +1,9 @@
--- Module implementing the LuaRocks "search" command.
-- Queries LuaRocks servers.
-module("luarocks.search", package.seeall)
+--module("luarocks.search", package.seeall)
+local search = {}
+package.loaded["luarocks.search"] = search
local dir = require("luarocks.dir")
local path = require("luarocks.path")
@@ -10,9 +12,9 @@ local deps = require("luarocks.deps")
local cfg = require("luarocks.cfg")
local util = require("luarocks.util")
-help_summary = "Query the LuaRocks servers."
-help_arguments = "[--source] [--binary] { <name> [<version>] | --all }"
-help = [[
+search.help_summary = "Query the LuaRocks servers."
+search.help_arguments = "[--source] [--binary] { <name> [<version>] | --all }"
+search.help = [[
--source Return only rockspecs and source rocks,
to be used with the "build" command.
--binary Return only pure Lua and binary rocks (rocks that can be used
@@ -124,7 +126,7 @@ end
-- @param table: The results table, where keys are package names and
-- versions are tables matching version strings to an array of servers.
-- If a table was given in the "results" parameter, that is the result value.
-function disk_search(repo, query, results)
+function search.disk_search(repo, query, results)
assert(type(repo) == "string")
assert(type(query) == "table")
assert(type(results) == "table" or not results)
@@ -136,17 +138,18 @@ function disk_search(repo, query, results)
end
query_arch_as_table(query)
- for _, name in pairs(fs.list_dir(repo)) do
+ for name in fs.dir(repo) do
local pathname = dir.path(repo, name)
local rname, rversion, rarch = path.parse_name(name)
- if fs.is_dir(pathname) then
- for _, version in pairs(fs.list_dir(pathname)) do
+
+ if rname and (pathname:match(".rockspec$") or pathname:match(".rock$")) then
+ store_if_match(results, repo, rname, rversion, rarch, query)
+ elseif fs.is_dir(pathname) then
+ for version in fs.dir(pathname) do
if version:match("-%d+$") then
store_if_match(results, repo, name, version, "installed", query)
end
end
- elseif rname then
- store_if_match(results, repo, rname, rversion, rarch, query)
end
end
return results
@@ -163,15 +166,15 @@ end
-- is used. The special value "any" is also recognized, returning all
-- matches regardless of architecture.
-- @return true or, in case of errors, nil and an error message.
-function manifest_search(results, repo, query)
+function search.manifest_search(results, repo, query)
assert(type(results) == "table")
assert(type(repo) == "string")
assert(type(query) == "table")
query_arch_as_table(query)
- local manifest, err = manif.load_manifest(repo)
+ local manifest, err, errcode = manif.load_manifest(repo)
if not manifest then
- return nil, "Failed loading manifest: "..err
+ return nil, err, errcode
end
for name, versions in pairs(manifest.repository) do
for version, items in pairs(versions) do
@@ -188,27 +191,37 @@ end
-- @return table: A table where keys are package names
-- and values are tables matching version strings to an array of
-- rocks servers; if no results are found, an empty table is returned.
-function search_repos(query)
+function search.search_repos(query)
assert(type(query) == "table")
local results = {}
for _, repo in ipairs(cfg.rocks_servers) do
- if type(repo) == "string" then
- repo = { repo }
- end
- for _, mirror in ipairs(repo) do
- local protocol, pathname = dir.split_url(mirror)
- if protocol == "file" then
- mirror = pathname
+ if not cfg.disabled_servers[repo] then
+ if type(repo) == "string" then
+ repo = { repo }
end
- local ok, err = manifest_search(results, mirror, query)
- if ok then
- break
- else
- util.warning("Failed searching manifest: "..err)
+ for _, mirror in ipairs(repo) do
+ local protocol, pathname = dir.split_url(mirror)
+ if protocol == "file" then
+ mirror = pathname
+ end
+ local ok, err, errcode = search.manifest_search(results, mirror, query)
+ if errcode == "network" then
+ cfg.disabled_servers[repo] = true
+ end
+ if ok then
+ break
+ else
+ util.warning("Failed searching manifest: "..err)
+ end
end
end
end
+ -- search through rocks in cfg.rocks_provided
+ local provided_repo = "provided by VM or rocks_provided"
+ for name, versions in pairs(cfg.rocks_provided) do
+ store_if_match(results, provided_repo, name, versions, "installed", query)
+ end
return results
end
@@ -216,7 +229,7 @@ end
-- @param name string: The query name.
-- @param version string or nil:
-- @return table: A query in table format
-function make_query(name, version)
+function search.make_query(name, version)
assert(type(name) == "string")
assert(type(version) == "string" or not version)
@@ -265,14 +278,20 @@ end
-- @return string or table or (nil, string): URL for matching rock if
-- a single one was found, a table of candidates if it could not narrow to
-- a single result, or nil followed by an error message.
-function find_suitable_rock(query)
+function search.find_suitable_rock(query)
assert(type(query) == "table")
- local results = search_repos(query)
+ local results = search.search_repos(query)
local first = next(results)
if not first then
return nil, "No results matching query were found."
elseif not next(results, first) then
+ if cfg.rocks_provided[query.name] ~= nil then
+ -- do not install versions that listed in cfg.rocks_provided
+ return nil, "Rock "..query.name..
+ " "..cfg.rocks_provided[query.name]..
+ " was found but it is provided by VM or 'rocks_provided' in the config file."
+ end
return pick_latest_version(query.name, results[first])
else
return results
@@ -283,7 +302,7 @@ end
-- @param results table: A table where keys are package names and versions
-- are tables matching version strings to an array of rocks servers.
-- @param porcelain boolean or nil: A flag to force machine-friendly output.
-function print_results(results, porcelain)
+function search.print_results(results, porcelain)
assert(type(results) == "table")
assert(type(porcelain) == "boolean" or not porcelain)
@@ -293,6 +312,7 @@ function print_results(results, porcelain)
end
for version, repos in util.sortedpairs(versions, deps.compare_versions) do
for _, repo in ipairs(repos) do
+ repo.repo = dir.normalize(repo.repo)
if porcelain then
util.printout(package, version, repo.arch, repo.repo)
else
@@ -337,14 +357,14 @@ end
-- @param name string: A rock name
-- @param version string or nil: A version number may also be given.
-- @return The result of the action function, or nil and an error message.
-function act_on_src_or_rockspec(action, name, version, ...)
+function search.act_on_src_or_rockspec(action, name, version, ...)
assert(type(action) == "function")
assert(type(name) == "string")
assert(type(version) == "string" or not version)
- local query = make_query(name, version)
+ local query = search.make_query(name, version)
query.arch = "src|rockspec"
- local results, err = find_suitable_rock(query)
+ local results, err = search.find_suitable_rock(query)
if type(results) == "string" then
return action(results, ...)
else
@@ -357,7 +377,7 @@ end
-- @param version string or nil: a version may also be passed.
-- @return boolean or (nil, string): True if build was successful; nil and an
-- error message otherwise.
-function run(...)
+function search.run(...)
local flags, name, version = util.parse_flags(...)
if flags["all"] then
@@ -368,19 +388,21 @@ function run(...)
return nil, "Enter name and version or use --all. "..util.see_help("search")
end
- local query = make_query(name:lower(), version)
+ local query = search.make_query(name:lower(), version)
query.exact_name = false
- local results, err = search_repos(query)
+ local results, err = search.search_repos(query)
local porcelain = flags["porcelain"]
util.title("Search results:", porcelain, "=")
local sources, binaries = split_source_and_binary_results(results)
if next(sources) and not flags["binary"] then
util.title("Rockspecs and source rocks:", porcelain)
- print_results(sources, porcelain)
+ search.print_results(sources, porcelain)
end
if next(binaries) and not flags["source"] then
util.title("Binary and pure-Lua rocks:", porcelain)
- print_results(binaries, porcelain)
+ search.print_results(binaries, porcelain)
end
return true
end
+
+return search
diff --git a/luarocks/src/luarocks/show.lua b/luarocks/src/luarocks/show.lua
index 536085a..3243c0c 100644
--- a/luarocks/src/luarocks/show.lua
+++ b/luarocks/src/luarocks/show.lua
@@ -1,19 +1,19 @@
-
--- Module implementing the LuaRocks "show" command.
-- Shows information about an installed rock.
-module("luarocks.show", package.seeall)
+--module("luarocks.show", package.seeall)
+local show = {}
+package.loaded["luarocks.show"] = show
local search = require("luarocks.search")
local cfg = require("luarocks.cfg")
local util = require("luarocks.util")
local path = require("luarocks.path")
-local dir = require("luarocks.dir")
local deps = require("luarocks.deps")
local fetch = require("luarocks.fetch")
local manif = require("luarocks.manif")
-help_summary = "Shows information about an installed rock."
+show.help_summary = "Shows information about an installed rock."
-help = [[
+show.help = [[
<argument> is an existing package name.
Without any flags, show all module information.
With these flags, return only the desired information:
@@ -55,33 +55,14 @@ local function format_text(text)
return (table.concat(paragraphs, "\n\n"):gsub("%s$", ""))
end
-local function module_name(mod, filename, name, version, repo, manifest)
- local base_dir
- if filename:match("%.lua$") then
- base_dir = path.deploy_lua_dir(repo)
- else
- base_dir = path.deploy_lib_dir(repo)
- end
-
- return dir.path(base_dir, filename)
-end
-
---- Driver function for "show" command.
--- @param name or nil: an existing package name.
--- @param version string or nil: a version may also be passed.
--- @return boolean: True if succeeded, nil on errors.
-function run(...)
- local flags, name, version = util.parse_flags(...)
- if not name then
- return nil, "Argument missing. "..util.see_help("show")
- end
+function show.pick_installed_rock(name, version, tree)
local results = {}
local query = search.make_query(name, version)
query.exact_name = true
local tree_map = {}
local trees = cfg.rocks_trees
- if flags["tree"] then
- trees = { flags["tree"] }
+ if tree then
+ trees = { tree }
end
for _, tree in ipairs(trees) do
local rocks_dir = path.rocks_dir(tree)
@@ -103,8 +84,26 @@ function run(...)
for _, rp in ipairs(repositories) do repo_url = rp.repo end
end
-
local repo = tree_map[repo_url]
+ return name, version, repo, repo_url
+end
+
+--- Driver function for "show" command.
+-- @param name or nil: an existing package name.
+-- @param version string or nil: a version may also be passed.
+-- @return boolean: True if succeeded, nil on errors.
+function show.run(...)
+ local flags, name, version = util.parse_flags(...)
+ if not name then
+ return nil, "Argument missing. "..util.see_help("show")
+ end
+
+ local repo, repo_url
+ name, version, repo, repo_url = show.pick_installed_rock(name, version, flags["tree"])
+ if not name then
+ return nil, version
+ end
+
local directory = path.install_dir(name,version,repo)
local rockspec_file = path.rockspec_file(name, version, repo)
local rockspec, err = fetch.load_local_rockspec(rockspec_file)
@@ -118,7 +117,7 @@ function run(...)
if flags["rock-tree"] then util.printout(path.rocks_tree_to_string(repo))
elseif flags["rock-dir"] then util.printout(directory)
elseif flags["home"] then util.printout(descript.homepage)
- elseif flags["modules"] then util.printout(keys_as_string(minfo.modules))
+ elseif flags["modules"] then util.printout(keys_as_string(minfo.modules, "\n"))
elseif flags["deps"] then util.printout(keys_as_string(minfo.dependencies))
elseif flags["rockspec"] then util.printout(rockspec_file)
elseif flags["mversion"] then util.printout(version)
@@ -154,3 +153,5 @@ function run(...)
return true
end
+
+return show
diff --git a/luarocks/src/luarocks/tools/patch.lua b/luarocks/src/luarocks/tools/patch.lua
index baaacfc..8df3093 100644
--- a/luarocks/src/luarocks/tools/patch.lua
+++ b/luarocks/src/luarocks/tools/patch.lua
@@ -6,12 +6,13 @@
-- Code is heavilly based on the Python-based patch.py version 8.06-1
-- Copyright (c) 2008 rainforce.org, MIT License
-- Project home: http://code.google.com/p/python-patch/ .
+-- Version 0.1
-module("luarocks.tools.patch", package.seeall)
+--module("luarocks.tools.patch", package.seeall)
+local patch = {}
local fs = require("luarocks.fs")
-
-local version = '0.1'
+local util = require("luarocks.util")
local io = io
local os = os
@@ -47,12 +48,6 @@ local function table_copy(t)
return t2
end
--- Returns boolean whether array t contains value v.
-local function array_contains(t, v)
- for _,v2 in ipairs(t) do if v == v2 then return true end end
- return false
-end
-
local function exists(filename)
local fh = io.open(filename)
local result = fh ~= nil
@@ -158,7 +153,7 @@ local function match_linerange(line)
return m1, m2, m3, m4
end
-function read_patch(filename, data)
+function patch.read_patch(filename, data)
-- define possible file regions that will direct the parser flow
local state = 'header'
-- 'header' - comments before the patch body
@@ -284,7 +279,7 @@ function read_patch(filename, data)
local advance
if state == 'filenames' then
if startswith(line, "--- ") then
- if array_contains(files.source, nextfileno) then
+ if util.array_contains(files.source, nextfileno) then
all_ok = false
warning(format("skipping invalid patch for %s",
files.source[nextfileno+1]))
@@ -304,7 +299,7 @@ function read_patch(filename, data)
table.insert(files.source, match)
end
elseif not startswith(line, "+++ ") then
- if array_contains(files.source, nextfileno) then
+ if util.array_contains(files.source, nextfileno) then
all_ok = false
warning(format("skipping invalid patch with no target for %s",
files.source[nextfileno+1]))
@@ -315,7 +310,7 @@ function read_patch(filename, data)
end
state = 'header'
else
- if array_contains(files.target, nextfileno) then
+ if util.array_contains(files.target, nextfileno) then
all_ok = false
warning(format("skipping invalid patch - double target at line %d",
lineno+1))
@@ -354,7 +349,7 @@ function read_patch(filename, data)
if not advance and state == 'hunkhead' then
local m1, m2, m3, m4 = match_linerange(line)
if not m1 then
- if not array_contains(files.hunks, nextfileno-1) then
+ if not util.array_contains(files.hunks, nextfileno-1) then
all_ok = false
warning(format("skipping invalid patch with no hunks for file %s",
files.target[nextfileno]))
@@ -401,7 +396,6 @@ local function find_hunk(file, h, hno)
for i=0,#file do
local found = true
local location = lineno
- local total = #h.text - fuzz
for l, hline in ipairs(h.text) do
if l > fuzz then
-- todo: \ No newline at the end of file
@@ -452,9 +446,6 @@ local function load_file(filename)
end
local function find_hunks(file, hunks)
- local matched = true
- local lineno = 1
- local hno = nil
for hno, h in ipairs(hunks) do
find_hunk(file, h, hno)
end
@@ -463,7 +454,6 @@ end
local function check_patched(file, hunks)
local matched = true
local lineno = 1
- local hno = nil
local ok, err = pcall(function()
if #file == 0 then
error 'nomatch'
@@ -569,15 +559,15 @@ local function strip_dirs(filename, strip)
return filename
end
-function apply_patch(patch, strip)
+function patch.apply_patch(the_patch, strip)
local all_ok = true
- local total = #patch.source
- for fileno, filename in ipairs(patch.source) do
+ local total = #the_patch.source
+ for fileno, filename in ipairs(the_patch.source) do
filename = strip_dirs(filename, strip)
local continue
local f2patch = filename
if not exists(f2patch) then
- f2patch = strip_dirs(patch.target[fileno], strip)
+ f2patch = strip_dirs(the_patch.target[fileno], strip)
f2patch = fs.absolute_name(f2patch)
if not exists(f2patch) then --FIX:if f2patch nil
warning(format("source/target file does not exist\n--- %s\n+++ %s",
@@ -598,7 +588,7 @@ function apply_patch(patch, strip)
info(format("processing %d/%d:\t %s", fileno, total, filename))
-- validate before patching
- local hunks = patch.hunks[fileno]
+ local hunks = the_patch.hunks[fileno]
local file = load_file(filename)
local hunkno = 1
local hunk = hunks[hunkno]
@@ -710,3 +700,5 @@ function apply_patch(patch, strip)
-- todo: check for premature eof
return all_ok
end
+
+return patch
diff --git a/luarocks/src/luarocks/tools/tar.lua b/luarocks/src/luarocks/tools/tar.lua
index ba01a41..03f7de3 100644
--- a/luarocks/src/luarocks/tools/tar.lua
+++ b/luarocks/src/luarocks/tools/tar.lua
@@ -1,6 +1,7 @@
--- A pure-Lua implementation of untar (unpacking .tar archives)
-module("luarocks.tools.tar", package.seeall)
+--module("luarocks.tools.tar", package.seeall)
+local tar = {}
local fs = require("luarocks.fs")
local dir = require("luarocks.dir")
@@ -82,7 +83,7 @@ local function read_header_block(block)
return header
end
-function untar(filename, destdir)
+function tar.untar(filename, destdir)
assert(type(filename) == "string")
assert(type(destdir) == "string")
@@ -119,11 +120,13 @@ function untar(filename, destdir)
end
local pathname = dir.path(destdir, header.name)
if header.typeflag == "directory" then
- fs.make_dir(pathname)
+ local ok, err = fs.make_dir(pathname)
+ if not ok then return nil, err end
elseif header.typeflag == "file" then
local dirname = dir.dir_name(pathname)
if dirname ~= "" then
- fs.make_dir(dirname)
+ local ok, err = fs.make_dir(dirname)
+ if not ok then return nil, err end
end
local file_handle = io.open(pathname, "wb")
file_handle:write(file_data)
@@ -142,3 +145,5 @@ function untar(filename, destdir)
end
return true
end
+
+return tar
diff --git a/luarocks/src/luarocks/tools/zip.lua b/luarocks/src/luarocks/tools/zip.lua
index 35428d9..40cc089 100644
--- a/luarocks/src/luarocks/tools/zip.lua
+++ b/luarocks/src/luarocks/tools/zip.lua
@@ -1,7 +1,8 @@
--- A Lua implementation of .zip file archiving (used for creating .rock files),
-- using only lua-zlib.
-module("luarocks.tools.zip", package.seeall)
+--module("luarocks.tools.zip", package.seeall)
+local zip = {}
local zlib = require("zlib")
local fs = require("luarocks.fs")
@@ -188,7 +189,7 @@ end
--- Return a zip handle open for writing.
-- @param name filename of the zipfile to be created.
-- @return a zip handle, or nil in case of error.
-function new_zipwriter(name)
+function zip.new_zipwriter(name)
local zw = {}
@@ -214,8 +215,8 @@ end
-- additional arguments.
-- @return boolean or (boolean, string): true on success,
-- false and an error message on failure.
-function zip(zipfile, ...)
- local zw = new_zipwriter(zipfile)
+function zip.zip(zipfile, ...)
+ local zw = zip.new_zipwriter(zipfile)
if not zw then
return nil, "error opening "..zipfile
end
@@ -243,3 +244,5 @@ function zip(zipfile, ...)
return ok, err
end
+
+return zip
diff --git a/luarocks/src/luarocks/type_check.lua b/luarocks/src/luarocks/type_check.lua
index 28e6e7b..a78c484 100644
--- a/luarocks/src/luarocks/type_check.lua
+++ b/luarocks/src/luarocks/type_check.lua
@@ -1,14 +1,15 @@
-
--- Type-checking functions.
-- Functions and definitions for doing a basic lint check on files
-- loaded by LuaRocks.
-module("luarocks.type_check", package.seeall)
+--module("luarocks.type_check", package.seeall)
+local type_check = {}
+package.loaded["luarocks.type_check"] = type_check
local cfg = require("luarocks.cfg")
-rockspec_format = "1.0"
+type_check.rockspec_format = "1.0"
-rockspec_types = {
+local rockspec_types = {
rockspec_format = "string",
MUST_package = "string",
MUST_version = "[%w.]+-[%d]+",
@@ -74,15 +75,22 @@ rockspec_types = {
}
}
-function load_extensions()
- rockspec_format = "1.1"
+type_check.rockspec_order = {"rockspec_format", "package", "version",
+ { "source", { "url", "tag", "branch", "md5" } },
+ { "description", {"summary", "detailed", "homepage", "license" } },
+ "supported_platforms", "dependencies", "external_dependencies",
+ { "build", {"type", "modules", "copy_directories", "platforms"} },
+ "hooks"}
+
+function type_check.load_extensions()
+ type_check.rockspec_format = "1.1"
rockspec_types.deploy = {
wrap_bin_scripts = true,
}
end
if cfg.use_extensions then
- load_extensions()
+ type_check.load_extensions()
end
rockspec_types.build.platforms.ANY = rockspec_types.build
@@ -91,7 +99,7 @@ rockspec_types.external_dependencies.platforms.ANY = rockspec_types.external_dep
rockspec_types.MUST_source.platforms.ANY = rockspec_types.MUST_source
rockspec_types.hooks.platforms.ANY = rockspec_types.hooks
-manifest_types = {
+local manifest_types = {
MUST_repository = {
-- packages
ANY = {
@@ -176,8 +184,10 @@ local function type_check_item(name, item, expected, context)
return nil, "Type mismatch on field "..context..name..": expected a string"
end
if expected ~= "string" then
- if not item:match("^"..expected.."$") then
- return nil, "Type mismatch on field "..context..name..": invalid value "..item
+ if item_type ~= "string" then
+ return nil, "Type mismatch on field "..context..name..": expected a string, got a "..type(item)
+ elseif not item:match("^"..expected.."$") then
+ return nil, "Type mismatch on field "..context..name..": invalid value "..item.." does not match '"..expected.."'"
end
end
elseif expected_type == "table" then
@@ -240,18 +250,35 @@ type_check_table = function(tbl, types, context)
return true
end
+local function check_undeclared_globals(globals, types)
+ local undeclared = {}
+ for glob, _ in pairs(globals) do
+ if not (types[glob] or types["MUST_"..glob]) then
+ table.insert(undeclared, glob)
+ end
+ end
+ if #undeclared == 1 then
+ return nil, "Unknown variable: "..undeclared[1]
+ elseif #undeclared > 1 then
+ return nil, "Unknown variables: "..table.concat(undeclared, ", ")
+ end
+ return true
+end
+
--- Type check a rockspec table.
-- Verify the correctness of elements from a
-- rockspec table, reporting on unknown fields and type
-- mismatches.
-- @return boolean or (nil, string): true if type checking
-- succeeded, or nil and an error message if it failed.
-function type_check_rockspec(rockspec)
+function type_check.type_check_rockspec(rockspec, globals)
assert(type(rockspec) == "table")
if rockspec.rockspec_format then
-- relies on global state
- load_extensions()
+ type_check.load_extensions()
end
+ local ok, err = check_undeclared_globals(globals, rockspec_types)
+ if not ok then return nil, err end
return type_check_table(rockspec, rockspec_types, "")
end
@@ -261,7 +288,11 @@ end
-- mismatches.
-- @return boolean or (nil, string): true if type checking
-- succeeded, or nil and an error message if it failed.
-function type_check_manifest(manifest)
+function type_check.type_check_manifest(manifest, globals)
assert(type(manifest) == "table")
+ local ok, err = check_undeclared_globals(globals, manifest_types)
+ if not ok then return nil, err end
return type_check_table(manifest, manifest_types, "")
end
+
+return type_check
diff --git a/luarocks/src/luarocks/unpack.lua b/luarocks/src/luarocks/unpack.lua
index 6715381..9204e26 100644
--- a/luarocks/src/luarocks/unpack.lua
+++ b/luarocks/src/luarocks/unpack.lua
@@ -1,7 +1,9 @@
--- Module implementing the LuaRocks "unpack" command.
-- Unpack the contents of a rock.
-module("luarocks.unpack", package.seeall)
+--module("luarocks.unpack", package.seeall)
+local unpack = {}
+package.loaded["luarocks.unpack"] = unpack
local fetch = require("luarocks.fetch")
local fs = require("luarocks.fs")
@@ -9,12 +11,14 @@ local util = require("luarocks.util")
local build = require("luarocks.build")
local dir = require("luarocks.dir")
-help_summary = "Unpack the contents of a rock."
-help_arguments = "{<rock>|<name> [<version>]}"
-help = [[
+unpack.help_summary = "Unpack the contents of a rock."
+unpack.help_arguments = "[--force] {<rock>|<name> [<version>]}"
+unpack.help = [[
Unpacks the contents of a rock in a newly created directory.
Argument may be a rock file, or the name of a rock in a rocks server.
In the latter case, the app version may be given as a second argument.
+
+--force Unpack files even if the output directory already exists.
]]
--- Load a rockspec file to the given directory, fetches the source
@@ -31,14 +35,17 @@ local function unpack_rockspec(rockspec_file, dir_name)
if not rockspec then
return nil, "Failed loading rockspec "..rockspec_file..": "..err
end
- fs.change_dir(dir_name)
+ local ok, err = fs.change_dir(dir_name)
+ if not ok then return nil, err end
local ok, sources_dir = fetch.fetch_sources(rockspec, true, ".")
if not ok then
return nil, sources_dir
end
- fs.change_dir(dir_name)
+ ok, err = fs.change_dir(sources_dir)
+ if not ok then return nil, err end
build.apply_patches(rockspec)
fs.pop_dir()
+ fs.pop_dir()
return rockspec
end
@@ -57,7 +64,8 @@ local function unpack_rock(rock_file, dir_name, kind)
if not ok then
return nil, "Failed unzipping rock "..rock_file, errcode
end
- fs.change_dir(dir_name)
+ ok, err = fs.change_dir(dir_name)
+ if not ok then return nil, err end
local rockspec_file = dir_name..".rockspec"
local rockspec, err = fetch.load_rockspec(rockspec_file)
if not rockspec then
@@ -69,7 +77,8 @@ local function unpack_rock(rock_file, dir_name, kind)
if not ok then
return nil, err
end
- fs.change_dir(rockspec.source.dir)
+ ok, err = fs.change_dir(rockspec.source.dir)
+ if not ok then return nil, err end
build.apply_patches(rockspec)
fs.pop_dir()
end
@@ -83,7 +92,7 @@ end
-- @param file string: A rockspec or .rock URL.
-- @return boolean or (nil, string): true if successful or nil followed
-- by an error message.
-local function run_unpacker(file)
+local function run_unpacker(file, force)
assert(type(file) == "string")
local base_name = dir.base_name(file)
@@ -95,11 +104,15 @@ local function run_unpacker(file)
if not extension then
return nil, file.." does not seem to be a valid filename."
end
-
- if (fs.exists(dir_name)) then
+
+ local exists = fs.exists(dir_name)
+ if exists and not force then
return nil, "Directory "..dir_name.." already exists."
end
- fs.make_dir(dir_name)
+ if not exists then
+ local ok, err = fs.make_dir(dir_name)
+ if not ok then return nil, err end
+ end
local rollback = util.schedule_function(fs.delete, fs.absolute_name(dir_name))
local rockspec, err
@@ -134,7 +147,7 @@ end
-- version may also be passed.
-- @return boolean or (nil, string): true if successful or nil followed
-- by an error message.
-function run(...)
+function unpack.run(...)
local flags, name, version = util.parse_flags(...)
assert(type(version) == "string" or not version)
@@ -143,9 +156,11 @@ function run(...)
end
if name:match(".*%.rock") or name:match(".*%.rockspec") then
- return run_unpacker(name)
+ return run_unpacker(name, flags["force"])
else
local search = require("luarocks.search")
return search.act_on_src_or_rockspec(run_unpacker, name, version)
end
end
+
+return unpack
diff --git a/luarocks/src/luarocks/upload.lua b/luarocks/src/luarocks/upload.lua
new file mode 100644
index 0000000..d87313a
--- /dev/null
+++ b/luarocks/src/luarocks/upload.lua
@@ -0,0 +1,92 @@
+
+local upload = {}
+
+local util = require("luarocks.util")
+local fetch = require("luarocks.fetch")
+local pack = require("luarocks.pack")
+local cfg = require("luarocks.cfg")
+local Api = require("luarocks.upload.api")
+
+upload.help_summary = "Upload a rockspec to the public rocks repository."
+upload.help_arguments = "[--skip-pack] [--api-key=<key>] [--force] <rockspec>"
+upload.help = [[
+<rockspec> Pack a source rock file (.src.rock extension),
+ upload rockspec and source rock to server.
+--skip-pack Do not pack and send source rock.
+--api-key=<key> Give it an API key. It will be stored for subsequent uses.
+--force Replace existing rockspec if the same revision of
+ a module already exists. This should be used only
+ in case of upload mistakes: when updating a rockspec,
+ increment the revision number instead.
+]]
+
+function upload.run(...)
+ local flags, fname = util.parse_flags(...)
+ if not fname then
+ return nil, "Missing rockspec. "..util.see_help("upload")
+ end
+
+ local api, err = Api.new(flags)
+ if not api then
+ return nil, err
+ end
+ if cfg.verbose then
+ api.debug = true
+ end
+
+ local rockspec, err, errcode = fetch.load_rockspec(fname)
+ if err then
+ return nil, err, errcode
+ end
+
+ util.printout("Sending " .. tostring(fname) .. " ...")
+ local res, err = api:method("check_rockspec", {
+ package = rockspec.package,
+ version = rockspec.version
+ })
+ if not res then return nil, err end
+
+ if not res.module then
+ util.printout("Will create new module (" .. tostring(rockspec.package) .. ")")
+ end
+ if res.version and not flags["force"] then
+ return nil, "Revision "..rockspec.version.." already exists on the server. "..util.see_help("upload")
+ end
+
+ local rock_fname
+ if not flags["skip-pack"] then
+ util.printout("Packing " .. tostring(rockspec.package))
+ rock_fname, err = pack.pack_source_rock(fname)
+ if not rock_fname then
+ return nil, err
+ end
+ end
+
+ local multipart = require("luarocks.upload.multipart")
+
+ res, err = api:method("upload", nil, {
+ rockspec_file = multipart.new_file(fname)
+ })
+ if not res then return nil, err end
+
+ if res.is_new and #res.manifests == 0 then
+ util.printerr("Warning: module not added to root manifest due to name taken.")
+ end
+
+ local module_url = res.module_url
+
+ if rock_fname then
+ util.printout(("Sending " .. tostring(rock_fname) .. " ..."))
+ res, err = api:method("upload_rock/" .. tostring(res.version.id), nil, {
+ rock_file = multipart.new_file(rock_fname)
+ })
+ if not res then return nil, err end
+ end
+
+ util.printout()
+ util.printout("Done: " .. tostring(module_url))
+ util.printout()
+ return true
+end
+
+return upload
diff --git a/luarocks/src/luarocks/upload/api.lua b/luarocks/src/luarocks/upload/api.lua
new file mode 100644
index 0000000..c588335
--- /dev/null
+++ b/luarocks/src/luarocks/upload/api.lua
@@ -0,0 +1,270 @@
+
+local api = {}
+
+local cfg = require("luarocks.cfg")
+local fs = require("luarocks.fs")
+local util = require("luarocks.util")
+local persist = require("luarocks.persist")
+local multipart = require("luarocks.upload.multipart")
+
+local Api = {}
+
+local function upload_config_file()
+ local _, _, home_conf, home_ok = cfg.which_config()
+ if not home_conf then
+ return nil
+ end
+ return (home_conf:gsub("/[^/]+$", "/upload_config.lua"))
+end
+
+function Api:load_config()
+ local upload_conf = upload_config_file()
+ print(upload_conf)
+ if not upload_conf then return nil end
+ local cfg, err = persist.load_into_table(upload_conf)
+ return cfg
+end
+
+function Api:save_config()
+ -- Test configuration before saving it.
+ local res, err = self:raw_method("status")
+ if not res then
+ return nil, err
+ end
+ if res.errors then
+ util.printerr("Server says: " .. tostring(res.errors[1]))
+ return
+ end
+ local upload_conf = upload_config_file()
+ if not upload_conf then return nil end
+ persist.save_from_table(upload_conf, self.config)
+ fs.chmod(upload_conf, "0600")
+end
+
+function Api:check_version()
+ if not self._server_tool_version then
+ local tool_version = cfg.upload.tool_version
+ local res, err = self:request(tostring(self.config.server) .. "/api/tool_version", {
+ current = tool_version
+ })
+ if not res then
+ return nil, err
+ end
+ if not res.version then
+ return nil, "failed to fetch tool version"
+ end
+ self._server_tool_version = res.version
+ if res.force_update then
+ return nil, "Your upload client is too out of date to continue, please upgrade LuaRocks."
+ end
+ if res.version ~= tool_version then
+ util.printerr("Warning: Your LuaRocks is out of date, consider upgrading.")
+ end
+ end
+ return true
+end
+
+function Api:method(...)
+ local res, err = self:raw_method(...)
+ if not res then
+ return nil, err
+ end
+ if res.errors then
+ if res.errors[1] == "Invalid key" then
+ return nil, res.errors[1] .. " (use the --api-key flag to change)"
+ end
+ local msg = table.concat(res.errors, ", ")
+ return nil, "API Failed: " .. msg
+ end
+ return res
+end
+
+function Api:raw_method(path, ...)
+ self:check_version()
+ local url = tostring(self.config.server) .. "/api/" .. tostring(cfg.upload.api_version) .. "/" .. tostring(self.config.key) .. "/" .. tostring(path)
+ return self:request(url, ...)
+end
+
+local function encode_query_string(t, sep)
+ if sep == nil then
+ sep = "&"
+ end
+ local i = 0
+ local buf = { }
+ for k, v in pairs(t) do
+ if type(k) == "number" and type(v) == "table" then
+ k, v = v[1], v[2]
+ end
+ buf[i + 1] = multipart.url_escape(k)
+ buf[i + 2] = "="
+ buf[i + 3] = multipart.url_escape(v)
+ buf[i + 4] = sep
+ i = i + 4
+ end
+ buf[i] = nil
+ return table.concat(buf)
+end
+
+-- An ode to the multitude of JSON libraries out there...
+local function require_json()
+ for _, lib in ipairs({ "cjson", "dkjson", "json" }) do
+ local json_ok, json = pcall(require, lib)
+ if json_ok then
+ return json_ok, json
+ end
+ end
+ return nil
+end
+
+local ltn12_ok, ltn12 = pcall(require, "ltn12")
+if not ltn12_ok then -- If not using LuaSocket and/or LuaSec...
+
+function Api:request(url, params, post_params)
+ local vars = cfg.variables
+ local json_ok, json = require_json()
+ if not json_ok then return nil, "A JSON library is required for this command." end
+
+ if cfg.downloader == "wget" then
+ local curl_ok = fs.execute_quiet(vars.CURL, "--version")
+ if not curl_ok then
+ return nil, "Missing network helper program 'curl'.\nMake sure 'curl' is installed and available from your path."
+ end
+ end
+
+ if not self.config.key then
+ return nil, "Must have API key before performing any actions."
+ end
+ local body
+ local headers = {}
+ if params and next(params) then
+ url = url .. ("?" .. encode_query_string(params))
+ end
+ local method = "GET"
+ local out
+ local tmpfile = fs.tmpname()
+ if post_params then
+ method = "POST"
+ local curl_cmd = fs.Q(vars.CURL).." -f -k -L --silent --user-agent \""..cfg.user_agent.." via curl\" "
+ for k,v in pairs(post_params) do
+ local var = v
+ if type(v) == "table" then
+ var = "@"..v.fname
+ end
+ curl_cmd = curl_cmd .. "--form \""..k.."="..var.."\" "
+ end
+ if cfg.connection_timeout and cfg.connection_timeout > 0 then
+ curl_cmd = curl_cmd .. "--connect-timeout "..tonumber(cfg.connection_timeout).." "
+ end
+ ok = fs.execute_string(curl_cmd..fs.Q(url).." -o "..fs.Q(tmpfile))
+ else
+ local ok, err = fs.download(url, tmpfile)
+ if not ok then
+ return nil, "API failure: " .. tostring(err) .. " - " .. tostring(url)
+ end
+ end
+
+ local tmpfd = io.open(tmpfile)
+ if not tmpfd then
+ os.remove(tmpfile)
+ return nil, "API failure reading temporary file - " .. tostring(url)
+ end
+ out = tmpfd:read("*a")
+ tmpfd:close()
+ os.remove(tmpfile)
+
+ if self.debug then
+ util.printout("[" .. tostring(method) .. " via curl] " .. tostring(url) .. " ... ")
+ end
+
+ return json.decode(out)
+end
+
+else -- use LuaSocket and LuaSec
+
+local warned_luasec = false
+
+function Api:request(url, params, post_params)
+ local json_ok, json = require_json()
+ if not json_ok then return nil, "A JSON library is required for this command." end
+ local server = tostring(self.config.server)
+ local http_ok, http
+ local via = "luasocket"
+ if server:match("^https://") then
+ http_ok, http = pcall(require, "ssl.https")
+ if http_ok then
+ via = "luasec"
+ else
+ if not warned_luasec then
+ util.printerr("LuaSec is not available; using plain HTTP. Install 'luasec' to enable HTTPS.")
+ warned_luasec = true
+ end
+ http_ok, http = pcall(require, "socket.http")
+ server = server:gsub("^https", "http")
+ url = url:gsub("^https", "http")
+ via = "luasocket"
+ end
+ else
+ http_ok, http = pcall(require, "socket.http")
+ end
+ if not http_ok then
+ return nil, "Failed loading socket library!"
+ end
+
+ if not self.config.key then
+ return nil, "Must have API key before performing any actions."
+ end
+ local body
+ local headers = {}
+ if params and next(params) then
+ url = url .. ("?" .. encode_query_string(params))
+ end
+ if post_params then
+ local boundary
+ body, boundary = multipart.encode(post_params)
+ headers["Content-length"] = #body
+ headers["Content-type"] = "multipart/form-data; boundary=" .. tostring(boundary)
+ end
+ local method = post_params and "POST" or "GET"
+ if self.debug then
+ util.printout("[" .. tostring(method) .. " via "..via.."] " .. tostring(url) .. " ... ")
+ end
+ local out = {}
+ local _, status = http.request({
+ url = url,
+ headers = headers,
+ method = method,
+ sink = ltn12.sink.table(out),
+ source = body and ltn12.source.string(body)
+ })
+ if self.debug then
+ util.printout(tostring(status))
+ end
+ if status ~= 200 then
+ return nil, "API returned " .. tostring(status) .. " - " .. tostring(url)
+ end
+ return json.decode(table.concat(out))
+end
+
+end
+
+function api.new(flags, name)
+ local self = {}
+ setmetatable(self, { __index = Api })
+ self.config = self:load_config() or {}
+ self.config.server = flags["server"] or self.config.server or cfg.upload.server
+ self.config.version = self.config.version or cfg.upload.version
+ self.config.key = flags["api-key"] or self.config.key
+ self.debug = flags["debug"]
+ if not self.config.key then
+ return nil, "You need an API key to upload rocks.\n" ..
+ "Navigate to "..self.config.server.."/settings to get a key\n" ..
+ "and then pass it through the --api-key=<key> flag."
+ end
+ if flags["api-key"] then
+ self:save_config()
+ end
+ return self
+end
+
+return api
+
diff --git a/luarocks/src/luarocks/upload/multipart.lua b/luarocks/src/luarocks/upload/multipart.lua
new file mode 100644
index 0000000..5677657
--- /dev/null
+++ b/luarocks/src/luarocks/upload/multipart.lua
@@ -0,0 +1,112 @@
+
+local multipart = {}
+
+local File = {}
+
+local unpack = unpack or table.unpack
+
+math.randomseed(os.time())
+
+-- socket.url.escape(s) from LuaSocket 3.0rc1
+function multipart.url_escape(s)
+ return (string.gsub(s, "([^A-Za-z0-9_])", function(c)
+ return string.format("%%%02x", string.byte(c))
+ end))
+end
+
+function File:mime()
+ if not self.mimetype then
+ local mimetypes_ok, mimetypes = pcall(require, "mimetypes")
+ if mimetypes_ok then
+ self.mimetype = mimetypes.guess(self.fname)
+ else
+ self.mimetype = "application/octet-stream"
+ end
+ end
+ return self.mimetype
+end
+
+function File:content()
+ local fd = io.open(self.fname)
+ if not fd then
+ return nil, "Failed to open file: "..self.fname
+ end
+ local data = fd:read("*a")
+ fd:close()
+ return data
+end
+
+local function rand_string(len)
+ local shuffled = {}
+ for i = 1, len do
+ local r = math.random(97, 122)
+ if math.random() >= 0.5 then
+ r = r - 32
+ end
+ shuffled[i] = r
+ end
+ return string.char(unpack(shuffled))
+end
+
+-- multipart encodes params
+-- returns encoded string,boundary
+-- params is an a table of tuple tables:
+-- params = {
+-- {key1, value2},
+-- {key2, value2},
+-- key3: value3
+-- }
+function multipart.encode(params)
+ local tuples = { }
+ for i = 1, #params do
+ tuples[i] = params[i]
+ end
+ for k,v in pairs(params) do
+ if type(k) == "string" then
+ table.insert(tuples, {k, v})
+ end
+ end
+ local chunks = {}
+ for _, tuple in ipairs(tuples) do
+ local k,v = unpack(tuple)
+ k = multipart.url_escape(k)
+ local buffer = { 'Content-Disposition: form-data; name="' .. k .. '"' }
+ local content
+ if type(v) == "table" and v.__class == File then
+ buffer[1] = buffer[1] .. ('; filename="' .. v.fname:gsub(".*/", "") .. '"')
+ table.insert(buffer, "Content-type: " .. v:mime())
+ content = v:content()
+ else
+ content = v
+ end
+ table.insert(buffer, "")
+ table.insert(buffer, content)
+ table.insert(chunks, table.concat(buffer, "\r\n"))
+ end
+ local boundary
+ while not boundary do
+ boundary = "Boundary" .. rand_string(16)
+ for _, chunk in ipairs(chunks) do
+ if chunk:find(boundary) then
+ boundary = nil
+ break
+ end
+ end
+ end
+ local inner = "\r\n--" .. boundary .. "\r\n"
+ return table.concat({ "--", boundary, "\r\n",
+ table.concat(chunks, inner),
+ "\r\n", "--", boundary, "--", "\r\n" }), boundary
+end
+
+function multipart.new_file(fname, mime)
+ local self = {}
+ setmetatable(self, { __index = File })
+ self.__class = File
+ self.fname = fname
+ self.mimetype = mime
+ return self
+end
+
+return multipart
+
diff --git a/luarocks/src/luarocks/util.lua b/luarocks/src/luarocks/util.lua
index ba20acf..8772883 100644
--- a/luarocks/src/luarocks/util.lua
+++ b/luarocks/src/luarocks/util.lua
@@ -4,9 +4,10 @@
-- inside specific functions) to avoid interdependencies,
-- as this is used in the bootstrapping stage of luarocks.cfg.
-local global_env = _G
+--module("luarocks.util", package.seeall)
+local util = {}
-module("luarocks.util", package.seeall)
+local unpack = unpack or table.unpack
local scheduled_functions = {}
local debug = require("debug")
@@ -18,7 +19,7 @@ local debug = require("debug")
-- @param ... arguments to be passed to function.
-- @return table: A token representing the scheduled execution,
-- which can be used to remove the item later from the list.
-function schedule_function(f, ...)
+function util.schedule_function(f, ...)
assert(type(f) == "function")
local item = { fn = f, args = {...} }
@@ -30,7 +31,7 @@ end
-- This is useful for cancelling a rollback of a completed operation.
-- @param item table: The token representing the scheduled function that was
-- returned from the schedule_function call.
-function remove_scheduled_function(item)
+function util.remove_scheduled_function(item)
for k, v in pairs(scheduled_functions) do
if v == item then
table.remove(scheduled_functions, k)
@@ -44,7 +45,7 @@ end
-- corresponding cleanup functions. Calling this function will run
-- these function, erasing temporaries.
-- Functions are executed in the inverse order they were scheduled.
-function run_scheduled_functions()
+function util.run_scheduled_functions()
local fs = require("luarocks.fs")
fs.change_dir_to_root()
for i = #scheduled_functions, 1, -1 do
@@ -58,7 +59,7 @@ end
-- so it does not include beginning- and end-of-string markers (^$)
-- @param s string: The input string
-- @return string: The equivalent pattern
-function matchquote(s)
+function util.matchquote(s)
return (s:gsub("[?%-+*%[%].%%()$^]","%%%1"))
end
@@ -67,7 +68,7 @@ end
-- For example, given "foo", "--tux=beep", "--bla", "bar", "--baz",
-- it would return the following:
-- {["bla"] = true, ["tux"] = "beep", ["baz"] = true}, "foo", "bar".
-function parse_flags(...)
+function util.parse_flags(...)
local args = {...}
local flags = {}
for i = #args, 1, -1 do
@@ -92,7 +93,7 @@ end
-- in the flags table. If no flags are passed as varargs, the
-- entire flags table is forwarded.
-- @return string... A variable number of strings
-function forward_flags(flags, ...)
+function util.forward_flags(flags, ...)
assert(type(flags) == "table")
local out = {}
local filter = select('#', ...)
@@ -121,14 +122,14 @@ end
-- @param dst Destination table, which will receive src's contents.
-- @param src Table which provides new contents to dst.
-- @see platform_overrides
-function deep_merge(dst, src)
+function util.deep_merge(dst, src)
for k, v in pairs(src) do
if type(v) == "table" then
if not dst[k] then
dst[k] = {}
end
if type(dst[k]) == "table" then
- deep_merge(dst[k], v)
+ util.deep_merge(dst[k], v)
else
dst[k] = v
end
@@ -151,7 +152,7 @@ end
-- tbl.x are preserved).
-- @param tbl table or nil: Table which may contain a "platforms" field;
-- if it doesn't (or if nil is passed), this function does nothing.
-function platform_overrides(tbl)
+function util.platform_overrides(tbl)
assert(type(tbl) == "table" or not tbl)
local cfg = require("luarocks.cfg")
@@ -162,7 +163,7 @@ function platform_overrides(tbl)
for _, platform in ipairs(cfg.platforms) do
local platform_tbl = tbl.platforms[platform]
if platform_tbl then
- deep_merge(tbl, platform_tbl)
+ util.deep_merge(tbl, platform_tbl)
end
end
end
@@ -194,15 +195,15 @@ end
-- @param needed_set: a set where keys are the names of
-- needed variables.
-- @param msg string: the warning message to display.
-function warn_if_not_used(var_defs, needed_set, msg)
+function util.warn_if_not_used(var_defs, needed_set, msg)
needed_set = make_shallow_copy(needed_set)
- for var,val in pairs(var_defs) do
+ for _, val in pairs(var_defs) do
for used in val:gmatch(var_format_pattern) do
needed_set[used] = nil
end
end
- for var,_ in pairs(needed_set) do
- warning(msg:format(var))
+ for var, _ in pairs(needed_set) do
+ util.warning(msg:format(var))
end
end
@@ -213,7 +214,7 @@ local function warn_failed_matches(line)
local any_failed = false
if line:match(var_format_pattern) then
for unmatched in line:gmatch(var_format_pattern) do
- warning("unmatched variable " .. unmatched)
+ util.warning("unmatched variable " .. unmatched)
any_failed = true
end
end
@@ -228,7 +229,7 @@ end
-- @param tbl table: Table to have its string values modified.
-- @param vars table: Table containing string-string key-value pairs
-- representing variables to replace in the strings values of tbl.
-function variable_substitutions(tbl, vars)
+function util.variable_substitutions(tbl, vars)
assert(type(tbl) == "table")
assert(type(vars) == "table")
@@ -249,7 +250,7 @@ end
--- Return an array of keys of a table.
-- @param tbl table: The input table.
-- @return table: The array of keys.
-function keys(tbl)
+function util.keys(tbl)
local ks = {}
for k,_ in pairs(tbl) do
table.insert(ks, k)
@@ -277,7 +278,7 @@ end
-- to be used by table.sort when sorting keys.
-- @see sortedpairs
local function sortedpairs_iterator(tbl, sort_function)
- local ks = keys(tbl)
+ local ks = util.keys(tbl)
if not sort_function or type(sort_function) == "function" then
table.sort(ks, sort_function or default_sort)
for _, k in ipairs(ks) do
@@ -315,41 +316,50 @@ end
-- is a string representing the field name, and the second element is a priority table
-- for that key.
-- @return function: the iterator function.
-function sortedpairs(tbl, sort_function)
+function util.sortedpairs(tbl, sort_function)
return coroutine.wrap(function() sortedpairs_iterator(tbl, sort_function) end)
end
-function starts_with(s, prefix)
+function util.lua_versions()
+ local versions = { "5.1", "5.2", "5.3" }
+ local i = 0
+ return function()
+ i = i + 1
+ return versions[i]
+ end
+end
+
+function util.starts_with(s, prefix)
return s:sub(1,#prefix) == prefix
end
--- Print a line to standard output
-function printout(...)
+function util.printout(...)
io.stdout:write(table.concat({...},"\t"))
io.stdout:write("\n")
end
--- Print a line to standard error
-function printerr(...)
+function util.printerr(...)
io.stderr:write(table.concat({...},"\t"))
io.stderr:write("\n")
end
--- Display a warning message.
-- @param msg string: the warning message
-function warning(msg)
- printerr("Warning: "..msg)
+function util.warning(msg)
+ util.printerr("Warning: "..msg)
end
-function title(msg, porcelain, underline)
+function util.title(msg, porcelain, underline)
if porcelain then return end
- printout()
- printout(msg)
- printout((underline or "-"):rep(#msg))
- printout()
+ util.printout()
+ util.printout(msg)
+ util.printout((underline or "-"):rep(#msg))
+ util.printout()
end
-function this_program(default)
+function util.this_program(default)
local i = 1
local last, cur = default, default
while i do
@@ -362,13 +372,32 @@ function this_program(default)
return last:sub(2)
end
-function see_help(command, program)
- return "See '"..this_program(program or "luarocks")..' help '..command.."'."
+function util.deps_mode_help(program)
+ local cfg = require("luarocks.cfg")
+ return [[
+--deps-mode=<mode> How to handle dependencies. Four modes are supported:
+ * all - use all trees from the rocks_trees list
+ for finding dependencies
+ * one - use only the current tree (possibly set
+ with --tree)
+ * order - use trees based on order (use the current
+ tree and all trees below it on the rocks_trees list)
+ * none - ignore dependencies altogether.
+ The default mode may be set with the deps_mode entry
+ in the configuration file.
+ The current default is "]]..cfg.deps_mode..[[".
+ Type ']]..util.this_program(program or "luarocks")..[[' with no arguments to see
+ your list of rocks trees.
+]]
+end
+
+function util.see_help(command, program)
+ return "See '"..util.this_program(program or "luarocks")..' help'..(command and " "..command or "").."'."
end
-- from http://lua-users.org/wiki/SplitJoin
-- by PhilippeLhoste
-function split_string(str, delim, maxNb)
+function util.split_string(str, delim, maxNb)
-- Eliminate bad cases...
if string.find(str, delim) == nil then
return { str }
@@ -397,12 +426,13 @@ end
-- Example: given ("a;b;c;a;b;d", ";"), returns "a;b;c;d".
-- @param list string: A path string (from $PATH or package.path)
-- @param sep string: The separator
-function remove_path_dupes(list, sep)
+function util.remove_path_dupes(list, sep)
assert(type(list) == "string")
assert(type(sep) == "string")
- local parts = split_string(list, sep)
+ local parts = util.split_string(list, sep)
local final, entries = {}, {}
for _, part in ipairs(parts) do
+ part = part:gsub("//", "/")
if not entries[part] then
table.insert(final, part)
entries[part] = true
@@ -428,7 +458,7 @@ end
-- @param name string: is the name of the table (optional)
-- @param indent string: is a first indentation (optional).
-- @return string: the pretty-printed table
-function show_table(t, name, indent)
+function util.show_table(t, name, indent)
local cart -- a container
local autoref -- for self references
@@ -494,7 +524,7 @@ function show_table(t, name, indent)
return cart .. autoref
end
-function array_contains(tbl, value)
+function util.array_contains(tbl, value)
for _, v in ipairs(tbl) do
if v == value then
return true
@@ -502,3 +532,12 @@ function array_contains(tbl, value)
end
return false
end
+
+-- Quote Lua string, analogous to fs.Q.
+-- @param s A string, such as "hello"
+-- @return string: A quoted string, such as '"hello"'
+function util.LQ(s)
+ return ("%q"):format(s)
+end
+
+return util
diff --git a/luarocks/src/luarocks/validate.lua b/luarocks/src/luarocks/validate.lua
index 1e1e69e..e6e09c3 100644
--- a/luarocks/src/luarocks/validate.lua
+++ b/luarocks/src/luarocks/validate.lua
@@ -1,6 +1,8 @@
--- Sandboxed test of build/install of all packages in a repository (unfinished and disabled).
-module("luarocks.validate", package.seeall)
+--module("luarocks.validate", package.seeall)
+local validate = {}
+package.loaded["luarocks.validate"] = validate
local fs = require("luarocks.fs")
local dir = require("luarocks.dir")
@@ -10,9 +12,9 @@ local build = require("luarocks.build")
local install = require("luarocks.install")
local util = require("luarocks.util")
-help_summary = "Sandboxed test of build/install of all packages in a repository."
+validate.help_summary = "Sandboxed test of build/install of all packages in a repository."
-help = [[
+validate.help = [[
<argument>, if given, is a local repository pathname.
]]
@@ -73,7 +75,12 @@ local function validate_rock(file)
return ok, err, errcode
end
-local function validate(repo, flags)
+function validate.run(...)
+ local flags, repo = util.parse_flags(...)
+ repo = repo or cfg.rocks_dir
+
+ util.printout("Verifying contents of "..repo)
+
local results = {
ok = {}
}
@@ -85,7 +92,7 @@ local function validate(repo, flags)
if not fs.exists(repo) then
return nil, repo.." is not a local repository."
end
- for _, file in pairs(fs.list_dir(repo)) do for _=1,1 do
+ for file in fs.dir(repo) do for _=1,1 do
if file == "manifest" or file == "index.html" then
break -- continue for
end
@@ -149,12 +156,5 @@ local function validate(repo, flags)
return true
end
-function run(...)
- local flags, repo = util.parse_flags(...)
- repo = repo or cfg.rocks_dir
-
- util.printout("Verifying contents of "..repo)
-
- return validate(repo, flags)
-end
+return validate
diff --git a/luarocks/src/luarocks/write_rockspec.lua b/luarocks/src/luarocks/write_rockspec.lua
new file mode 100644
index 0000000..403cbc8
--- /dev/null
+++ b/luarocks/src/luarocks/write_rockspec.lua
@@ -0,0 +1,340 @@
+
+--module("luarocks.write_rockspec", package.seeall)
+local write_rockspec = {}
+package.loaded["luarocks.write_rockspec"] = write_rockspec
+
+local dir = require("luarocks.dir")
+local fetch = require("luarocks.fetch")
+local fs = require("luarocks.fs")
+local path = require("luarocks.path")
+local persist = require("luarocks.persist")
+local type_check = require("luarocks.type_check")
+local util = require("luarocks.util")
+
+write_rockspec.help_summary = "Write a template for a rockspec file."
+write_rockspec.help_arguments = "[--output=<file> ...] [<name>] [<version>] {<url>|<path>}"
+write_rockspec.help = [[
+This command writes an initial version of a rockspec file,
+based on an URL or a local path. You may use a relative path such as '.'.
+If a local path is given, name and version arguments are mandatory.
+For URLs, LuaRocks will attempt to infer name and version if not given.
+
+If a repository URL is given with no version, it creates an 'scm' rock.
+
+Note that the generated file is a _starting point_ for writing a
+rockspec, and is not guaranteed to be complete or correct.
+
+--output=<file> Write the rockspec with the given filename.
+ If not given, a file is written in the current
+ directory with a filename based on given name and version.
+--license="<string>" A license string, such as "MIT/X11" or "GNU GPL v3".
+--summary="<txt>" A short one-line description summary.
+--detailed="<txt>" A longer description string.
+--homepage=<url> Project homepage.
+--lua-version=<ver> Supported Lua versions. Accepted values are "5.1", "5.2",
+ "5.3", "5.1,5.2", "5.2,5.3", or "5.1,5.2,5.3".
+--tag=<tag> Tag to use. Will attempt to extract version number from it.
+--lib=<lib>[,<lib>] A comma-separated list of libraries that C files need to
+ link to.
+]]
+
+local function open_file(name)
+ return io.open(dir.path(fs.current_dir(), name), "r")
+end
+
+local function get_url(rockspec)
+ local file, temp_dir, err_code, err_file, err_temp_dir = fetch.fetch_sources(rockspec, false)
+ if err_code == "source.dir" then
+ file, temp_dir = err_file, err_temp_dir
+ elseif not file then
+ util.warning("Could not fetch sources - "..temp_dir)
+ return false
+ end
+ util.printout("File successfully downloaded. Making checksum and checking base dir...")
+ if fetch.is_basic_protocol(rockspec.source.protocol) then
+ rockspec.source.md5 = fs.get_md5(file)
+ end
+ local inferred_dir, found_dir = fetch.find_base_dir(file, temp_dir, rockspec.source.url)
+ return true, found_dir or inferred_dir, temp_dir
+end
+
+local function configure_lua_version(rockspec, luaver)
+ if luaver == "5.1" then
+ table.insert(rockspec.dependencies, "lua ~> 5.1")
+ elseif luaver == "5.2" then
+ table.insert(rockspec.dependencies, "lua ~> 5.2")
+ elseif luaver == "5.3" then
+ table.insert(rockspec.dependencies, "lua ~> 5.3")
+ elseif luaver == "5.1,5.2" then
+ table.insert(rockspec.dependencies, "lua >= 5.1, < 5.3")
+ elseif luaver == "5.2,5.3" then
+ table.insert(rockspec.dependencies, "lua >= 5.2, < 5.4")
+ elseif luaver == "5.1,5.2,5.3" then
+ table.insert(rockspec.dependencies, "lua >= 5.1, < 5.4")
+ else
+ util.warning("Please specify supported Lua version with --lua-version=<ver>. "..util.see_help("write_rockspec"))
+ end
+end
+
+local function detect_description(rockspec)
+ local fd = open_file("README.md") or open_file("README")
+ if not fd then return end
+ local data = fd:read("*a")
+ fd:close()
+ local paragraph = data:match("\n\n([^%[].-)\n\n")
+ if not paragraph then paragraph = data:match("\n\n(.*)") end
+ if paragraph then
+ if #paragraph < 80 then
+ rockspec.description.summary = paragraph:gsub("\n", "")
+ rockspec.description.detailed = paragraph
+ else
+ local summary = paragraph:gsub("\n", " "):match("([^.]*%.) ")
+ if summary then
+ rockspec.description.summary = summary:gsub("\n", "")
+ end
+ rockspec.description.detailed = paragraph
+ end
+ end
+end
+
+local function detect_mit_license(data)
+ local strip_copyright = (data:gsub("Copyright [^\n]*\n", ""))
+ local sum = 0
+ for i = 1, #strip_copyright do
+ local num = string.byte(strip_copyright:sub(i,i))
+ if num > 32 and num <= 128 then
+ sum = sum + num
+ end
+ end
+ return sum == 78656
+end
+
+local function show_license(rockspec)
+ local fd = open_file("COPYING") or open_file("LICENSE") or open_file("MIT-LICENSE.txt")
+ if not fd then return nil end
+ local data = fd:read("*a")
+ fd:close()
+ local is_mit = detect_mit_license(data)
+ util.title("License for "..rockspec.package..":")
+ util.printout(data)
+ util.printout()
+ return is_mit
+end
+
+local function get_cmod_name(file)
+ local fd = open_file(file)
+ if not fd then return nil end
+ local data = fd:read("*a")
+ fd:close()
+ return (data:match("int%s+luaopen_([a-zA-Z0-9_]+)"))
+end
+
+local luamod_blacklist = {
+ test = true,
+ tests = true,
+}
+
+local function fill_as_builtin(rockspec, libs)
+ rockspec.build.type = "builtin"
+ rockspec.build.modules = {}
+ local prefix = ""
+
+ for _, parent in ipairs({"src", "lua"}) do
+ if fs.is_dir(parent) then
+ fs.change_dir(parent)
+ prefix = parent.."/"
+ break
+ end
+ end
+
+ local incdirs, libdirs
+ if libs then
+ incdirs, libdirs = {}, {}
+ for _, lib in ipairs(libs) do
+ local upper = lib:upper()
+ incdirs[#incdirs+1] = "$("..upper.."_INCDIR)"
+ libdirs[#libdirs+1] = "$("..upper.."_LIBDIR)"
+ end
+ end
+
+ for _, file in ipairs(fs.find()) do
+ local luamod = file:match("(.*)%.lua$")
+ if luamod and not luamod_blacklist[luamod] then
+ rockspec.build.modules[path.path_to_module(file)] = prefix..file
+ else
+ local cmod = file:match("(.*)%.c$")
+ if cmod then
+ local modname = get_cmod_name(file) or path.path_to_module(file:gsub("%.c$", ".lua"))
+ rockspec.build.modules[modname] = {
+ sources = prefix..file,
+ libraries = libs,
+ incdirs = incdirs,
+ libdirs = libdirs,
+ }
+ end
+ end
+ end
+
+ for _, directory in ipairs({ "doc", "docs", "samples", "tests" }) do
+ if fs.is_dir(directory) then
+ if not rockspec.build.copy_directories then
+ rockspec.build.copy_directories = {}
+ end
+ table.insert(rockspec.build.copy_directories, directory)
+ end
+ end
+
+ if prefix ~= "" then
+ fs.pop_dir()
+ end
+end
+
+local function rockspec_cleanup(rockspec)
+ rockspec.source.file = nil
+ rockspec.source.protocol = nil
+ rockspec.variables = nil
+ rockspec.name = nil
+end
+
+function write_rockspec.run(...)
+ local flags, name, version, url_or_dir = util.parse_flags(...)
+
+ if not name then
+ return nil, "Missing arguments. "..util.see_help("write_rockspec")
+ end
+
+ if name and not version then
+ url_or_dir = name
+ name = nil
+ elseif not url_or_dir then
+ url_or_dir = version
+ end
+
+ if flags["tag"] == true then
+ return nil, "Incorrect usage: --tag requires an argument. "..util.see_help("write_rockspec")
+ end
+
+ if flags["tag"] then
+ if not version then
+ version = flags["tag"]:gsub("^v", "")
+ end
+ end
+
+ local protocol, pathname = dir.split_url(url_or_dir)
+ if not fetch.is_basic_protocol(protocol) then
+ if not name then
+ name = dir.base_name(url_or_dir):gsub("%.[^.]+$", "")
+ end
+ if not version then
+ version = "scm"
+ end
+ elseif protocol ~= "file" then
+ local filename = dir.base_name(url_or_dir)
+ local newname, newversion = filename:match("(.*)-([^-]+)")
+ if (not name) and newname then
+ name = newname
+ end
+ if (not version) and newversion then
+ version = newversion:gsub(".[a-z]+$", ""):gsub(".tar$", "")
+ end
+ if not (name and version) then
+ return nil, "Missing name and version arguments. "..util.see_help("write_rockspec")
+ end
+ elseif not version then
+ return nil, "Missing name and version arguments. "..util.see_help("write_rockspec")
+ end
+
+ local filename = flags["output"] or dir.path(fs.current_dir(), name:lower().."-"..version.."-1.rockspec")
+
+ if not flags["homepage"] and url_or_dir:match("^git://github.com") then
+ flags["homepage"] = "http://"..url_or_dir:match("^[^:]+://(.*)")
+ end
+
+ local rockspec = {
+ package = name,
+ name = name:lower(),
+ version = version.."-1",
+ source = {
+ url = "*** please add URL for source tarball, zip or repository here ***",
+ tag = flags["tag"],
+ },
+ description = {
+ summary = flags["summary"] or "*** please specify description summary ***",
+ detailed = flags["detailed"] or "*** please enter a detailed description ***",
+ homepage = flags["homepage"] or "*** please enter a project homepage ***",
+ license = flags["license"] or "*** please specify a license ***",
+ },
+ dependencies = {},
+ build = {},
+ }
+ path.configure_paths(rockspec)
+ rockspec.source.protocol = protocol
+
+ configure_lua_version(rockspec, flags["lua-version"])
+
+ local local_dir = url_or_dir
+
+ if url_or_dir:match("://") then
+ rockspec.source.url = url_or_dir
+ rockspec.source.file = dir.base_name(url_or_dir)
+ rockspec.source.dir = "dummy"
+ if not fetch.is_basic_protocol(rockspec.source.protocol) then
+ if version ~= "scm" then
+ rockspec.source.tag = flags["tag"] or "v" .. version
+ end
+ end
+ rockspec.source.dir = nil
+ local ok, base_dir, temp_dir = get_url(rockspec)
+ if ok then
+ if base_dir ~= dir.base_name(url_or_dir) then
+ rockspec.source.dir = base_dir
+ end
+ end
+ if base_dir then
+ local_dir = dir.path(temp_dir, base_dir)
+ else
+ local_dir = nil
+ end
+ end
+
+ if not local_dir then
+ local_dir = "."
+ end
+
+ local libs = nil
+ if flags["lib"] then
+ libs = {}
+ rockspec.external_dependencies = {}
+ for lib in flags["lib"]:gmatch("([^,]+)") do
+ table.insert(libs, lib)
+ rockspec.external_dependencies[lib:upper()] = {
+ library = lib
+ }
+ end
+ end
+
+ local ok, err = fs.change_dir(local_dir)
+ if not ok then return nil, "Failed reaching files from project - error entering directory "..local_dir end
+
+ detect_description(rockspec)
+
+ local is_mit = show_license(rockspec)
+
+ if is_mit and not flags["license"] then
+ rockspec.description.license = "MIT"
+ end
+
+ fill_as_builtin(rockspec, libs)
+
+ rockspec_cleanup(rockspec)
+
+ persist.save_from_table(filename, rockspec, type_check.rockspec_order)
+
+ util.printout()
+ util.printout("Wrote template at "..filename.." -- you should now edit and finish it.")
+ util.printout()
+
+ return true
+end
+
+return write_rockspec
diff --git a/luarocks/test/testfiles/missing_external-0.1-1.rockspec b/luarocks/test/testfiles/missing_external-0.1-1.rockspec
new file mode 100644
index 0000000..5f8e621
--- /dev/null
+++ b/luarocks/test/testfiles/missing_external-0.1-1.rockspec
@@ -0,0 +1,24 @@
+package = "missing_external"
+version = "0.1-1"
+source = {
+ -- any valid URL
+ url = "https://raw.github.com/keplerproject/luarocks/master/src/luarocks/build.lua"
+}
+description = {
+ summary = "Missing external dependency",
+}
+external_dependencies = {
+ INEXISTENT = {
+ library = "inexistentlib*",
+ header = "inexistentheader*.h",
+ }
+}
+dependencies = {
+ "lua >= 5.1"
+}
+build = {
+ type = "builtin",
+ modules = {
+ build = "build.lua"
+ }
+}
diff --git a/luarocks/test/testing.sh b/luarocks/test/testing.sh
index c06bd27..b0d95c3 100755
--- a/luarocks/test/testing.sh
+++ b/luarocks/test/testing.sh
@@ -1,4 +1,4 @@
-#!/bin/sh -e
+#!/bin/bash -e
# Setup #########################################
@@ -7,13 +7,45 @@
exit 1
}
+if [ -z "$*" ]
+then
+ ps aux | grep -q '[s]shd' || {
+ echo "Run sudo /bin/sshd in order to perform all tests."
+ exit 1
+ }
+fi
+
+if [ "$1" == "--travis" ]
+then
+ travis=true
+ shift
+fi
+
+luaversion=5.1.5
+
+if [ "$1" == "--lua" ]
+then
+ shift
+ luaversion=$1
+ shift
+fi
+
testing_dir="$PWD"
-testing_tree="$testing_dir/testing"
-testing_sys_tree="$testing_dir/testing_sys"
-testing_tree_copy="$testing_dir/testing_copy"
-testing_sys_tree_copy="$testing_dir/testing_sys_copy"
-testing_cache="$testing_dir/testing_cache"
+testing_tree="$testing_dir/testing-$luaversion"
+testing_sys_tree="$testing_dir/testing_sys-$luaversion"
+testing_tree_copy="$testing_dir/testing_copy-$luaversion"
+testing_sys_tree_copy="$testing_dir/testing_sys_copy-$luaversion"
+testing_cache="$testing_dir/testing_cache-$luaversion"
+testing_server="$testing_dir/testing_server-$luaversion"
+
+
+if [ "$1" == "--clean" ]
+then
+ shift
+ rm -rf "$testing_cache"
+ rm -rf "$testing_server"
+fi
[ "$1" ] || rm -f luacov.stats.out
rm -f luacov.report.out
@@ -23,12 +55,25 @@ rm -rf "$testing_tree"
rm -rf "$testing_sys_tree"
rm -rf "$testing_tree_copy"
rm -rf "$testing_sys_tree_copy"
-rm -rf "$testing_cache"
+rm -rf "$testing_dir/testing_config.lua"
+rm -rf "$testing_dir/testing_config_show_downloads.lua"
+rm -rf "$testing_dir/testing_config_sftp.lua"
+rm -rf "$testing_dir/luacov.config"
+
+mkdir -p "$testing_cache"
+
+[ "$1" = "clean" ] && {
+ rm -f luacov.stats.out
+ exit 0
+}
cat <<EOF > $testing_dir/testing_config.lua
rocks_trees = {
"$testing_tree",
- "$testing_sys_tree",
+ { name = "system", root = "$testing_sys_tree" },
+}
+rocks_servers = {
+ "$testing_server"
}
local_cache = "$testing_cache"
upload_server = "testing"
@@ -38,7 +83,23 @@ upload_servers = {
rsync = "localhost/tmp/luarocks_testing",
},
}
+external_deps_dirs = {
+ "/usr/local",
+ "/usr",
+ -- These are used for a test that fails, so it
+ -- can point to invalid paths:
+ {
+ prefix = "/opt",
+ bin = "bin",
+ include = "include",
+ lib = { "lib", "lib64" },
+ }
+}
EOF
+(
+ cat $testing_dir/testing_config.lua
+ echo "show_downloads = true"
+) > $testing_dir/testing_config_show_downloads.lua
cat <<EOF > $testing_dir/testing_config_sftp.lua
rocks_trees = {
"$testing_tree",
@@ -76,23 +137,123 @@ export LUAROCKS_CONFIG="$testing_dir/testing_config.lua"
export LUA_PATH=
export LUA_CPATH=
-luadir="/Programs/Lua/Current"
+if [ "$travis" ]
+then
+ luadir=/tmp/lua-$luaversion
+ pushd /tmp
+ if [ ! -e "$luadir/bin/lua" ]
+ then
+ mkdir -p lua
+ echo "Downloading lua $luaversion..."
+ wget "http://www.lua.org/ftp/lua-$luaversion.tar.gz" &> /dev/null
+ tar zxpf "lua-$luaversion.tar.gz"
+ cd "lua-$luaversion"
+ echo "Building lua $luaversion..."
+ make linux INSTALL_TOP="$luadir" &> /dev/null
+ make install INSTALL_TOP="$luadir" &> /dev/null
+ fi
+ popd
+else
+ luadir="/Programs/Lua/Current"
+fi
+
+if [ `uname -m` = i686 ]
+then
+ platform="linux-x86"
+else
+ platform="linux-x86_64"
+fi
+
lua="$luadir/bin/lua"
+version_luasocket=3.0rc1
+verrev_luasocket=${version_luasocket}-1
+srcdir_luasocket=luasocket-3.0-rc1
+
+version_cprint=0.1
+verrev_cprint=0.1-1
+
+version_luacov=0.5
+verrev_luacov=0.5-1
+version_lxsh=0.8.6
+version_validate_args=1.5.4
+verrev_validate_args=1.5.4-1
+verrev_lxsh=${version_lxsh}-2
+
+luasec=luasec
+
cd ..
./configure --with-lua="$luadir"
make clean
make src/luarocks/site_config.lua
make dev
cd src
-
-echo $LUA_PATH
-
-luarocks_nocov="$lua $PWD/bin/luarocks"
-luarocks="$lua -erequire('luacov.runner')('$testing_dir/luacov.config') $PWD/bin/luarocks"
-luarocks_admin="$lua -erequire('luacov.runner')('$testing_dir/luacov.config') $PWD/bin/luarocks-admin"
-
-$luarocks_nocov download luacov
+basedir=$PWD
+run_lua() {
+ if [ "$1" = "--noecho" ]; then shift; noecho=1; else noecho=0; fi
+ if [ "$1" = "--nocov" ]; then shift; nocov=1; else nocov=0; fi
+ if [ "$noecho" = 0 ]
+ then
+ echo $*
+ fi
+ cmd=$1
+ shift
+ if [ "$nocov" = 0 ]
+ then
+ "$lua" -e"require('luacov.runner')('$testing_dir/luacov.config')" "$basedir/bin/$cmd" "$@"
+ else
+ "$lua" "$basedir/bin/$cmd" "$@"
+ fi
+}
+luarocks="run_lua luarocks"
+luarocks_nocov="run_lua --nocov luarocks"
+luarocks_noecho="run_lua --noecho luarocks"
+luarocks_noecho_nocov="run_lua --noecho --nocov luarocks"
+luarocks_admin="run_lua luarocks-admin"
+luarocks_admin_nocov="run_lua --nocov luarocks-admin"
+
+###################################################
+
+mkdir -p "$testing_server"
+(
+ cd "$testing_server"
+ luarocks_repo="http://luarocks.org/repositories/rocks"
+ luarocks_scm_repo="http://luarocks.org/repositories/rocks-scm"
+ get() { [ -e `basename "$1"` ] || wget -c "$1"; }
+ get "$luarocks_repo/luacov-${verrev_luacov}.src.rock"
+ get "$luarocks_repo/luacov-${verrev_luacov}.rockspec"
+ get "$luarocks_repo/luadoc-3.0.1-1.src.rock"
+ get "$luarocks_repo/lualogging-1.3.0-1.src.rock"
+ get "$luarocks_repo/luasocket-${verrev_luasocket}.src.rock"
+ get "$luarocks_repo/luasocket-${verrev_luasocket}.rockspec"
+ get "$luarocks_repo/luafilesystem-1.6.2-1.src.rock"
+ get "$luarocks_repo/stdlib-35-1.src.rock"
+ get "$luarocks_repo/luarepl-0.4-1.src.rock"
+ get "$luarocks_repo/validate-args-1.5.4-1.rockspec"
+ get "$luarocks_scm_repo/luasec-scm-1.rockspec"
+ get "$luarocks_repo/luabitop-1.0.2-1.rockspec"
+ get "$luarocks_repo/lpty-1.0.1-1.src.rock"
+ get "$luarocks_repo/cprint-${verrev_cprint}.src.rock"
+ get "$luarocks_repo/cprint-${verrev_cprint}.rockspec"
+ get "$luarocks_repo/wsapi-1.6-1.src.rock"
+ get "$luarocks_repo/lxsh-${verrev_lxsh}.src.rock"
+ get "$luarocks_repo/abelhas-1.0-1.rockspec"
+ get "$luarocks_repo/lzlib-0.4.work3-1.src.rock"
+ get "$luarocks_repo/lpeg-0.12-1.src.rock"
+ get "$luarocks_repo/luaposix-31-1.src.rock"
+ get "$luarocks_repo/md5-1.2-1.src.rock"
+ get "$luarocks_repo/lrandom-20120430.51-1.src.rock"
+ get "$luarocks_repo/lrandom-20120430.52-1.src.rock"
+ get "$luarocks_repo/lrandom-20120430.51-1.rockspec"
+ get "$luarocks_repo/lrandom-20120430.52-1.rockspec"
+)
+$luarocks_admin_nocov make_manifest "$testing_server"
+
+###################################################
+
+checksum_path() {
+ ( cd "$1"; find . -printf "%s %p\n" | md5sum )
+}
build_environment() {
rm -rf "$testing_tree"
@@ -101,21 +262,55 @@ build_environment() {
rm -rf "$testing_sys_tree_copy"
mkdir -p "$testing_tree"
mkdir -p "$testing_sys_tree"
+ $luarocks_admin_nocov make_manifest "$testing_cache"
for package in "$@"
do
- $luarocks_nocov build --tree="$testing_sys_tree" $package
+ $luarocks_nocov install --only-server="$testing_cache" --tree="$testing_sys_tree" $package || {
+ $luarocks_nocov build --tree="$testing_sys_tree" $package
+ $luarocks_nocov pack --tree="$testing_sys_tree" $package; mv $package-*.rock "$testing_cache"
+ }
done
- eval `$luarocks_nocov path --bin`
+ eval `$luarocks_noecho_nocov path --bin`
cp -a "$testing_tree" "$testing_tree_copy"
cp -a "$testing_sys_tree" "$testing_sys_tree_copy"
+ testing_tree_copy_md5=`checksum_path "$testing_tree_copy"`
+ testing_sys_tree_copy_md5=`checksum_path "$testing_sys_tree_copy"`
}
reset_environment() {
- rm -rf "$testing_tree"
- rm -rf "$testing_sys_tree"
- cp -a "$testing_tree_copy" "$testing_tree"
- cp -a "$testing_sys_tree_copy" "$testing_sys_tree"
+ testing_tree_md5=`checksum_path "$testing_tree"`
+ testing_sys_tree_md5=`checksum_path "$testing_sys_tree"`
+ if [ "$testing_tree_md5" != "$testing_tree_copy_md5" ]
+ then
+ rm -rf "$testing_tree"
+ cp -a "$testing_tree_copy" "$testing_tree"
+ fi
+ if [ "$testing_sys_tree_md5" != "$testing_sys_tree_copy_md5" ]
+ then
+ rm -rf "$testing_sys_tree"
+ cp -a "$testing_sys_tree_copy" "$testing_sys_tree"
+ fi
+}
+
+need() {
+ echo "Obtaining $1 $2..."
+ if $luarocks show $1 &> /dev/null
+ then
+ echo "Already available"
+ return
+ fi
+ platrock="$1-$2.$platform.rock"
+ if [ ! -e "$testing_cache/$platrock" ]
+ then
+ echo "Building $1 $2..."
+ $luarocks_nocov build --pack-binary-rock $1 $2
+ mv "$platrock" "$testing_cache"
+ fi
+ echo "Installing $1 $2..."
+ $luarocks_nocov install "$testing_cache/$platrock"
+ return
}
+need_luasocket() { need luasocket $verrev_luasocket; }
# Tests #########################################
@@ -134,7 +329,10 @@ fail_lint_noarg() { $luarocks lint; }
fail_search_noarg() { $luarocks search; }
fail_show_noarg() { $luarocks show; }
fail_unpack_noarg() { $luarocks unpack; }
+fail_remove_noarg() { $luarocks remove; }
+fail_doc_noarg() { $luarocks doc; }
fail_new_version_noarg() { $luarocks new_version; }
+fail_write_rockspec_noarg() { $luarocks write_rockspec; }
fail_build_invalid() { $luarocks build invalid; }
fail_download_invalid() { $luarocks download invalid; }
@@ -146,77 +344,103 @@ fail_new_version_invalid() { $luarocks new_version invalid; }
fail_make_norockspec() { $luarocks make; }
fail_build_blank_arg() { $luarocks build --tree="" lpeg; }
-test_build_withpatch() { $luarocks build luadoc; }
-test_build_diffversion() { $luarocks build luacov 0.1; }
+test_build_withpatch() { need_luasocket; $luarocks build luadoc; }
+test_build_diffversion() { $luarocks build luacov ${version_luacov}; }
test_build_command() { $luarocks build stdlib; }
test_build_install_bin() { $luarocks build luarepl; }
-fail_build_nohttps() { $luarocks install luasocket && $luarocks download --rockspec validate-args 1.5.4 && $luarocks build ./validate-args-1.5.4-1.rockspec && rm ./validate-args-1.5.4-1.rockspec; }
-test_build_https() { $luarocks download --rockspec validate-args 1.5.4 && $luarocks install luasec && $luarocks build ./validate-args-1.5.4-1.rockspec && rm ./validate-args-1.5.4-1.rockspec; }
-test_build_supported_platforms() { $luarocks build xctrl; }
+test_build_nohttps() { need_luasocket; $luarocks download --rockspec validate-args ${verrev_validate_args} && $luarocks build ./validate-args-${version_validate_args}-1.rockspec && rm ./validate-args-${version_validate_args}-1.rockspec; }
+test_build_https() { need_luasocket; $luarocks download --rockspec validate-args ${verrev_validate_args} && $luarocks install $luasec && $luarocks build ./validate-args-${verrev_validate_args}.rockspec && rm ./validate-args-${verrev_validate_args}.rockspec; }
+test_build_supported_platforms() { $luarocks build lpty; }
+fail_build_missing_external() { $luarocks build "$testing_dir/testfiles/missing_external-0.1-1.rockspec" INEXISTENT_INCDIR="/invalid/dir"; }
+
+test_build_deps_partial_match() { $luarocks build lrandom; }
+test_build_show_downloads() { export LUAROCKS_CONFIG="$testing_dir/testing_config_show_downloads.lua" && $luarocks build alien; export LUAROCKS_CONFIG="$testing_dir/testing_config.lua"; }
test_download_all() { $luarocks download --all validate-args && rm validate-args-*; }
-test_download_rockspecversion() { $luarocks download --rockspec validate-args 1.5.4 && rm validate-args-*; }
+test_download_rockspecversion() { $luarocks download --rockspec validate-args ${verrev_validate_args} && rm validate-args-*; }
test_help() { $luarocks help; }
-test_install_binaryrock() { $luarocks build luasocket && $luarocks pack luasocket && $luarocks install ./luasocket-2.0.2-5.linux-x86.rock && rm ./luasocket-2.0.2-5.linux-x86.rock; }
+test_install_binaryrock() { $luarocks build --pack-binary-rock cprint && $luarocks install ./cprint-${verrev_cprint}.${platform}.rock && rm ./cprint-${verrev_cprint}.${platform}.rock; }
test_install_with_bin() { $luarocks install wsapi; }
+fail_install_notazipfile() { $luarocks install "$testing_dir/testfiles/not_a_zipfile-1.0-1.src.rock"; }
-test_lint_ok() { $luarocks download --rockspec validate-args 1.5.4 && $luarocks lint ./validate-args-1.5.4-1.rockspec && rm ./validate-args-1.5.4-1.rockspec; }
+test_lint_ok() { $luarocks download --rockspec validate-args ${verrev_validate_args} && $luarocks lint ./validate-args-${verrev_validate_args}.rockspec && rm ./validate-args-${verrev_validate_args}.rockspec; }
+fail_lint_type_mismatch_string() { $luarocks lint "$testing_dir/testfiles/type_mismatch_string-1.0-1.rockspec"; }
+fail_lint_type_mismatch_version() { $luarocks lint "$testing_dir/testfiles/type_mismatch_version-1.0-1.rockspec"; }
+fail_lint_type_mismatch_table() { $luarocks lint "$testing_dir/testfiles/type_mismatch_table-1.0-1.rockspec"; }
test_list() { $luarocks list; }
test_list_porcelain() { $luarocks list --porcelain; }
-test_make() { rm -rf ./luasocket-2.0.2-5 && $luarocks download --src luasocket && $luarocks unpack ./luasocket-2.0.2-5.src.rock && cd luasocket-2.0.2-5/luasocket-2.0.2 && $luarocks make && cd ../.. && rm -rf ./luasocket-2.0.2-5; }
-test_make_pack_binary_rock() { rm -rf ./lxsh-0.8.6-1 && $luarocks download --src lxsh 0.8.6-1 && $luarocks unpack ./lxsh-0.8.6-1.src.rock && cd lxsh-0.8.6-1/lxsh-0.8.6-1 && $luarocks make --deps-mode=none --pack-binary-rock && [ -e ./lxsh-0.8.6-1.all.rock ] && cd ../.. && rm -rf ./lxsh-0.8.6-1; }
+test_make_with_rockspec() { rm -rf ./luasocket-${verrev_luasocket} && $luarocks download --src luasocket && $luarocks unpack ./luasocket-${verrev_luasocket}.src.rock && cd luasocket-${verrev_luasocket}/${srcdir_luasocket} && $luarocks make luasocket-${verrev_luasocket}.rockspec && cd ../.. && rm -rf ./luasocket-${verrev_luasocket}; }
+test_make_default_rockspec() { rm -rf ./lxsh-${verrev_lxsh} && $luarocks download --src lxsh ${verrev_lxsh} && $luarocks unpack ./lxsh-${verrev_lxsh}.src.rock && cd lxsh-${verrev_lxsh}/lxsh-${version_lxsh}-1 && $luarocks make && cd ../.. && rm -rf ./lxsh-${verrev_lxsh}; }
+test_make_pack_binary_rock() { rm -rf ./lxsh-${verrev_lxsh} && $luarocks download --src lxsh ${verrev_lxsh} && $luarocks unpack ./lxsh-${verrev_lxsh}.src.rock && cd lxsh-${verrev_lxsh}/lxsh-${version_lxsh}-1 && $luarocks make --deps-mode=none --pack-binary-rock && [ -e ./lxsh-${verrev_lxsh}.all.rock ] && cd ../.. && rm -rf ./lxsh-${verrev_lxsh}; }
+fail_make_which_rockspec() { rm -rf ./luasocket-${verrev_luasocket} && $luarocks download --src luasocket && $luarocks unpack ./luasocket-${verrev_luasocket}.src.rock && cd luasocket-${verrev_luasocket}/${srcdir_luasocket} && $luarocks make && cd ../.. && rm -rf ./luasocket-${verrev_luasocket}; }
-test_new_version() { $luarocks download --rockspec luacov 0.1 && $luarocks new_version ./luacov-0.1-1.rockspec 0.2 && rm ./luacov-0.*; }
+test_new_version() { $luarocks download --rockspec luacov ${version_luacov} && $luarocks new_version ./luacov-${version_luacov}-1.rockspec 0.2 && rm ./luacov-0.*; }
+test_new_version_url() { $luarocks download --rockspec abelhas 1.0 && $luarocks new_version ./abelhas-1.0-1.rockspec 1.1 https://github.com/downloads/ittner/abelhas/abelhas-1.1.tar.gz && rm ./abelhas-*; }
test_pack() { $luarocks list && $luarocks pack luacov && rm ./luacov-*.rock; }
-test_pack_src() { $luarocks download --rockspec luasocket && $luarocks pack ./luasocket-2.0.2-5.rockspec && rm ./luasocket-2.0.2-*.rock; }
+test_pack_src() { $luarocks install $luasec && $luarocks download --rockspec luasocket && $luarocks pack ./luasocket-${verrev_luasocket}.rockspec && rm ./luasocket-${version_luasocket}-*.rock; }
test_path() { $luarocks path --bin; }
+test_path_lr_path() { $luarocks path --lr-path; }
+test_path_lr_cpath() { $luarocks path --lr-cpath; }
+test_path_lr_bin() { $luarocks path --lr-bin; }
fail_purge_missing_tree() { $luarocks purge --tree="$testing_tree"; }
test_purge() { $luarocks purge --tree="$testing_sys_tree"; }
-test_remove() { $luarocks build luacov 0.1 && $luarocks remove luacov 0.1; }
-#fail_remove_deps() { $luarocks build luadoc && $luarocks remove luasocket; }
+test_remove() { $luarocks build luacov ${version_luacov} && $luarocks remove luacov ${version_luacov}; }
+test_remove_force() { need_luasocket; $luarocks build lualogging && $luarocks remove --force luasocket; }
+fail_remove_deps() { need_luasocket; $luarocks build lualogging && $luarocks remove luasocket; }
+fail_remove_invalid_name() { $luarocks remove invalid.rock; }
test_search_found() { $luarocks search zlib; }
test_search_missing() { $luarocks search missing_rock; }
test_show() { $luarocks show luacov; }
test_show_modules() { $luarocks show --modules luacov; }
-test_show_depends() { $luarocks install luasec && $luarocks show luasec; }
-test_show_oldversion() { $luarocks install luacov 0.1 && $luarocks show luacov 0.1; }
+test_show_depends() { need_luasocket; $luarocks install $luasec && $luarocks show luasec; }
+test_show_oldversion() { $luarocks install luacov ${version_luacov} && $luarocks show luacov ${version_luacov}; }
-test_unpack_download() { rm -rf ./luasocket-2.0.2-5 && $luarocks unpack luasocket && rm -rf ./luasocket-2.0.2-5; }
-test_unpack_src() { rm -rf ./luasocket-2.0.2-5 && $luarocks download --src luasocket && $luarocks unpack ./luasocket-2.0.2-5.src.rock && rm -rf ./luasocket-2.0.2-5; }
-test_unpack_rockspec() { rm -rf ./luasocket-2.0.2-5 && $luarocks download --rockspec luasocket && $luarocks unpack ./luasocket-2.0.2-5.rockspec && rm -rf ./luasocket-2.0.2-5; }
-test_unpack_binary() { rm -rf ./luasocket-2.0.2-5 && $luarocks build luasocket && $luarocks pack luasocket && $luarocks unpack ./luasocket-2.0.2-5.linux-x86.rock && rm -rf ./luasocket-2.0.2-5; }
+test_unpack_download() { rm -rf ./cprint-${verrev_cprint} && $luarocks unpack cprint && rm -rf ./cprint-${verrev_cprint}; }
+test_unpack_src() { rm -rf ./cprint-${verrev_cprint} && $luarocks download --src cprint && $luarocks unpack ./cprint-${verrev_cprint}.src.rock && rm -rf ./cprint-${verrev_cprint}; }
+test_unpack_rockspec() { rm -rf ./cprint-${verrev_cprint} && $luarocks download --rockspec cprint && $luarocks unpack ./cprint-${verrev_cprint}.rockspec && rm -rf ./cprint-${verrev_cprint}; }
+test_unpack_binary() { rm -rf ./cprint-${verrev_cprint} && $luarocks build cprint && $luarocks pack cprint && $luarocks unpack ./cprint-${verrev_cprint}.${platform}.rock && rm -rf ./cprint-${verrev_cprint}; }
test_admin_help() { $luarocks_admin help; }
test_admin_make_manifest() { $luarocks_admin make_manifest; }
-test_admin_add_rsync() { $luarocks_admin --server=testing add ./luasocket-2.0.2-5.src.rock; }
-test_admin_add_sftp() { export LUAROCKS_CONFIG="$testing_dir/testing_config_sftp.lua" && $luarocks_admin --server=testing add ./luasocket-2.0.2-5.src.rock; export LUAROCKS_CONFIG="$testing_dir/testing_config.lua"; }
+test_admin_add_rsync() { if [ "$travis" ]; then return; fi; $luarocks_admin --server=testing add "$testing_server/luasocket-${verrev_luasocket}.src.rock"; }
+test_admin_add_sftp() { if [ "$travis" ]; then return; fi; export LUAROCKS_CONFIG="$testing_dir/testing_config_sftp.lua" && $luarocks_admin --server=testing add ./luasocket-${verrev_luasocket}.src.rock; export LUAROCKS_CONFIG="$testing_dir/testing_config.lua"; }
fail_admin_add_missing() { $luarocks_admin --server=testing add; }
-fail_admin_invalidserver() { $luarocks_admin --server=invalid add ./luasocket-2.0.2-5.src.rock; }
-fail_admin_invalidrock() { $luarocks_admin --server=testing add invalid; }
-test_admin_refresh_cache() { $luarocks_admin --server=testing refresh_cache; }
-test_admin_remove() { $luarocks_admin --server=testing remove luasocket; }
+fail_admin_invalidserver() { $luarocks_admin --server=invalid add "$testing_server/luasocket-${verrev_luasocket}.src.rock"; }
+fail_admin_invalidrock() { if [ "$travis" ]; then return 1; fi; $luarocks_admin --server=testing add invalid; }
+test_admin_refresh_cache() { if [ "$travis" ]; then return; fi; $luarocks_admin --server=testing refresh_cache; }
+test_admin_remove() { if [ "$travis" ]; then return; fi; $luarocks_admin --server=testing remove luasocket-${verrev_luasocket}.src.rock; }
fail_admin_remove_missing() { $luarocks_admin --server=testing remove; }
fail_deps_mode_invalid_arg() { $luarocks remove luacov --deps-mode; }
-test_deps_mode_one() { $luarocks build --tree="$testing_sys_tree" lpeg && $luarocks list && $luarocks build --deps-mode=one --tree="$testing_tree" lxsh && [ `$luarocks list --tree="$testing_tree" --porcelain lpeg | wc -l` = 1 ]; }
-test_deps_mode_order() { $luarocks build --tree="$testing_sys_tree" lpeg && $luarocks build --deps-mode=order --tree="$testing_tree" lxsh && [ `$luarocks list --tree="$testing_tree" --porcelain lpeg | wc -l` = 0 ]; }
-test_deps_mode_order_sys() { $luarocks build --tree="$testing_tree" lpeg && $luarocks build --deps-mode=order --tree="$testing_sys_tree" lxsh && [ `$luarocks list --tree="$testing_sys_tree" --porcelain lpeg | wc -l` = 1 ]; }
-test_deps_mode_all_sys() { $luarocks build --tree="$testing_tree" lpeg && $luarocks build --deps-mode=all --tree="$testing_sys_tree" lxsh && [ `$luarocks list --tree="$testing_sys_tree" --porcelain lpeg | wc -l` = 0 ]; }
-test_deps_mode_none() { $luarocks build --tree="$testing_tree" --deps-mode=none lxsh; [ `$luarocks list --tree="$testing_tree" --porcelain lpeg | wc -l` = 0 ]; }
-test_deps_mode_nodeps_alias() { $luarocks build --tree="$testing_tree" --nodeps lxsh; [ `$luarocks list --tree="$testing_tree" --porcelain lpeg | wc -l` = 0 ]; }
-test_deps_mode_make_order() { $luarocks build --tree="$testing_sys_tree" lpeg && rm -rf ./lxsh-0.8.6-1 && $luarocks download --src lxsh 0.8.6-1 && $luarocks unpack ./lxsh-0.8.6-1.src.rock && cd lxsh-0.8.6-1/lxsh-0.8.6-1 && $luarocks make --tree="$testing_tree" --deps-mode=order && cd ../.. && [ `$luarocks list --tree="$testing_tree" --porcelain lpeg | wc -l` = 0 ] && rm -rf ./lxsh-0.8.6-1; }
-test_deps_mode_make_order_sys() { $luarocks build --tree="$testing_tree" lpeg && rm -rf ./lxsh-0.8.6-1 && $luarocks download --src lxsh 0.8.6-1 && $luarocks unpack ./lxsh-0.8.6-1.src.rock && cd lxsh-0.8.6-1/lxsh-0.8.6-1 && $luarocks make --tree="$testing_sys_tree" --deps-mode=order && cd ../.. && [ `$luarocks list --tree="$testing_tree" --porcelain lpeg | wc -l` = 1 ] && rm -rf ./lxsh-0.8.6-1; }
+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 ]; }
+test_deps_mode_order() { $luarocks build --tree="system" lpeg && $luarocks build --deps-mode=order --tree="$testing_tree" lxsh && $luarocks_noecho list --tree="$testing_tree" --porcelain lpeg && [ `$luarocks_noecho list --tree="$testing_tree" --porcelain lpeg | wc -l` = 0 ]; }
+test_deps_mode_order_sys() { $luarocks build --tree="$testing_tree" lpeg && $luarocks build --deps-mode=order --tree="$testing_sys_tree" lxsh && [ `$luarocks_noecho list --tree="$testing_sys_tree" --porcelain lpeg | wc -l` = 1 ]; }
+test_deps_mode_all_sys() { $luarocks build --tree="$testing_tree" lpeg && $luarocks build --deps-mode=all --tree="$testing_sys_tree" lxsh && [ `$luarocks_noecho list --tree="$testing_sys_tree" --porcelain lpeg | wc -l` = 0 ]; }
+test_deps_mode_none() { $luarocks build --tree="$testing_tree" --deps-mode=none lxsh; [ `$luarocks_noecho list --tree="$testing_tree" --porcelain lpeg | wc -l` = 0 ]; }
+test_deps_mode_nodeps_alias() { $luarocks build --tree="$testing_tree" --nodeps lxsh; [ `$luarocks_noecho list --tree="$testing_tree" --porcelain lpeg | wc -l` = 0 ]; }
+test_deps_mode_make_order() { $luarocks build --tree="$testing_sys_tree" lpeg && rm -rf ./lxsh-${verrev_lxsh} && $luarocks download --src lxsh ${verrev_lxsh} && $luarocks unpack ./lxsh-${verrev_lxsh}.src.rock && cd lxsh-${verrev_lxsh}/lxsh-${version_lxsh}-1 && $luarocks make --tree="$testing_tree" --deps-mode=order && cd ../.. && [ `$luarocks_noecho list --tree="$testing_tree" --porcelain lpeg | wc -l` = 0 ] && rm -rf ./lxsh-${verrev_lxsh}; }
+test_deps_mode_make_order_sys() { $luarocks build --tree="$testing_tree" lpeg && rm -rf ./lxsh-${verrev_lxsh} && $luarocks download --src lxsh ${verrev_lxsh} && $luarocks unpack ./lxsh-${verrev_lxsh}.src.rock && cd lxsh-${verrev_lxsh}/lxsh-${version_lxsh}-1 && $luarocks make --tree="$testing_sys_tree" --deps-mode=order && cd ../.. && [ `$luarocks_noecho list --tree="$testing_tree" --porcelain lpeg | wc -l` = 1 ] && rm -rf ./lxsh-${verrev_lxsh}; }
+
+test_write_rockspec() { $luarocks write_rockspec git://github.com/keplerproject/luarocks; }
+test_write_rockspec_lib() { $luarocks write_rockspec git://github.com/mbalmer/luafcgi --lib=fcgi --license="3-clause BSD" --lua-version=5.1,5.2; }
+test_write_rockspec_fullargs() { $luarocks write_rockspec git://github.com/keplerproject/luarocks --lua-version=5.1,5.2 --license="MIT/X11" --homepage="http://www.luarocks.org" --summary="A package manager for Lua modules"; }
+fail_write_rockspec_args() { $luarocks write_rockspec invalid; }
+fail_write_rockspec_args_url() { $luarocks write_rockspec http://example.com/invalid.zip; }
+test_write_rockspec_http() { $luarocks write_rockspec http://luarocks.org/releases/luarocks-2.1.0.tar.gz --lua-version=5.1; }
+test_write_rockspec_basedir() { $luarocks write_rockspec https://github.com/downloads/Olivine-Labs/luassert/luassert-1.2.tar.gz --lua-version=5.1; }
+
+test_doc() { $luarocks install luarepl; $luarocks doc luarepl; }
# Driver #########################################
@@ -232,7 +456,6 @@ run_tests() {
else echo "FAIL: Unexpected failure."; exit 1
fi
done
-
grep "^fail_$1.*(" < $testing_dir/testing.sh | cut -d'(' -f1 | while read test
do
echo "-------------------------------------------"
@@ -247,11 +470,17 @@ run_tests() {
}
run_with_minimal_environment() {
+ echo "==========================================="
+ echo "Running with minimal environment"
+ echo "==========================================="
build_environment luacov
run_tests $1
}
run_with_full_environment() {
+ echo "==========================================="
+ echo "Running with full environment"
+ echo "==========================================="
build_environment luacov luafilesystem luasocket luabitop luaposix md5 lzlib
run_tests $1
}
@@ -266,4 +495,10 @@ run_all_tests $1
$testing_sys_tree/bin/luacov -c $testing_dir/luacov.config src/luarocks src/bin
-cat $testing_dir/luacov.report.out
+if [ "$travis" ]
+then
+ grep "Summary" -B1 -A1000 $testing_dir/luacov.report.out
+else
+ cat "$testing_dir/luacov.report.out"
+fi
+
diff --git a/luarocks/win32/bin/create_reg_file.lua b/luarocks/win32/LuaRocks.reg.lua
index 2eb7583..2eb7583 100644
--- a/luarocks/win32/bin/create_reg_file.lua
+++ b/luarocks/win32/LuaRocks.reg.lua
diff --git a/luarocks/win32/bin/LuaRocks.reg.template b/luarocks/win32/LuaRocks.reg.template
index 82cc180..82cc180 100644
--- a/luarocks/win32/bin/LuaRocks.reg.template
+++ b/luarocks/win32/LuaRocks.reg.template
diff --git a/luarocks/win32/bin/chmod.exe b/luarocks/win32/bin/chmod.exe
deleted file mode 100644
index 9655cfd..0000000
--- a/luarocks/win32/bin/chmod.exe
+++ /dev/null
Binary files differ
diff --git a/luarocks/win32/bin/objdump.exe b/luarocks/win32/bin/objdump.exe
deleted file mode 100644
index 4429d10..0000000
--- a/luarocks/win32/bin/objdump.exe
+++ /dev/null
Binary files differ
diff --git a/luarocks/win32/bin/rm.exe b/luarocks/win32/bin/rm.exe
deleted file mode 100755
index 8e79306..0000000
--- a/luarocks/win32/bin/rm.exe
+++ /dev/null
Binary files differ
diff --git a/luarocks/win32/bin/lua.ico b/luarocks/win32/lua.ico
index 56dc4fe..56dc4fe 100644
--- a/luarocks/win32/bin/lua.ico
+++ b/luarocks/win32/lua.ico
Binary files differ
diff --git a/luarocks/win32/bin/luarocksw.bat b/luarocks/win32/luarocksw.bat
index 313508d..8ac0292 100644
--- a/luarocks/win32/bin/luarocksw.bat
+++ b/luarocks/win32/luarocksw.bat
@@ -34,14 +34,14 @@ if [%1]==[removeall] goto REMOVEALL
REM execute LuaRocks and wait for results
echo executing: luarocks %*
-call %MYPATH%luarocks %*
+call "%MYPATH%luarocks" %*
pause
goto END
:REMOVEALL
for /f "delims=-" %%a in ("%~n2") do (
echo executing: luarocks remove %%a
- %MYPATH%luarocks remove "%%a"
+ "%MYPATH%luarocks" remove "%%a"
pause
goto END
)
diff --git a/luarocks/win32/pe-parser.lua b/luarocks/win32/pe-parser.lua
new file mode 100644
index 0000000..30bb839
--- /dev/null
+++ b/luarocks/win32/pe-parser.lua
@@ -0,0 +1,546 @@
+---------------------------------------------------------------------------------------
+-- Lua module to parse a Portable Executable (.exe , .dll, etc.) file and extract metadata.
+--
+-- Version 0.1, [copyright (c) 2013 - Thijs Schreijer](http://www.thijsschreijer.nl)
+-- @name pe-parser
+-- @class module
+
+local M = {}
+
+--- Table with named constants/flag-constants.
+-- Named elements can be looked up by their name in the `const` table. The sub tables are index by value.
+-- For flag fields the name is extended with `_flags`.
+-- @usage -- lookup descriptive name for the myobj.Magic value
+-- local desc = pe.const.Magic(myobj.Magic)
+--
+-- -- get list of flag names, indexed by flag values, for the Characteristics field
+-- local flag_list = pe.const.Characteristics_flags
+M.const = {
+ Magic = {
+ ["10b"] = "PE32",
+ ["20b"] = "PE32+",
+ },
+ Machine = {
+ ["0"] = "IMAGE_FILE_MACHINE_UNKNOWN",
+ ["1d3"] = "IMAGE_FILE_MACHINE_AM33",
+ ["8664"] = "IMAGE_FILE_MACHINE_AMD64",
+ ["1c0"] = "IMAGE_FILE_MACHINE_ARM",
+ ["1c4"] = "IMAGE_FILE_MACHINE_ARMNT",
+ ["aa64"] = "IMAGE_FILE_MACHINE_ARM64",
+ ["ebc"] = "IMAGE_FILE_MACHINE_EBC",
+ ["14c"] = "IMAGE_FILE_MACHINE_I386",
+ ["200"] = "IMAGE_FILE_MACHINE_IA64",
+ ["9041"] = "IMAGE_FILE_MACHINE_M32R",
+ ["266"] = "IMAGE_FILE_MACHINE_MIPS16",
+ ["366"] = "IMAGE_FILE_MACHINE_MIPSFPU",
+ ["466"] = "IMAGE_FILE_MACHINE_MIPSFPU16",
+ ["1f0"] = "IMAGE_FILE_MACHINE_POWERPC",
+ ["1f1"] = "IMAGE_FILE_MACHINE_POWERPCFP",
+ ["166"] = "IMAGE_FILE_MACHINE_R4000",
+ ["1a2"] = "IMAGE_FILE_MACHINE_SH3",
+ ["1a3"] = "IMAGE_FILE_MACHINE_SH3DSP",
+ ["1a6"] = "IMAGE_FILE_MACHINE_SH4",
+ ["1a8"] = "IMAGE_FILE_MACHINE_SH5",
+ ["1c2"] = "IMAGE_FILE_MACHINE_THUMB",
+ ["169"] = "IMAGE_FILE_MACHINE_WCEMIPSV2",
+ },
+ Characteristics_flags = {
+ ["1"] = "IMAGE_FILE_RELOCS_STRIPPED",
+ ["2"] = "IMAGE_FILE_EXECUTABLE_IMAGE",
+ ["4"] = "IMAGE_FILE_LINE_NUMS_STRIPPED",
+ ["8"] = "IMAGE_FILE_LOCAL_SYMS_STRIPPED",
+ ["10"] = "IMAGE_FILE_AGGRESSIVE_WS_TRIM",
+ ["20"] = "IMAGE_FILE_LARGE_ADDRESS_AWARE",
+ ["40"] = "Reserved for future use",
+ ["80"] = "IMAGE_FILE_BYTES_REVERSED_LO",
+ ["100"] = "IMAGE_FILE_32BIT_MACHINE",
+ ["200"] = "IMAGE_FILE_DEBUG_STRIPPED",
+ ["400"] = "IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP",
+ ["800"] = "IMAGE_FILE_NET_RUN_FROM_SWAP",
+ ["1000"] = "IMAGE_FILE_SYSTEM",
+ ["2000"] = "IMAGE_FILE_DLL",
+ ["4000"] = "IMAGE_FILE_UP_SYSTEM_ONLY",
+ ["8000"] = "IMAGE_FILE_BYTES_REVERSED_HI",
+ },
+ Subsystem = {
+ ["0"] = "IMAGE_SUBSYSTEM_UNKNOWN",
+ ["1"] = "IMAGE_SUBSYSTEM_NATIVE",
+ ["2"] = "IMAGE_SUBSYSTEM_WINDOWS_GUI",
+ ["3"] = "IMAGE_SUBSYSTEM_WINDOWS_CUI",
+ ["7"] = "IMAGE_SUBSYSTEM_POSIX_CUI",
+ ["9"] = "IMAGE_SUBSYSTEM_WINDOWS_CE_GUI",
+ ["a"] = "IMAGE_SUBSYSTEM_EFI_APPLICATION",
+ ["b"] = "IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER",
+ ["c"] = "IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER",
+ ["d"] = "IMAGE_SUBSYSTEM_EFI_ROM",
+ ["e"] = "IMAGE_SUBSYSTEM_XBOX",
+ },
+ DllCharacteristics_flags = {
+ ["40"] = "IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE",
+ ["80"] = "IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY",
+ ["100"] = "IMAGE_DLL_CHARACTERISTICS_NX_COMPAT",
+ ["200"] = "IMAGE_DLLCHARACTERISTICS_NO_ISOLATION",
+ ["400"] = "IMAGE_DLLCHARACTERISTICS_NO_SEH",
+ ["800"] = "IMAGE_DLLCHARACTERISTICS_NO_BIND",
+ ["2000"] = "IMAGE_DLLCHARACTERISTICS_WDM_DRIVER",
+ ["8000"] = "IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE",
+ },
+ Sections = {
+ Characteristics_flags = {
+ ["8"] = "IMAGE_SCN_TYPE_NO_PAD",
+ ["20"] = "IMAGE_SCN_CNT_CODE",
+ ["40"] = "IMAGE_SCN_CNT_INITIALIZED_DATA",
+ ["80"] = "IMAGE_SCN_CNT_UNINITIALIZED_ DATA",
+ ["100"] = "IMAGE_SCN_LNK_OTHER",
+ ["200"] = "IMAGE_SCN_LNK_INFO",
+ ["800"] = "IMAGE_SCN_LNK_REMOVE",
+ ["1000"] = "IMAGE_SCN_LNK_COMDAT",
+ ["8000"] = "IMAGE_SCN_GPREL",
+ ["20000"] = "IMAGE_SCN_MEM_PURGEABLE",
+ ["20000"] = "IMAGE_SCN_MEM_16BIT",
+ ["40000"] = "IMAGE_SCN_MEM_LOCKED",
+ ["80000"] = "IMAGE_SCN_MEM_PRELOAD",
+ ["100000"] = "IMAGE_SCN_ALIGN_1BYTES",
+ ["200000"] = "IMAGE_SCN_ALIGN_2BYTES",
+ ["300000"] = "IMAGE_SCN_ALIGN_4BYTES",
+ ["400000"] = "IMAGE_SCN_ALIGN_8BYTES",
+ ["500000"] = "IMAGE_SCN_ALIGN_16BYTES",
+ ["600000"] = "IMAGE_SCN_ALIGN_32BYTES",
+ ["700000"] = "IMAGE_SCN_ALIGN_64BYTES",
+ ["800000"] = "IMAGE_SCN_ALIGN_128BYTES",
+ ["900000"] = "IMAGE_SCN_ALIGN_256BYTES",
+ ["a00000"] = "IMAGE_SCN_ALIGN_512BYTES",
+ ["b00000"] = "IMAGE_SCN_ALIGN_1024BYTES",
+ ["c00000"] = "IMAGE_SCN_ALIGN_2048BYTES",
+ ["d00000"] = "IMAGE_SCN_ALIGN_4096BYTES",
+ ["e00000"] = "IMAGE_SCN_ALIGN_8192BYTES",
+ ["1000000"] = "IMAGE_SCN_LNK_NRELOC_OVFL",
+ ["2000000"] = "IMAGE_SCN_MEM_DISCARDABLE",
+ ["4000000"] = "IMAGE_SCN_MEM_NOT_CACHED",
+ ["8000000"] = "IMAGE_SCN_MEM_NOT_PAGED",
+ ["10000000"] = "IMAGE_SCN_MEM_SHARED",
+ ["20000000"] = "IMAGE_SCN_MEM_EXECUTE",
+ ["40000000"] = "IMAGE_SCN_MEM_READ",
+ ["80000000"] = "IMAGE_SCN_MEM_WRITE",
+ },
+ },
+
+}
+
+
+--- convert integer to HEX representation
+-- @param IN the number to convert to hex
+-- @param len the size to return, any result smaller will be prefixed by "0"s
+-- @return string containing hex representation
+function M.toHex(IN, len)
+ local B,K,OUT,I,D=16,"0123456789abcdef","",0
+ while IN>0 do
+ I=I+1
+ IN,D=math.floor(IN/B),math.fmod(IN,B)+1
+ OUT=string.sub(K,D,D)..OUT
+ end
+ len = len or string.len(OUT)
+ if len<1 then len = 1 end
+ return (string.rep("0",len) .. OUT):sub(-len,-1)
+end
+
+--- convert HEX to integer
+-- @param IN the string to convert to dec
+-- @return number in dec format
+function M.toDec(IN)
+ assert(type(IN)=="string")
+ local OUT = 0
+ IN = IN:lower()
+ while #IN > 0 do
+ local b = string.find("0123456789abcdef",IN:sub(1,1))
+ OUT = OUT * 16 + (b-1)
+ IN = IN:sub(2,-1)
+ end
+ return OUT
+end
+
+local function get_int(str)
+ -- convert a byte-sequence to an integer
+ assert(str)
+ local r = 0
+ for i = #str, 1, -1 do
+ r = r*256 + string.byte(str,i,i)
+ end
+ return r
+end
+
+local function get_hex(str)
+ -- convert a byte-sequence to a hex string
+ assert(str)
+ local r = ""
+ for i = #str, 1, -1 do
+ r = r .. M.toHex(string.byte(str,i,i),2)
+ end
+ while (#r > 1) and (r:sub(1,1) == "0") do
+ r = r:sub(2, -1)
+ end
+ return r
+end
+
+local function get_list(list, f, add_to)
+ -- list: list of tables with 'size' and 'name' and is_str
+ -- f: file to read from
+ -- add_to: table to add results to (optional)
+ local r = add_to or {}
+ for i, t in ipairs(list) do
+ assert(r[t.name] == nil, "Value for '"..t.name.."' already set")
+ local val,err = f:read(t.size) -- read specified size in bytes
+ val = val or "\0"
+ if t.is_str then -- entry is marked as a string value, read as such
+ for i = 1, #val do
+ if val:sub(i,i) == "\0" then
+ r[t.name] = val:sub(1,i-1)
+ break
+ end
+ end
+ r[t.name] = r[t.name] or val
+ else -- entry not marked, so always read as hex value
+ r[t.name] = get_hex(val)
+ end
+ end
+ return r
+end
+
+--- Calculates the fileoffset of a given RVA.
+-- This function is also available as a method on the parsed output table
+-- @param obj a parsed object (return value from `parse`)
+-- @param RVA an RVA value to convert to a fileoffset (either number or hex-string)
+-- @return fileoffset of the given RVA (number)
+M.get_fileoffset = function(obj, RVA)
+ -- given an object with a section table, and an RVA, it returns
+ -- the fileoffset for the data
+ if type(RVA)=="string" then RVA = M.toDec(RVA) end
+ local section
+ for i, s in ipairs(obj.Sections) do
+ if M.toDec(s.VirtualAddress) <= RVA and M.toDec(s.VirtualAddress) + M.toDec(s.VirtualSize) >= RVA then
+ section = s
+ break
+ end
+ end
+ if not section then return nil, "No match RVA with Section list, RVA out of bounds" end
+ return RVA - M.toDec(section.VirtualAddress) + M.toDec(section.PointerToRawData)
+end
+
+local function readstring(f)
+ -- reads a null-terminated string from the current file posistion
+ local name = ""
+ while true do
+ local c = f:read(1)
+ if c == "\0" then break end
+ name = name .. c
+ end
+ return name
+end
+
+--- Parses a file and extracts the information.
+-- All numbers are delivered as "string" types containing hex values, see `toHex` and `toDec` conversion functions.
+-- @return table with data, or nil + error
+-- @usage local pe = require("pe-parser")
+-- local obj = pe.parse("c:\lua\lua.exe")
+-- obj:dump()
+M.parse = function(target)
+
+ local list = { -- list of known architectures
+ [332] = "x86", -- IMAGE_FILE_MACHINE_I386
+ [512] = "x86_64", -- IMAGE_FILE_MACHINE_IA64
+ [34404] = "x86_64", -- IMAGE_FILE_MACHINE_AMD64
+ }
+
+ local f, err = io.open(target, "rb")
+ if not f then return nil, err end
+
+ local MZ = f:read(2)
+ if MZ ~= "MZ" then
+ f:close()
+ return nil, "Not a valid image"
+ end
+
+ f:seek("set", 60) -- position of PE header position
+ local peoffset = get_int(f:read(4)) -- read position of PE header
+
+ f:seek("set", peoffset) -- move to position of PE header
+ local out = get_list({
+ { size = 4,
+ name = "PEheader",
+ is_str = true },
+ { size = 2,
+ name = "Machine" },
+ { size = 2,
+ name = "NumberOfSections"},
+ { size = 4,
+ name = "TimeDateStamp" },
+ { size = 4,
+ name = "PointerToSymbolTable"},
+ { size = 4,
+ name = "NumberOfSymbols"},
+ { size = 2,
+ name = "SizeOfOptionalHeader"},
+ { size = 2,
+ name = "Characteristics"},
+ }, f)
+
+ if out.PEheader ~= "PE" then
+ f:close()
+ return nil, "Invalid PE header"
+ end
+ out.PEheader = nil -- remove it, has no value
+ out.dump = M.dump -- export dump function as a method
+
+ if M.toDec(out.SizeOfOptionalHeader) > 0 then
+ -- parse optional header; standard
+ get_list({
+ { size = 2,
+ name = "Magic" },
+ { size = 1,
+ name = "MajorLinkerVersion"},
+ { size = 1,
+ name = "MinorLinkerVersion"},
+ { size = 4,
+ name = "SizeOfCode"},
+ { size = 4,
+ name = "SizeOfInitializedData"},
+ { size = 4,
+ name = "SizeOfUninitializedData"},
+ { size = 4,
+ name = "AddressOfEntryPoint"},
+ { size = 4,
+ name = "BaseOfCode"},
+ }, f, out)
+ local plus = (out.Magic == "20b")
+ if not plus then -- plain PE32, not PE32+
+ get_list({
+ { size = 4,
+ name = "BaseOfData" },
+ }, f, out)
+ end
+ -- parse optional header; windows-fields
+ local plussize = 4
+ if plus then plussize = 8 end
+ get_list({
+ { size = plussize,
+ name = "ImageBase"},
+ { size = 4,
+ name = "SectionAlignment"},
+ { size = 4,
+ name = "FileAlignment"},
+ { size = 2,
+ name = "MajorOperatingSystemVersion"},
+ { size = 2,
+ name = "MinorOperatingSystemVersion"},
+ { size = 2,
+ name = "MajorImageVersion"},
+ { size = 2,
+ name = "MinorImageVersion"},
+ { size = 2,
+ name = "MajorSubsystemVersion"},
+ { size = 2,
+ name = "MinorSubsystemVersion"},
+ { size = 4,
+ name = "Win32VersionValue"},
+ { size = 4,
+ name = "SizeOfImage"},
+ { size = 4,
+ name = "SizeOfHeaders"},
+ { size = 4,
+ name = "CheckSum"},
+ { size = 2,
+ name = "Subsystem"},
+ { size = 2,
+ name = "DllCharacteristics"},
+ { size = plussize,
+ name = "SizeOfStackReserve"},
+ { size = plussize,
+ name = "SizeOfStackCommit"},
+ { size = plussize,
+ name = "SizeOfHeapReserve"},
+ { size = plussize,
+ name = "SizeOfHeapCommit"},
+ { size = 4,
+ name = "LoaderFlags"},
+ { size = 4,
+ name = "NumberOfRvaAndSizes"},
+ }, f, out)
+ -- Read data directory entries
+ for i = 1, M.toDec(out.NumberOfRvaAndSizes) do
+ out.DataDirectory = out.DataDirectory or {}
+ out.DataDirectory[i] = get_list({
+ { size = 4,
+ name = "VirtualAddress"},
+ { size = 4,
+ name = "Size"},
+ }, f)
+ end
+ for i, name in ipairs{"ExportTable", "ImportTable", "ResourceTable",
+ "ExceptionTable", "CertificateTable", "BaseRelocationTable",
+ "Debug", "Architecture", "GlobalPtr", "TLSTable",
+ "LoadConfigTable", "BoundImport", "IAT",
+ "DelayImportDescriptor", "CLRRuntimeHeader", "Reserved"} do
+ out.DataDirectory[name] = out.DataDirectory[i]
+ if out.DataDirectory[name] then out.DataDirectory[name].name = name end
+ end
+ end
+
+ -- parse section table
+ for i = 1, M.toDec(out.NumberOfSections) do
+ out.Sections = out.Sections or {}
+ out.Sections[i] = get_list({
+ { size = 8,
+ name = "Name",
+ is_str = true},
+ { size = 4,
+ name = "VirtualSize"},
+ { size = 4,
+ name = "VirtualAddress"},
+ { size = 4,
+ name = "SizeOfRawData"},
+ { size = 4,
+ name = "PointerToRawData"},
+ { size = 4,
+ name = "PointerToRelocations"},
+ { size = 4,
+ name = "PointerToLinenumbers"},
+ { size = 2,
+ name = "NumberOfRelocations"},
+ { size = 2,
+ name = "NumberOfLinenumbers"},
+ { size = 4,
+ name = "Characteristics"},
+ }, f)
+ end
+ -- we now have section data, so add RVA convertion method
+ out.get_fileoffset = M.get_fileoffset
+
+ -- get the import table
+ f:seek("set", out:get_fileoffset(out.DataDirectory.ImportTable.VirtualAddress))
+ local done = false
+ local cnt = 1
+ while not done do
+ local dll = get_list({
+ { size = 4,
+ name = "ImportLookupTableRVA"},
+ { size = 4,
+ name = "TimeDateStamp"},
+ { size = 4,
+ name = "ForwarderChain"},
+ { size = 4,
+ name = "NameRVA"},
+ { size = 4,
+ name = "ImportAddressTableRVA"},
+ }, f)
+ if M.toDec(dll.NameRVA) == 0 then
+ -- this is the final NULL entry, so we're done
+ done = true
+ else
+ -- store the import entry
+ out.DataDirectory.ImportTable[cnt] = dll
+ cnt = cnt + 1
+ end
+ end
+ -- resolve imported DLL names
+ for i, dll in ipairs(out.DataDirectory.ImportTable) do
+ f:seek("set", out:get_fileoffset(dll.NameRVA))
+ dll.Name = readstring(f)
+ end
+
+ f:close()
+ return out
+end
+
+-- pad a string (prefix) to a specific length
+local function pad(str, l, chr)
+ chr = chr or " "
+ l = l or 0
+ return string.rep(chr,l-#str)..str
+end
+
+--- Dumps the output parsed.
+-- This function is also available as a method on the parsed output table
+M.dump = function(obj)
+ local l = 0
+ for k,v in pairs(obj) do if #k > l then l = #k end end
+
+ for k,v in pairs(obj) do
+ if (M.const[k] and type(v)=="string") then
+ -- look up named value
+ print(k..string.rep(" ", l - #k + 1)..": "..M.const[k][v])
+ elseif M.const[k.."_flags"] then
+ -- flags should be listed
+ print(k..string.rep(" ", l - #k + 1)..": "..v.." (flag field)")
+ else
+ -- regular values
+ if type(v) == "number" then
+ print(k..string.rep(" ", l - #k + 1)..": "..v.." (dec)")
+ else
+ if (type(v)=="string") and (k ~= "DataDirectory") and (k ~= "Sections") then
+ print(k..string.rep(" ", l - #k + 1)..": "..v)
+ end
+ end
+ end
+ end
+
+ if obj.DataDirectory then
+ print("DataDirectory (RVA, size):")
+ for i, v in ipairs(obj.DataDirectory) do
+ print(" Entry "..M.toHex(i-1).." "..pad(v.VirtualAddress,8,"0").." "..pad(v.Size,8,"0").." "..v.name)
+ end
+ end
+
+ if obj.Sections then
+ print("Sections:")
+ print("idx name RVA VSize Offset RawSize")
+ for i, v in ipairs(obj.Sections) do
+ print(" "..i.." "..v.Name.. string.rep(" ",9-#v.Name)..pad(v.VirtualAddress,8,"0").." "..pad(v.VirtualSize,8,"0").." "..pad(v.PointerToRawData,8,"0").." "..pad(v.SizeOfRawData,8,"0"))
+ end
+ end
+
+ print("Imports:")
+ for i, dll in ipairs(obj.DataDirectory.ImportTable) do
+ print(" "..dll.Name)
+ end
+end
+
+--- Checks the msvcrt dll the binary was linked against.
+-- Mixing and matching dlls only works when they all are using the same runtime, if
+-- not unexpected errors will probably occur.
+-- Checks the binary provided and then traverses all imported dlls to find the msvcrt
+-- used (it will only look for the dlls in the same directory).
+-- @param infile binary file to check
+-- @return msvcrt name (uppercase, without extension) + file where the reference was found, or nil + error
+function M.msvcrt(infile)
+ local path, file = infile:match("(.+)\\(.+)$")
+ if not path then
+ path = ""
+ file = infile
+ else
+ path=path .. "\\"
+ end
+ local obj, err = M.parse(path..file)
+ if not obj then return obj, err end
+
+ for i, dll in ipairs(obj.DataDirectory.ImportTable) do
+ dll = dll.Name:upper()
+ local result = dll:match('(MSVCR%d*)%.DLL')
+ if not result then
+ result = dll:match('(MSVCRT)%.DLL')
+ end
+ -- success, found it return name + binary where it was found
+ if result then return result, infile end
+ end
+
+ -- not found, so traverse all imported dll's
+ for i, dll in ipairs(obj.DataDirectory.ImportTable) do
+ local rt, ref = M.msvcrt(path..dll.Name)
+ if rt then
+ return rt, ref -- found it
+ end
+ end
+
+ return nil, "No msvcrt found"
+end
+
+return M
diff --git a/luarocks/win32/bin/rclauncher.c b/luarocks/win32/rclauncher.c
index 77459f4..77459f4 100644
--- a/luarocks/win32/bin/rclauncher.c
+++ b/luarocks/win32/rclauncher.c
diff --git a/luarocks/win32/bin/7z.dll b/luarocks/win32/tools/7z.dll
index c0ff7fb..c0ff7fb 100644
--- a/luarocks/win32/bin/7z.dll
+++ b/luarocks/win32/tools/7z.dll
Binary files differ
diff --git a/luarocks/win32/bin/7z.exe b/luarocks/win32/tools/7z.exe
index 5e3d6f9..5e3d6f9 100644
--- a/luarocks/win32/bin/7z.exe
+++ b/luarocks/win32/tools/7z.exe
Binary files differ
diff --git a/luarocks/win32/bin/cp.exe b/luarocks/win32/tools/cp.exe
index 0ef4fe8..0ef4fe8 100755..100644
--- a/luarocks/win32/bin/cp.exe
+++ b/luarocks/win32/tools/cp.exe
Binary files differ
diff --git a/luarocks/win32/bin/find.exe b/luarocks/win32/tools/find.exe
index 85192fb..85192fb 100755..100644
--- a/luarocks/win32/bin/find.exe
+++ b/luarocks/win32/tools/find.exe
Binary files differ
diff --git a/luarocks/win32/bin/libeay32.dll b/luarocks/win32/tools/libeay32.dll
index 8d31f86..8d31f86 100644
--- a/luarocks/win32/bin/libeay32.dll
+++ b/luarocks/win32/tools/libeay32.dll
Binary files differ
diff --git a/luarocks/win32/bin/libiconv2.dll b/luarocks/win32/tools/libiconv2.dll
index 544dd92..544dd92 100644
--- a/luarocks/win32/bin/libiconv2.dll
+++ b/luarocks/win32/tools/libiconv2.dll
Binary files differ
diff --git a/luarocks/win32/bin/libintl3.dll b/luarocks/win32/tools/libintl3.dll
index ec11e6b..ec11e6b 100644
--- a/luarocks/win32/bin/libintl3.dll
+++ b/luarocks/win32/tools/libintl3.dll
Binary files differ
diff --git a/luarocks/win32/bin/libssl32.dll b/luarocks/win32/tools/libssl32.dll
index a30ff0e..a30ff0e 100644
--- a/luarocks/win32/bin/libssl32.dll
+++ b/luarocks/win32/tools/libssl32.dll
Binary files differ
diff --git a/luarocks/win32/bin/ls.exe b/luarocks/win32/tools/ls.exe
index 96ff2e5..96ff2e5 100755..100644
--- a/luarocks/win32/bin/ls.exe
+++ b/luarocks/win32/tools/ls.exe
Binary files differ
diff --git a/luarocks/win32/bin/md5sum.exe b/luarocks/win32/tools/md5sum.exe
index 4ae9f74..4ae9f74 100644
--- a/luarocks/win32/bin/md5sum.exe
+++ b/luarocks/win32/tools/md5sum.exe
Binary files differ
diff --git a/luarocks/win32/bin/mkdir.exe b/luarocks/win32/tools/mkdir.exe
index 83e57d9..83e57d9 100755..100644
--- a/luarocks/win32/bin/mkdir.exe
+++ b/luarocks/win32/tools/mkdir.exe
Binary files differ
diff --git a/luarocks/win32/bin/mv.exe b/luarocks/win32/tools/mv.exe
index 9fb65bb..9fb65bb 100755..100644
--- a/luarocks/win32/bin/mv.exe
+++ b/luarocks/win32/tools/mv.exe
Binary files differ
diff --git a/luarocks/win32/bin/pwd.exe b/luarocks/win32/tools/pwd.exe
index 7dd114d..7dd114d 100755..100644
--- a/luarocks/win32/bin/pwd.exe
+++ b/luarocks/win32/tools/pwd.exe
Binary files differ
diff --git a/luarocks/win32/bin/rmdir.exe b/luarocks/win32/tools/rmdir.exe
index 6a85c3c..6a85c3c 100755..100644
--- a/luarocks/win32/bin/rmdir.exe
+++ b/luarocks/win32/tools/rmdir.exe
Binary files differ
diff --git a/luarocks/win32/bin/test.exe b/luarocks/win32/tools/test.exe
index 94c95f9..94c95f9 100755..100644
--- a/luarocks/win32/bin/test.exe
+++ b/luarocks/win32/tools/test.exe
Binary files differ
diff --git a/luarocks/win32/bin/uname.exe b/luarocks/win32/tools/uname.exe
index 3e2f4cf..3e2f4cf 100755..100644
--- a/luarocks/win32/bin/uname.exe
+++ b/luarocks/win32/tools/uname.exe
Binary files differ
diff --git a/luarocks/win32/bin/wget.exe b/luarocks/win32/tools/wget.exe
index 54b372e..54b372e 100644
--- a/luarocks/win32/bin/wget.exe
+++ b/luarocks/win32/tools/wget.exe
Binary files differ