diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2010-02-24 02:54:47 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2010-02-24 02:54:47 +0000 |
commit | 519f1bc295f59ceaccc3e287bd769a9467433398 (patch) | |
tree | 7b4f0096ea8a50a4c0338b1bbc39c5fd285537c7 | |
parent | f14fb50e2ae182807aadc6513af90bedaa867f0f (diff) | |
download | ruby-519f1bc295f59ceaccc3e287bd769a9467433398.tar.gz |
* merged from trunk r26697:26747.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/mvm@26748 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
156 files changed, 3357 insertions, 3002 deletions
diff --git a/.merged-trunk-revision b/.merged-trunk-revision index b15816706f..e7579bb242 100644 --- a/.merged-trunk-revision +++ b/.merged-trunk-revision @@ -1 +1 @@ -26697 +26747 @@ -1,3 +1,91 @@ +Wed Feb 24 11:52:05 2010 Nobuyoshi Nakada <nobu@ruby-lang.org> + + * dln.c (translit_separator): moved back from load.c again. + + * dln_find.c: split from dln.c. + +Wed Feb 24 09:31:33 2010 Nobuyoshi Nakada <nobu@ruby-lang.org> + + * ext/digest/extconf.rb: use OpenSSL only when all transform + functions are available. + +Wed Feb 24 00:39:17 2010 Yusuke Endoh <mame@tsg.ne.jp> + + * string.c (str_new_empty): String#split, partition, rpartition + taints the resulting strings if self is tainted. + +Mon Feb 22 21:35:33 2010 Tanaka Akira <akr@fsij.org> + + * ext/digest/sha2/sha2init.c: test OpenSSL more strictly. + +Mon Feb 22 11:52:30 2010 Nobuyoshi Nakada <nobu@ruby-lang.org> + + * lib/rubygems: update to 1.3.6. + +Mon Feb 22 11:21:18 2010 Nobuyoshi Nakada <nobu@ruby-lang.org> + + * ext/digest/sha2: Use OpenSSL's SHA1 engine if available. + +Sun Feb 21 21:20:17 2010 Nobuyoshi Nakada <nobu@ruby-lang.org> + + * lib/mkmf.rb (create_makefile, install_files): honor srcprefix + argument if given. [ruby-dev:40449] + +Sun Feb 21 13:29:57 2010 Nobuyoshi Nakada <nobu@ruby-lang.org> + + * lib/rubygems/rubygems_version.rb: outdated. [ruby-core:28275] + +Sun Feb 21 06:24:12 2010 Alexander Zavorine <alexandre.zavorine@nokia.com> + + * symbian/setup (config.h): HAVE_STRUCT_TIMEZONE, VOID_UNSETENV, and RUBY_LIB_VERSION_STYLE defined. + * symbian/setup (ruby.mmp): SOURCE node.c added. + +Sat Feb 20 14:36:16 2010 Yukihiro Matsumoto <matz@ruby-lang.org> + + * vm.c (vm_backtrace_each): use called_id when method definition + structure is already freed. [ruby-dev:40234] [ruby-core:27959] + +Fri Feb 19 00:04:19 2010 Yusuke Endoh <mame@tsg.ne.jp> + + * lib/drb/drb.rb (DRbServer#stop_service): join killed thread to + ensure service stops. [ruby-dev:40441] + +Thu Feb 18 22:31:15 2010 Yusuke Endoh <mame@tsg.ne.jp> + + * math.c (math_atanh): raise ERANGE without calling atanh if absolute + value is 1 to achieve platform-independent math. [ruby-core:28219] + + * math.c (math_lgamma): return [Infinity, 1] without calling lgamma_r + if argument is infinity or -infinity. [ruby-core:28219] + +Thu Feb 18 22:28:00 2010 Kenta Murata <mrkn@mrkn.jp> + + * configure.in: new --with-ext and --with-out-ext options for extmk. + * tool/mkconfig.rb: normalizing --with-out-ext to --without-ext. + +Thu Feb 18 21:50:00 2010 Tanaka Akira <akr@fsij.org> + + * pack.c (pack_unpack): call PACK_ITEM_ADJUST for 'Q'. + +Thu Feb 18 02:14:26 2010 Yusuke Endoh <mame@tsg.ne.jp> + + * io.c (io_fread, io_getpartial, io_read, io_sysread): by using lock, + prohibit modification of buffer string during read (which had caused + EFAULT or SEGV). [ruby-dev:40437] + + * test/ruby/test_io.rb: rewrite tests for the old behavior. + +Wed Feb 17 21:34:01 2010 Yusuke Endoh <mame@tsg.ne.jp> + + * regcomp.c (setup_tree, onig_compile): optimize .* at last by + converting into (?>.*), which does not backtrack. [ruby-core:27791] + + * test/ruby/test_regexp.rb: add a test for above. + +Wed Feb 17 21:26:53 2010 Tanaka Akira <akr@fsij.org> + + * bootstraptest/runner.rb (assert_normal_exit): add :timeout option. + Wed Feb 17 17:05:39 2010 Nobuyoshi Nakada <nobu@ruby-lang.org> * vm_insnhelper.c (vm_call_cfunc): removed unused variable. diff --git a/KNOWNBUGS.rb b/KNOWNBUGS.rb index a1b426a6d4..5c0e4d5156 100644 --- a/KNOWNBUGS.rb +++ b/KNOWNBUGS.rb @@ -3,14 +3,14 @@ # So all tests will cause failure. # -assert_finish 1, %q{ +assert_normal_exit %q{ open("tst-remove-load.rb", "w") {|f| - f << <<'End' -module Kernel - remove_method :load -end -raise -End + f << <<-'End' + module Kernel + remove_method :load + end + raise + End } load "tst-remove-load.rb" -}, '[ruby-dev:40234] [ruby-core:27959]' +}, '[ruby-dev:40234] [ruby-core:27959]', :timeout => 1 diff --git a/Makefile.in b/Makefile.in index 7b1ac4a3b9..bed0aaff91 100644 --- a/Makefile.in +++ b/Makefile.in @@ -181,7 +181,8 @@ uncommon.mk: $(srcdir)/common.mk sed 's/{\$$([^(){}]*)[^{}]*}//g' $< > $@ config.status: $(srcdir)/configure $(srcdir)/enc/Makefile.in - PWD= MINIRUBY="$(MINIRUBY)" $(SHELL) ./config.status --recheck + @PWD= MINIRUBY="$(MINIRUBY)"; set $(SHELL) ./config.status --recheck; \ + exec 3>&1; exit `exec 4>&1; { "$$@" 3>&- 4>&-; echo $$? 1>&4; } | fgrep -v '(cached)' 1>&3` $(srcdir)/configure: $(srcdir)/configure.in $(CHDIR) $(srcdir) && exec $(AUTOCONF) diff --git a/bootstraptest/runner.rb b/bootstraptest/runner.rb index b48329665a..9d98afcb89 100755 --- a/bootstraptest/runner.rb +++ b/bootstraptest/runner.rb @@ -213,16 +213,32 @@ def assert_valid_syntax(testsrc, message = '') } end -def assert_normal_exit(testsrc, message = '', ignore_signals = nil) +def assert_normal_exit(testsrc, *rest) + opt = {} + opt = rest.pop if Hash === rest.last + message, ignore_signals = rest + message ||= '' + timeout = opt[:timeout] newtest $stderr.puts "\##{@count} #{@location}" if @verbose faildesc = nil filename = make_srcfile(testsrc) old_stderr = $stderr.dup + timeout_signaled = false begin - $stderr.reopen("assert_normal_exit_stderr.log", "w") - `#{@ruby} -W0 #{filename}` - status = $? + $stderr.reopen("assert_normal_exit.log", "w") + io = IO.popen("#{@ruby} -W0 #{filename}") + pid = io.pid + th = Thread.new { + io.read + io.close + $? + } + if !th.join(timeout) + Process.kill :KILL, pid + timeout_signaled = true + end + status = th.value ensure $stderr.reopen(old_stderr) old_stderr.close @@ -235,8 +251,11 @@ def assert_normal_exit(testsrc, message = '', ignore_signals = nil) if signame sigdesc = "SIG#{signame} (#{sigdesc})" end + if timeout_signaled + sigdesc << " (timeout)" + end faildesc = pretty(testsrc, "killed by #{sigdesc}", nil) - stderr_log = File.read("assert_normal_exit_stderr.log") + stderr_log = File.read("assert_normal_exit.log") if !stderr_log.empty? faildesc << "\n" if /\n\z/ !~ faildesc stderr_log << "\n" if /\n\z/ !~ stderr_log @@ -34,6 +34,7 @@ COMMONOBJS = array.$(OBJEXT) \ compar.$(OBJEXT) \ complex.$(OBJEXT) \ dir.$(OBJEXT) \ + dln_find.$(OBJEXT) \ enum.$(OBJEXT) \ enumerator.$(OBJEXT) \ error.$(OBJEXT) \ @@ -528,6 +529,7 @@ complex.$(OBJEXT): {$(VPATH)}complex.c $(RUBY_H_INCLUDES) dir.$(OBJEXT): {$(VPATH)}dir.c $(RUBY_H_INCLUDES) {$(VPATH)}util.h \ $(ENCODING_H_INCLUDES) dln.$(OBJEXT): {$(VPATH)}dln.c {$(VPATH)}dln.h $(RUBY_H_INCLUDES) +dln_find.$(OBJEXT): {$(VPATH)}dln.c {$(VPATH)}dln.h $(RUBY_H_INCLUDES) dmydln.$(OBJEXT): {$(VPATH)}dmydln.c dln.$(OBJEXT) dmyext.$(OBJEXT): {$(VPATH)}dmyext.c dmyencoding.$(OBJEXT): {$(VPATH)}dmyencoding.c $(RUBY_H_INCLUDES) \ diff --git a/configure.in b/configure.in index 90a56902f4..f602880258 100644 --- a/configure.in +++ b/configure.in @@ -1937,6 +1937,12 @@ AS_CASE(["$target_os"], [nextstep* | openstep* | rhapsody* | darwin*], [ STRIP='strip -A -n']) +AC_ARG_WITH(ext, + AC_HELP_STRING([--with-ext=EXTS], + [pass to --with-ext option of extmk.rb])) +AC_ARG_WITH(out-ext, + AC_HELP_STRING([--with-out-ext=EXTS], + [pass to --without-ext option of extmk.rb])) EXTSTATIC= AC_SUBST(EXTSTATIC)dnl AC_ARG_WITH(static-linked-ext, @@ -100,8 +100,6 @@ dln_loaderror(const char *format, ...) } #endif -#ifndef NO_DLN_LOAD - #if defined(HAVE_DLOPEN) && !defined(USE_DLN_A_OUT) && !defined(_AIX) && !defined(MACOSX_DYLD) && !defined(_UNICOSMP) /* dynamic load with dlopen() */ # define USE_DLN_DLOPEN @@ -1220,15 +1218,21 @@ aix_loaderror(const char *pathname) } #endif -#endif /* NO_DLN_LOAD */ +#if defined(DLN_NEEDS_ALT_SEPARATOR) && DLN_NEEDS_ALT_SEPARATOR +#define translit_separator(src) do { \ + char *tmp = ALLOCA_N(char, strlen(src) + 1), *p = tmp, c; \ + do { \ + *p++ = ((c = *file++) == '/') ? DLN_NEEDS_ALT_SEPARATOR : c; \ + } while (c); \ + str = tmp; \ + } while (0) +#else +#define translit_separator(str) (void)(str) +#endif void* dln_load(const char *file) { -#ifdef NO_DLN_LOAD - dln_loaderror("this executable file can't load extension libraries"); -#else - #if !defined(_AIX) && !defined(NeXT) const char *error = 0; #define DLN_ERROR() (error = dln_strerror(), strcpy(ALLOCA_N(char, strlen(error) + 1), error)) @@ -1272,6 +1276,7 @@ dln_load(const char *file) char *buf; /* Load the file as an object one */ init_funcname(&buf, file); + translit_separator(file); #ifdef USE_DLN_DLOPEN #define DLN_DEFINED @@ -1492,236 +1497,5 @@ dln_load(const char *file) dln_loaderror("%s - %s", error, file); #endif -#endif /* NO_DLN_LOAD */ return 0; /* dummy return */ } - -static char *dln_find_1(const char *fname, const char *path, char *buf, size_t size, int exe_flag); - -char * -dln_find_exe_r(const char *fname, const char *path, char *buf, size_t size) -{ - char *envpath = 0; - - if (!path) { - path = getenv(PATH_ENV); - if (path) path = envpath = strdup(path); - } - - if (!path) { -#if defined(_WIN32) - path = "/usr/local/bin;/usr/ucb;/usr/bin;/bin;."; -#else - path = "/usr/local/bin:/usr/ucb:/usr/bin:/bin:."; -#endif - } - buf = dln_find_1(fname, path, buf, size, 1); - if (envpath) free(envpath); - return buf; -} - -char * -dln_find_file_r(const char *fname, const char *path, char *buf, size_t size) -{ - if (!path) path = "."; - return dln_find_1(fname, path, buf, size, 0); -} - -#ifndef HAVE_MVM -static char fbuf[MAXPATHLEN]; - -char * -dln_find_exe(const char *fname, const char *path) -{ - return dln_find_exe_r(fname, path, fbuf, sizeof(fbuf)); -} - -char * -dln_find_file(const char *fname, const char *path) -{ - return dln_find_file_r(fname, path, fbuf, sizeof(fbuf)); -} -#endif - -static char * -dln_find_1(const char *fname, const char *path, char *fbuf, size_t size, - int exe_flag /* non 0 if looking for executable. */) -{ - register const char *dp; - register const char *ep; - register char *bp; - struct stat st; - size_t i, fspace; -#ifdef DOSISH - static const char extension[][5] = { - EXECUTABLE_EXTS, - }; - size_t j; - int is_abs = 0, has_path = 0; - const char *ext = 0; -#endif - const char *p = fname; - - static const char pathname_too_long[] = "openpath: pathname too long (ignored)\n\ -\tDirectory \"%.*s\"\n\tFile \"%s\"\n"; -#define PATHNAME_TOO_LONG() fprintf(stderr, pathname_too_long, (int)(bp - fbuf), fbuf, fname) - -#define RETURN_IF(expr) if (expr) return (char *)fname; - - RETURN_IF(!fname); -#ifdef DOSISH -# ifndef CharNext -# define CharNext(p) ((p)+1) -# endif -# ifdef DOSISH_DRIVE_LETTER - if (((p[0] | 0x20) - 'a') < 26 && p[1] == ':') { - p += 2; - is_abs = 1; - } -# endif - switch (*p) { - case '/': case '\\': - is_abs = 1; - p++; - } - has_path = is_abs; - while (*p) { - switch (*p) { - case '/': case '\\': - has_path = 1; - ext = 0; - p++; - break; - case '.': - ext = p; - p++; - break; - default: - p = CharNext(p); - } - } - if (ext) { - for (j = 0; STRCASECMP(ext, extension[j]); ) { - if (++j == sizeof(extension) / sizeof(extension[0])) { - ext = 0; - break; - } - } - } - ep = bp = 0; - if (!exe_flag) { - RETURN_IF(is_abs); - } - else if (has_path) { - RETURN_IF(ext); - i = p - fname; - if (i + 1 > size) goto toolong; - fspace = size - i - 1; - bp = fbuf; - ep = p; - memcpy(fbuf, fname, i + 1); - goto needs_extension; - } - p = fname; -#endif - - if (*p == '.' && *++p == '.') ++p; - RETURN_IF(*p == '/'); - RETURN_IF(exe_flag && strchr(fname, '/')); - -#undef RETURN_IF - - for (dp = path;; dp = ++ep) { - register size_t l; - - /* extract a component */ - ep = strchr(dp, PATH_SEP[0]); - if (ep == NULL) - ep = dp+strlen(dp); - - /* find the length of that component */ - l = ep - dp; - bp = fbuf; - fspace = size - 2; - if (l > 0) { - /* - ** If the length of the component is zero length, - ** start from the current directory. If the - ** component begins with "~", start from the - ** user's $HOME environment variable. Otherwise - ** take the path literally. - */ - - if (*dp == '~' && (l == 1 || -#if defined(DOSISH) - dp[1] == '\\' || -#endif - dp[1] == '/')) { - char *home; - - home = getenv("HOME"); - if (home != NULL) { - i = strlen(home); - if (fspace < i) - goto toolong; - fspace -= i; - memcpy(bp, home, i); - bp += i; - } - dp++; - l--; - } - if (l > 0) { - if (fspace < l) - goto toolong; - fspace -= l; - memcpy(bp, dp, l); - bp += l; - } - - /* add a "/" between directory and filename */ - if (ep[-1] != '/') - *bp++ = '/'; - } - - /* now append the file name */ - i = strlen(fname); - if (fspace < i) { - toolong: - PATHNAME_TOO_LONG(); - goto next; - } - fspace -= i; - memcpy(bp, fname, i + 1); - -#if defined(DOSISH) - if (exe_flag && !ext) { - needs_extension: - for (j = 0; j < sizeof(extension) / sizeof(extension[0]); j++) { - if (fspace < strlen(extension[j])) { - PATHNAME_TOO_LONG(); - continue; - } - strlcpy(bp + i, extension[j], fspace); - if (stat(fbuf, &st) == 0) - return fbuf; - } - goto next; - } -#endif /* _WIN32 or __EMX__ */ - - if (stat(fbuf, &st) == 0) { - if (exe_flag == 0) return fbuf; - /* looking for executable */ - if (!S_ISDIR(st.st_mode) && eaccess(fbuf, X_OK) == 0) - return fbuf; - } - next: - /* if not, and no other alternatives, life is bleak */ - if (*ep == '\0') { - return NULL; - } - - /* otherwise try the next component in the search path */ - } -} diff --git a/dln_find.c b/dln_find.c new file mode 100644 index 0000000000..44da94a9b3 --- /dev/null +++ b/dln_find.c @@ -0,0 +1,306 @@ +/********************************************************************** + + dln.c - + + $Author$ + created at: Tue Jan 18 17:05:06 JST 1994 + + Copyright (C) 1993-2007 Yukihiro Matsumoto + +**********************************************************************/ + +#ifdef RUBY_EXPORT +#include "ruby/ruby.h" +#define dln_notimplement rb_notimplement +#define dln_memerror rb_memerror +#define dln_exit rb_exit +#define dln_loaderror rb_loaderror +#else +#define dln_notimplement --->>> dln not implemented <<<--- +#define dln_memerror abort +#define dln_exit exit +static void dln_loaderror(const char *format, ...); +#endif +#include "dln.h" + +#ifdef HAVE_STDLIB_H +# include <stdlib.h> +#endif + +#ifdef USE_DLN_A_OUT +char *dln_argv0; +#endif + +#if defined(HAVE_ALLOCA_H) +#include <alloca.h> +#endif + +#ifdef HAVE_STRING_H +# include <string.h> +#else +# include <strings.h> +#endif + +#ifndef xmalloc +void *xmalloc(); +void *xcalloc(); +void *xrealloc(); +#endif + +#define free(x) xfree(x) + +#include <stdio.h> +#if defined(_WIN32) +#include "missing/file.h" +#endif +#include <sys/types.h> +#include <sys/stat.h> + +#ifndef S_ISDIR +# define S_ISDIR(m) ((m & S_IFMT) == S_IFDIR) +#endif + +#ifdef HAVE_SYS_PARAM_H +# include <sys/param.h> +#endif +#ifndef MAXPATHLEN +# define MAXPATHLEN 1024 +#endif + +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif + +#ifndef _WIN32 +char *getenv(); +#endif + +static char *dln_find_1(const char *fname, const char *path, char *buf, size_t size, int exe_flag); + +char * +dln_find_exe_r(const char *fname, const char *path, char *buf, size_t size) +{ + char *envpath = 0; + + if (!path) { + path = getenv(PATH_ENV); + if (path) path = envpath = strdup(path); + } + + if (!path) { +#if defined(_WIN32) + path = "/usr/local/bin;/usr/ucb;/usr/bin;/bin;."; +#else + path = "/usr/local/bin:/usr/ucb:/usr/bin:/bin:."; +#endif + } + buf = dln_find_1(fname, path, buf, size, 1); + if (envpath) free(envpath); + return buf; +} + +char * +dln_find_file_r(const char *fname, const char *path, char *buf, size_t size) +{ + if (!path) path = "."; + return dln_find_1(fname, path, buf, size, 0); +} + +#ifndef HAVE_MVM +static char fbuf[MAXPATHLEN]; + +char * +dln_find_exe(const char *fname, const char *path) +{ + return dln_find_exe_r(fname, path, fbuf, sizeof(fbuf)); +} + +char * +dln_find_file(const char *fname, const char *path) +{ + return dln_find_file_r(fname, path, fbuf, sizeof(fbuf)); +} +#endif + +static char * +dln_find_1(const char *fname, const char *path, char *fbuf, size_t size, + int exe_flag /* non 0 if looking for executable. */) +{ + register const char *dp; + register const char *ep; + register char *bp; + struct stat st; + size_t i, fspace; +#ifdef DOSISH + static const char extension[][5] = { + EXECUTABLE_EXTS, + }; + size_t j; + int is_abs = 0, has_path = 0; + const char *ext = 0; +#endif + const char *p = fname; + + static const char pathname_too_long[] = "openpath: pathname too long (ignored)\n\ +\tDirectory \"%.*s\"\n\tFile \"%s\"\n"; +#define PATHNAME_TOO_LONG() fprintf(stderr, pathname_too_long, (int)(bp - fbuf), fbuf, fname) + +#define RETURN_IF(expr) if (expr) return (char *)fname; + + RETURN_IF(!fname); +#ifdef DOSISH +# ifndef CharNext +# define CharNext(p) ((p)+1) +# endif +# ifdef DOSISH_DRIVE_LETTER + if (((p[0] | 0x20) - 'a') < 26 && p[1] == ':') { + p += 2; + is_abs = 1; + } +# endif + switch (*p) { + case '/': case '\\': + is_abs = 1; + p++; + } + has_path = is_abs; + while (*p) { + switch (*p) { + case '/': case '\\': + has_path = 1; + ext = 0; + p++; + break; + case '.': + ext = p; + p++; + break; + default: + p = CharNext(p); + } + } + if (ext) { + for (j = 0; STRCASECMP(ext, extension[j]); ) { + if (++j == sizeof(extension) / sizeof(extension[0])) { + ext = 0; + break; + } + } + } + ep = bp = 0; + if (!exe_flag) { + RETURN_IF(is_abs); + } + else if (has_path) { + RETURN_IF(ext); + i = p - fname; + if (i + 1 > size) goto toolong; + fspace = size - i - 1; + bp = fbuf; + ep = p; + memcpy(fbuf, fname, i + 1); + goto needs_extension; + } + p = fname; +#endif + + if (*p == '.' && *++p == '.') ++p; + RETURN_IF(*p == '/'); + RETURN_IF(exe_flag && strchr(fname, '/')); + +#undef RETURN_IF + + for (dp = path;; dp = ++ep) { + register size_t l; + + /* extract a component */ + ep = strchr(dp, PATH_SEP[0]); + if (ep == NULL) + ep = dp+strlen(dp); + + /* find the length of that component */ + l = ep - dp; + bp = fbuf; + fspace = size - 2; + if (l > 0) { + /* + ** If the length of the component is zero length, + ** start from the current directory. If the + ** component begins with "~", start from the + ** user's $HOME environment variable. Otherwise + ** take the path literally. + */ + + if (*dp == '~' && (l == 1 || +#if defined(DOSISH) + dp[1] == '\\' || +#endif + dp[1] == '/')) { + char *home; + + home = getenv("HOME"); + if (home != NULL) { + i = strlen(home); + if (fspace < i) + goto toolong; + fspace -= i; + memcpy(bp, home, i); + bp += i; + } + dp++; + l--; + } + if (l > 0) { + if (fspace < l) + goto toolong; + fspace -= l; + memcpy(bp, dp, l); + bp += l; + } + + /* add a "/" between directory and filename */ + if (ep[-1] != '/') + *bp++ = '/'; + } + + /* now append the file name */ + i = strlen(fname); + if (fspace < i) { + toolong: + PATHNAME_TOO_LONG(); + goto next; + } + fspace -= i; + memcpy(bp, fname, i + 1); + +#if defined(DOSISH) + if (exe_flag && !ext) { + needs_extension: + for (j = 0; j < sizeof(extension) / sizeof(extension[0]); j++) { + if (fspace < strlen(extension[j])) { + PATHNAME_TOO_LONG(); + continue; + } + strlcpy(bp + i, extension[j], fspace); + if (stat(fbuf, &st) == 0) + return fbuf; + } + goto next; + } +#endif /* _WIN32 or __EMX__ */ + + if (stat(fbuf, &st) == 0) { + if (exe_flag == 0) return fbuf; + /* looking for executable */ + if (!S_ISDIR(st.st_mode) && eaccess(fbuf, X_OK) == 0) + return fbuf; + } + next: + /* if not, and no other alternatives, life is bleak */ + if (*ep == '\0') { + return NULL; + } + + /* otherwise try the next component in the search path */ + } +} @@ -1,2 +1,7 @@ -#define NO_DLN_LOAD 1 -#include "dln.c" +#include "ruby/ruby.h" + +void* +dln_load(const char *file) +{ + rb_loaderror("this executable file can't load extension libraries"); +} diff --git a/doc/rubygems/ChangeLog b/doc/rubygems/ChangeLog index b5ef160dcf..2e67a4c2c5 100644 --- a/doc/rubygems/ChangeLog +++ b/doc/rubygems/ChangeLog @@ -1,8 +1,148 @@ -Tue Dec 8 16:19:05 2009 Nobuyoshi Nakada <nobu@ruby-lang.org> +# -*- coding: utf-8 -*- - * lib/rubygems: update to 1.3.5. +2010-02-20 Eric Hodel <drbrain@segment7.net> -# -*- coding: utf-8 -*- + * lib/rubygems.rb: 1.3.6. + * test/*: Windows test fixes + * lib/rubygems/remote_fetcher.rb: Fix same file detection on windows. + +2010-02-15 Eric Hodel <drbrain@segment7.net> + + * lib/rubygems/config_file.rb: Fix use of ConfigFile#api_key= vs + #rubygems_api_key=. Patch by Nick Quaranto. + +2010-02-12 Eric Hodel <drbrain@segment7.net> + + * Rakefile: RubyGems doesn't depend on previous RubyGems. + +2010-02-11 Eric Hodel <drbrain@segment7.net> + + * lib/rubygems.rb: http://rubygems.org is now the default source. + * lib/rubygems/dependency.rb: Only warn once about + #version_requirement + +2010-02-09 Eric Hodel <drbrain@segment7.net> + + * bin/update_rubygems: Use system, exec more correctly, remove + useless puts. + * lib/rubygems/commands/query_command.rb: List every version when + --prerelease --all is given. + +2010-02-08 Eric Hodel <drbrain@segment7.net> + + * lib/rubygems/commands/dependency_command.rb: Support --prerelease. + * lib/rubygems/commands/fetch_command.rb: Support --prerelease. + * lib/rubygems/format.rb: Don't crash on empty files. Bug #27292 by + Ian Ragsdale. + * lib/rubygems/server.rb: Fix markup. Bug #27045 by Eric Young. + * History.txt: RubyGems 1.3.6 release notes. + +2010-02-07 Eric Hodel <drbrain@segment7.net> + + * lib/rubygems/dependency_installer.rb: Allow prerelease gems to + depend on non-prerelease gems. + +2010-02-06 Eric Hodel <drbrain@segment7.net> + + * test/test_gem_commands_specification_command.rb: Don't enforce YAML + format. Patch #27791 by Aaron Patterson. + * lib/rubygems/version.rb: Allow captial letters in prerelease + versions. + * lib/rubygems/config_file.rb: Explain format of ~/.gemrc. Bug + #27698 by J Smith. + * lib/rubygems/gem_path_searcher.rb: Handle nil require_paths. + Patch #27334 by Roger Pack. + * lib/rubygems/server.rb: Handle --bind option. Patch #27357 by + Bruno Michel. + * lib/rubygems/doc_manager: gem rdoc --overwrite to preserve built + rdoc. Patch #25982 by Akinori MUSHA. + * lib/rubygems/commands/which_command.rb: Fail if no paths were + found. Adapted patch #27681 by Caio Chassot. + * lib/rubygems/remote_fetcher.rb: Don't copy if the file is where we + want it. Patch #27409 by Jakub Šťastný. + +2010-02-01 John Barnette <jbarnette@rubygems.org> + + * lib/rubygems/command*: Add 'gem push' and 'gem owner' for + interacting with modern/Gemcutter sources [Nick Quaranto] + +2010-01-18 Eric Hodel <drbrain@segment7.net> + + * lib/rubygems/dependency_list.rb: Ignore development dependencies + unless explicitly needed. Bug #27608 by Roger Pack. + +2010-01-12 John Barnette <jbarnette@rubygems.org> + + * Rakefile: Don't add development deps when building the + rubygems-update gem, it borks older versions when they're updating + from a stub index. + +2009-12-22 Evan Phoenix <evan@fallingsnow.net> + + * lib/rubygems/spec_fetcher.rb: Don't bother re-Marshaling the spec + YAML list. + +2009-11-04 John Barnette <jbarnette@rubygems.org> + + * lib/rubygems/timer.rb: Removed. The deprecation sun set in July. + +2009-10-14 John Barnette <jbarnette@rubygems.org> + + * lib/rubygems/dependency.rb: Burndown/cleanup. Refactored code + and tests. Gem::Dependency.version_requirement(s) is deprecated in + favor of Gem::Dependency.requirement. + + * lib/rubygems/requirement.rb: Burndown/cleanup. Refactored code + and tests. See test/support/shortcuts.rb for some new test helpers. + +2009-10-13 John Barnette <jbarnette@rubygems.org> + + * lib/rubygems/local_remote_options.rb: Make --source additive, + not exclusive. If exclusive sources are desired, use + --clear-sources first. + +2009-09-29 John Barnette <jbarnette@rubyforge.org> + + * lib/rubygems/spec_fetcher.rb: Be slightly more robust when faced + with corrupted indexes. + +2009-09-03 John Barnette <jbarnette@rubyforge.org> + + * LOTS: Use "raise" consistently, not "fail". + +2009-09-01 John Barnette <jbarnette@rubyforge.org> + + * lib/rubygems/version.rb: Gem::Version immutability + burndown. Changed canonical internal representation to an + Array. Refactored significant amounts of the internals for + clarity. Breaking change: Gem::Version::Requirement is no longer + available, use Gem::Requirement instead. Breaking change: custom + YAML marshaling is gone. Credit to Yehuda Katz for certain bits of + a related patch. + * test/test_gem_dependency.rb: Moved a bunch of tests over from + test_gem_version.rb. Work in progress. + * test/test_gem_specification.rb: Removed a failing YAML + test. Many more will be going away shortly. + * test/test_gem_version.rb: Significant refactoring for + maintainability and clarity. Moved a ton of poorly-placed tests to + test_gem_dependency.rb for future refactoring. + +2009-08-19 Ryan Davis <ryand-ruby@zenspider.com> + + * lib/rubygems.rb: Cleanup of rdoc and file layout. + * lib/rubygems/versions.rb: Added Version#spermy_recommendation + and fixed bug in Version::Part#inspect. General cleanup. + +2009-07-29 John Barnette <jbarnette@rubyforge.org> + + * lib/rubygems/package/tar_input.rb: Add Maglev to the list of + implementations with working Zlib. Bug #26790 by Peter McLain. + +2009-07-21 Eric Hodel <drbrain@segment7.net> + + * lib/rubygems.rb: 1.3.5. + * lib/rubygems/package.rb: Remove dangling digest require. Reported + by Jeremy Kemper. 2009-06-25 Eric Hodel <drbrain@segment7.net> @@ -12,6 +152,8 @@ Tue Dec 8 16:19:05 2009 Nobuyoshi Nakada <nobu@ruby-lang.org> 2009-06-23 Eric Hodel <drbrain@segment7.net> * release_notes/rel_1_3_5.rdoc: RubyGems 1.3.5 release notes. + * lib/rubygems/builder.rb: Only print out with verbose. + * lib/rubygems/package_task.rb: Only print out with -t. 2009-06-12 Ryan Davis <ryand@zenspider.com> @@ -19,8 +161,26 @@ Tue Dec 8 16:19:05 2009 Nobuyoshi Nakada <nobu@ruby-lang.org> 2009-06-10 Phil Hagelberg <technomancy@gmail.com> + * lib/rubygems/installer.rb: --user-install is no longer enabled by + default. * lib/rubygems/source_index.rb: Fix use of prerelease gems. +2009-06-04 Eric Hodel <drbrain@segment7.net> + + * util/gem_prelude.rb.template: Backports from 1.9. + +2009-06-03 Eric Hodel <drbrain@segment7.net> + + * bin/gem: Support 1.8.6+ + * lib/rubygems/digest*: Removed, support dropped for Ruby < 1.8.6 + * lib/rubygems/installer.rb: Support env(1) in wrong path, use + /bin/sh if shebang has options. By Nobu, ruby trunk r22853. + * lib/rubygems/config_file.rb: Switch to stdcall for appdata folder. + [ruby-core:22601]. + * lib/rubygems.rb: Use only File::expand_path on 1.9 for home dir. + Don't recklessly create directories. Simplify RbConfig::datadir + definition. + 2009-05-30 Eric Hodel <drbrain@segment7.net> * lib/rubygems/commands/which_command.rb: Only print out directory diff --git a/doc/rubygems/History.txt b/doc/rubygems/History.txt index 86ea9398f2..4a80b1bfb4 100644 --- a/doc/rubygems/History.txt +++ b/doc/rubygems/History.txt @@ -1,4 +1,57 @@ -=== 1.3.5 / 2009-07-21 +# -*- coding: utf-8 -*- + +=== 1.3.6 / 2010-02-17 + +NOTE: + +http://rubygems.org is now the default source for downloading gems. + +You may have sources set via ~/.gemrc, so you should replace +http://gems.rubyforge.org with http://rubygems.org + +http://gems.rubyforge.org will continue to work for the forseeable future. + +New features: + +* `gem` commands + * Added `gem push` and `gem owner` for interacting with modern/Gemcutter + sources + * `gem dep` now supports --prerelease. + * `gem fetch` now supports --prerelease. + * `gem server` now supports --bind. Patch #27357 by Bruno Michel. + * `gem rdoc` no longer overwrites built documentation. Use --overwrite + force rebuilding. Patch #25982 by Akinori MUSHA. +* Captial letters are now allowed in prerelease versions. + +Bug fixes: + +* Development deps are no longer added to rubygems-update gem so older + versions can update sucessfully. +* Installer bugs: + * Prerelease gems can now depend on non-prerelease gems. + * Development dependencies are ignored unless explicitly needed. Bug #27608 + by Roger Pack. +* `gem` commands + * `gem which` now fails if no paths were found. Adapted patch #27681 by + Caio Chassot. + * `gem server` no longer has invalid markup. Bug #27045 by Eric Young. + * `gem list` and friends show both prerelease and regular gems when + --prerelease --all is given +* Gem::Format no longer crashes on empty files. Bug #27292 by Ian Ragsdale. +* Gem::GemPathSearcher handles nil require_paths. Patch #27334 by Roger Pack. +* Gem::RemoteFetcher no longer copies the file if it is where we want it. + Patch #27409 by Jakub Šťastný. + +Deprecation Notices: + +* lib/rubygems/timer.rb has been removed. +* Gem::Dependency#version_requirements is deprecated and will be removed on or + after August 2010. +* Bulk index update is no longer supported. +* Gem::manage_gems was removed in 1.3.3. +* Time::today was removed in 1.3.3. + +=== 1.3.5 / 2009-07-21 Bug fixes: diff --git a/doc/rubygems/README b/doc/rubygems/README index 0e42112760..68a52593d4 100644 --- a/doc/rubygems/README +++ b/doc/rubygems/README @@ -1,8 +1,9 @@ = RubyGems +* http://rubygems.org/ +* http://docs.rubygems.org/ * http://rubygems.rubyforge.org/ * http://rubyforge.org/projects/rubygems -* http://rubygems.org/ == DESCRIPTION @@ -15,7 +16,7 @@ See Gem for information on RubyGems (or `ri Gem`) To upgrade to the latest RubyGems, run: - $ gem install --system # you might need to be an administrator or root + $ gem update --system # you might need to be an administrator or root NOTE: RubyGems 1.1 and 1.2 have problems upgrading when there is no rubygems-update installed. You will need to use the following instructions diff --git a/ext/digest/sha2/depend b/ext/digest/sha2/depend index 225d6ad52b..00e18e158d 100644 --- a/ext/digest/sha2/depend +++ b/ext/digest/sha2/depend @@ -3,3 +3,4 @@ sha2.o: sha2.c sha2.h $(srcdir)/../defs.h $(hdrdir)/ruby.h \ sha2init.o: sha2init.c $(srcdir)/../digest.h $(hdrdir)/ruby.h \ $(topdir)/config.h $(hdrdir)/defines.h $(hdrdir)/intern.h \ sha2.h $(srcdir)/../defs.h +sha2ossl.o: sha2ossl.h $(srcdir)/../defs.h diff --git a/ext/digest/sha2/extconf.rb b/ext/digest/sha2/extconf.rb index c15043f113..d4af8702aa 100644 --- a/ext/digest/sha2/extconf.rb +++ b/ext/digest/sha2/extconf.rb @@ -6,10 +6,19 @@ require "mkmf" $defs << "-DHAVE_CONFIG_H" $INCFLAGS << " -I$(srcdir)/.." -$objs = [ - "sha2.#{$OBJEXT}", - "sha2init.#{$OBJEXT}", -] +$objs = [ "sha2init.#{$OBJEXT}" ] + +dir_config("openssl") + +if !with_config("bundled-sha2") && + have_library("crypto") && + %w[SHA256 SHA512].all? {|d| have_func("#{d}_Transform", "openssl/sha.h")} + $objs << "sha2ossl.#{$OBJEXT}" + $defs << "-DSHA2_USE_OPENSSL" +else + have_type("u_int8_t") + $objs << "sha2.#{$OBJEXT}" +end have_header("sys/cdefs.h") diff --git a/ext/digest/sha2/sha2.c b/ext/digest/sha2/sha2.c index 253e54f265..6e4a99c1e3 100644 --- a/ext/digest/sha2/sha2.c +++ b/ext/digest/sha2/sha2.c @@ -234,7 +234,7 @@ void SHA512_Transform(SHA512_CTX*, const sha2_word64*); /*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/ /* Hash constant words K for SHA-256: */ -const static sha2_word32 K256[64] = { +static const sha2_word32 K256[64] = { 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, @@ -254,7 +254,7 @@ const static sha2_word32 K256[64] = { }; /* Initial hash value H for SHA-256: */ -const static sha2_word32 sha256_initial_hash_value[8] = { +static const sha2_word32 sha256_initial_hash_value[8] = { 0x6a09e667UL, 0xbb67ae85UL, 0x3c6ef372UL, @@ -266,7 +266,7 @@ const static sha2_word32 sha256_initial_hash_value[8] = { }; /* Hash constant words K for SHA-384 and SHA-512: */ -const static sha2_word64 K512[80] = { +static const sha2_word64 K512[80] = { ULL(0x428a2f98d728ae22), ULL(0x7137449123ef65cd), ULL(0xb5c0fbcfec4d3b2f), ULL(0xe9b5dba58189dbbc), ULL(0x3956c25bf348b538), ULL(0x59f111f1b605d019), @@ -310,7 +310,7 @@ const static sha2_word64 K512[80] = { }; /* Initial hash value H for SHA-384 */ -const static sha2_word64 sha384_initial_hash_value[8] = { +static const sha2_word64 sha384_initial_hash_value[8] = { ULL(0xcbbb9d5dc1059ed8), ULL(0x629a292a367cd507), ULL(0x9159015a3070dd17), @@ -322,7 +322,7 @@ const static sha2_word64 sha384_initial_hash_value[8] = { }; /* Initial hash value H for SHA-512 */ -const static sha2_word64 sha512_initial_hash_value[8] = { +static const sha2_word64 sha512_initial_hash_value[8] = { ULL(0x6a09e667f3bcc908), ULL(0xbb67ae8584caa73b), ULL(0x3c6ef372fe94f82b), @@ -536,7 +536,7 @@ void SHA256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) { /* Sanity check: */ assert(context != (SHA256_CTX*)0 && data != (sha2_byte*)0); - usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; + usedspace = (unsigned int)((context->bitcount >> 3) % SHA256_BLOCK_LENGTH); if (usedspace > 0) { /* Calculate how much free space is available in the buffer */ freespace = SHA256_BLOCK_LENGTH - usedspace; @@ -573,11 +573,7 @@ void SHA256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) { usedspace = freespace = 0; } -#ifdef RUBY -void SHA256_Finish(SHA256_CTX* context, sha2_byte digest[]) { -#else void SHA256_Final(sha2_byte digest[], SHA256_CTX* context) { -#endif sha2_word32 *d = (sha2_word32*)digest; unsigned int usedspace; @@ -586,7 +582,7 @@ void SHA256_Final(sha2_byte digest[], SHA256_CTX* context) { /* If no digest buffer is passed, we don't bother doing this: */ if (digest != (sha2_byte*)0) { - usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; + usedspace = (unsigned int)((context->bitcount >> 3) % SHA256_BLOCK_LENGTH); #if BYTE_ORDER == LITTLE_ENDIAN /* Convert FROM host byte order */ REVERSE64(context->bitcount,context->bitcount); @@ -648,12 +644,7 @@ char *SHA256_End(SHA256_CTX* context, char buffer[]) { assert(context != (SHA256_CTX*)0); if (buffer != (char*)0) { -#ifdef RUBY - SHA256_Finish(context, digest); -#else SHA256_Final(digest, context); -#endif - for (i = 0; i < SHA256_DIGEST_LENGTH; i++) { *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; *buffer++ = sha2_hex_digits[*d & 0x0f]; @@ -866,7 +857,7 @@ void SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) { /* Sanity check: */ assert(context != (SHA512_CTX*)0 && data != (sha2_byte*)0); - usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; + usedspace = (unsigned int)((context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH); if (usedspace > 0) { /* Calculate how much free space is available in the buffer */ freespace = SHA512_BLOCK_LENGTH - usedspace; @@ -906,7 +897,7 @@ void SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) { void SHA512_Last(SHA512_CTX* context) { unsigned int usedspace; - usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; + usedspace = (unsigned int)((context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH); #if BYTE_ORDER == LITTLE_ENDIAN /* Convert FROM host byte order */ REVERSE64(context->bitcount[0],context->bitcount[0]); @@ -944,11 +935,7 @@ void SHA512_Last(SHA512_CTX* context) { SHA512_Transform(context, (sha2_word64*)context->buffer); } -#ifdef RUBY -void SHA512_Finish(SHA512_CTX* context, sha2_byte digest[]) { -#else void SHA512_Final(sha2_byte digest[], SHA512_CTX* context) { -#endif sha2_word64 *d = (sha2_word64*)digest; /* Sanity check: */ @@ -985,12 +972,7 @@ char *SHA512_End(SHA512_CTX* context, char buffer[]) { assert(context != (SHA512_CTX*)0); if (buffer != (char*)0) { -#ifdef RUBY - SHA512_Finish(context, digest); -#else SHA512_Final(digest, context); -#endif - for (i = 0; i < SHA512_DIGEST_LENGTH; i++) { *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; *buffer++ = sha2_hex_digits[*d & 0x0f]; @@ -1027,11 +1009,7 @@ void SHA384_Update(SHA384_CTX* context, const sha2_byte* data, size_t len) { SHA512_Update((SHA512_CTX*)context, data, len); } -#ifdef RUBY -void SHA384_Finish(SHA384_CTX* context, sha2_byte digest[]) { -#else void SHA384_Final(sha2_byte digest[], SHA384_CTX* context) { -#endif sha2_word64 *d = (sha2_word64*)digest; /* Sanity check: */ @@ -1068,12 +1046,7 @@ char *SHA384_End(SHA384_CTX* context, char buffer[]) { assert(context != (SHA384_CTX*)0); if (buffer != (char*)0) { -#ifdef RUBY - SHA384_Finish(context, digest); -#else SHA384_Final(digest, context); -#endif - for (i = 0; i < SHA384_DIGEST_LENGTH; i++) { *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; *buffer++ = sha2_hex_digits[*d & 0x0f]; diff --git a/ext/digest/sha2/sha2.h b/ext/digest/sha2/sha2.h index 3536b31330..1231de5ca2 100644 --- a/ext/digest/sha2/sha2.h +++ b/ext/digest/sha2/sha2.h @@ -91,11 +91,18 @@ extern "C" { * uintXX_t (from inttypes.h), you may need to define things by hand * for your system: */ -#if 0 -typedef unsigned char u_int8_t; /* 1-byte (8-bits) */ -typedef unsigned int u_int32_t; /* 4-bytes (32-bits) */ -typedef unsigned long long u_int64_t; /* 8-bytes (64-bits) */ +#ifndef SHA2_USE_INTTYPES_H +# ifdef HAVE_U_INT8_T +typedef u_int8_t uint8_t; /* 1-byte (8-bits) */ +typedef u_int32_t uint32_t; /* 4-bytes (32-bits) */ +typedef u_int64_t uint64_t; /* 8-bytes (64-bits) */ +# else +typedef unsigned char uint8_t; /* 1-byte (8-bits) */ +typedef unsigned int uint32_t; /* 4-bytes (32-bits) */ +typedef unsigned long long uint64_t; /* 8-bytes (64-bits) */ +# endif #endif + /* * Most BSD systems already define u_intXX_t types, as does Linux. * Some systems, however, like Compaq's Tru64 Unix instead can use @@ -112,8 +119,6 @@ typedef unsigned long long u_int64_t; /* 8-bytes (64-bits) */ * * cc -DSHA2_USE_INTTYPES_H ... */ -#ifdef SHA2_USE_INTTYPES_H - typedef struct _SHA256_CTX { uint32_t state[8]; uint64_t bitcount; @@ -125,21 +130,6 @@ typedef struct _SHA512_CTX { uint8_t buffer[SHA512_BLOCK_LENGTH]; } SHA512_CTX; -#else /* SHA2_USE_INTTYPES_H */ - -typedef struct _SHA256_CTX { - u_int32_t state[8]; - u_int64_t bitcount; - u_int8_t buffer[SHA256_BLOCK_LENGTH]; -} SHA256_CTX; -typedef struct _SHA512_CTX { - u_int64_t state[8]; - u_int64_t bitcount[2]; - u_int8_t buffer[SHA512_BLOCK_LENGTH]; -} SHA512_CTX; - -#endif /* SHA2_USE_INTTYPES_H */ - typedef SHA512_CTX SHA384_CTX; @@ -148,70 +138,51 @@ typedef SHA512_CTX SHA384_CTX; #define SHA256_Init rb_Digest_SHA256_Init #define SHA256_Update rb_Digest_SHA256_Update #define SHA256_Finish rb_Digest_SHA256_Finish +#define SHA256_Data rb_Digest_SHA256_Data +#define SHA256_End rb_Digest_SHA256_End +#define SHA256_Last rb_Digest_SHA256_Last +#define SHA256_Transform rb_Digest_SHA256_Transform +#define SHA256_Final(d, c) SHA256_Finish(c, d) #define SHA384_Init rb_Digest_SHA384_Init #define SHA384_Update rb_Digest_SHA384_Update #define SHA384_Finish rb_Digest_SHA384_Finish +#define SHA384_Data rb_Digest_SHA384_Data +#define SHA384_End rb_Digest_SHA384_End +#define SHA384_Last rb_Digest_SHA384_Last +#define SHA384_Transform rb_Digest_SHA384_Transform +#define SHA384_Final(d, c) SHA384_Finish(c, d) #define SHA512_Init rb_Digest_SHA512_Init #define SHA512_Update rb_Digest_SHA512_Update #define SHA512_Finish rb_Digest_SHA512_Finish +#define SHA512_Data rb_Digest_SHA512_Data +#define SHA512_End rb_Digest_SHA512_End +#define SHA512_Last rb_Digest_SHA512_Last +#define SHA512_Transform rb_Digest_SHA512_Transform +#define SHA512_Final(d, c) SHA512_Finish(c, d) #endif /* RUBY */ + #ifndef NOPROTO -#ifdef SHA2_USE_INTTYPES_H void SHA256_Init(SHA256_CTX *); void SHA256_Update(SHA256_CTX*, const uint8_t*, size_t); -#ifdef RUBY -void SHA256_Finish(SHA256_CTX*, uint8_t[SHA256_DIGEST_LENGTH]); -#else void SHA256_Final(uint8_t[SHA256_DIGEST_LENGTH], SHA256_CTX*); -#endif /* RUBY */ char* SHA256_End(SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]); char* SHA256_Data(const uint8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]); void SHA384_Init(SHA384_CTX*); void SHA384_Update(SHA384_CTX*, const uint8_t*, size_t); -#ifdef RUBY -void SHA384_Finish(SHA384_CTX*, uint8_t[SHA384_DIGEST_LENGTH]); -#else void SHA384_Final(uint8_t[SHA384_DIGEST_LENGTH], SHA384_CTX*); -#endif /* RUBY */ char* SHA384_End(SHA384_CTX*, char[SHA384_DIGEST_STRING_LENGTH]); char* SHA384_Data(const uint8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]); void SHA512_Init(SHA512_CTX*); void SHA512_Update(SHA512_CTX*, const uint8_t*, size_t); -#ifdef RUBY -void SHA512_Finish(SHA512_CTX*, uint8_t[SHA512_DIGEST_LENGTH]); -#else void SHA512_Final(uint8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*); -#endif /* RUBY */ char* SHA512_End(SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH]); char* SHA512_Data(const uint8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]); -#else /* SHA2_USE_INTTYPES_H */ - -void SHA256_Init(SHA256_CTX *); -void SHA256_Update(SHA256_CTX*, const u_int8_t*, size_t); -void SHA256_Final(u_int8_t[SHA256_DIGEST_LENGTH], SHA256_CTX*); -char* SHA256_End(SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]); -char* SHA256_Data(const u_int8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]); - -void SHA384_Init(SHA384_CTX*); -void SHA384_Update(SHA384_CTX*, const u_int8_t*, size_t); -void SHA384_Final(u_int8_t[SHA384_DIGEST_LENGTH], SHA384_CTX*); -char* SHA384_End(SHA384_CTX*, char[SHA384_DIGEST_STRING_LENGTH]); -char* SHA384_Data(const u_int8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]); - -void SHA512_Init(SHA512_CTX*); -void SHA512_Update(SHA512_CTX*, const u_int8_t*, size_t); -void SHA512_Final(u_int8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*); -char* SHA512_End(SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH]); -char* SHA512_Data(const u_int8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]); - -#endif /* SHA2_USE_INTTYPES_H */ - #else /* NOPROTO */ void SHA256_Init(); diff --git a/ext/digest/sha2/sha2init.c b/ext/digest/sha2/sha2init.c index 8b79e950a6..13df4bcb78 100644 --- a/ext/digest/sha2/sha2init.c +++ b/ext/digest/sha2/sha2init.c @@ -2,7 +2,11 @@ /* $Id$ */ #include "digest.h" +#if defined(SHA2_USE_OPENSSL) +#include "sha2ossl.h" +#else #include "sha2.h" +#endif #define FOREACH_BITLEN(func) func(256) func(384) func(512) diff --git a/ext/digest/sha2/sha2ossl.c b/ext/digest/sha2/sha2ossl.c new file mode 100644 index 0000000000..86824e72f4 --- /dev/null +++ b/ext/digest/sha2/sha2ossl.c @@ -0,0 +1,11 @@ +#include "defs.h" +#include "sha2ossl.h" + +#define SHA_Finish(bit) \ + void SHA##bit##_Finish(SHA##bit##_CTX *ctx, char *buf) \ + { SHA##bit##_Final((unsigned char *)buf, ctx);} +#define SHA384_Final SHA512_Final + +SHA_Finish(256) +SHA_Finish(384) +SHA_Finish(512) diff --git a/ext/digest/sha2/sha2ossl.h b/ext/digest/sha2/sha2ossl.h new file mode 100644 index 0000000000..4229d14cf9 --- /dev/null +++ b/ext/digest/sha2/sha2ossl.h @@ -0,0 +1,17 @@ +#ifndef SHA2OSSL_H_INCLUDED +#define SHA2OSSL_H_INCLUDED + +#include <stddef.h> +#include <openssl/sha.h> + +#define SHA256_BLOCK_LENGTH SHA256_CBLOCK +#define SHA384_BLOCK_LENGTH SHA512_CBLOCK +#define SHA512_BLOCK_LENGTH SHA512_CBLOCK + +typedef SHA512_CTX SHA384_CTX; + +void SHA256_Finish(SHA256_CTX *ctx, char *buf); +void SHA384_Finish(SHA384_CTX *ctx, char *buf); +void SHA512_Finish(SHA512_CTX *ctx, char *buf); + +#endif diff --git a/ext/socket/basicsocket.c b/ext/socket/basicsocket.c index fdbbd15781..46253df898 100644 --- a/ext/socket/basicsocket.c +++ b/ext/socket/basicsocket.c @@ -198,7 +198,7 @@ bsock_close_write(VALUE sock) * }; * * In this case #setsockopt could be called like this: - * optval = IPAddr.new("224.0.0.251") + Socket::INADDR_ANY + * optval = IPAddr.new("224.0.0.251").hton + IPAddr.new(Socket::INADDR_ANY, Socket::AF_INET).hton * sock.setsockopt(Socket::IPPROTO_IP, Socket::IP_ADD_MEMBERSHIP, optval) * */ @@ -1484,6 +1484,7 @@ io_fread(VALUE str, long offset, rb_io_t *fptr) long n = len; long c; + rb_str_locktmp(str); if (READ_DATA_PENDING(fptr) == 0) { while (n > 0) { again: @@ -1501,6 +1502,7 @@ io_fread(VALUE str, long offset, rb_io_t *fptr) if ((n -= c) <= 0) break; rb_thread_wait_fd(fptr->fd); } + rb_str_unlocktmp(str); return len - n; } @@ -1516,6 +1518,7 @@ io_fread(VALUE str, long offset, rb_io_t *fptr) break; } } + rb_str_unlocktmp(str); return len - n; } @@ -1807,18 +1810,15 @@ io_getpartial(int argc, VALUE *argv, VALUE io, int nonblock) if (!nonblock) READ_CHECK(fptr); - if (RSTRING_LEN(str) != len) { - modified: - rb_raise(rb_eRuntimeError, "buffer string modified"); - } n = read_buffered_data(RSTRING_PTR(str), len, fptr); if (n <= 0) { again: - if (RSTRING_LEN(str) != len) goto modified; if (nonblock) { rb_io_set_nonblock(fptr); } + rb_str_locktmp(str); n = rb_read_internal(fptr->fd, RSTRING_PTR(str), len); + rb_str_unlocktmp(str); if (n < 0) { if (!nonblock && rb_io_wait_readable(fptr->fd)) goto again; @@ -1938,14 +1938,21 @@ io_readpartial(int argc, VALUE *argv, VALUE io) * until io is readable for avoiding busy loop. * This can be done as follows. * + * # emulates blocking read (readpartial). * begin * result = io.read_nonblock(maxlen) - * rescue IO::WaitReadable, Errno::EINTR + * rescue IO::WaitReadable * IO.select([io]) * retry * end * - * Note that this is identical to readpartial + * Although IO#read_nonblock doesn't raise IO::WaitWritable. + * OpenSSL::Buffering#read_nonblock can raise IO::WaitWritable. + * If IO and SSL should be used polymorphically, + * IO::WaitWritable should be rescued too. + * See the document of OpenSSL::Buffering#read_nonblock for sample code. + * + * Note that this method is identical to readpartial * except the non-blocking flag is set. */ @@ -2133,9 +2140,6 @@ io_read(int argc, VALUE *argv, VALUE io) if (len == 0) return str; READ_CHECK(fptr); - if (RSTRING_LEN(str) != len) { - rb_raise(rb_eRuntimeError, "buffer string modified"); - } n = io_fread(str, 0, fptr); if (n == 0) { if (fptr->fd < 0) return Qnil; @@ -3850,11 +3854,10 @@ rb_io_sysread(int argc, VALUE *argv, VALUE io) n = fptr->fd; rb_thread_wait_fd(fptr->fd); rb_io_check_closed(fptr); - if (RSTRING_LEN(str) != ilen) { - rb_raise(rb_eRuntimeError, "buffer string modified"); - } + rb_str_locktmp(str); n = rb_read_internal(fptr->fd, RSTRING_PTR(str), ilen); + rb_str_unlocktmp(str); if (n == -1) { rb_sys_fail_path(fptr->pathv); diff --git a/lib/drb/drb.rb b/lib/drb/drb.rb index a2c11f980d..4712306fe0 100644 --- a/lib/drb/drb.rb +++ b/lib/drb/drb.rb @@ -1394,7 +1394,7 @@ module DRb if Thread.current['DRb'] && Thread.current['DRb']['server'] == self Thread.current['DRb']['stop_service'] = true else - @thread.kill + @thread.kill.join end end diff --git a/lib/mkmf.rb b/lib/mkmf.rb index fc9353e5cd..3b667a68bf 100644 --- a/lib/mkmf.rb +++ b/lib/mkmf.rb @@ -624,7 +624,7 @@ end def install_files(mfile, ifiles, map = nil, srcprefix = nil) ifiles or return ifiles.empty? and return - srcprefix ||= '$(srcdir)' + srcprefix ||= "$(srcdir)/#{srcprefix}".chomp('/') RbConfig::expand(srcdir = srcprefix.dup) dirs = [] path = Hash.new {|h, i| h[i] = dirs.push([i])[-1]} @@ -1684,7 +1684,7 @@ def create_makefile(target, srcprefix = nil) target_prefix = "" end - srcprefix = "$(srcdir)/#{srcprefix}".chomp('/') + srcprefix ||= "$(srcdir)/#{srcprefix}".chomp('/') RbConfig.expand(srcdir = srcprefix.dup) ext = ".#{$OBJEXT}" diff --git a/lib/rubygems.rb b/lib/rubygems.rb index 8ae4243e68..dd086bc821 100644 --- a/lib/rubygems.rb +++ b/lib/rubygems.rb @@ -9,71 +9,6 @@ require 'rubygems/defaults' require 'thread' require 'etc' -module Gem - - RubyGemsVersion = VERSION = '1.3.5' - - ## - # Raised when RubyGems is unable to load or activate a gem. Contains the - # name and version requirements of the gem that either conflicts with - # already activated gems or that RubyGems is otherwise unable to activate. - - class LoadError < ::LoadError - - ## - # Name of gem - - attr_accessor :name - - ## - # Version requirement of gem - - attr_accessor :version_requirement - - end - -end - -module Kernel - # defined in gem_prelude.rb - undef gem - - ## - # Use Kernel#gem to activate a specific version of +gem_name+. - # - # +version_requirements+ is a list of version requirements that the - # specified gem must match, most commonly "= example.version.number". See - # Gem::Requirement for how to specify a version requirement. - # - # If you will be activating the latest version of a gem, there is no need to - # call Kernel#gem, Kernel#require will do the right thing for you. - # - # Kernel#gem returns true if the gem was activated, otherwise false. If the - # gem could not be found, didn't match the version requirements, or a - # different version was already activated, an exception will be raised. - # - # Kernel#gem should be called *before* any require statements (otherwise - # RubyGems may load a conflicting library version). - # - # In older RubyGems versions, the environment variable GEM_SKIP could be - # used to skip activation of specified gems, for example to test out changes - # that haven't been installed yet. Now RubyGems defers to -I and the - # RUBYLIB environment variable to skip activation of a gem. - # - # Example: - # - # GEM_SKIP=libA:libB ruby -I../libA -I../libB ./mycode.rb - - def gem(gem_name, *version_requirements) # :doc: - skip_list = (ENV['GEM_SKIP'] || "").split(/:/) - raise Gem::LoadError, "skipping #{gem_name}" if skip_list.include? gem_name - Gem.activate(gem_name, *version_requirements) - end - - private :gem - -end - ## # RubyGems is the Ruby standard for publishing and managing third party # libraries. @@ -88,6 +23,7 @@ end # # * {Creating Gems}[http://docs.rubygems.org/read/chapter/5] # * Gem::Specification +# * Gem::Version for version dependency notes # # Further RubyGems documentation can be found at: # @@ -98,7 +34,8 @@ end # == RubyGems Plugins # # As of RubyGems 1.3.2, RubyGems will load plugins installed in gems or -# $LOAD_PATH. Plugins must be named 'rubygems_plugin' are discovered via +# $LOAD_PATH. Plugins must be named 'rubygems_plugin' (.rb, .so, etc) and +# placed at the root of your gem's #require_path. Plugins are discovered via # Gem::find_files then loaded. Take care when implementing a plugin as your # plugin file may be loaded multiple times if multiple versions of your gem # are installed. @@ -124,7 +61,7 @@ end # == Bugs # # You can submit bugs to the -# {RubyGems bug tracker}[http://rubyforge.org/tracker/?atid=575&group_id=126&func=browse] +# {RubyGems bug tracker}[http://rubyforge.org/tracker/?atid=575&group_id=126] # on RubyForge # # == Credits @@ -133,26 +70,26 @@ end # # RubyGems was originally developed at RubyConf 2003 by: # -# * Rich Kilmer -- rich(at)infoether.com -# * Chad Fowler -- chad(at)chadfowler.com -# * David Black -- dblack(at)wobblini.net +# * Rich Kilmer -- rich(at)infoether.com +# * Chad Fowler -- chad(at)chadfowler.com +# * David Black -- dblack(at)wobblini.net # * Paul Brannan -- paul(at)atdesk.com -# * Jim Weirch -- {jim(at)weirichhouse.org}[mailto:jim@weirichhouse.org] +# * Jim Weirch -- jim(at)weirichhouse.org # # Contributors: # -# * Gavin Sinclair -- gsinclair(at)soyabean.com.au -# * George Marrows -- george.marrows(at)ntlworld.com -# * Dick Davies -- rasputnik(at)hellooperator.net +# * Gavin Sinclair -- gsinclair(at)soyabean.com.au +# * George Marrows -- george.marrows(at)ntlworld.com +# * Dick Davies -- rasputnik(at)hellooperator.net # * Mauricio Fernandez -- batsman.geo(at)yahoo.com -# * Simon Strandgaard -- neoneye(at)adslhome.dk -# * Dave Glasser -- glasser(at)mit.edu -# * Paul Duncan -- pabs(at)pablotron.org -# * Ville Aine -- vaine(at)cs.helsinki.fi -# * Eric Hodel -- drbrain(at)segment7.net -# * Daniel Berger -- djberg96(at)gmail.com -# * Phil Hagelberg -- technomancy(at)gmail.com -# * Ryan Davis +# * Simon Strandgaard -- neoneye(at)adslhome.dk +# * Dave Glasser -- glasser(at)mit.edu +# * Paul Duncan -- pabs(at)pablotron.org +# * Ville Aine -- vaine(at)cs.helsinki.fi +# * Eric Hodel -- drbrain(at)segment7.net +# * Daniel Berger -- djberg96(at)gmail.com +# * Phil Hagelberg -- technomancy(at)gmail.com +# * Ryan Davis -- ryand-ruby(at)zenspider.com # # (If your name is missing, PLEASE let us know!) # @@ -161,6 +98,20 @@ end # -The RubyGems Team module Gem + RubyGemsVersion = VERSION = '1.3.6' + + ## + # Raised when RubyGems is unable to load or activate a gem. Contains the + # name and version requirements of the gem that either conflicts with + # already activated gems or that RubyGems is otherwise unable to activate. + + class LoadError < ::LoadError + # Name of gem + attr_accessor :name + + # Version requirement of gem + attr_accessor :version_requirement + end ## # Configuration settings from ::RbConfig @@ -170,19 +121,19 @@ module Gem require 'rbconfig' ConfigMap.merge!( - :EXEEXT => RbConfig::CONFIG["EXEEXT"], - :RUBY_SO_NAME => RbConfig::CONFIG["RUBY_SO_NAME"], - :arch => RbConfig::CONFIG["arch"], - :bindir => RbConfig::CONFIG["bindir"], - :datadir => RbConfig::CONFIG["datadir"], - :libdir => RbConfig::CONFIG["libdir"], - :rubylibprefix => RbConfig::CONFIG["rubylibprefix"], + :EXEEXT => RbConfig::CONFIG["EXEEXT"], + :RUBY_SO_NAME => RbConfig::CONFIG["RUBY_SO_NAME"], + :arch => RbConfig::CONFIG["arch"], + :bindir => RbConfig::CONFIG["bindir"], + :datadir => RbConfig::CONFIG["datadir"], + :libdir => RbConfig::CONFIG["libdir"], + :rubylibprefix => RbConfig::CONFIG["rubylibprefix"], :ruby_install_name => RbConfig::CONFIG["ruby_install_name"], - :ruby_version => RbConfig::CONFIG["ruby_version"], - :sitedir => RbConfig::CONFIG["sitedir"], - :sitelibdir => RbConfig::CONFIG["sitelibdir"], - :vendordir => RbConfig::CONFIG["vendordir"] , - :vendorlibdir => RbConfig::CONFIG["vendorlibdir"] + :ruby_version => RbConfig::CONFIG["ruby_version"], + :sitedir => RbConfig::CONFIG["sitedir"], + :sitelibdir => RbConfig::CONFIG["sitelibdir"], + :vendordir => RbConfig::CONFIG["vendordir"] , + :vendorlibdir => RbConfig::CONFIG["vendorlibdir"] ) ## @@ -253,11 +204,11 @@ module Gem end unless gem.respond_to?(:name) and - gem.respond_to?(:version_requirements) then + gem.respond_to?(:requirement) then gem = Gem::Dependency.new(gem, version_requirements) end - matches = Gem.source_index.find_name(gem.name, gem.version_requirements) + matches = Gem.source_index.find_name(gem.name, gem.requirement) report_activate_error(gem) if matches.empty? if @loaded_specs[gem.name] then @@ -275,7 +226,7 @@ module Gem e = Gem::LoadError.new msg e.name = gem.name - e.version_requirement = gem.version_requirements + e.version_requirement = gem.requirement raise e end @@ -351,7 +302,7 @@ module Gem requirements = Gem::Requirement.default if requirements.empty? unless gem.respond_to?(:name) and - gem.respond_to?(:version_requirements) then + gem.respond_to?(:requirement) then gem = Gem::Dependency.new gem, requirements end @@ -731,14 +682,15 @@ module Gem # The directory prefix this RubyGems was installed at. def self.prefix - prefix = File.dirname File.expand_path(__FILE__) + dir = File.dirname File.expand_path(__FILE__) + prefix = File.dirname(dir) - if File.dirname(prefix) == File.expand_path(ConfigMap[:sitelibdir]) or - File.dirname(prefix) == File.expand_path(ConfigMap[:libdir]) or - 'lib' != File.basename(prefix) then + if prefix == File.expand_path(ConfigMap[:sitelibdir]) or + prefix == File.expand_path(ConfigMap[:libdir]) or + 'lib' != File.basename(dir) then nil else - File.dirname prefix + prefix end end @@ -797,15 +749,15 @@ module Gem if matches.empty? then error = Gem::LoadError.new( - "Could not find RubyGem #{gem.name} (#{gem.version_requirements})\n") + "Could not find RubyGem #{gem.name} (#{gem.requirement})\n") else error = Gem::LoadError.new( "RubyGem version error: " + - "#{gem.name}(#{matches.first.version} not #{gem.version_requirements})\n") + "#{gem.name}(#{matches.first.version} not #{gem.requirement})\n") end error.name = gem.name - error.version_requirement = gem.version_requirements + error.version_requirement = gem.requirement raise error end @@ -1054,6 +1006,46 @@ module Gem end +module Kernel + # defined in gem_prelude.rb + undef gem + + ## + # Use Kernel#gem to activate a specific version of +gem_name+. + # + # +version_requirements+ is a list of version requirements that the + # specified gem must match, most commonly "= example.version.number". See + # Gem::Requirement for how to specify a version requirement. + # + # If you will be activating the latest version of a gem, there is no need to + # call Kernel#gem, Kernel#require will do the right thing for you. + # + # Kernel#gem returns true if the gem was activated, otherwise false. If the + # gem could not be found, didn't match the version requirements, or a + # different version was already activated, an exception will be raised. + # + # Kernel#gem should be called *before* any require statements (otherwise + # RubyGems may load a conflicting library version). + # + # In older RubyGems versions, the environment variable GEM_SKIP could be + # used to skip activation of specified gems, for example to test out changes + # that haven't been installed yet. Now RubyGems defers to -I and the + # RUBYLIB environment variable to skip activation of a gem. + # + # Example: + # + # GEM_SKIP=libA:libB ruby -I../libA -I../libB ./mycode.rb + + def gem(gem_name, *version_requirements) # :doc: + skip_list = (ENV['GEM_SKIP'] || "").split(/:/) + raise Gem::LoadError, "skipping #{gem_name}" if skip_list.include? gem_name + Gem.activate(gem_name, *version_requirements) + end + + private :gem + +end + ## # Return the path to the data directory associated with the named package. If # the package is loaded as a gem, return the gem specific data directory. @@ -1093,6 +1085,12 @@ Gem.clear_paths plugins = Gem.find_files 'rubygems_plugin' plugins.each do |plugin| + + # Skip older versions of the GemCutter plugin: Its commands are in + # RubyGems proper now. + + next if plugin =~ /gemcutter-0\.[0-3]/ + begin load plugin rescue => e diff --git a/lib/rubygems/builder.rb b/lib/rubygems/builder.rb index 3061b752ce..9e7f262243 100644 --- a/lib/rubygems/builder.rb +++ b/lib/rubygems/builder.rb @@ -11,6 +11,7 @@ class Gem::Builder include Gem::UserInteraction + ## # Constructs a builder instance for the provided specification # @@ -33,7 +34,7 @@ class Gem::Builder @spec.validate @signer = sign write_package - say success + say success if Gem.configuration.verbose @spec.file_name end @@ -42,7 +43,7 @@ class Gem::Builder Successfully built RubyGem Name: #{@spec.name} Version: #{@spec.version} - File: #{@spec.full_name+'.gem'} + File: #{@spec.file_name} EOM end @@ -86,5 +87,6 @@ EOM end end end + end diff --git a/lib/rubygems/command.rb b/lib/rubygems/command.rb index dab4366270..08692bdb70 100644 --- a/lib/rubygems/command.rb +++ b/lib/rubygems/command.rb @@ -160,8 +160,8 @@ class Gem::Command end ## - # Get the single gem name from the command line. Fail if there is no gem - # name or if there is more than one gem name given. + # Get a single gem name from the command line. Fail if there is no gem name + # or if there is more than one gem name given. def get_one_gem_name args = options[:args] @@ -248,11 +248,12 @@ class Gem::Command # Invoke the command with the given list of arguments. def invoke(*args) - handle_options(args) - if options[:help] + handle_options args + + if options[:help] then show_help - elsif @when_invoked - @when_invoked.call(options) + elsif @when_invoked then + @when_invoked.call options else execute end @@ -362,37 +363,39 @@ class Gem::Command def create_option_parser @parser = OptionParser.new - @parser.separator("") + @parser.separator nil regular_options = @option_groups.delete :options configure_options "", regular_options @option_groups.sort_by { |n,_| n.to_s }.each do |group_name, option_list| + @parser.separator nil configure_options group_name, option_list end + @parser.separator nil configure_options "Common", Gem::Command.common_options - @parser.separator("") unless arguments.empty? - @parser.separator(" Arguments:") + @parser.separator nil + @parser.separator " Arguments:" arguments.split(/\n/).each do |arg_desc| - @parser.separator(" #{arg_desc}") + @parser.separator " #{arg_desc}" end - @parser.separator("") end - @parser.separator(" Summary:") + @parser.separator nil + @parser.separator " Summary:" wrap(@summary, 80 - 4).split("\n").each do |line| - @parser.separator(" #{line.strip}") + @parser.separator " #{line.strip}" end if description then formatted = description.split("\n\n").map do |chunk| - wrap(chunk, 80 - 4) - end.join("\n") + wrap chunk, 80 - 4 + end.join "\n" - @parser.separator "" + @parser.separator nil @parser.separator " Description:" formatted.split("\n").each do |line| @parser.separator " #{line.rstrip}" @@ -400,10 +403,10 @@ class Gem::Command end unless defaults_str.empty? - @parser.separator("") - @parser.separator(" Defaults:") + @parser.separator nil + @parser.separator " Defaults:" defaults_str.split(/\n/).each do |line| - @parser.separator(" #{line}") + @parser.separator " #{line}" end end end @@ -471,33 +474,33 @@ class Gem::Command # :stopdoc: - HELP = %{ - RubyGems is a sophisticated package manager for Ruby. This is a - basic help message containing pointers to more information. - - Usage: - gem -h/--help - gem -v/--version - gem command [arguments...] [options...] - - Examples: - gem install rake - gem list --local - gem build package.gemspec - gem help install - - Further help: - gem help commands list all 'gem' commands - gem help examples show some examples of usage - gem help platforms show information about platforms - gem help <COMMAND> show help on COMMAND - (e.g. 'gem help install') - gem server present a web page at - http://localhost:8808/ - with info about installed gems - Further information: - http://rubygems.rubyforge.org - }.gsub(/^ /, '') + HELP = <<-HELP +RubyGems is a sophisticated package manager for Ruby. This is a +basic help message containing pointers to more information. + + Usage: + gem -h/--help + gem -v/--version + gem command [arguments...] [options...] + + Examples: + gem install rake + gem list --local + gem build package.gemspec + gem help install + + Further help: + gem help commands list all 'gem' commands + gem help examples show some examples of usage + gem help platforms show information about platforms + gem help <COMMAND> show help on COMMAND + (e.g. 'gem help install') + gem server present a web page at + http://localhost:8808/ + with info about installed gems + Further information: + http://rubygems.rubyforge.org + HELP # :startdoc: diff --git a/lib/rubygems/command_manager.rb b/lib/rubygems/command_manager.rb index cd1fd6b568..11344f1fb6 100644 --- a/lib/rubygems/command_manager.rb +++ b/lib/rubygems/command_manager.rb @@ -58,7 +58,9 @@ class Gem::CommandManager register_command :lock register_command :mirror register_command :outdated + register_command :owner register_command :pristine + register_command :push register_command :query register_command :rdoc register_command :search diff --git a/lib/rubygems/commands/dependency_command.rb b/lib/rubygems/commands/dependency_command.rb index 44b269bb11..61e3b59fd7 100644 --- a/lib/rubygems/commands/dependency_command.rb +++ b/lib/rubygems/commands/dependency_command.rb @@ -15,6 +15,7 @@ class Gem::Commands::DependencyCommand < Gem::Command add_version_option add_platform_option + add_prerelease_option add_option('-R', '--[no-]reverse-dependencies', 'Include reverse dependencies in the output') do @@ -59,6 +60,7 @@ class Gem::Commands::DependencyCommand < Gem::Command end dependency = Gem::Dependency.new pattern, options[:version] + dependency.prerelease = options[:prerelease] if options[:reverse_dependencies] and remote? and not local? then alert_error 'Only reverse dependencies for local gems are supported.' @@ -75,7 +77,10 @@ class Gem::Commands::DependencyCommand < Gem::Command fetcher = Gem::SpecFetcher.fetcher begin - fetcher.find_matching(dependency).each do |spec_tuple, source_uri| + specs_and_sources = fetcher.find_matching(dependency, false, true, + dependency.prerelease?) + + specs_and_sources.each do |spec_tuple, source_uri| spec = fetcher.fetch_spec spec_tuple, URI.parse(source_uri) source_indexes[source_uri].add_spec spec @@ -120,8 +125,8 @@ class Gem::Commands::DependencyCommand < Gem::Command if options[:pipe_format] then specs.values.sort_by { |_, spec| spec }.each do |_, spec| unless spec.dependencies.empty? - spec.dependencies.each do |dep| - say "#{dep.name} --version '#{dep.version_requirements}'" + spec.dependencies.sort_by { |dep| dep.name }.each do |dep| + say "#{dep.name} --version '#{dep.requirement}'" end end end @@ -147,7 +152,7 @@ class Gem::Commands::DependencyCommand < Gem::Command response = '' response << ' ' * level + "Gem #{spec.full_name}\n" unless spec.dependencies.empty? then - spec.dependencies.each do |dep| + spec.dependencies.sort_by { |dep| dep.name }.each do |dep| response << ' ' * level + " #{dep}\n" end end @@ -163,7 +168,7 @@ class Gem::Commands::DependencyCommand < Gem::Command dep = Gem::Dependency.new(*dep) unless Gem::Dependency === dep if spec.name == dep.name and - dep.version_requirements.satisfied_by?(spec.version) then + dep.requirement.satisfied_by?(spec.version) then result << [sp.full_name, dep] end end diff --git a/lib/rubygems/commands/environment_command.rb b/lib/rubygems/commands/environment_command.rb index e672da54f0..f3550cae28 100644 --- a/lib/rubygems/commands/environment_command.rb +++ b/lib/rubygems/commands/environment_command.rb @@ -118,7 +118,7 @@ lib/rubygems/defaults/operating_system.rb end else - fail Gem::CommandLineError, "Unknown enviroment option [#{arg}]" + raise Gem::CommandLineError, "Unknown enviroment option [#{arg}]" end say out true diff --git a/lib/rubygems/commands/fetch_command.rb b/lib/rubygems/commands/fetch_command.rb index 76c9924e6b..b12e1b4a5d 100644 --- a/lib/rubygems/commands/fetch_command.rb +++ b/lib/rubygems/commands/fetch_command.rb @@ -17,6 +17,7 @@ class Gem::Commands::FetchCommand < Gem::Command add_version_option add_platform_option + add_prerelease_option end def arguments # :nodoc: @@ -39,12 +40,12 @@ class Gem::Commands::FetchCommand < Gem::Command gem_names.each do |gem_name| dep = Gem::Dependency.new gem_name, version + dep.prerelease = options[:prerelease] - specs_and_sources = Gem::SpecFetcher.fetcher.fetch dep, all + specs_and_sources = Gem::SpecFetcher.fetcher.fetch(dep, false, true, + dep.prerelease?) - specs_and_sources.sort_by { |spec,| spec.version } - - spec, source_uri = specs_and_sources.last + spec, source_uri = specs_and_sources.sort_by { |s,| s.version }.last if spec.nil? then alert_error "Could not find #{gem_name} in any repository" @@ -52,7 +53,7 @@ class Gem::Commands::FetchCommand < Gem::Command end path = Gem::RemoteFetcher.fetcher.download spec, source_uri - FileUtils.mv path, "#{spec.full_name}.gem" + FileUtils.mv path, spec.file_name say "Downloaded #{spec.full_name}" end diff --git a/lib/rubygems/commands/install_command.rb b/lib/rubygems/commands/install_command.rb index af2d8bd739..df6b3e5f2c 100644 --- a/lib/rubygems/commands/install_command.rb +++ b/lib/rubygems/commands/install_command.rb @@ -32,6 +32,7 @@ class Gem::Commands::InstallCommand < Gem::Command add_local_remote_options add_platform_option add_version_option + add_prerelease_option "to be installed. (Only for listed gems)" end def arguments # :nodoc: diff --git a/lib/rubygems/commands/mirror_command.rb b/lib/rubygems/commands/mirror_command.rb index 959b8eaec3..7cb8583326 100644 --- a/lib/rubygems/commands/mirror_command.rb +++ b/lib/rubygems/commands/mirror_command.rb @@ -51,7 +51,7 @@ Multiple sources and destinations may be specified. Dir.mkdir gems_dir end - sourceindex_data = '' + source_index_data = '' say "fetching: #{get_from}/Marshal.#{Gem.marshal_version}.Z" @@ -70,18 +70,18 @@ Multiple sources and destinations may be specified. end open File.join(get_from.to_s, "Marshal.#{Gem.marshal_version}.Z"), "rb" do |y| - sourceindex_data = Zlib::Inflate.inflate y.read + source_index_data = Zlib::Inflate.inflate y.read open File.join(save_to, "Marshal.#{Gem.marshal_version}"), "wb" do |out| - out.write sourceindex_data + out.write source_index_data end end - sourceindex = Marshal.load(sourceindex_data) + source_index = Marshal.load source_index_data - progress = ui.progress_reporter sourceindex.size, - "Fetching #{sourceindex.size} gems" - sourceindex.each do |fullname, gem| - gem_file = "#{fullname}.gem" + progress = ui.progress_reporter source_index.size, + "Fetching #{source_index.size} gems" + source_index.each do |fullname, gem| + gem_file = gem.file_name gem_dest = File.join gems_dir, gem_file unless File.exist? gem_dest then diff --git a/lib/rubygems/commands/owner_command.rb b/lib/rubygems/commands/owner_command.rb new file mode 100644 index 0000000000..e88734e8fb --- /dev/null +++ b/lib/rubygems/commands/owner_command.rb @@ -0,0 +1,75 @@ +require 'rubygems/command' +require 'rubygems/local_remote_options' +require 'rubygems/gemcutter_utilities' + +class Gem::Commands::OwnerCommand < Gem::Command + include Gem::LocalRemoteOptions + include Gem::GemcutterUtilities + + def description # :nodoc: + 'Manage gem owners on RubyGems.org.' + end + + def arguments # :nodoc: + "GEM gem to manage owners for" + end + + def initialize + super 'owner', description + add_proxy_option + defaults.merge! :add => [], :remove => [] + + add_option '-a', '--add EMAIL', 'Add an owner' do |value, options| + options[:add] << value + end + + add_option '-r', '--remove EMAIL', 'Remove an owner' do |value, options| + options[:remove] << value + end + end + + def execute + sign_in + name = get_one_gem_name + + add_owners name, options[:add] + remove_owners name, options[:remove] + show_owners name + end + + def show_owners name + response = rubygems_api_request :get, "api/v1/gems/#{name}/owners.yaml" do |request| + request.add_field "Authorization", Gem.configuration.rubygems_api_key + end + + with_response response do |resp| + owners = YAML.load resp.body + + say "Owners for gem: #{name}" + owners.each do |owner| + say "- #{owner['email']}" + end + end + end + + def add_owners name, owners + manage_owners :post, name, owners + end + + def remove_owners name, owners + manage_owners :delete, name, owners + end + + def manage_owners method, name, owners + owners.each do |owner| + response = rubygems_api_request method, "api/v1/gems/#{name}/owners" do |request| + request.set_form_data 'email' => owner + request.add_field "Authorization", Gem.configuration.rubygems_api_key + end + + with_response response + end + end + +end + diff --git a/lib/rubygems/commands/pristine_command.rb b/lib/rubygems/commands/pristine_command.rb index d47fe54edd..ef11129d2c 100644 --- a/lib/rubygems/commands/pristine_command.rb +++ b/lib/rubygems/commands/pristine_command.rb @@ -74,7 +74,7 @@ revert the gem. say "Restoring gem(s) to pristine condition..." specs.each do |spec| - gem = Dir[File.join(Gem.dir, 'cache', "#{spec.full_name}.gem")].first + gem = Dir[File.join(Gem.dir, 'cache', spec.file_name)].first if gem.nil? then alert_error "Cached gem for #{spec.full_name} not found, use `gem install` to restore" diff --git a/lib/rubygems/commands/push_command.rb b/lib/rubygems/commands/push_command.rb new file mode 100644 index 0000000000..cabcd3d94d --- /dev/null +++ b/lib/rubygems/commands/push_command.rb @@ -0,0 +1,45 @@ +require 'rubygems/command' +require 'rubygems/local_remote_options' +require 'rubygems/gemcutter_utilities' + +class Gem::Commands::PushCommand < Gem::Command + include Gem::LocalRemoteOptions + include Gem::GemcutterUtilities + + def description # :nodoc: + 'Push a gem up to RubyGems.org' + end + + def arguments # :nodoc: + "GEM built gem to push up" + end + + def usage # :nodoc: + "#{program_name} GEM" + end + + def initialize + super 'push', description + add_proxy_option + end + + def execute + sign_in + send_gem get_one_gem_name + end + + def send_gem name + say "Pushing gem to RubyGems.org..." + + response = rubygems_api_request :post, "api/v1/gems" do |request| + request.body = Gem.read_binary name + request.add_field "Content-Length", request.body.size + request.add_field "Content-Type", "application/octet-stream" + request.add_field "Authorization", Gem.configuration.rubygems_api_key + end + + with_response response + end + +end + diff --git a/lib/rubygems/commands/query_command.rb b/lib/rubygems/commands/query_command.rb index 88f7f0b54e..7dd0a4a0d6 100644 --- a/lib/rubygems/commands/query_command.rb +++ b/lib/rubygems/commands/query_command.rb @@ -45,7 +45,7 @@ class Gem::Commands::QueryCommand < Gem::Command options[:all] = value end - add_option( '--prerelease', + add_option( '--[no-]prerelease', 'Display prerelease versions') do |value, options| options[:prerelease] = value end @@ -111,6 +111,9 @@ class Gem::Commands::QueryCommand < Gem::Command begin fetcher = Gem::SpecFetcher.fetcher spec_tuples = fetcher.find_matching dep, all, false, prerelease + + spec_tuples += fetcher.find_matching dep, false, false, true if + prerelease and all rescue Gem::RemoteFetcher::FetchError => e if prerelease then raise Gem::OperationNotSupportedError, diff --git a/lib/rubygems/commands/rdoc_command.rb b/lib/rubygems/commands/rdoc_command.rb index 92f215705a..ea0f3ad592 100644 --- a/lib/rubygems/commands/rdoc_command.rb +++ b/lib/rubygems/commands/rdoc_command.rb @@ -8,7 +8,7 @@ class Gem::Commands::RdocCommand < Gem::Command def initialize super 'rdoc', 'Generates RDoc for pre-installed gems', :version => Gem::Requirement.default, - :include_rdoc => true, :include_ri => true + :include_rdoc => true, :include_ri => true, :overwrite => false add_option('--all', 'Generate RDoc/RI documentation for all', @@ -17,15 +17,20 @@ class Gem::Commands::RdocCommand < Gem::Command end add_option('--[no-]rdoc', - 'Include RDoc generated documents') do |value, options| + 'Generate RDoc HTML') do |value, options| options[:include_rdoc] = value end add_option('--[no-]ri', - 'Include RI generated documents') do |value, options| + 'Generate RI data') do |value, options| options[:include_ri] = value end + add_option('--[no-]overwrite', + 'Overwrite installed documents') do |value, options| + options[:overwrite] = value + end + add_version_option end @@ -34,7 +39,14 @@ class Gem::Commands::RdocCommand < Gem::Command end def defaults_str # :nodoc: - "--version '#{Gem::Requirement.default}' --rdoc --ri" + "--version '#{Gem::Requirement.default}' --rdoc --ri --no-overwrite" + end + + def description # :nodoc: + <<-DESC +The rdoc command builds RDoc and RI documentation for installed gems. Use +--overwrite to force rebuilding of documentation. + DESC end def usage # :nodoc: @@ -53,24 +65,27 @@ class Gem::Commands::RdocCommand < Gem::Command end if specs.empty? - fail "Failed to find gem #{gem_name} to generate RDoc for #{options[:version]}" + raise "Failed to find gem #{gem_name} to generate RDoc for #{options[:version]}" end if options[:include_ri] - specs.each do |spec| - Gem::DocManager.new(spec).generate_ri + specs.sort.each do |spec| + doc = Gem::DocManager.new(spec) + doc.generate_ri if options[:overwrite] || !doc.ri_installed? end Gem::DocManager.update_ri_cache end if options[:include_rdoc] - specs.each do |spec| - Gem::DocManager.new(spec).generate_rdoc + specs.sort.each do |spec| + doc = Gem::DocManager.new(spec) + doc.generate_rdoc if options[:overwrite] || !doc.rdoc_installed? end end true end + end diff --git a/lib/rubygems/commands/server_command.rb b/lib/rubygems/commands/server_command.rb index f8b990d304..6bc58367e9 100644 --- a/lib/rubygems/commands/server_command.rb +++ b/lib/rubygems/commands/server_command.rb @@ -36,6 +36,12 @@ class Gem::Commands::ServerCommand < Gem::Command add_option '--[no-]daemon', 'run as a daemon' do |daemon, options| options[:daemon] = daemon end + + add_option '-b', '--bind=HOST,HOST', + 'addresses to bind', Array do |address, options| + options[:addresses] ||= [] + options[:addresses].push(*address) + end end def defaults_str # :nodoc: diff --git a/lib/rubygems/commands/setup_command.rb b/lib/rubygems/commands/setup_command.rb index 5bd5ebd468..f5f5185f86 100644 --- a/lib/rubygems/commands/setup_command.rb +++ b/lib/rubygems/commands/setup_command.rb @@ -2,7 +2,6 @@ require 'rubygems/command' require 'fileutils' require 'rbconfig' require 'tmpdir' -require 'pathname' ## # Installs RubyGems itself. This command is ordinarily only available from a @@ -117,6 +116,8 @@ By default, this RubyGems will install gem as: say "RubyGems #{Gem::VERSION} installed" + uninstall_old_gemcutter + install_rdoc say @@ -359,5 +360,14 @@ abort "#{deprecation_message}" r.document args end + def uninstall_old_gemcutter + require 'rubygems/uninstaller' + + ui = Gem::Uninstaller.new('gemcutter', :all => true, :ignore => true, + :version => '< 0.4') + ui.uninstall + rescue Gem::InstallError + end + end diff --git a/lib/rubygems/commands/unpack_command.rb b/lib/rubygems/commands/unpack_command.rb index 075dc04203..84a53b107a 100644 --- a/lib/rubygems/commands/unpack_command.rb +++ b/lib/rubygems/commands/unpack_command.rb @@ -41,7 +41,7 @@ class Gem::Commands::UnpackCommand < Gem::Command path = get_path name, options[:version] if path then - basename = File.basename(path).sub(/\.gem$/, '') + basename = File.basename(path, '.gem') target_dir = File.expand_path File.join(options[:target], basename) FileUtils.mkdir_p target_dir Gem::Installer.new(path, :unpack => true).unpack target_dir @@ -79,7 +79,7 @@ class Gem::Commands::UnpackCommand < Gem::Command # We expect to find (basename).gem in the 'cache' directory. # Furthermore, the name match must be exact (ignoring case). if gemname =~ /^#{selected.name}$/i - filename = selected.full_name + '.gem' + filename = selected.file_name path = nil Gem.path.find do |gem_dir| diff --git a/lib/rubygems/commands/update_command.rb b/lib/rubygems/commands/update_command.rb index 9974b2b54b..4b0439df1f 100644 --- a/lib/rubygems/commands/update_command.rb +++ b/lib/rubygems/commands/update_command.rb @@ -28,8 +28,8 @@ class Gem::Commands::UpdateCommand < Gem::Command end add_local_remote_options - add_platform_option + add_prerelease_option "as update targets" end def arguments # :nodoc: @@ -51,7 +51,7 @@ class Gem::Commands::UpdateCommand < Gem::Command say "Updating RubyGems" unless options[:args].empty? then - fail "No gem names are allowed with the --system option" + raise "No gem names are allowed with the --system option" end rubygems_update = Gem::Specification.new diff --git a/lib/rubygems/commands/which_command.rb b/lib/rubygems/commands/which_command.rb index 7c2d188324..b785f15660 100644 --- a/lib/rubygems/commands/which_command.rb +++ b/lib/rubygems/commands/which_command.rb @@ -27,13 +27,11 @@ class Gem::Commands::WhichCommand < Gem::Command "--no-gems-first --no-all" end - def usage # :nodoc: - "#{program_name} FILE [FILE ...]" - end - def execute searcher = Gem::GemPathSearcher.new + found = false + options[:args].each do |arg| dirs = $LOAD_PATH spec = searcher.find arg @@ -44,19 +42,19 @@ class Gem::Commands::WhichCommand < Gem::Command else dirs = $LOAD_PATH + gem_paths(spec) end - - say "(checking gem #{spec.full_name} for #{arg})" if - Gem.configuration.verbose and $stdout.tty? end paths = find_paths arg, dirs if paths.empty? then - say "Can't find ruby library file or shared library #{arg}" + alert_error "Can't find ruby library file or shared library #{arg}" else say paths + found = true end end + + terminate_interaction 1 unless found end def find_paths(package_name, dirs) @@ -80,7 +78,7 @@ class Gem::Commands::WhichCommand < Gem::Command end def usage # :nodoc: - "#{program_name} FILE [...]" + "#{program_name} FILE [FILE ...]" end end diff --git a/lib/rubygems/config_file.rb b/lib/rubygems/config_file.rb index 3562805c62..3498d06540 100644 --- a/lib/rubygems/config_file.rb +++ b/lib/rubygems/config_file.rb @@ -4,10 +4,26 @@ # See LICENSE.txt for permissions. #++ -require 'yaml' - -# Store the gem command options specified in the configuration file. The -# config file object acts much like a hash. +## +# Gem::ConfigFile RubyGems options and gem command options from ~/.gemrc. +# +# ~/.gemrc is a YAML file that uses strings to match gem command arguments and +# symbols to match RubyGems options. +# +# Gem command arguments use a String key that matches the command name and +# allow you to specify default arguments: +# +# install: --no-rdoc --no-ri +# update: --no-rdoc --no-ri +# +# You can use <tt>gem:</tt> to set default arguments for all commands. +# +# RubyGems options use symbol keys. Valid options are: +# +# +:backtrace+:: See #backtrace +# +:benchmark+:: See #benchmark +# +:sources+:: Sets Gem::sources +# +:verbose+:: See #verbose class Gem::ConfigFile @@ -46,49 +62,74 @@ class Gem::ConfigFile SYSTEM_WIDE_CONFIG_FILE = File.join system_config_path, 'gemrc' + ## # List of arguments supplied to the config file object. + attr_reader :args - # Where to look for gems + ## + # Where to look for gems (deprecated) + attr_accessor :path + ## + # Where to install gems (deprecated) + attr_accessor :home + ## # True if we print backtraces on errors. + attr_writer :backtrace + ## # True if we are benchmarking this run. + attr_accessor :benchmark - # Bulk threshold value. If the number of missing gems are above - # this threshold value, then a bulk download technique is used. + ## + # Bulk threshold value. If the number of missing gems are above this + # threshold value, then a bulk download technique is used. (deprecated) + attr_accessor :bulk_threshold + ## # Verbose level of output: # * false -- No output # * true -- Normal output # * :loud -- Extra output + attr_accessor :verbose + ## # True if we want to update the SourceInfoCache every time, false otherwise + attr_accessor :update_sources + ## + # API key for RubyGems.org + + attr_reader :rubygems_api_key + + ## # Create the config file object. +args+ is the list of arguments # from the command line. # # The following command line options are handled early here rather # than later at the time most command options are processed. # - # * --config-file and --config-file==NAME -- Obviously these need - # to be handled by the ConfigFile object to ensure we get the - # right config file. - # - # * --backtrace -- Backtrace needs to be turned on early so that - # errors before normal option parsing can be properly handled. + # <tt>--config-file</tt>, <tt>--config-file==NAME</tt>:: + # Obviously these need to be handled by the ConfigFile object to ensure we + # get the right config file. # - # * --debug -- Enable Ruby level debug messages. Handled early - # for the same reason as --backtrace. + # <tt>--backtrace</tt>:: + # Backtrace needs to be turned on early so that errors before normal + # option parsing can be properly handled. # + # <tt>--debug</tt>:: + # Enable Ruby level debug messages. Handled early for the same reason as + # --backtrace. + def initialize(arg_list) @config_file_name = nil need_config_file_name = false @@ -125,21 +166,53 @@ class Gem::ConfigFile @hash = @hash.merge user_config # HACK these override command-line args, which is bad - @backtrace = @hash[:backtrace] if @hash.key? :backtrace - @benchmark = @hash[:benchmark] if @hash.key? :benchmark - @bulk_threshold = @hash[:bulk_threshold] if @hash.key? :bulk_threshold - Gem.sources = @hash[:sources] if @hash.key? :sources - @verbose = @hash[:verbose] if @hash.key? :verbose - @update_sources = @hash[:update_sources] if @hash.key? :update_sources - @path = @hash[:gempath] if @hash.key? :gempath - @home = @hash[:gemhome] if @hash.key? :gemhome + @backtrace = @hash[:backtrace] if @hash.key? :backtrace + @benchmark = @hash[:benchmark] if @hash.key? :benchmark + @bulk_threshold = @hash[:bulk_threshold] if @hash.key? :bulk_threshold + @home = @hash[:gemhome] if @hash.key? :gemhome + @path = @hash[:gempath] if @hash.key? :gempath + @update_sources = @hash[:update_sources] if @hash.key? :update_sources + @verbose = @hash[:verbose] if @hash.key? :verbose + + load_rubygems_api_key + Gem.sources = @hash[:sources] if @hash.key? :sources handle_arguments arg_list end + ## + # Location of RubyGems.org credentials + + def credentials_path + File.join(Gem.user_home, '.gem', 'credentials') + end + + def load_rubygems_api_key + api_key_hash = File.exists?(credentials_path) ? load_file(credentials_path) : @hash + + @rubygems_api_key = api_key_hash[:rubygems_api_key] if api_key_hash.key? :rubygems_api_key + end + + def rubygems_api_key=(api_key) + config = load_file(credentials_path).merge(:rubygems_api_key => api_key) + + dirname = File.dirname(credentials_path) + Dir.mkdir(dirname) unless File.exists?(dirname) + + require 'yaml' + + File.open(credentials_path, 'w') do |f| + f.write config.to_yaml + end + + @rubygems_api_key = api_key + end + def load_file(filename) + return {} unless filename and File.exists?(filename) begin - YAML.load(File.read(filename)) if filename and File.exist?(filename) + require 'yaml' + YAML.load(File.read(filename)) rescue ArgumentError warn "Failed to load #{config_file_name}" rescue Errno::EACCES @@ -233,8 +306,9 @@ class Gem::ConfigFile # Writes out this config file, replacing its source. def write - File.open config_file_name, 'w' do |fp| - fp.write self.to_yaml + require 'yaml' + open config_file_name, 'w' do |io| + io.write to_yaml end end diff --git a/lib/rubygems/defaults.rb b/lib/rubygems/defaults.rb index c9680104c7..c3c4737892 100644 --- a/lib/rubygems/defaults.rb +++ b/lib/rubygems/defaults.rb @@ -9,7 +9,7 @@ module Gem # An Array of the default sources that come with RubyGems def self.default_sources - %w[http://gems.rubyforge.org/] + %w[http://rubygems.org/] end ## diff --git a/lib/rubygems/dependency.rb b/lib/rubygems/dependency.rb index d142265c5d..351991067d 100644 --- a/lib/rubygems/dependency.rb +++ b/lib/rubygems/dependency.rb @@ -1,14 +1,22 @@ -#-- -# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. -# All rights reserved. -# See LICENSE.txt for permissions. -#++ +require "rubygems/requirement" ## -# The Dependency class holds a Gem name and a Gem::Requirement +# The Dependency class holds a Gem name and a Gem::Requirement. class Gem::Dependency + # :stopdoc: + @warned_version_requirement = false + + def self.warned_version_requirement + @warned_version_requirement + end + + def self.warned_version_requirement= value + @warned_version_requirement = value + end + # :startdoc: + ## # Valid dependency types. #-- @@ -16,9 +24,9 @@ class Gem::Dependency # Gem::Specification::CURRENT_SPECIFICATION_VERSION as well. TYPES = [ - :development, - :runtime, - ] + :development, + :runtime, + ] ## # Dependency name or regular expression. @@ -26,122 +34,172 @@ class Gem::Dependency attr_accessor :name ## - # Dependency type. + # Allows you to force this dependency to be a prerelease. - attr_reader :type + attr_writer :prerelease ## - # Dependent versions. - - attr_writer :version_requirements - - ## - # Orders dependencies by name only. + # Dependency type. - def <=>(other) - [@name] <=> [other.name] - end + attr_reader :type ## - # Constructs a dependency with +name+ and +requirements+. + # Constructs a dependency with +name+ and +requirements+. The last + # argument can optionally be the dependency type, which defaults to + # <tt>:runtime</tt>. - def initialize(name, version_requirements, type=:runtime) - @name = name + def initialize name, *requirements + type = Symbol === requirements.last ? requirements.pop : :runtime + requirements = requirements.first if 1 == requirements.length # unpack unless TYPES.include? type - raise ArgumentError, "Valid types are #{TYPES.inspect}, not #{@type.inspect}" + raise ArgumentError, "Valid types are #{TYPES.inspect}, " + + "not #{@type.inspect}" end - @type = type + @name = name + @requirement = Gem::Requirement.create requirements + @type = type + @prerelease = false - @version_requirements = Gem::Requirement.create version_requirements - @version_requirement = nil # Avoid warnings. - end + # This is for Marshal backwards compatability. See the comments in + # +requirement+ for the dirty details. - def version_requirements - normalize if defined? @version_requirement and @version_requirement - @version_requirements + @version_requirements = @requirement end - def requirement_list - version_requirements.as_list - end + ## + # What does this dependency require? - alias requirements_list requirement_list + ## + # A dependency's hash is the XOR of the hashes of +name+, +type+, + # and +requirement+. - def normalize - ver = @version_requirement.instance_variable_get :@version - @version_requirements = Gem::Requirement.new([ver]) - @version_requirement = nil + def hash # :nodoc: + name.hash ^ type.hash ^ requirement.hash end - def to_s # :nodoc: - "#{name} (#{version_requirements}, #{@type || :runtime})" + def inspect # :nodoc: + "<%s type=%p name=%p requirements=%p>" % + [self.class, @type, @name, requirement.to_s] + end + + ## + # Does this dependency require a prerelease? + + def prerelease? + @prerelease || requirement.prerelease? end def pretty_print(q) # :nodoc: q.group 1, 'Gem::Dependency.new(', ')' do - q.pp @name + q.pp name q.text ',' q.breakable - q.pp @version_requirements + q.pp requirement q.text ',' q.breakable - q.pp @type + q.pp type end end - def ==(other) # :nodoc: - self.class === other && - self.name == other.name && - self.type == other.type && - self.version_requirements == other.version_requirements + def requirement + return @requirement if defined?(@requirement) and @requirement + + # @version_requirements and @version_requirement are legacy ivar + # names, and supported here because older gems need to keep + # working and Dependency doesn't implement marshal_dump and + # marshal_load. In a happier world, this would be an + # attr_accessor. The horrifying instance_variable_get you see + # below is also the legacy of some old restructurings. + # + # Note also that because of backwards compatibility (loading new + # gems in an old RubyGems installation), we can't add explicit + # marshaling to this class until we want to make a big + # break. Maybe 2.0. + # + # Children, define explicit marshal and unmarshal behavior for + # public classes. Marshal formats are part of your public API. + + if defined?(@version_requirement) && @version_requirement + version = @version_requirement.instance_variable_get :@version + @version_requirement = nil + @version_requirements = Gem::Requirement.new version + end + + @requirement = @version_requirements if defined?(@version_requirements) end ## - # Uses this dependency as a pattern to compare to +other+. This dependency - # will match if the name matches the other's name, and other has only an - # equal version requirement that satisfies this dependency. + # Rails subclasses Gem::Dependency and uses this method, so we'll hack + # around it. - def =~(other) - other = if self.class === other then - other - else - return false unless other.respond_to? :name and - other.respond_to? :version + alias __requirement requirement # :nodoc: - Gem::Dependency.new other.name, other.version - end + def requirements_list + requirement.as_list + end - pattern = @name - pattern = /\A#{Regexp.escape @name}\Z/ unless Regexp === pattern + def to_s # :nodoc: + "#{name} (#{requirement}, #{type})" + end - return false unless pattern =~ other.name + def version_requirements # :nodoc: + unless Gem::Dependency.warned_version_requirement then + warn "#{Gem.location_of_caller.join ':'}:Warning: " \ + "Gem::Dependency#version_requirements is deprecated " \ + "and will be removed on or after August 2010. " \ + "Use #requirement" - reqs = other.version_requirements.requirements + Gem::Dependency.warned_version_requirement = true + end - return false unless reqs.length == 1 - return false unless reqs.first.first == '=' + __requirement + end - version = reqs.first.last + alias_method :version_requirement, :version_requirements - version_requirements.satisfied_by? version + def == other # :nodoc: + Gem::Dependency === other && + self.name == other.name && + self.type == other.type && + self.requirement == other.requirement end ## - # A dependency's hash is the sum of the hash of the #name, #type and - # #version_requirements + # Dependencies are ordered by name. - def hash - name.hash + type.hash + version_requirements.hash + def <=> other + [@name] <=> [other.name] end - def inspect # :nodoc: - "<%s type=%p name=%p requirements=%p>" % [self.class, @type, @name, - version_requirements.to_s] + ## + # Uses this dependency as a pattern to compare to +other+. This + # dependency will match if the name matches the other's name, and + # other has only an equal version requirement that satisfies this + # dependency. + + def =~ other + unless Gem::Dependency === other + other = Gem::Dependency.new other.name, other.version rescue return false + end + + pattern = name + pattern = /\A#{Regexp.escape pattern}\Z/ unless Regexp === pattern + + return false unless pattern =~ other.name + + reqs = other.requirement.requirements + + return false unless reqs.length == 1 + return false unless reqs.first.first == '=' + + version = reqs.first.last + + requirement.satisfied_by? version end end diff --git a/lib/rubygems/dependency_installer.rb b/lib/rubygems/dependency_installer.rb index beea212818..9d9aaba400 100644 --- a/lib/rubygems/dependency_installer.rb +++ b/lib/rubygems/dependency_installer.rb @@ -38,7 +38,7 @@ class Gem::DependencyInstaller # :format_executable:: See Gem::Installer#initialize. # :ignore_dependencies:: Don't install any dependencies. # :install_dir:: See Gem::Installer#install. - # :prerelease:: Allow prerelease versions + # :prerelease:: Allow prerelease versions. See #install. # :security_policy:: See Gem::Installer::new and Gem::Security. # :user_install:: See Gem::Installer.new # :wrappers:: See Gem::Installer::new @@ -89,14 +89,18 @@ class Gem::DependencyInstaller if @domain == :both or @domain == :remote then begin - requirements = dep.version_requirements.requirements.map do |req, ver| + requirements = dep.requirement.requirements.map do |req, ver| req end - all = !@prerelease && (requirements.length > 1 || + all = !dep.prerelease? && + # we only need latest if there's one requirement and it is + # guaranteed to match the newest specs + (requirements.length > 1 or (requirements.first != ">=" and requirements.first != ">")) - found = Gem::SpecFetcher.fetcher.fetch dep, all, true, @prerelease + found = Gem::SpecFetcher.fetcher.fetch dep, all, true, dep.prerelease? + gems_and_sources.push(*found) rescue Gem::RemoteFetcher::FetchError => e @@ -120,7 +124,7 @@ class Gem::DependencyInstaller def gather_dependencies specs = @specs_and_sources.map { |spec,_| spec } - dependency_list = Gem::DependencyList.new + dependency_list = Gem::DependencyList.new @development dependency_list.add(*specs) unless @ignore_dependencies then @@ -143,7 +147,7 @@ class Gem::DependencyInstaller @source_index.any? do |_, installed_spec| dep.name == installed_spec.name and - dep.version_requirements.satisfied_by? installed_spec.version + dep.requirement.satisfied_by? installed_spec.version end end @@ -164,7 +168,9 @@ class Gem::DependencyInstaller # +version+. Returns an Array of specs and sources required for # installation of the gem. - def find_spec_by_name_and_version gem_name, version = Gem::Requirement.default + def find_spec_by_name_and_version(gem_name, + version = Gem::Requirement.default, + prerelease = false) spec_and_source = nil glob = if File::ALT_SEPARATOR then @@ -189,6 +195,7 @@ class Gem::DependencyInstaller if spec_and_source.nil? then dep = Gem::Dependency.new gem_name, version + dep.prerelease = true if prerelease spec_and_sources = find_gems_with_sources(dep).reverse spec_and_source = spec_and_sources.find { |spec, source| @@ -205,13 +212,24 @@ class Gem::DependencyInstaller end ## - # Installs the gem and all its dependencies. Returns an Array of installed - # gems specifications. + # Installs the gem +dep_or_name+ and all its dependencies. Returns an Array + # of installed gem specifications. + # + # If the +:prerelease+ option is set and there is a prerelease for + # +dep_or_name+ the prerelease version will be installed. + # + # Unless explicitly specified as a prerelease dependency, prerelease gems + # that +dep_or_name+ depend on will not be installed. + # + # If c-1.a depends on b-1 and a-1.a and there is a gem b-1.a available then + # c-1.a, b-1 and a-1.a will be installed. b-1.a will need to be installed + # separately. def install dep_or_name, version = Gem::Requirement.default if String === dep_or_name then - find_spec_by_name_and_version dep_or_name, version + find_spec_by_name_and_version dep_or_name, version, @prerelease else + dep_or_name.prerelease = @prerelease @specs_and_sources = [find_gems_with_sources(dep_or_name).last] end diff --git a/lib/rubygems/dependency_list.rb b/lib/rubygems/dependency_list.rb index a73a32d545..25d469d68c 100644 --- a/lib/rubygems/dependency_list.rb +++ b/lib/rubygems/dependency_list.rb @@ -6,23 +6,41 @@ require 'tsort' +## +# Gem::DependencyList is used for installing and uninstalling gems in the +# correct order to avoid conflicts. + class Gem::DependencyList include Enumerable include TSort - def self.from_source_index(src_index) - deps = new + ## + # Allows enabling/disabling use of development dependencies + + attr_accessor :development - src_index.each do |full_name, spec| - deps.add spec + ## + # Creates a DependencyList from a Gem::SourceIndex +source_index+ + + def self.from_source_index(source_index) + list = new + + source_index.each do |full_name, spec| + list.add spec end - deps + list end - def initialize + ## + # Creates a new DependencyList. If +development+ is true, development + # dependencies will be included. + + def initialize development = false @specs = [] + + @development = development end ## @@ -33,8 +51,9 @@ class Gem::DependencyList end ## - # Return a list of the specifications in the dependency list, sorted in - # order so that no spec in the list depends on a gem earlier in the list. + # Return a list of the gem specifications in the dependency list, sorted in + # order so that no gemspec in the list depends on a gemspec earlier in the + # list. # # This is useful when removing gems from a set of installed gems. By # removing them in the returned order, you don't get into as many dependency @@ -77,6 +96,10 @@ class Gem::DependencyList @specs.find { |spec| spec.full_name == full_name } end + def inspect # :nodoc: + "#<%s:0x%x %p>" % [self.class, object_id, map { |s| s.full_name }] + end + ## # Are all the dependencies in the list satisfied? @@ -89,10 +112,10 @@ class Gem::DependencyList end ## - # Is is ok to remove a gem from the dependency list? + # Is is ok to remove a gemspec from the dependency list? # # If removing the gemspec creates breaks a currently ok dependency, then it - # is NOT ok to remove the gem. + # is NOT ok to remove the gemspec. def ok_to_remove?(full_name) gem_to_remove = find_name full_name @@ -117,13 +140,16 @@ class Gem::DependencyList } end + ## + # Removes the gemspec matching +full_name+ from the dependency list + def remove_by_name(full_name) @specs.delete_if { |spec| spec.full_name == full_name } end ## # Return a hash of predecessors. <tt>result[spec]</tt> is an Array of - # gemspecs that have a dependency satisfied by the named spec. + # gemspecs that have a dependency satisfied by the named gemspec. def spec_predecessors result = Hash.new { |h,k| h[k] = [] } @@ -152,7 +178,10 @@ class Gem::DependencyList def tsort_each_child(node, &block) specs = @specs.sort.reverse - node.dependencies.each do |dep| + dependencies = node.runtime_dependencies + dependencies.push(*node.development_dependencies) if @development + + dependencies.each do |dep| specs.each do |spec| if spec.satisfies_requirement? dep then begin diff --git a/lib/rubygems/digest/md5.rb b/lib/rubygems/digest/md5.rb deleted file mode 100644 index 2bc8f9c138..0000000000 --- a/lib/rubygems/digest/md5.rb +++ /dev/null @@ -1,13 +0,0 @@ -#-- -# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. -# All rights reserved. -# See LICENSE.txt for permissions. -#++ - -require 'digest/md5' - -# :stopdoc: -module Gem - MD5 = Digest::MD5 -end -# :startdoc: diff --git a/lib/rubygems/digest/sha1.rb b/lib/rubygems/digest/sha1.rb deleted file mode 100644 index 2d91c0f45a..0000000000 --- a/lib/rubygems/digest/sha1.rb +++ /dev/null @@ -1,11 +0,0 @@ -#-- -# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. -# All rights reserved. -# See LICENSE.txt for permissions. -#++ - -require 'digest/sha1' - -module Gem - SHA1 = Digest::SHA1 -end diff --git a/lib/rubygems/digest/sha2.rb b/lib/rubygems/digest/sha2.rb deleted file mode 100644 index 91cb236165..0000000000 --- a/lib/rubygems/digest/sha2.rb +++ /dev/null @@ -1,11 +0,0 @@ -#-- -# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. -# All rights reserved. -# See LICENSE.txt for permissions. -#++ - -require 'digest/sha2' - -module Gem - SHA256 = Digest::SHA256 -end diff --git a/lib/rubygems/doc_manager.rb b/lib/rubygems/doc_manager.rb index e1c8e03b91..a4976ae10a 100644 --- a/lib/rubygems/doc_manager.rb +++ b/lib/rubygems/doc_manager.rb @@ -98,6 +98,13 @@ class Gem::DocManager end ## + # Is the RI documentation installed? + + def ri_installed? + File.exist?(File.join(@doc_dir, "ri")) + end + + ## # Generate the RI documents for this gem spec. # # Note that if both RI and RDoc documents are generated from the same diff --git a/lib/rubygems/format.rb b/lib/rubygems/format.rb index 80aae56215..82eaf9e77e 100644 --- a/lib/rubygems/format.rb +++ b/lib/rubygems/format.rb @@ -14,25 +14,22 @@ require 'rubygems/package' class Gem::Format - attr_accessor :spec, :file_entries, :gem_path + attr_accessor :spec + attr_accessor :file_entries + attr_accessor :gem_path extend Gem::UserInteraction ## - # Constructs an instance of a Format object, representing the gem's - # data structure. - # - # gem:: [String] The file name of the gem - # + # Constructs a Format representing the gem's data which came from +gem_path+ + def initialize(gem_path) @gem_path = gem_path end ## - # Reads the named gem file and returns a Format object, representing - # the data from the gem file - # - # file_path:: [String] Path to the gem file + # Reads the gem +file_path+ using +security_policy+ and returns a Format + # representing the data in the gem def self.from_file_by_path(file_path, security_policy = nil) format = nil @@ -41,25 +38,24 @@ class Gem::Format raise Gem::Exception, "Cannot load gem at [#{file_path}] in #{Dir.pwd}" end - # check for old version gem - if File.read(file_path, 20).include?("MD5SUM =") + start = File.read file_path, 20 + + if start.nil? or start.length < 20 then + nil + elsif start.include?("MD5SUM =") # old version gems require 'rubygems/old_format' - format = Gem::OldFormat.from_file_by_path(file_path) + Gem::OldFormat.from_file_by_path file_path else open file_path, Gem.binary_mode do |io| - format = from_io io, file_path, security_policy + from_io io, file_path, security_policy end end - - return format end ## - # Reads a gem from an io stream and returns a Format object, representing - # the data from the gem file - # - # io:: [IO] Stream from which to read the gem + # Reads a gem from +io+ at +gem_path+ using +security_policy+ and returns a + # Format representing the data from the gem def self.from_io(io, gem_path="(io)", security_policy = nil) format = new gem_path diff --git a/lib/rubygems/gem_openssl.rb b/lib/rubygems/gem_openssl.rb index bdaad8050a..7891d596c4 100644 --- a/lib/rubygems/gem_openssl.rb +++ b/lib/rubygems/gem_openssl.rb @@ -30,7 +30,7 @@ module Gem def ensure_ssl_available unless ssl_available? - fail Gem::Exception, "SSL is not installed on this system" + raise Gem::Exception, "SSL is not installed on this system" end end end diff --git a/lib/rubygems/gem_path_searcher.rb b/lib/rubygems/gem_path_searcher.rb index 2232a574e3..6ee3c078d5 100644 --- a/lib/rubygems/gem_path_searcher.rb +++ b/lib/rubygems/gem_path_searcher.rb @@ -1,9 +1,3 @@ -#-- -# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. -# All rights reserved. -# See LICENSE.txt for permissions. -#++ - ## # GemPathSearcher has the capability to find loadable files inside # gems. It generates data up front to speed up searches later. @@ -14,14 +8,16 @@ class Gem::GemPathSearcher # Initialise the data we need to make searches later. def initialize - # We want a record of all the installed gemspecs, in the order - # we wish to examine them. + # We want a record of all the installed gemspecs, in the order we wish to + # examine them. @gemspecs = init_gemspecs - # Map gem spec to glob of full require_path directories. - # Preparing this information may speed up searches later. + + # Map gem spec to glob of full require_path directories. Preparing this + # information may speed up searches later. @lib_dirs = {} + @gemspecs.each do |spec| - @lib_dirs[spec.object_id] = lib_dirs_for(spec) + @lib_dirs[spec.object_id] = lib_dirs_for spec end end @@ -72,6 +68,7 @@ class Gem::GemPathSearcher # Some of the intermediate results are cached in @lib_dirs for speed. def matching_files(spec, path) + return [] unless @lib_dirs[spec.object_id] # case no paths glob = File.join @lib_dirs[spec.object_id], "#{path}#{Gem.suffix_pattern}" Dir[glob].select { |f| File.file? f.untaint } end @@ -95,7 +92,8 @@ class Gem::GemPathSearcher # '/usr/local/lib/ruby/gems/1.8/gems/foobar-1.0/{lib,ext}' def lib_dirs_for(spec) - "#{spec.full_gem_path}/{#{spec.require_paths.join(',')}}" + "#{spec.full_gem_path}/{#{spec.require_paths.join(',')}}" if + spec.require_paths end end diff --git a/lib/rubygems/gemcutter_utilities.rb b/lib/rubygems/gemcutter_utilities.rb new file mode 100644 index 0000000000..225bd704f9 --- /dev/null +++ b/lib/rubygems/gemcutter_utilities.rb @@ -0,0 +1,49 @@ +require 'net/http' +require 'rubygems/remote_fetcher' + +module Gem::GemcutterUtilities + + def sign_in + return if Gem.configuration.rubygems_api_key + + say "Enter your RubyGems.org credentials." + say "Don't have an account yet? Create one at http://rubygems.org/sign_up" + + email = ask " Email: " + password = ask_for_password "Password: " + say "\n" + + response = rubygems_api_request :get, "api/v1/api_key" do |request| + request.basic_auth email, password + end + + with_response response do |resp| + say "Signed in." + Gem.configuration.rubygems_api_key = resp.body + end + end + + def rubygems_api_request(method, path, &block) + host = ENV['RUBYGEMS_HOST'] || 'https://rubygems.org' + uri = URI.parse "#{host}/#{path}" + + request_method = Net::HTTP.const_get method.to_s.capitalize + + Gem::RemoteFetcher.fetcher.request(uri, request_method, &block) + end + + def with_response(resp) + case resp + when Net::HTTPSuccess then + if block_given? then + yield resp + else + say resp.body + end + else + say resp.body + terminate_interaction 1 + end + end + +end diff --git a/lib/rubygems/indexer.rb b/lib/rubygems/indexer.rb index aff8d8de17..baa582447d 100644 --- a/lib/rubygems/indexer.rb +++ b/lib/rubygems/indexer.rb @@ -58,7 +58,7 @@ class Gem::Indexer def initialize(directory, options = {}) unless ''.respond_to? :to_xs then - fail "Gem::Indexer requires that the XML Builder library be installed:" \ + raise "Gem::Indexer requires that the XML Builder library be installed:" \ "\n\tgem install builder" end @@ -350,7 +350,7 @@ class Gem::Indexer end index.sort_by { |_, spec| [-spec.date.to_i, spec] }.each do |_, spec| - gem_path = CGI.escapeHTML "http://#{@rss_gems_host}/gems/#{spec.full_name}.gem" + gem_path = CGI.escapeHTML "http://#{@rss_gems_host}/gems/#{spec.file_name}" size = File.stat(spec.loaded_from).size rescue next description = spec.description || spec.summary || '' diff --git a/lib/rubygems/install_update_options.rb b/lib/rubygems/install_update_options.rb index a43a2a171c..c3fa2d5edd 100644 --- a/lib/rubygems/install_update_options.rb +++ b/lib/rubygems/install_update_options.rb @@ -95,8 +95,7 @@ module Gem::InstallUpdateOptions add_option(:"Install/Update", '--[no-]user-install', 'Install in user\'s home directory instead', - 'of GEM_HOME. Defaults to using home', - 'only if GEM_HOME is not writable.') do |value, options| + 'of GEM_HOME.') do |value, options| options[:user_install] = value end @@ -105,13 +104,6 @@ module Gem::InstallUpdateOptions "dependencies") do |value, options| options[:development] = true end - - add_option(:"Install/Update", "--prerelease", - "Install prerelease versions of a gem if", - "available. Defaults to skipping", - "prereleases.") do |value, options| - options[:prerelease] = true - end end ## diff --git a/lib/rubygems/installer.rb b/lib/rubygems/installer.rb index d6075dd0a2..50f8d20b33 100644 --- a/lib/rubygems/installer.rb +++ b/lib/rubygems/installer.rb @@ -5,7 +5,6 @@ #++ require 'fileutils' -require 'pathname' require 'rbconfig' require 'rubygems/format' @@ -58,17 +57,11 @@ class Gem::Installer attr_reader :spec - @home_install_warning = false @path_warning = false class << self ## - # True if we've warned about ~/.gems install - - attr_accessor :home_install_warning - - ## # True if we've warned about PATH not including Gem.bindir attr_accessor :path_warning @@ -112,7 +105,7 @@ class Gem::Installer @env_shebang = options[:env_shebang] @force = options[:force] gem_home = options[:install_dir] - @gem_home = Pathname.new(gem_home).expand_path + @gem_home = File.expand_path(gem_home) @ignore_dependencies = options[:ignore_dependencies] @format_executable = options[:format_executable] @security_policy = options[:security_policy] @@ -127,27 +120,6 @@ class Gem::Installer raise Gem::InstallError, "invalid gem format for #{@gem}" end - begin - FileUtils.mkdir_p @gem_home - rescue Errno::EACCES, Errno::ENOTDIR - # We'll divert to ~/.gems below - end - - if not File.writable? @gem_home or - # TODO: Shouldn't have to test for existence of bindir; tests need it. - (@gem_home.to_s == Gem.dir and File.exist? Gem.bindir and - not File.writable? Gem.bindir) then - if options[:user_install] == false then # You don't want to use ~ - raise Gem::FilePermissionError, @gem_home - elsif options[:user_install].nil? then - unless self.class.home_install_warning or options[:unpack] then - alert_warning "Installing to ~/.gem since #{@gem_home} and\n\t #{Gem.bindir} aren't both writable." - self.class.home_install_warning = true - end - end - options[:user_install] = true - end - if options[:user_install] and not options[:unpack] then @gem_home = Gem.user_dir @@ -158,12 +130,11 @@ class Gem::Installer self.class.path_warning = true end end - - FileUtils.mkdir_p @gem_home unless File.directory? @gem_home - # If it's still not writable, you've got issues. - raise Gem::FilePermissionError, @gem_home unless File.writable? @gem_home end + FileUtils.mkdir_p @gem_home + raise Gem::FilePermissionError, @gem_home unless File.writable? @gem_home + @spec = @format.spec @gem_dir = File.join(@gem_home, "gems", @spec.full_name).untaint @@ -189,14 +160,15 @@ class Gem::Installer unless @force then if rrv = @spec.required_ruby_version then unless rrv.satisfied_by? Gem.ruby_version then - raise Gem::InstallError, "#{@spec.name} requires Ruby version #{rrv}" + raise Gem::InstallError, "#{@spec.name} requires Ruby version #{rrv}." end end if rrgv = @spec.required_rubygems_version then unless rrgv.satisfied_by? Gem::Version.new(Gem::RubyGemsVersion) then raise Gem::InstallError, - "#{@spec.name} requires RubyGems version #{rrgv}" + "#{@spec.name} requires RubyGems version #{rrgv}. " + + "Try 'gem update --system' to update RubyGems itself." end end @@ -235,8 +207,7 @@ class Gem::Installer say @spec.post_install_message unless @spec.post_install_message.nil? - @spec.loaded_from = File.join(@gem_home, 'specifications', - "#{@spec.full_name}.gemspec") + @spec.loaded_from = File.join(@gem_home, 'specifications', @spec.spec_name) @source_index.add_spec @spec @@ -268,7 +239,7 @@ class Gem::Installer # True if the gems in the source_index satisfy +dependency+. def installation_satisfies_dependency?(dependency) - @source_index.find_name(dependency.name, dependency.version_requirements).size > 0 + @source_index.find_name(dependency.name, dependency.requirement).size > 0 end ## @@ -287,8 +258,7 @@ class Gem::Installer def write_spec rubycode = @spec.to_ruby - file_name = File.join @gem_home, 'specifications', - "#{@spec.full_name}.gemspec" + file_name = File.join @gem_home, 'specifications', @spec.spec_name file_name.untaint @@ -522,7 +492,7 @@ Results logged to #{File.join(Dir.pwd, 'gem_make.out')} # Ensures that files can't be installed outside the gem directory. def extract_files - expand_and_validate_gem_dir + @gem_dir = File.expand_path @gem_dir raise ArgumentError, "format required to extract from" if @format.nil? @@ -566,24 +536,5 @@ Results logged to #{File.join(Dir.pwd, 'gem_make.out')} end end - private - - ## - # HACK Pathname is broken on windows. - - def absolute_path? pathname - pathname.absolute? or (Gem.win_platform? and pathname.to_s =~ /\A[a-z]:/i) - end - - def expand_and_validate_gem_dir - @gem_dir = Pathname.new(@gem_dir).expand_path - - unless absolute_path?(@gem_dir) then # HACK is this possible after #expand_path? - raise ArgumentError, "install directory %p not absolute" % @gem_dir - end - - @gem_dir = @gem_dir.to_s - end - end diff --git a/lib/rubygems/package.rb b/lib/rubygems/package.rb index 9cb393b0c7..0fd64025ad 100644 --- a/lib/rubygems/package.rb +++ b/lib/rubygems/package.rb @@ -1,3 +1,4 @@ +# -*- coding: iso-8859-1 -*- #++ # Copyright (C) 2004 Mauricio Julio Fernández Pradier # See LICENSE.txt for additional licensing information. @@ -9,7 +10,6 @@ require 'stringio' require 'yaml' require 'zlib' -require 'rubygems/digest/md5' require 'rubygems/security' require 'rubygems/specification' diff --git a/lib/rubygems/package/f_sync_dir.rb b/lib/rubygems/package/f_sync_dir.rb index 1915ab3ecb..e15035ec37 100644 --- a/lib/rubygems/package/f_sync_dir.rb +++ b/lib/rubygems/package/f_sync_dir.rb @@ -1,3 +1,4 @@ +# -*- coding: iso-8859-1 -*- #++ # Copyright (C) 2004 Mauricio Julio Fernández Pradier # See LICENSE.txt for additional licensing information. diff --git a/lib/rubygems/package/tar_header.rb b/lib/rubygems/package/tar_header.rb index 44c6695cf9..0689c319b9 100644 --- a/lib/rubygems/package/tar_header.rb +++ b/lib/rubygems/package/tar_header.rb @@ -1,3 +1,4 @@ +# -*- coding: iso-8859-1 -*- #++ # Copyright (C) 2004 Mauricio Julio Fernández Pradier # See LICENSE.txt for additional licensing information. diff --git a/lib/rubygems/package/tar_input.rb b/lib/rubygems/package/tar_input.rb index 9f901023b8..6c286585e9 100644 --- a/lib/rubygems/package/tar_input.rb +++ b/lib/rubygems/package/tar_input.rb @@ -1,3 +1,4 @@ +# -*- coding: iso-8859-1 -*- #++ # Copyright (C) 2004 Mauricio Julio Fernández Pradier # See LICENSE.txt for additional licensing information. @@ -199,7 +200,8 @@ class Gem::Package::TarInput # times. And that's the way it is. def zipped_stream(entry) - if defined? Rubinius then + if defined? Rubinius or defined? Maglev then + # these implementations have working Zlib zis = Zlib::GzipReader.new entry dis = zis.read is = StringIO.new(dis) diff --git a/lib/rubygems/package/tar_output.rb b/lib/rubygems/package/tar_output.rb index dfb74af9fc..98fa8b8fe1 100644 --- a/lib/rubygems/package/tar_output.rb +++ b/lib/rubygems/package/tar_output.rb @@ -1,3 +1,4 @@ +# -*- coding: iso-8859-1 -*- #++ # Copyright (C) 2004 Mauricio Julio Fernández Pradier # See LICENSE.txt for additional licensing information. diff --git a/lib/rubygems/package/tar_reader.rb b/lib/rubygems/package/tar_reader.rb index 1a2fbaf678..b28714d124 100644 --- a/lib/rubygems/package/tar_reader.rb +++ b/lib/rubygems/package/tar_reader.rb @@ -1,3 +1,4 @@ +# -*- coding: iso-8859-1 -*- #++ # Copyright (C) 2004 Mauricio Julio Fernández Pradier # See LICENSE.txt for additional licensing information. diff --git a/lib/rubygems/package/tar_writer.rb b/lib/rubygems/package/tar_writer.rb index 6f11529302..b5fc89e55e 100644 --- a/lib/rubygems/package/tar_writer.rb +++ b/lib/rubygems/package/tar_writer.rb @@ -1,3 +1,4 @@ +# -*- coding: iso-8859-1 -*- #++ # Copyright (C) 2004 Mauricio Julio Fernández Pradier # See LICENSE.txt for additional licensing information. diff --git a/lib/rubygems/package_task.rb b/lib/rubygems/package_task.rb index e80b1eceaf..bb0a60464e 100644 --- a/lib/rubygems/package_task.rb +++ b/lib/rubygems/package_task.rb @@ -97,22 +97,27 @@ class Gem::PackageTask < Rake::PackageTask def define super + task :package => [:gem] + + gem_file = gem_spec.file_name + gem_path = File.join package_dir, gem_file + desc "Build the gem file #{gem_file}" - task :gem => ["#{package_dir}/#{gem_file}"] - file "#{package_dir}/#{gem_file}" => [package_dir] + @gem_spec.files do - when_writing("Creating #{gem_spec.full_name}.gem") { + task :gem => [gem_path] + + trace = Rake.application.options.trace + Gem.configuration.verbose = trace + + file gem_path => [package_dir] + @gem_spec.files do + when_writing "Creating #{gem_spec.file_name}" do Gem::Builder.new(gem_spec).build - verbose(true) { - mv gem_file, "#{package_dir}/#{gem_file}" - } - } + verbose trace do + mv gem_file, gem_path + end + end end end - def gem_file - "#{@gem_spec.full_name}.gem" - end - end diff --git a/lib/rubygems/remote_fetcher.rb b/lib/rubygems/remote_fetcher.rb index 945523e5b0..dbd4cef816 100644 --- a/lib/rubygems/remote_fetcher.rb +++ b/lib/rubygems/remote_fetcher.rb @@ -81,7 +81,7 @@ class Gem::RemoteFetcher cache_dir = File.join(Gem.user_dir, 'cache') end - gem_file_name = "#{spec.full_name}.gem" + gem_file_name = spec.file_name local_gem_path = File.join cache_dir, gem_file_name FileUtils.mkdir_p cache_dir rescue nil unless File.exist? cache_dir @@ -138,12 +138,18 @@ class Gem::RemoteFetcher say "Using local gem #{local_gem_path}" if Gem.configuration.really_verbose when nil then # TODO test for local overriding cache + source_path = if Gem.win_platform? && source_uri.scheme && + !source_uri.path.include?(':') then + "#{source_uri.scheme}:#{source_uri.path}" + else + source_uri.path + end + + source_path = URI.unescape source_path + begin - if Gem.win_platform? && source_uri.scheme && !source_uri.path.include?(':') - FileUtils.cp URI.unescape(source_uri.scheme + ':' + source_uri.path), local_gem_path - else - FileUtils.cp URI.unescape(source_uri.path), local_gem_path - end + FileUtils.cp source_path, local_gem_path unless + File.expand_path(source_path) == File.expand_path(local_gem_path) rescue Errno::EACCES local_gem_path = source_uri.to_s end @@ -317,6 +323,8 @@ class Gem::RemoteFetcher request.add_field 'If-Modified-Since', last_modified.rfc2822 end + yield request if block_given? + connection = connection_for uri retried = false @@ -324,10 +332,16 @@ class Gem::RemoteFetcher begin @requests[connection.object_id] += 1 + + say "#{request.method} #{uri}" if + Gem.configuration.really_verbose response = connection.request request - say "#{request.method} #{response.code} #{response.message}: #{uri}" if + say "#{response.code} #{response.message}" if Gem.configuration.really_verbose + rescue Net::HTTPBadResponse + say "bad response" if Gem.configuration.really_verbose + reset connection raise FetchError.new('too many bad responses', uri) if bad_response @@ -337,7 +351,7 @@ class Gem::RemoteFetcher # HACK work around EOFError bug in Net::HTTP # NOTE Errno::ECONNABORTED raised a lot on Windows, and make impossible # to install gems. - rescue EOFError, Errno::ECONNABORTED, Errno::ECONNRESET + rescue EOFError, Errno::ECONNABORTED, Errno::ECONNRESET, Errno::EPIPE requests = @requests[connection.object_id] say "connection reset after #{requests} requests, retrying" if Gem.configuration.really_verbose diff --git a/lib/rubygems/requirement.rb b/lib/rubygems/requirement.rb index 471d84eb61..d9b510a76d 100644 --- a/lib/rubygems/requirement.rb +++ b/lib/rubygems/requirement.rb @@ -1,41 +1,33 @@ -#-- -# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. -# All rights reserved. -# See LICENSE.txt for permissions. -#++ +require "rubygems/version" ## -# Requirement version includes a prefaced comparator in addition -# to a version number. -# -# A Requirement object can actually contain multiple, er, -# requirements, as in (> 1.2, < 2.0). +# A Requirement is a set of one or more version restrictions. It supports a +# few (<tt>=, !=, >, <, >=, <=, ~></tt>) different restriction operators. class Gem::Requirement - include Comparable - attr_reader :requirements - - OPS = { + OPS = { #:nodoc: "=" => lambda { |v, r| v == r }, "!=" => lambda { |v, r| v != r }, - ">" => lambda { |v, r| v > r }, - "<" => lambda { |v, r| v < r }, + ">" => lambda { |v, r| v > r }, + "<" => lambda { |v, r| v < r }, ">=" => lambda { |v, r| v >= r }, "<=" => lambda { |v, r| v <= r }, "~>" => lambda { |v, r| v = v.release; v >= r && v < r.bump } } - OP_RE = OPS.keys.map{ |k| Regexp.quote k }.join '|' + quoted = OPS.keys.map { |k| Regexp.quote k }.join "|" + PATTERN = /\A\s*(#{quoted})?\s*(#{Gem::Version::VERSION_PATTERN})\s*\z/ ## - # Factory method to create a Gem::Requirement object. Input may be a - # Version, a String, or nil. Intended to simplify client code. + # Factory method to create a Gem::Requirement object. Input may be + # a Version, a String, or nil. Intended to simplify client code. # - # If the input is "weird", the default version requirement is returned. + # If the input is "weird", the default version requirement is + # returned. - def self.create(input) + def self.create input case input when Gem::Requirement then input @@ -43,9 +35,9 @@ class Gem::Requirement new input else if input.respond_to? :to_str then - self.new [input.to_str] + new [input.to_str] else - self.default + default end end end @@ -58,113 +50,99 @@ class Gem::Requirement # "A default "version requirement" can surely _only_ be '> 0'." def self.default - self.new ['>= 0'] + new '>= 0' end ## - # Constructs a Requirement from +requirements+ which can be a String, a - # Gem::Version, or an Array of those. See #parse for details on the - # formatting of requirement strings. - - def initialize(requirements) - @requirements = case requirements - when Array then - requirements.map do |requirement| - parse(requirement) - end - else - [parse(requirements)] - end - @version = nil # Avoid warnings. - end + # Parse +obj+, returning an <tt>[op, version]</tt> pair. +obj+ can + # be a String or a Gem::Version. + # + # If +obj+ is a String, it can be either a full requirement + # specification, like <tt>">= 1.2"</tt>, or a simple version number, + # like <tt>"1.2"</tt>. + # + # parse("> 1.0") # => [">", "1.0"] + # parse("1.0") # => ["=", "1.0"] + # parse(Gem::Version.new("1.0")) # => ["=, "1.0"] - ## - # Marshal raw requirements, rather than the full object + def self.parse obj + return ["=", obj] if Gem::Version === obj - def marshal_dump # :nodoc: - [@requirements] + unless PATTERN =~ obj.to_s + raise ArgumentError, "Illformed requirement [#{obj.inspect}]" + end + + [$1 || "=", Gem::Version.new($2)] end ## - # Load custom marshal format + # An array of requirement pairs. The first element of the pair is + # the op, and the second is the Gem::Version. - def marshal_load(array) # :nodoc: - @requirements = array[0] - @version = nil + attr_reader :requirements #:nodoc: + + ## + # Constructs a requirement from +requirements+. Requirements can be + # Strings, Gem::Versions, or Arrays of those. +nil+ and duplicate + # requirements are ignored. An empty set of +requirements+ is the + # same as <tt>">= 0"</tt>. + + def initialize *requirements + requirements = requirements.flatten + requirements.compact! + requirements.uniq! + + requirements << ">= 0" if requirements.empty? + @requirements = requirements.map! { |r| self.class.parse r } end - def to_s # :nodoc: - as_list.join(", ") + def as_list # :nodoc: + requirements.map { |op, version| "#{op} #{version}" } end - def pretty_print(q) # :nodoc: - q.group 1, 'Gem::Requirement.new(', ')' do - q.pp as_list - end + def hash # :nodoc: + requirements.hash end - def as_list - normalize - @requirements.map do |op, version| "#{op} #{version}" end + def marshal_dump # :nodoc: + [@requirements] end - def normalize - return if not defined? @version or @version.nil? - @requirements = [parse(@version)] - @nums = nil - @version = nil - @op = nil + def marshal_load array # :nodoc: + @requirements = array[0] end - ## - # True if this requirement satisfied by the Gem::Version +version+. + def prerelease? + requirements.any? { |r| r.last.prerelease? } + end - def satisfied_by?(version) - normalize - @requirements.all? { |op, rv| satisfy?(op, version, rv) } + def pretty_print q # :nodoc: + q.group 1, 'Gem::Requirement.new(', ')' do + q.pp as_list + end end ## - # Is "+version+ +op+ +required_version+" satisfied? + # True if +version+ satisfies this Requirement. - def satisfy?(op, version, required_version) - OPS[op].call(version, required_version) - end - - def prerelease? - # TODO: why is @requirements a nested array? - @requirements.any?{ |r| r[1].prerelease? } + def satisfied_by? version + requirements.all? { |op, rv| OPS[op].call version, rv } end - ## - # Parse the version requirement obj returning the operator and version. - # - # The requirement can be a String or a Gem::Version. A String can be an - # operator (<, <=, =, >=, >, !=, ~>), a version number, or both, operator - # first. - - def parse(obj) - case obj - when /^\s*(#{OP_RE})\s*(#{Gem::Version::VERSION_PATTERN})\s*$/o then - [$1, Gem::Version.new($2)] - when /^\s*(#{Gem::Version::VERSION_PATTERN})\s*$/o then - ['=', Gem::Version.new($1)] - when /^\s*(#{OP_RE})\s*$/o then - [$1, Gem::Version.new('0')] - when Gem::Version then - ['=', obj] - else - fail ArgumentError, "Illformed requirement [#{obj.inspect}]" - end + def to_s # :nodoc: + as_list.join ", " end - def <=>(other) # :nodoc: + def <=> other # :nodoc: to_s <=> other.to_s end +end - def hash # :nodoc: - to_s.hash - end +# :stopdoc: +# Gem::Version::Requirement is used in a lot of old YAML specs. It's aliased +# here for backwards compatibility. I'd like to remove this, maybe in RubyGems +# 2.0. -end +::Gem::Version::Requirement = ::Gem::Requirement +# :startdoc: diff --git a/lib/rubygems/rubygems_version.rb b/lib/rubygems/rubygems_version.rb deleted file mode 100644 index eda0a0e906..0000000000 --- a/lib/rubygems/rubygems_version.rb +++ /dev/null @@ -1,19 +0,0 @@ -#-- -# DO NOT EDIT -# This file is auto-generated by build scripts. -# See: rake update_version -#++ - -module Gem - - ## - # The version of RubyGems you are using - - RubyGemsVersion = '1.3.4' - - ## - # The version of RubyGems you are using (duplicated for familiarity) - - VERSION = RubyGemsVersion - -end diff --git a/lib/rubygems/server.rb b/lib/rubygems/server.rb index 44bee74abf..24c9e044e1 100644 --- a/lib/rubygems/server.rb +++ b/lib/rubygems/server.rb @@ -39,9 +39,9 @@ class Gem::Server SEARCH = <<-SEARCH <form class="headerSearch" name="headerSearchForm" method="get" action="/rdoc"> <div id="search" style="float:right"> - <span>Filter/Search</span> - <input id="q" type="text" style="width:10em" name="q"/> - <button type="submit" style="display:none" /> + <label for="q">Filter/Search</label> + <input id="q" type="text" style="width:10em" name="q"> + <button type="submit" style="display:none"></button> </div> </form> SEARCH @@ -426,15 +426,17 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; } RDOC_SEARCH def self.run(options) - new(options[:gemdir], options[:port], options[:daemon]).run + new(options[:gemdir], options[:port], options[:daemon], + options[:addresses]).run end - def initialize(gem_dir, port, daemon) + def initialize(gem_dir, port, daemon, addresses = nil) Socket.do_not_reverse_lookup = true @gem_dir = gem_dir @port = port @daemon = daemon + @addresses = addresses logger = WEBrick::Log.new nil, WEBrick::BasicLog::FATAL @server = WEBrick::HTTPServer.new :DoNotListen => true, :Logger => logger @@ -498,6 +500,37 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; } end end + ## + # Creates server sockets based on the addresses option. If no addresses + # were given a server socket for all interfaces is created. + + def listen addresses = @addresses + addresses = [nil] unless addresses + + listeners = 0 + + addresses.each do |address| + begin + @server.listen address, @port + @server.listeners[listeners..-1].each do |listener| + host, port = listener.addr.values_at 2, 1 + host = "[#{host}]" if host =~ /:/ # we don't reverse lookup + say "Server started at http://#{host}:#{port}" + end + + listeners = @server.listeners.length + rescue SystemCallError + next + end + end + + if @server.listeners.empty? then + say "Unable to start a server." + say "Check for running servers or your --bind and --port arguments" + terminate_interaction 1 + end + end + def quick(req, res) @source_index.refresh! @@ -566,7 +599,7 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; } deps = spec.dependencies.map do |dep| { "name" => dep.name, "type" => dep.type, - "version" => dep.version_requirements.to_s, } + "version" => dep.requirement.to_s, } end deps = deps.sort_by { |dep| [dep["name"].downcase, dep["version"]] } @@ -602,7 +635,7 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; } "only_one_executable" => true, "full_name" => "rubygems-#{Gem::RubyGemsVersion}", "has_deps" => false, - "homepage" => "http://rubygems.org/", + "homepage" => "http://docs.rubygems.org/", "name" => 'rubygems', "rdoc_installed" => true, "summary" => "RubyGems itself", @@ -716,9 +749,7 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; } end def run - @server.listen nil, @port - - say "Starting gem server on http://localhost:#{@port}/" + listen WEBrick::Daemon.start if @daemon diff --git a/lib/rubygems/source_index.rb b/lib/rubygems/source_index.rb index 8caf7b2e35..ac5d8add1e 100644 --- a/lib/rubygems/source_index.rb +++ b/lib/rubygems/source_index.rb @@ -303,7 +303,7 @@ class Gem::SourceIndex version_requirement = platform_only || Gem::Requirement.default when Gem::Dependency then only_platform = platform_only - version_requirement = gem_pattern.version_requirements + version_requirement = gem_pattern.requirement gem_pattern = if Regexp === gem_pattern.name then gem_pattern.name elsif gem_pattern.name.empty? then diff --git a/lib/rubygems/spec_fetcher.rb b/lib/rubygems/spec_fetcher.rb index a5f33183dd..6d1fa9f63d 100644 --- a/lib/rubygems/spec_fetcher.rb +++ b/lib/rubygems/spec_fetcher.rb @@ -197,7 +197,7 @@ class Gem::SpecFetcher if type == :all list.values.map do |gems| - gems.reject! { |g| g[1].prerelease? } + gems.reject! { |g| !g[1] || g[1].prerelease? } end end @@ -242,7 +242,7 @@ class Gem::SpecFetcher FileUtils.mkdir_p cache_dir open local_file, 'wb' do |io| - Marshal.dump specs, io + io << spec_dump end rescue end diff --git a/lib/rubygems/specification.rb b/lib/rubygems/specification.rb index 3630b4adf5..472d60817b 100644 --- a/lib/rubygems/specification.rb +++ b/lib/rubygems/specification.rb @@ -17,7 +17,7 @@ class Date; end # for ruby_code if date.rb wasn't required # defined in a .gemspec file or a Rakefile, and looks like this: # # spec = Gem::Specification.new do |s| -# s.name = 'rfoo' +# s.name = 'example' # s.version = '1.0' # s.summary = 'Example gem specification' # ... @@ -409,15 +409,19 @@ class Gem::Specification # :startdoc: ## - # Specification constructor. Assigns the default values to the attributes - # and yields itself for further initialization. + # Specification constructor. Assigns the default values to the + # attributes and yields itself for further + # initialization. Optionally takes +name+ and +version+. - def initialize + def initialize name = nil, version = nil @new_platform = nil assign_defaults @loaded = false @loaded_from = nil + self.name = name if name + self.version = version if version + yield self if block_given? @@gather.call(self) if @@gather @@ -498,7 +502,7 @@ class Gem::Specification def self.load(filename) gemspec = nil - fail "NESTED Specification.load calls not allowed!" if @@gather + raise "NESTED Specification.load calls not allowed!" if @@gather @@gather = proc { |gs| gemspec = gs } data = File.read(filename) eval(data) @@ -598,10 +602,12 @@ class Gem::Specification end ## - # The default (generated) file name of the gem. + # The default (generated) file name of the gem. See also #spec_name. + # + # spec.file_name # => "example-1.0.gem" def file_name - full_name + ".gem" + full_name + '.gem' end ## @@ -620,7 +626,7 @@ class Gem::Specification def satisfies_requirement?(dependency) return @name == dependency.name && - dependency.version_requirements.satisfied_by?(@version) + dependency.requirement.satisfied_by?(@version) end ## @@ -630,6 +636,15 @@ class Gem::Specification [@name, @version, @new_platform == Gem::Platform::RUBY ? -1 : 1] end + ## + # The default name of the gemspec. See also #file_name + # + # spec.spec_name # => "example-1.0.gemspec" + + def spec_name + full_name + '.gemspec' + end + def <=>(other) # :nodoc: sort_obj <=> other.sort_obj end @@ -1033,14 +1048,18 @@ class Gem::Specification ## # :attr_accessor: rubygems_version # - # The version of RubyGems used to create this gem + # The version of RubyGems used to create this gem. + # + # Do not set this, it is set automatically when the gem is packaged. required_attribute :rubygems_version, Gem::RubyGemsVersion ## # :attr_accessor: specification_version # - # The Gem::Specification version of this gemspec + # The Gem::Specification version of this gemspec. + # + # Do not set this, it is set automatically when the gem is packaged. required_attribute :specification_version, CURRENT_SPECIFICATION_VERSION @@ -1062,6 +1081,8 @@ class Gem::Specification # :attr_accessor: date # # The date this gem was created + # + # Do not set this, it is set automatically when the gem is packaged. required_attribute :date, TODAY @@ -1069,13 +1090,20 @@ class Gem::Specification # :attr_accessor: summary # # A short summary of this gem's description. Displayed in `gem list -d`. + # + # The description should be more detailed than the summary. For example, + # you might wish to copy the entire README into the description. + # + # As of RubyGems 1.3.2 newlines are no longer stripped. required_attribute :summary ## # :attr_accessor: require_paths # - # Paths in the gem to add to $LOAD_PATH when this gem is activated + # Paths in the gem to add to $LOAD_PATH when this gem is activated. + # + # The default 'lib' is typically sufficient. required_attribute :require_paths, ['lib'] @@ -1085,6 +1113,13 @@ class Gem::Specification # :attr_accessor: email # # A contact email for this gem + # + # If you are providing multiple authors and multiple emails they should be + # in the same order such that: + # + # Hash[*spec.authors.zip(spec.emails).flatten] + # + # Gives a hash of author name to email address. attribute :email @@ -1122,6 +1157,8 @@ class Gem::Specification # :attr_accessor: default_executable # # The default executable for this gem. + # + # This is not used. attribute :default_executable @@ -1149,7 +1186,7 @@ class Gem::Specification ## # :attr_accessor: required_ruby_version # - # The ruby of version required by this gem + # The version of ruby required by this gem attribute :required_ruby_version, Gem::Requirement.default @@ -1164,6 +1201,9 @@ class Gem::Specification # :attr_accessor: platform # # The platform this gem runs on. See Gem::Platform for details. + # + # Setting this to any value other than Gem::Platform::RUBY or + # Gem::Platform::CURRENT is probably wrong. attribute :platform, Gem::Platform::RUBY @@ -1192,7 +1232,14 @@ class Gem::Specification ## # :attr_accessor: authors # - # The list of authors who wrote this gem + # The list of author names who wrote this gem. + # + # If you are providing multiple authors and multiple emails they should be + # in the same order such that: + # + # Hash[*spec.authors.zip(spec.emails).flatten] + # + # Gives a hash of author name to email address. array_attribute :authors @@ -1228,21 +1275,21 @@ class Gem::Specification ## # :attr_accessor: rdoc_options # - # An ARGV-style array of options to RDoc + # An ARGV style array of options to RDoc array_attribute :rdoc_options ## # :attr_accessor: extra_rdoc_files # - # Extra files to add to RDoc + # Extra files to add to RDoc such as README or doc/examples.txt array_attribute :extra_rdoc_files ## # :attr_accessor: executables # - # Executables included in the gem + # Executables included in the gem. array_attribute :executables @@ -1266,6 +1313,9 @@ class Gem::Specification # :attr_reader: dependencies # # A list of Gem::Dependency objects this gem depends on. + # + # Use #add_dependency or #add_development_dependency to add dependencies to + # a gem. array_attribute :dependencies diff --git a/lib/rubygems/test_utilities.rb b/lib/rubygems/test_utilities.rb index 751c13441b..9a4759cb99 100644 --- a/lib/rubygems/test_utilities.rb +++ b/lib/rubygems/test_utilities.rb @@ -23,6 +23,7 @@ require 'rubygems/remote_fetcher' class Gem::FakeFetcher attr_reader :data + attr_reader :last_request attr_accessor :paths def initialize @@ -30,16 +31,20 @@ class Gem::FakeFetcher @paths = [] end - def fetch_path path, mtime = nil + def find_data(path) path = path.to_s @paths << path - raise ArgumentError, 'need full URI' unless path =~ %r'^http://' + raise ArgumentError, 'need full URI' unless path =~ %r'^https?://' unless @data.key? path then raise Gem::RemoteFetcher::FetchError.new("no data for #{path}", path) end - data = @data[path] + @data[path] + end + + def fetch_path path, mtime = nil + data = find_data(path) if data.respond_to?(:call) then data.call @@ -52,6 +57,30 @@ class Gem::FakeFetcher end end + # Thanks, FakeWeb! + def open_uri_or_path(path) + data = find_data(path) + body, code, msg = data + + response = Net::HTTPResponse.send(:response_class, code.to_s).new("1.0", code.to_s, msg) + response.instance_variable_set(:@body, body) + response.instance_variable_set(:@read, true) + response + end + + def request(uri, request_class, last_modified = nil) + data = find_data(uri) + body, code, msg = data + + @last_request = request_class.new uri.request_uri + yield @last_request if block_given? + + response = Net::HTTPResponse.send(:response_class, code.to_s).new("1.0", code.to_s, msg) + response.instance_variable_set(:@body, body) + response.instance_variable_set(:@read, true) + response + end + def fetch_size(path) path = path.to_s @paths << path @@ -68,7 +97,7 @@ class Gem::FakeFetcher end def download spec, source_uri, install_dir = Gem.dir - name = "#{spec.full_name}.gem" + name = spec.file_name path = File.join(install_dir, 'cache', name) Gem.ensure_gem_subdirectories install_dir diff --git a/lib/rubygems/timer.rb b/lib/rubygems/timer.rb deleted file mode 100644 index 028e640230..0000000000 --- a/lib/rubygems/timer.rb +++ /dev/null @@ -1,28 +0,0 @@ -# -# This file defines a $log variable for logging, and a time() method for -# recording timing information. -# -#-- -# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. -# All rights reserved. -# See LICENSE.txt for permissions. -#++ - -require 'rubygems' - -file, lineno = Gem.location_of_caller - -warn "#{file}:#{lineno}:Warning: RubyGems' lib/rubygems/timer.rb deprecated and will be removed on or after June 2009." - -$log = Object.new - -# :stopdoc: -def $log.debug(message) - Gem.debug message -end - -def time(msg, width=25, &block) - Gem.time(msg, width, &block) -end -# :startdoc: - diff --git a/lib/rubygems/uninstaller.rb b/lib/rubygems/uninstaller.rb index 4bb777a2a2..1dea232634 100644 --- a/lib/rubygems/uninstaller.rb +++ b/lib/rubygems/uninstaller.rb @@ -202,7 +202,7 @@ class Gem::Uninstaller spec.name, spec.version, spec.original_platform].join '-' spec_dir = File.join spec.installation_path, 'specifications' - gemspec = File.join spec_dir, "#{spec.full_name}.gemspec" + gemspec = File.join spec_dir, spec.spec_name unless File.exist? gemspec then gemspec = File.join spec_dir, "#{original_platform_name}.gemspec" @@ -211,7 +211,7 @@ class Gem::Uninstaller FileUtils.rm_rf gemspec cache_dir = File.join spec.installation_path, 'cache' - gem = File.join cache_dir, "#{spec.full_name}.gem" + gem = File.join cache_dir, spec.file_name unless File.exist? gem then gem = File.join cache_dir, "#{original_platform_name}.gem" @@ -251,7 +251,7 @@ class Gem::Uninstaller spec.dependent_gems.each do |gem,dep,satlist| msg << ("#{gem.name}-#{gem.version} depends on " + - "[#{dep.name} (#{dep.version_requirements})]") + "[#{dep.name} (#{dep.requirement})]") end msg << 'If you remove this gems, one or more dependencies will not be met.' msg << 'Continue with Uninstall?' diff --git a/lib/rubygems/user_interaction.rb b/lib/rubygems/user_interaction.rb index 6a80c7c0bc..1ab948dcb6 100644 --- a/lib/rubygems/user_interaction.rb +++ b/lib/rubygems/user_interaction.rb @@ -112,6 +112,7 @@ module Gem::UserInteraction :alert_error, :alert_warning, :ask, + :ask_for_password, :ask_yes_no, :choose_from_list, :say, @@ -218,6 +219,50 @@ class Gem::StreamUI end ## + # Ask for a password. Does not echo response to terminal. + + def ask_for_password(question) + return nil if not @ins.tty? + + @outs.print(question + " ") + @outs.flush + + Gem.win_platform? ? ask_for_password_on_windows : ask_for_password_on_unix + end + + ## + # Asks for a password that works on windows. Ripped from the Heroku gem. + + def ask_for_password_on_windows + require "Win32API" + char = nil + password = '' + + while char = Win32API.new("crtdll", "_getch", [ ], "L").Call do + break if char == 10 || char == 13 # received carriage return or newline + if char == 127 || char == 8 # backspace and delete + password.slice!(-1, 1) + else + password << char.chr + end + end + + puts + password + end + + ## + # Asks for a password that works on unix + + def ask_for_password_on_unix + system "stty -echo" + password = @ins.gets + password.chomp! if password + system "stty echo" + password + end + + ## # Display a statement. def say(statement="") diff --git a/lib/rubygems/validator.rb b/lib/rubygems/validator.rb index c8384f1586..38ee62fd6d 100644 --- a/lib/rubygems/validator.rb +++ b/lib/rubygems/validator.rb @@ -93,9 +93,8 @@ class Gem::Validator next unless gems.include? gem_spec.name unless gems.empty? install_dir = gem_spec.installation_path - gem_path = File.join(install_dir, "cache", gem_spec.full_name) + ".gem" - spec_path = File.join(install_dir, "specifications", - gem_spec.full_name) + ".gemspec" + gem_path = File.join install_dir, "cache", gem_spec.file_name + spec_path = File.join install_dir, "specifications", gem_spec.spec_name gem_directory = gem_spec.full_gem_path unless File.directory? gem_directory then diff --git a/lib/rubygems/version.rb b/lib/rubygems/version.rb index f959429846..77403ff32b 100644 --- a/lib/rubygems/version.rb +++ b/lib/rubygems/version.rb @@ -1,9 +1,3 @@ -#-- -# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. -# All rights reserved. -# See LICENSE.txt for permissions. -#++ - ## # The Version class processes string versions into comparable # values. A version string should normally be a series of numbers @@ -24,72 +18,153 @@ # 2. 1.0.b # 3. 1.0.a # 4. 0.9 +# +# == How Software Changes +# +# Users expect to be able to specify a version constraint that gives them +# some reasonable expectation that new versions of a library will work with +# their software if the version constraint is true, and not work with their +# software if the version constraint is false. In other words, the perfect +# system will accept all compatible versions of the library and reject all +# incompatible versions. +# +# Libraries change in 3 ways (well, more than 3, but stay focused here!). +# +# 1. The change may be an implementation detail only and have no effect on +# the client software. +# 2. The change may add new features, but do so in a way that client software +# written to an earlier version is still compatible. +# 3. The change may change the public interface of the library in such a way +# that old software is no longer compatible. +# +# Some examples are appropriate at this point. Suppose I have a Stack class +# that supports a <tt>push</tt> and a <tt>pop</tt> method. +# +# === Examples of Category 1 changes: +# +# * Switch from an array based implementation to a linked-list based +# implementation. +# * Provide an automatic (and transparent) backing store for large stacks. +# +# === Examples of Category 2 changes might be: +# +# * Add a <tt>depth</tt> method to return the current depth of the stack. +# * Add a <tt>top</tt> method that returns the current top of stack (without +# changing the stack). +# * Change <tt>push</tt> so that it returns the item pushed (previously it +# had no usable return value). +# +# === Examples of Category 3 changes might be: +# +# * Changes <tt>pop</tt> so that it no longer returns a value (you must use +# <tt>top</tt> to get the top of the stack). +# * Rename the methods to <tt>push_item</tt> and <tt>pop_item</tt>. +# +# == RubyGems Rational Versioning +# +# * Versions shall be represented by three non-negative integers, separated +# by periods (e.g. 3.1.4). The first integers is the "major" version +# number, the second integer is the "minor" version number, and the third +# integer is the "build" number. +# +# * A category 1 change (implementation detail) will increment the build +# number. +# +# * A category 2 change (backwards compatible) will increment the minor +# version number and reset the build number. +# +# * A category 3 change (incompatible) will increment the major build number +# and reset the minor and build numbers. +# +# * Any "public" release of a gem should have a different version. Normally +# that means incrementing the build number. This means a developer can +# generate builds all day long for himself, but as soon as he/she makes a +# public release, the version must be updated. +# +# === Examples +# +# Let's work through a project lifecycle using our Stack example from above. +# +# Version 0.0.1:: The initial Stack class is release. +# Version 0.0.2:: Switched to a linked=list implementation because it is +# cooler. +# Version 0.1.0:: Added a <tt>depth</tt> method. +# Version 1.0.0:: Added <tt>top</tt> and made <tt>pop</tt> return nil +# (<tt>pop</tt> used to return the old top item). +# Version 1.1.0:: <tt>push</tt> now returns the value pushed (it used it +# return nil). +# Version 1.1.1:: Fixed a bug in the linked list implementation. +# Version 1.1.2:: Fixed a bug introduced in the last fix. +# +# Client A needs a stack with basic push/pop capability. He writes to the +# original interface (no <tt>top</tt>), so his version constraint looks +# like: +# +# gem 'stack', '~> 0.0' +# +# Essentially, any version is OK with Client A. An incompatible change to +# the library will cause him grief, but he is willing to take the chance (we +# call Client A optimistic). +# +# Client B is just like Client A except for two things: (1) He uses the +# <tt>depth</tt> method and (2) he is worried about future +# incompatibilities, so he writes his version constraint like this: +# +# gem 'stack', '~> 0.1' +# +# The <tt>depth</tt> method was introduced in version 0.1.0, so that version +# or anything later is fine, as long as the version stays below version 1.0 +# where incompatibilities are introduced. We call Client B pessimistic +# because he is worried about incompatible future changes (it is OK to be +# pessimistic!). +# +# == Preventing Version Catastrophe: +# +# From: http://blog.zenspider.com/2008/10/rubygems-howto-preventing-cata.html +# +# Let's say you're depending on the fnord gem version 2.y.z. If you +# specify your dependency as ">= 2.0.0" then, you're good, right? What +# happens if fnord 3.0 comes out and it isn't backwards compatible +# with 2.y.z? Your stuff will break as a result of using ">=". The +# better route is to specify your dependency with a "spermy" version +# specifier. They're a tad confusing, so here is how the dependency +# specifiers work: +# +# Specification From ... To (exclusive) +# ">= 3.0" 3.0 ... ∞ +# "~> 3.0" 3.0 ... 4.0 +# "~> 3.0.0" 3.0.0 ... 3.1 +# "~> 3.5" 3.5 ... 4.0 +# "~> 3.5.0" 3.5.0 ... 3.6 class Gem::Version - - class Part - include Comparable - - attr_reader :value - - def initialize(value) - @value = (value =~ /\A\d+\z/) ? value.to_i : value - end - - def to_s - self.value.to_s - end - - def inspect - @value - end - - def alpha? - String === value - end - - def numeric? - Fixnum === value - end - - def <=>(other) - if self.numeric? && other.alpha? then - 1 - elsif self.alpha? && other.numeric? then - -1 - else - self.value <=> other.value - end - end - - def succ - self.class.new(self.value.succ) - end - end - include Comparable - VERSION_PATTERN = '[0-9]+(\.[0-9a-z]+)*' + VERSION_PATTERN = '[0-9]+(\.[0-9a-zA-Z]+)*' # :nodoc: + ANCHORED_VERSION_PATTERN = /\A\s*(#{VERSION_PATTERN})*\s*\z/ # :nodoc: + + ## + # A string representation of this Version. attr_reader :version + alias to_s version - def self.correct?(version) - pattern = /\A\s*(#{VERSION_PATTERN})*\s*\z/ + ## + # True if the +version+ string matches RubyGems' requirements. - version.is_a? Integer or - version =~ pattern or - version.to_s =~ pattern + def self.correct? version + version.to_s =~ ANCHORED_VERSION_PATTERN end ## - # Factory method to create a Version object. Input may be a Version or a - # String. Intended to simplify client code. + # Factory method to create a Version object. Input may be a Version + # or a String. Intended to simplify client code. # # ver1 = Version.create('1.3.17') # -> (Version object) # ver2 = Version.create(ver1) # -> (ver1) # ver3 = Version.create(nil) # -> nil - def self.create(input) + def self.create input if input.respond_to? :version then input elsif input.nil? then @@ -103,149 +178,129 @@ class Gem::Version # Constructs a Version from the +version+ string. A version string is a # series of digits or ASCII letters separated by dots. - def initialize(version) + def initialize version raise ArgumentError, "Malformed version number string #{version}" unless self.class.correct?(version) - self.version = version - end + @version = version.to_s + @version.strip! - def inspect # :nodoc: - "#<#{self.class} #{@version.inspect}>" + segments # prime @segments end ## - # Dump only the raw version string, not the complete object + # Return a new version object where the next to the last revision + # number is one greater (e.g., 5.3.1 => 5.4). + # + # Pre-release (alpha) parts, e.g, 5.3.1.b2 => 5.4, are ignored. - def marshal_dump - [@version] + def bump + segments = self.segments.dup + segments.pop while segments.any? { |s| String === s } + segments.pop if segments.size > 1 + + segments[-1] = segments[-1].succ + self.class.new segments.join(".") end ## - # Load custom marshal format + # A Version is only eql? to another version if it's specified to the + # same precision. Version "1.0" is not the same as version "1". - def marshal_load(array) - self.version = array[0] + def eql? other + self.class === other and segments == other.segments end - def parts - @parts ||= normalize + def hash # :nodoc: + segments.hash end - ## - # Strip ignored trailing zeros. - - def normalize - parts_arr = parse_parts_from_version_string - if parts_arr.length != 1 - parts_arr.pop while parts_arr.last && parts_arr.last.value == 0 - parts_arr = [Part.new(0)] if parts_arr.empty? - end - parts_arr + def inspect # :nodoc: + "#<#{self.class} #{version.inspect}>" end ## - # Returns the text representation of the version + # Dump only the raw version string, not the complete object. It's a + # string for backwards (RubyGems 1.3.5 and earlier) compatibility. - def to_s - @version + def marshal_dump + [version] end - def to_yaml_properties - ['@version'] - end + ## + # Load custom marshal format. It's a string for backwards (RubyGems + # 1.3.5 and earlier) compatibility. - def version=(version) - @version = version.to_s.strip - normalize + def marshal_load array + initialize array[0] end - ## - # A version is considered a prerelease if any part contains a letter. + # A version is considered a prerelease if it contains a letter. def prerelease? - parts.any? { |part| part.alpha? } - end - - ## - # The release for this version (e.g. 1.2.0.a -> 1.2.0) - # Non-prerelease versions return themselves - def release - return self unless prerelease? - rel_parts = parts.dup - rel_parts.pop while rel_parts.any? { |part| part.alpha? } - self.class.new(rel_parts.join('.')) + @prerelease ||= segments.any? { |s| String === s } end - def yaml_initialize(tag, values) - self.version = values['version'] + def pretty_print q # :nodoc: + q.text "Gem::Version.new(#{version.inspect})" end - ## - # Compares this version with +other+ returning -1, 0, or 1 if the other - # version is larger, the same, or smaller than this one. + # The release for this version (e.g. 1.2.0.a -> 1.2.0). + # Non-prerelease versions return themselves. - def <=>(other) - return nil unless self.class === other - return 1 unless other - mine, theirs = balance(self.parts.dup, other.parts.dup) - mine <=> theirs - end + def release + return self unless prerelease? - def balance(a, b) - a << Part.new(0) while a.size < b.size - b << Part.new(0) while b.size < a.size - [a, b] + segments = self.segments.dup + segments.pop while segments.any? { |s| String === s } + self.class.new segments.join('.') end - ## - # A Version is only eql? to another version if it has the same version - # string. "1.0" is not the same version as "1". + def segments # :nodoc: - def eql?(other) - self.class === other and @version == other.version - end + # @segments is lazy so it can pick up @version values that come + # from old marshaled versions, which don't go through + # marshal_load. +segments+ is called in +initialize+ to "prime + # the pump" in normal cases. - def hash # :nodoc: - @version.hash + @segments ||= @version.scan(/[0-9a-z]+/i).map do |s| + /^\d+$/ =~ s ? s.to_i : s + end end ## - # Return a new version object where the next to the last revision number is - # one greater. (e.g. 5.3.1 => 5.4) - # - # Pre-release (alpha) parts are ignored. (e.g 5.3.1.b2 => 5.4) + # A recommended version for use with a ~> Requirement. - def bump - parts = parse_parts_from_version_string - parts.pop while parts.any? { |part| part.alpha? } - parts.pop if parts.size > 1 - parts[-1] = parts[-1].succ - self.class.new(parts.join(".")) - end + def spermy_recommendation + segments = self.segments.dup - def parse_parts_from_version_string # :nodoc: - @version.to_s.scan(/[0-9a-z]+/i).map { |s| Part.new(s) } - end + segments.pop while segments.any? { |s| String === s } + segments.pop while segments.size > 2 + segments.push 0 while segments.size < 2 - def pretty_print(q) # :nodoc: - q.text "Gem::Version.new(#{@version.inspect})" + "~> #{segments.join(".")}" end - #:stopdoc: + ## + # Compares this version with +other+ returning -1, 0, or 1 if the other + # version is larger, the same, or smaller than this one. - require 'rubygems/requirement' + def <=> other + return 1 unless other # HACK: comparable with nil? why? + return nil unless self.class === other - ## - # Gem::Requirement's original definition is nested in Version. - # Although an inappropriate place, current gems specs reference the nested - # class name explicitly. To remain compatible with old software loading - # gemspecs, we leave a copy of original definition in Version, but define an - # alias Gem::Requirement for use everywhere else. + lhsize = segments.size + rhsize = other.segments.size + limit = (lhsize > rhsize ? lhsize : rhsize) - 1 - Requirement = ::Gem::Requirement + 0.upto(limit) do |i| + lhs, rhs = segments[i] || 0, other.segments[i] || 0 - # :startdoc: + return -1 if String === lhs && Numeric === rhs + return 1 if Numeric === lhs && String === rhs + return lhs <=> rhs if lhs != rhs + end + return 0 + end end - diff --git a/lib/rubygems/version_option.rb b/lib/rubygems/version_option.rb index a69b732f78..a3de4dc9e7 100644 --- a/lib/rubygems/version_option.rb +++ b/lib/rubygems/version_option.rb @@ -6,10 +6,14 @@ require 'rubygems' +## # Mixin methods for --version and --platform Gem::Command options. + module Gem::VersionOption + ## # Add the --platform option to the option parser. + def add_platform_option(task = command, *wrap) OptionParser.accept Gem::Platform do |value| if value == Gem::Platform::RUBY then @@ -31,7 +35,19 @@ module Gem::VersionOption end end + ## + # Add the --prerelease option to the option parser. + + def add_prerelease_option(*wrap) + add_option("--[no-]prerelease", + "Allow prerelease versions of a gem", *wrap) do |value, options| + options[:prerelease] = value + end + end + + ## # Add the --version option to the option parser. + def add_version_option(task = command, *wrap) OptionParser.accept Gem::Requirement do |value| Gem::Requirement.new value @@ -536,17 +536,8 @@ load_failed(VALUE fname) static VALUE load_ext(VALUE path) { - VALUE result; - SCOPE_SET(NOEX_PUBLIC); -#if defined DLN_NEEDS_ALT_SEPARATOR && DLN_NEEDS_ALT_SEPARATOR - translit_char(RSTRING_PTR(path), '/', '\\'); -#endif - result = (VALUE)dln_load(RSTRING_PTR(path)); -#if defined DLN_NEEDS_ALT_SEPARATOR && DLN_NEEDS_ALT_SEPARATOR - translit_char(RSTRING_PTR(path), '\\', '/'); -#endif - return result; + return (VALUE)dln_load(RSTRING_PTR(path)); } VALUE @@ -308,6 +308,10 @@ math_atanh(VALUE obj, VALUE x) Need_Float(x); errno = 0; d0 = RFLOAT_VALUE(x); + if (d0 == 1.0 || d0 == -1.0) { + errno = ERANGE; + rb_sys_fail("atanh"); + } d = atanh(d0); domain_check(d0, d, "atanh"); infinity_check(x, d, "atanh"); @@ -713,6 +717,9 @@ math_lgamma(VALUE obj, VALUE x) Need_Float(x); errno = 0; d0 = RFLOAT_VALUE(x); + if (isinf(d0)) { + return rb_assoc_new(DBL2NUM(INFINITY), INT2FIX(1)); + } d = lgamma_r(d0, &sign); domain_check(d0, d, "lgamma"); v = DBL2NUM(d); @@ -1618,6 +1618,7 @@ pack_unpack(VALUE str, VALUE fmt) } PACK_ITEM_ADJUST(); break; + case 'L': PACK_LENGTH_ADJUST(unsigned long,4); while (len-- > 0) { @@ -1638,6 +1639,7 @@ pack_unpack(VALUE str, VALUE fmt) } PACK_ITEM_ADJUST(); break; + case 'Q': PACK_LENGTH_ADJUST_SIZE(QUAD_SIZE); while (len-- > 0) { @@ -1645,6 +1647,7 @@ pack_unpack(VALUE str, VALUE fmt) s += QUAD_SIZE; UNPACK_PUSH(rb_quad_unpack(tmp, 0)); } + PACK_ITEM_ADJUST(); break; case 'n': @@ -3643,6 +3643,7 @@ setup_comb_exp_check(Node* node, int state, ScanEnv* env) #define IN_NOT (1<<1) #define IN_REPEAT (1<<2) #define IN_VAR_REPEAT (1<<3) +#define IN_LAST (1<<4) /* setup_tree does the following work. 1. check empty loop. (set qn->target_empty_info) @@ -3664,7 +3665,8 @@ setup_tree(Node* node, regex_t* reg, int state, ScanEnv* env) { Node* prev = NULL_NODE; do { - r = setup_tree(NCAR(node), reg, state, env); + int s = IS_NOT_NULL(NCDR(node)) ? (state & ~IN_LAST) : state; + r = setup_tree(NCAR(node), reg, s, env); if (IS_NOT_NULL(prev) && r == 0) { r = next_setup(prev, NCAR(node), reg); } @@ -3795,6 +3797,20 @@ setup_tree(Node* node, regex_t* reg, int state, ScanEnv* env) } } #endif + + if ((state & IN_LAST) != 0 && qn->greedy && IS_REPEAT_INFINITE(qn->upper)) { + /* automatic posseivation a* (at last) ==> (?>a*) */ + if (qn->lower <= 1) { + int ttype = NTYPE(qn->target); + if (IS_NODE_TYPE_SIMPLE(ttype)) { + Node* en = onig_node_new_enclose(ENCLOSE_STOP_BACKTRACK); + CHECK_NULL_RETURN_MEMERR(en); + SET_ENCLOSE_STATUS(en, NST_STOP_BT_SIMPLE_REPEAT); + swap_node(node, en); + NENCLOSE(node)->target = en; + } + } + } } break; @@ -5423,7 +5439,7 @@ onig_compile(regex_t* reg, const UChar* pattern, const UChar* pattern_end, reg->num_call = 0; #endif - r = setup_tree(root, reg, 0, &scan_env); + r = setup_tree(root, reg, IN_LAST, &scan_env); if (r != 0) goto err_unset; #ifdef ONIG_DEBUG_PARSE_TREE @@ -748,6 +748,14 @@ RUBY_ALIAS_FUNCTION(rb_str_new5(VALUE obj, const char *ptr, long len), rb_str_new_with_class, (obj, ptr, len)) #define rb_str_new5 rb_str_new_with_class +static VALUE +str_new_empty(VALUE str) +{ + VALUE v = rb_str_new5(str, 0, 0); + OBJ_INFECT(v, str); + return v; +} + #define STR_BUF_MIN_SIZE 128 VALUE @@ -5600,7 +5608,7 @@ rb_str_split_m(int argc, VALUE *argv, VALUE str) regs = RMATCH_REGS(rb_backref_get()); if (start == end && BEG(0) == END(0)) { if (!ptr) { - rb_ary_push(result, rb_str_new("", 0)); + rb_ary_push(result, str_new_empty(str)); break; } else if (last_null == 1) { @@ -5628,7 +5636,7 @@ rb_str_split_m(int argc, VALUE *argv, VALUE str) for (idx=1; idx < regs->num_regs; idx++) { if (BEG(idx) == -1) continue; if (BEG(idx) == END(idx)) - tmp = rb_str_new5(str, 0, 0); + tmp = str_new_empty(str); else tmp = rb_str_subseq(str, BEG(idx), END(idx)-BEG(idx)); rb_ary_push(result, tmp); @@ -5638,7 +5646,7 @@ rb_str_split_m(int argc, VALUE *argv, VALUE str) } if (RSTRING_LEN(str) > 0 && (!NIL_P(limit) || RSTRING_LEN(str) > beg || lim < 0)) { if (RSTRING_LEN(str) == beg) - tmp = rb_str_new5(str, 0, 0); + tmp = str_new_empty(str); else tmp = rb_str_subseq(str, beg, RSTRING_LEN(str)-beg); rb_ary_push(result, tmp); @@ -6826,7 +6834,7 @@ rb_str_partition(VALUE str, VALUE sep) } if (pos < 0) { failed: - return rb_ary_new3(3, str, rb_str_new(0,0),rb_str_new(0,0)); + return rb_ary_new3(3, str, str_new_empty(str), str_new_empty(str)); } if (regex) { sep = rb_str_subpat(str, sep, INT2FIX(0)); @@ -6876,7 +6884,7 @@ rb_str_rpartition(VALUE str, VALUE sep) pos = rb_str_rindex(str, sep, pos); } if (pos < 0) { - return rb_ary_new3(3, rb_str_new(0,0),rb_str_new(0,0), str); + return rb_ary_new3(3, str_new_empty(str), str_new_empty(str), str); } if (regex) { sep = rb_reg_nth_match(0, rb_backref_get()); diff --git a/symbian/setup b/symbian/setup index d39bf6e4e7..04d30858af 100644 --- a/symbian/setup +++ b/symbian/setup @@ -79,6 +79,7 @@ define config_h @echo>>$(1) #define HAVE_STRUCT_STAT_ST_MTIMESPEC 1 @echo>>$(1) #define HAVE_STRUCT_STAT_ST_CTIMESPEC 1 @echo>>$(1) #define HAVE_STRUCT_TIMESPEC 1 +@echo>>$(1) #define HAVE_STRUCT_TIMEZONE 1 @echo>>$(1) #define HAVE_RB_FD_INIT 1 @echo>>$(1) #define GETGROUPS_T gid_t @echo>>$(1) #define RETSIGTYPE void @@ -143,6 +144,7 @@ define config_h @echo>>$(1) #define HAVE_SETGID 1 @echo>>$(1) #define HAVE_SETENV 1 @echo>>$(1) #define HAVE_UNSETENV 1 +@echo>>$(1) #define VOID_UNSETENV 1 @echo>>$(1) #define HAVE_MKTIME 1 @echo>>$(1) #define HAVE_CLOCK_GETTIME 1 @echo>>$(1) #define HAVE_GETTIMEOFDAY 1 @@ -169,7 +171,8 @@ define config_h @echo>>$(1) #define DLEXT_MAXLEN 4 @echo>>$(1) #define DLEXT ".dll" @echo>>$(1) #define EXECUTABLE_EXTS ".exe",".com",".cmd",".bat" -@echo>>$(1) #define DLN_NEEDS_ALT_SEPARATOR 1 +@echo>>$(1) #define DLN_NEEDS_ALT_SEPARATOR '\\' +@echo>>$(1) #define RUBY_LIB_VERSION_STYLE 3 @echo>>$(1) #define RUBY_LIB_PREFIX "C:/Data/Ruby/lib" @echo>>$(1) #define RUBY_SITE_LIB "E:/Data/Ruby/lib" @echo>>$(1) #define RUBY_VENDOR_LIB "C:/Data/Ruby/lib" @@ -253,6 +256,7 @@ define ruby_mmp @echo>>$(1) SOURCE main.c @echo>>$(1) SOURCE marshal.c @echo>>$(1) SOURCE math.c +@echo>>$(1) SOURCE node.c @echo>>$(1) SOURCE numeric.c @echo>>$(1) SOURCE object.c @echo>>$(1) SOURCE pack.c diff --git a/test/openssl/test_hmac.rb b/test/openssl/test_hmac.rb index 2f8d6bba20..23a3ce4264 100644 --- a/test/openssl/test_hmac.rb +++ b/test/openssl/test_hmac.rb @@ -4,15 +4,13 @@ rescue LoadError end require "test/unit" -if defined?(OpenSSL) - class OpenSSL::TestHMAC < Test::Unit::TestCase def setup - @digest = OpenSSL::Digest::MD5.new + @digest = OpenSSL::Digest::MD5 @key = "KEY" @data = "DATA" - @h1 = OpenSSL::HMAC.new(@key, @digest) - @h2 = OpenSSL::HMAC.new(@key, @digest) + @h1 = OpenSSL::HMAC.new(@key, @digest.new) + @h2 = OpenSSL::HMAC.new(@key, "MD5") end def teardown @@ -20,8 +18,14 @@ class OpenSSL::TestHMAC < Test::Unit::TestCase def test_hmac @h1.update(@data) - assert_equal(OpenSSL::HMAC.digest(@digest, @key, @data), @h1.digest, "digest") - assert_equal(OpenSSL::HMAC.hexdigest(@digest, @key, @data), @h1.hexdigest, "hexdigest") + @h2.update(@data) + assert_equal(@h1.digest, @h2.digest) + + assert_equal(OpenSSL::HMAC.digest(@digest.new, @key, @data), @h1.digest, "digest") + assert_equal(OpenSSL::HMAC.hexdigest(@digest.new, @key, @data), @h1.hexdigest, "hexdigest") + + assert_equal(OpenSSL::HMAC.digest("MD5", @key, @data), @h2.digest, "digest") + assert_equal(OpenSSL::HMAC.hexdigest("MD5", @key, @data), @h2.hexdigest, "hexdigest") end def test_dup @@ -29,6 +33,4 @@ class OpenSSL::TestHMAC < Test::Unit::TestCase h = @h1.dup assert_equal(@h1.digest, h.digest, "dup digest") end -end - -end +end if defined?(OpenSSL) diff --git a/test/ruby/test_beginendblock.rb b/test/ruby/test_beginendblock.rb index caed180613..2ddcddd43b 100644 --- a/test/ruby/test_beginendblock.rb +++ b/test/ruby/test_beginendblock.rb @@ -1,5 +1,6 @@ require 'test/unit' require 'tempfile' +require 'timeout' require_relative 'envutil' class TestBeginEndBlock < Test::Unit::TestCase @@ -96,8 +97,10 @@ EOW out = IO.popen( [ruby, '-e', 'STDERR.reopen(STDOUT)', - '-e', 'at_exit{Process.kill(:INT, $$); loop{}}']) {|f| - f.read + '-e', 'at_exit{Process.kill(:INT, $$); sleep 5 }']) {|f| + timeout(10) { + f.read + } } assert_match(/Interrupt$/, out) Process.kill(0, 0) rescue return # check if signal works diff --git a/test/ruby/test_io.rb b/test/ruby/test_io.rb index 0052a9263c..5fc3b133dd 100644 --- a/test/ruby/test_io.rb +++ b/test/ruby/test_io.rb @@ -823,15 +823,15 @@ class TestIO < Test::Unit::TestCase end) end - def test_readpartial_error + def test_readpartial_lock with_pipe do |r, w| s = "" t = Thread.new { r.readpartial(5, s) } 0 until s.size == 5 - s.clear + assert_raise(RuntimeError) { s.clear } w.write "foobarbaz" w.close - assert_raise(RuntimeError) { t.join } + assert_equal("fooba", t.value) end end @@ -858,15 +858,15 @@ class TestIO < Test::Unit::TestCase end) end - def test_read_error + def test_read_lock with_pipe do |r, w| s = "" t = Thread.new { r.read(5, s) } 0 until s.size == 5 - s.clear + assert_raise(RuntimeError) { s.clear } w.write "foobarbaz" w.close - assert_raise(RuntimeError) { t.join } + assert_equal("fooba", t.value) end end @@ -1312,6 +1312,19 @@ class TestIO < Test::Unit::TestCase end end + def test_reopen_inherit + mkcdtmpdir { + system(EnvUtil.rubybin, '-e', <<"End") + f = open("out", "w") + STDOUT.reopen(f) + STDERR.reopen(f) + system(#{EnvUtil.rubybin.dump}, '-e', 'STDOUT.print "out"') + system(#{EnvUtil.rubybin.dump}, '-e', 'STDERR.print "err"') +End + assert_equal("outerr", File.read("out")) + } + end + def test_foreach a = [] IO.foreach("|" + EnvUtil.rubybin + " -e 'puts :foo; puts :bar; puts :baz'") {|x| a << x } diff --git a/test/ruby/test_pack.rb b/test/ruby/test_pack.rb index 6101a30219..7cc3f0089e 100644 --- a/test/ruby/test_pack.rb +++ b/test/ruby/test_pack.rb @@ -491,4 +491,11 @@ class TestPack < Test::Unit::TestCase def test_length_too_big assert_raise(RangeError) { [].pack("C100000000000000000000") } end + + def test_short_string + %w[n N v V s S l L q Q].each {|fmt| + str = [1].pack(fmt) + assert_equal([1,nil], str.unpack("#{fmt}2")) + } + end end diff --git a/test/ruby/test_regexp.rb b/test/ruby/test_regexp.rb index 4cd35d5248..06c6d1c633 100644 --- a/test/ruby/test_regexp.rb +++ b/test/ruby/test_regexp.rb @@ -800,4 +800,11 @@ class TestRegexp < Test::Unit::TestCase assert_nothing_raised { eval("a = 1; /\#{ a }/; a") } assert_nothing_raised { eval("a = 1; /\#{ a }/o; a") } end + + def test_optimize_last_anycharstar + s = "1" + " " * 5000000 + assert_nothing_raised { s.match(/(\d) (.*)/) } + assert_equal("1", $1) + assert_equal(" " * 4999999, $2) + end end diff --git a/test/ruby/test_thread.rb b/test/ruby/test_thread.rb index 6707fc4a29..3c10cce3c3 100644 --- a/test/ruby/test_thread.rb +++ b/test/ruby/test_thread.rb @@ -232,8 +232,8 @@ class TestThread < Test::Unit::TestCase Thread.pass t2 = Thread.new { loop { } } t3 = Thread.new { }.join - p [Thread.current, t1, t2].sort_by {|t| t.object_id } - p Thread.list.sort_by {|t| t.object_id } + p [Thread.current, t1, t2].map{|t| t.object_id }.sort + p Thread.list.map{|t| t.object_id }.sort INPUT assert_equal(r.first, r.last) assert_equal([], e) diff --git a/test/rubygems/fake_certlib/openssl.rb b/test/rubygems/fake_certlib/openssl.rb index 948110f078..9de90c0a10 100644 --- a/test/rubygems/fake_certlib/openssl.rb +++ b/test/rubygems/fake_certlib/openssl.rb @@ -4,4 +4,4 @@ # See LICENSE.txt for permissions. #++ -fail LoadError, "no such file to load -- openssl" +raise LoadError, "no such file to load -- openssl" diff --git a/test/rubygems/functional.rb b/test/rubygems/functional.rb index 98e7cf6661..62f8c64d2d 100644 --- a/test/rubygems/functional.rb +++ b/test/rubygems/functional.rb @@ -1,10 +1,3 @@ -#!/usr/bin/env ruby -#-- -# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. -# All rights reserved. -# See LICENSE.txt for permissions. -#++ - require 'rubygems' require 'minitest/unit' require 'test/insure_session' diff --git a/test/rubygems/gem_installer_test_case.rb b/test/rubygems/gem_installer_test_case.rb index eeb328e7c4..ac353fbc43 100644 --- a/test/rubygems/gem_installer_test_case.rb +++ b/test/rubygems/gem_installer_test_case.rb @@ -20,12 +20,12 @@ class GemInstallerTestCase < RubyGemTestCase super @spec = quick_gem 'a' - @gem = File.join @tempdir, "#{@spec.full_name}.gem" + @gem = File.join @tempdir, @spec.file_name @installer = util_installer @spec, @gem, @gemhome @user_spec = quick_gem 'b' - @user_gem = File.join @tempdir, "#{@user_spec.full_name}.gem" + @user_gem = File.join @tempdir, @user_spec.file_name @user_installer = util_installer @user_spec, @user_gem, Gem.user_dir @user_installer.gem_dir = File.join(Gem.user_dir, 'gems', @@ -82,7 +82,7 @@ class GemInstallerTestCase < RubyGemTestCase def util_installer(spec, gem_path, gem_home) util_build_gem spec - FileUtils.mv File.join(@gemhome, 'cache', "#{spec.full_name}.gem"), + FileUtils.mv File.join(@gemhome, 'cache', spec.file_name), @tempdir installer = Gem::Installer.new gem_path diff --git a/test/rubygems/gemutilities.rb b/test/rubygems/gemutilities.rb index 43334f51e1..6a806a2367 100644 --- a/test/rubygems/gemutilities.rb +++ b/test/rubygems/gemutilities.rb @@ -1,9 +1,3 @@ -#-- -# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. -# All rights reserved. -# See LICENSE.txt for permissions. -#++ - at_exit { $SAFE = 1 } $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib')) @@ -82,6 +76,8 @@ class RubyGemTestCase < MiniTest::Unit::TestCase @orig_ruby = ruby end + Gem.ensure_gem_subdirectories @gemhome + @orig_ENV_HOME = ENV['HOME'] ENV['HOME'] = @userhome Gem.instance_variable_set :@user_home, nil @@ -159,7 +155,7 @@ class RubyGemTestCase < MiniTest::Unit::TestCase Gem.clear_paths if ruby = @orig_ruby - Gem.class_eval {@ruby = @ruby} + Gem.class_eval {@ruby = ruby} end if @orig_ENV_HOME then @@ -178,7 +174,7 @@ class RubyGemTestCase < MiniTest::Unit::TestCase end end - gem = File.join(@tempdir, "#{gem.full_name}.gem").untaint + gem = File.join(@tempdir, gem.file_name).untaint Gem::Installer.new(gem, :wrappers => true).install end @@ -256,7 +252,7 @@ class RubyGemTestCase < MiniTest::Unit::TestCase yield(s) if block_given? end - path = File.join "specifications", "#{spec.full_name}.gemspec" + path = File.join "specifications", spec.spec_name written_path = write_file path do |io| io.write(spec.to_ruby) end @@ -283,7 +279,7 @@ class RubyGemTestCase < MiniTest::Unit::TestCase Gem::Builder.new(spec).build end - FileUtils.mv "#{spec.full_name}.gem", + FileUtils.mv spec.file_name, File.join(@gemhome, 'cache', "#{spec.original_name}.gem") end end @@ -302,8 +298,7 @@ class RubyGemTestCase < MiniTest::Unit::TestCase cache_file = File.join @tempdir, 'gems', "#{spec.original_name}.gem" FileUtils.mv File.join(@gemhome, 'cache', "#{spec.original_name}.gem"), cache_file - FileUtils.rm File.join(@gemhome, 'specifications', - "#{spec.full_name}.gemspec") + FileUtils.rm File.join(@gemhome, 'specifications', spec.spec_name) spec.loaded_from = nil spec.loaded = false @@ -417,26 +412,6 @@ Also, a list: Gem::RemoteFetcher.fetcher = @fetcher end - def util_setup_source_info_cache(*specs) - require 'rubygems/source_info_cache' - require 'rubygems/source_info_cache_entry' - - specs = Hash[*specs.map { |spec| [spec.full_name, spec] }.flatten] - si = Gem::SourceIndex.new specs - - sice = Gem::SourceInfoCacheEntry.new si, 0 - sic = Gem::SourceInfoCache.new - - sic.set_cache_data( { @gem_repo => sice } ) - sic.update - sic.write_cache - sic.reset_cache_data - - Gem::SourceInfoCache.instance_variable_set :@cache, sic - - si - end - def util_setup_spec_fetcher(*specs) specs = Hash[*specs.map { |spec| [spec.full_name, spec] }.flatten] si = Gem::SourceIndex.new specs @@ -583,6 +558,35 @@ Also, a list: 'rake' end + ## + # Construct a new Gem::Dependency. + + def dep name, *requirements + Gem::Dependency.new name, *requirements + end + + ## + # Construct a new Gem::Requirement. + + def req *requirements + return requirements.first if Gem::Requirement === requirements.first + Gem::Requirement.create requirements + end + + ## + # Construct a new Gem::Specification. + + def spec name, version, &block + Gem::Specification.new name, v(version), &block + end + + ## + # Construct a new Gem::Version. + + def v string + Gem::Version.create string + end + end MiniTest::Unit.autorun diff --git a/test/rubygems/insure_session.rb b/test/rubygems/insure_session.rb index 4ae706494a..8a6df89246 100644 --- a/test/rubygems/insure_session.rb +++ b/test/rubygems/insure_session.rb @@ -1,11 +1,3 @@ -#!/usr/bin/env ruby -#-- -# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. -# All rights reserved. -# See LICENSE.txt for permissions. -#++ - - require 'rubygems' def install_session diff --git a/test/rubygems/mockgemui.rb b/test/rubygems/mockgemui.rb index d5624960df..30a4e6f25a 100644 --- a/test/rubygems/mockgemui.rb +++ b/test/rubygems/mockgemui.rb @@ -1,11 +1,3 @@ -#!/usr/bin/env ruby -#-- -# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. -# All rights reserved. -# See LICENSE.txt for permissions. -#++ - - require 'stringio' require 'rubygems/user_interaction' diff --git a/test/rubygems/simple_gem.rb b/test/rubygems/simple_gem.rb index 4667a08749..e9207f95cc 100644 --- a/test/rubygems/simple_gem.rb +++ b/test/rubygems/simple_gem.rb @@ -1,10 +1,4 @@ -#-- -# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. -# All rights reserved. -# See LICENSE.txt for permissions. -#++ - - SIMPLE_GEM = <<-GEMDATA +SIMPLE_GEM = <<-GEMDATA MD5SUM = "b12a4d48febeb2289c539c2574c4b6f8" if $0 == __FILE__ require 'optparse' @@ -69,4 +63,4 @@ g1CKTjX9BGAj1w== eJwDAAAAAAE= --- eJwrKC0pVlAvzy9XyE3MU+cCACwiBP4= - GEMDATA +GEMDATA diff --git a/test/rubygems/test_config.rb b/test/rubygems/test_config.rb index 306562f585..3458a1a682 100644 --- a/test/rubygems/test_config.rb +++ b/test/rubygems/test_config.rb @@ -1,11 +1,4 @@ -#-- -# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. -# All rights reserved. -# See LICENSE.txt for permissions. -#++ - require_relative 'gemutilities' -require 'rbconfig' require 'rubygems' class TestConfig < RubyGemTestCase diff --git a/test/rubygems/test_gem.rb b/test/rubygems/test_gem.rb index e6d3f896b4..72074916b2 100644 --- a/test/rubygems/test_gem.rb +++ b/test/rubygems/test_gem.rb @@ -181,7 +181,7 @@ class TestGem < RubyGemTestCase end def test_self_default_sources - assert_equal %w[http://gems.rubyforge.org/], Gem.default_sources + assert_equal %w[http://rubygems.org/], Gem.default_sources end def test_self_dir @@ -441,13 +441,13 @@ class TestGem < RubyGemTestCase def test_self_refresh util_make_gems - a1_spec = File.join @gemhome, "specifications", "#{@a1.full_name}.gemspec" + a1_spec = File.join @gemhome, "specifications", @a1.spec_name FileUtils.mv a1_spec, @tempdir refute Gem.source_index.gems.include?(@a1.full_name) - FileUtils.mv File.join(@tempdir, "#{@a1.full_name}.gemspec"), a1_spec + FileUtils.mv File.join(@tempdir, @a1.spec_name), a1_spec Gem.refresh diff --git a/test/rubygems/test_gem_builder.rb b/test/rubygems/test_gem_builder.rb index 23895c45fa..e5493ffc13 100644 --- a/test/rubygems/test_gem_builder.rb +++ b/test/rubygems/test_gem_builder.rb @@ -1,9 +1,3 @@ -#-- -# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. -# All rights reserved. -# See LICENSE.txt for permissions. -#++ - require_relative 'gemutilities' require 'rubygems/builder' diff --git a/test/rubygems/test_gem_command.rb b/test/rubygems/test_gem_command.rb index 2fb1bb1ca5..7897979d8f 100644 --- a/test/rubygems/test_gem_command.rb +++ b/test/rubygems/test_gem_command.rb @@ -1,10 +1,3 @@ -#!/usr/bin/env ruby -#-- -# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. -# All rights reserved. -# See LICENSE.txt for permissions. -#++ - require_relative 'gemutilities' require 'rubygems/command' diff --git a/test/rubygems/test_gem_command_manager.rb b/test/rubygems/test_gem_command_manager.rb index 6cba52d3e2..143ea692bc 100644 --- a/test/rubygems/test_gem_command_manager.rb +++ b/test/rubygems/test_gem_command_manager.rb @@ -1,9 +1,3 @@ -#-- -# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. -# All rights reserved. -# See LICENSE.txt for permissions. -#++ - require_relative 'gemutilities' require 'rubygems/command_manager' diff --git a/test/rubygems/test_gem_commands_build_command.rb b/test/rubygems/test_gem_commands_build_command.rb index 32e66465d8..db29226b71 100644 --- a/test/rubygems/test_gem_commands_build_command.rb +++ b/test/rubygems/test_gem_commands_build_command.rb @@ -15,7 +15,7 @@ class TestGemCommandsBuildCommand < RubyGemTestCase end def test_execute - gemspec_file = File.join(@tempdir, "#{@gem.full_name}.gemspec") + gemspec_file = File.join(@tempdir, @gem.spec_name) File.open gemspec_file, 'w' do |gs| gs.write @gem.to_ruby @@ -25,7 +25,7 @@ class TestGemCommandsBuildCommand < RubyGemTestCase end def test_execute_yaml - gemspec_file = File.join(@tempdir, "#{@gem.full_name}.gemspec") + gemspec_file = File.join(@tempdir, @gem.spec_name) File.open gemspec_file, 'w' do |gs| gs.write @gem.to_yaml @@ -61,7 +61,7 @@ class TestGemCommandsBuildCommand < RubyGemTestCase assert_equal [], output assert_equal '', @ui.error - gem_file = File.join @tempdir, "#{gem.full_name}.gem" + gem_file = File.join @tempdir, gem.file_name assert File.exist?(gem_file) spec = Gem::Format.from_file_by_path(gem_file).spec diff --git a/test/rubygems/test_gem_commands_check_command.rb b/test/rubygems/test_gem_commands_check_command.rb index 43ac982341..83065cf218 100644 --- a/test/rubygems/test_gem_commands_check_command.rb +++ b/test/rubygems/test_gem_commands_check_command.rb @@ -1,9 +1,3 @@ -#-- -# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. -# All rights reserved. -# See LICENSE.txt for permissions. -#++ - require_relative 'gemutilities' require 'rubygems/commands/check_command' diff --git a/test/rubygems/test_gem_commands_dependency_command.rb b/test/rubygems/test_gem_commands_dependency_command.rb index 66e9d86d52..8463017d50 100644 --- a/test/rubygems/test_gem_commands_dependency_command.rb +++ b/test/rubygems/test_gem_commands_dependency_command.rb @@ -9,12 +9,13 @@ class TestGemCommandsDependencyCommand < RubyGemTestCase @cmd = Gem::Commands::DependencyCommand.new @cmd.options[:domain] = :local - util_setup_fake_fetcher + util_setup_fake_fetcher true end def test_execute quick_gem 'foo' do |gem| gem.add_dependency 'bar', '> 1' + gem.add_dependency 'baz', '> 1' end Gem.source_index = nil @@ -25,7 +26,8 @@ class TestGemCommandsDependencyCommand < RubyGemTestCase @cmd.execute end - assert_equal "Gem foo-2\n bar (> 1, runtime)\n\n", @ui.output + assert_equal "Gem foo-2\n bar (> 1, runtime)\n baz (> 1, runtime)\n\n", + @ui.output assert_equal '', @ui.error end @@ -41,6 +43,8 @@ class TestGemCommandsDependencyCommand < RubyGemTestCase expected = <<-EOF Gem a-1 +Gem a-2.a + Gem a-2 Gem a-3.a @@ -100,6 +104,8 @@ Gem pl-1-x86-linux expected = <<-EOF Gem a-1 +Gem a-2.a + Gem a-2 Gem a-3.a @@ -173,8 +179,7 @@ ERROR: Only reverse dependencies for local gems are supported. util_setup_spec_fetcher foo - FileUtils.rm File.join(@gemhome, 'specifications', - "#{foo.full_name}.gemspec") + FileUtils.rm File.join(@gemhome, 'specifications', foo.spec_name) @cmd.options[:args] = %w[foo] @cmd.options[:domain] = :remote @@ -187,43 +192,24 @@ ERROR: Only reverse dependencies for local gems are supported. assert_equal '', @ui.error end - def test_execute_remote_legacy - foo = quick_gem 'foo' do |gem| - gem.add_dependency 'bar', '> 1' - end - + def test_execute_prerelease @fetcher = Gem::FakeFetcher.new Gem::RemoteFetcher.fetcher = @fetcher - Gem::SpecFetcher.fetcher = nil - si = util_setup_source_info_cache foo - - @fetcher.data["#{@gem_repo}yaml"] = YAML.dump si - @fetcher.data["#{@gem_repo}Marshal.#{Gem.marshal_version}"] = - si.dump - - @fetcher.data.delete "#{@gem_repo}latest_specs.#{Gem.marshal_version}.gz" + util_setup_spec_fetcher @a2_pre - FileUtils.rm File.join(@gemhome, 'specifications', - "#{foo.full_name}.gemspec") + FileUtils.rm File.join(@gemhome, 'specifications', @a2_pre.spec_name) - @cmd.options[:args] = %w[foo] + @cmd.options[:args] = %w[a] @cmd.options[:domain] = :remote + @cmd.options[:prerelease] = true use_ui @ui do @cmd.execute end - assert_equal "Gem foo-2\n bar (> 1, runtime)\n\n", @ui.output - - expected = <<-EOF -WARNING: RubyGems 1.2+ index not found for: -\t#{@gem_repo} - -RubyGems will revert to legacy indexes degrading performance. - EOF - - assert_equal expected, @ui.error + assert_equal "Gem a-2.a\n\n", @ui.output + assert_equal '', @ui.error end end diff --git a/test/rubygems/test_gem_commands_fetch_command.rb b/test/rubygems/test_gem_commands_fetch_command.rb index fe60680a67..07e38b4b99 100644 --- a/test/rubygems/test_gem_commands_fetch_command.rb +++ b/test/rubygems/test_gem_commands_fetch_command.rb @@ -15,8 +15,8 @@ class TestGemCommandsFetchCommand < RubyGemTestCase util_setup_fake_fetcher util_setup_spec_fetcher @a2 - @fetcher.data["#{@gem_repo}gems/#{@a2.full_name}.gem"] = - File.read(File.join(@gemhome, 'cache', "#{@a2.full_name}.gem")) + @fetcher.data["#{@gem_repo}gems/#{@a2.file_name}"] = + File.read(File.join(@gemhome, 'cache', @a2.file_name)) @cmd.options[:args] = [@a2.name] @@ -26,19 +26,21 @@ class TestGemCommandsFetchCommand < RubyGemTestCase end end - assert File.exist?(File.join(@tempdir, "#{@a2.full_name}.gem")), + assert File.exist?(File.join(@tempdir, @a2.file_name)), "#{@a2.full_name} fetched" end - def test_execute_legacy - util_setup_fake_fetcher - util_setup_source_info_cache @a2 + def test_execute_prerelease + util_setup_fake_fetcher true + util_setup_spec_fetcher @a2, @a2_pre - @fetcher.data["#{@gem_repo}yaml"] = '' - @fetcher.data["#{@gem_repo}gems/#{@a2.full_name}.gem"] = - File.read(File.join(@gemhome, 'cache', "#{@a2.full_name}.gem")) + @fetcher.data["#{@gem_repo}gems/#{@a2.file_name}"] = + File.read(File.join(@gemhome, 'cache', @a2.file_name)) + @fetcher.data["#{@gem_repo}gems/#{@a2_pre.file_name}"] = + File.read(File.join(@gemhome, 'cache', @a2_pre.file_name)) @cmd.options[:args] = [@a2.name] + @cmd.options[:prerelease] = true use_ui @ui do Dir.chdir @tempdir do @@ -46,8 +48,8 @@ class TestGemCommandsFetchCommand < RubyGemTestCase end end - assert File.exist?(File.join(@tempdir, "#{@a2.full_name}.gem")), - "#{@a2.full_name} fetched" + assert File.exist?(File.join(@tempdir, @a2_pre.file_name)), + "#{@a2_pre.full_name} not fetched" end end diff --git a/test/rubygems/test_gem_commands_install_command.rb b/test/rubygems/test_gem_commands_install_command.rb index d7bc20d6ae..0a3071b719 100644 --- a/test/rubygems/test_gem_commands_install_command.rb +++ b/test/rubygems/test_gem_commands_install_command.rb @@ -15,10 +15,10 @@ class TestGemCommandsInstallCommand < RubyGemTestCase util_setup_fake_fetcher(:prerelease) util_setup_spec_fetcher @a2, @a2_pre - @fetcher.data["#{@gem_repo}gems/#{@a2.full_name}.gem"] = - read_binary(File.join(@gemhome, 'cache', "#{@a2.full_name}.gem")) - @fetcher.data["#{@gem_repo}gems/#{@a2_pre.full_name}.gem"] = - read_binary(File.join(@gemhome, 'cache', "#{@a2_pre.full_name}.gem")) + @fetcher.data["#{@gem_repo}gems/#{@a2.file_name}"] = + read_binary(File.join(@gemhome, 'cache', @a2.file_name)) + @fetcher.data["#{@gem_repo}gems/#{@a2_pre.file_name}"] = + read_binary(File.join(@gemhome, 'cache', @a2_pre.file_name)) @cmd.options[:args] = [@a2.name] @@ -37,10 +37,10 @@ class TestGemCommandsInstallCommand < RubyGemTestCase util_setup_fake_fetcher(:prerelease) util_setup_spec_fetcher @a2, @a2_pre - @fetcher.data["#{@gem_repo}gems/#{@a2.full_name}.gem"] = - read_binary(File.join(@gemhome, 'cache', "#{@a2.full_name}.gem")) - @fetcher.data["#{@gem_repo}gems/#{@a2_pre.full_name}.gem"] = - read_binary(File.join(@gemhome, 'cache', "#{@a2_pre.full_name}.gem")) + @fetcher.data["#{@gem_repo}gems/#{@a2.file_name}"] = + read_binary(File.join(@gemhome, 'cache', @a2.file_name)) + @fetcher.data["#{@gem_repo}gems/#{@a2_pre.file_name}"] = + read_binary(File.join(@gemhome, 'cache', @a2_pre.file_name)) @cmd.handle_options [@a2_pre.name, '--version', @a2_pre.version.to_s] assert @cmd.options[:prerelease] @@ -79,7 +79,7 @@ class TestGemCommandsInstallCommand < RubyGemTestCase util_setup_fake_fetcher @cmd.options[:domain] = :local - FileUtils.mv File.join(@gemhome, 'cache', "#{@a2.full_name}.gem"), + FileUtils.mv File.join(@gemhome, 'cache', @a2.file_name), File.join(@tempdir) @cmd.options[:args] = [@a2.name] @@ -109,7 +109,7 @@ class TestGemCommandsInstallCommand < RubyGemTestCase util_setup_fake_fetcher @cmd.options[:user_install] = false - FileUtils.mv File.join(@gemhome, 'cache', "#{@a2.full_name}.gem"), + FileUtils.mv File.join(@gemhome, 'cache', @a2.file_name), File.join(@tempdir) @cmd.options[:args] = [@a2.name] @@ -178,10 +178,10 @@ class TestGemCommandsInstallCommand < RubyGemTestCase util_setup_fake_fetcher(:prerelease) util_setup_spec_fetcher @a2, @a2_pre - @fetcher.data["#{@gem_repo}gems/#{@a2.full_name}.gem"] = - read_binary(File.join(@gemhome, 'cache', "#{@a2.full_name}.gem")) - @fetcher.data["#{@gem_repo}gems/#{@a2_pre.full_name}.gem"] = - read_binary(File.join(@gemhome, 'cache', "#{@a2_pre.full_name}.gem")) + @fetcher.data["#{@gem_repo}gems/#{@a2.file_name}"] = + read_binary(File.join(@gemhome, 'cache', @a2.file_name)) + @fetcher.data["#{@gem_repo}gems/#{@a2_pre.file_name}"] = + read_binary(File.join(@gemhome, 'cache', @a2_pre.file_name)) @cmd.options[:prerelease] = true @cmd.options[:args] = [@a2_pre.name] @@ -204,8 +204,8 @@ class TestGemCommandsInstallCommand < RubyGemTestCase util_setup_fake_fetcher util_setup_spec_fetcher @a2 - @fetcher.data["#{@gem_repo}gems/#{@a2.full_name}.gem"] = - read_binary(File.join(@gemhome, 'cache', "#{@a2.full_name}.gem")) + @fetcher.data["#{@gem_repo}gems/#{@a2.file_name}"] = + read_binary(File.join(@gemhome, 'cache', @a2.file_name)) @cmd.options[:args] = [@a2.name] @@ -232,10 +232,10 @@ class TestGemCommandsInstallCommand < RubyGemTestCase util_setup_fake_fetcher @cmd.options[:domain] = :local - FileUtils.mv File.join(@gemhome, 'cache', "#{@a2.full_name}.gem"), + FileUtils.mv File.join(@gemhome, 'cache', @a2.file_name), File.join(@tempdir) - FileUtils.mv File.join(@gemhome, 'cache', "#{@b2.full_name}.gem"), + FileUtils.mv File.join(@gemhome, 'cache', @b2.file_name), File.join(@tempdir) @cmd.options[:args] = [@a2.name, @b2.name] diff --git a/test/rubygems/test_gem_commands_mirror_command.rb b/test/rubygems/test_gem_commands_mirror_command.rb index 167d36f8c6..0c790ac24e 100644 --- a/test/rubygems/test_gem_commands_mirror_command.rb +++ b/test/rubygems/test_gem_commands_mirror_command.rb @@ -46,10 +46,10 @@ class TestGemCommandsMirrorCommand < RubyGemTestCase @cmd.execute end - assert File.exist?(File.join(mirror, 'gems', "#{@a1.full_name}.gem")) - assert File.exist?(File.join(mirror, 'gems', "#{@a2.full_name}.gem")) - assert File.exist?(File.join(mirror, 'gems', "#{@b2.full_name}.gem")) - assert File.exist?(File.join(mirror, 'gems', "#{@c1_2.full_name}.gem")) + assert File.exist?(File.join(mirror, 'gems', @a1.file_name)) + assert File.exist?(File.join(mirror, 'gems', @a2.file_name)) + assert File.exist?(File.join(mirror, 'gems', @b2.file_name)) + assert File.exist?(File.join(mirror, 'gems', @c1_2.file_name)) assert File.exist?(File.join(mirror, "Marshal.#{@marshal_version}")) ensure orig_HOME.nil? ? ENV.delete('HOME') : ENV['HOME'] = orig_HOME diff --git a/test/rubygems/test_gem_commands_outdated_command.rb b/test/rubygems/test_gem_commands_outdated_command.rb index 8b0d8fe6f0..1abfe0f984 100644 --- a/test/rubygems/test_gem_commands_outdated_command.rb +++ b/test/rubygems/test_gem_commands_outdated_command.rb @@ -19,12 +19,10 @@ class TestGemCommandsOutdatedCommand < RubyGemTestCase remote_10 = quick_gem 'foo', '1.0' remote_20 = quick_gem 'foo', '2.0' - remote_spec_file = File.join @gemhome, 'specifications', - remote_10.full_name + ".gemspec" + remote_spec_file = File.join @gemhome, 'specifications', remote_10.spec_name FileUtils.rm remote_spec_file - remote_spec_file = File.join @gemhome, 'specifications', - remote_20.full_name + ".gemspec" + remote_spec_file = File.join @gemhome, 'specifications', remote_20.spec_name FileUtils.rm remote_spec_file @fetcher = Gem::FakeFetcher.new diff --git a/test/rubygems/test_gem_commands_owner_command.rb b/test/rubygems/test_gem_commands_owner_command.rb new file mode 100644 index 0000000000..fa4281c6a7 --- /dev/null +++ b/test/rubygems/test_gem_commands_owner_command.rb @@ -0,0 +1,105 @@ +require_relative 'gemutilities' +require 'rubygems/commands/owner_command' + +class TestGemCommandsOwnerCommand < RubyGemTestCase + + def setup + super + + @fetcher = Gem::FakeFetcher.new + Gem::RemoteFetcher.fetcher = @fetcher + Gem.configuration.rubygems_api_key = "ed244fbf2b1a52e012da8616c512fa47f9aa5250" + + @cmd = Gem::Commands::OwnerCommand.new + end + + def test_show_owners + response = <<EOF +--- +- email: user1@example.com +- email: user2@example.com +EOF + + @fetcher.data["https://rubygems.org/api/v1/gems/freewill/owners.yaml"] = [response, 200, 'OK'] + + use_ui @ui do + @cmd.show_owners("freewill") + end + + assert_equal Net::HTTP::Get, @fetcher.last_request.class + assert_equal Gem.configuration.rubygems_api_key, @fetcher.last_request["Authorization"] + + assert_match %r{Owners for gem: freewill}, @ui.output + assert_match %r{- user1@example.com}, @ui.output + assert_match %r{- user2@example.com}, @ui.output + end + + def test_show_owners_denied + response = "You don't have permission to push to this gem" + @fetcher.data["https://rubygems.org/api/v1/gems/freewill/owners.yaml"] = [response, 403, 'Forbidden'] + + assert_raises MockGemUi::TermError do + use_ui @ui do + @cmd.show_owners("freewill") + end + end + + assert_match response, @ui.output + end + + def test_add_owners + response = "Owner added successfully." + @fetcher.data["https://rubygems.org/api/v1/gems/freewill/owners"] = [response, 200, 'OK'] + + use_ui @ui do + @cmd.add_owners("freewill", ["user-new1@example.com"]) + end + + assert_equal Net::HTTP::Post, @fetcher.last_request.class + assert_equal Gem.configuration.rubygems_api_key, @fetcher.last_request["Authorization"] + assert_equal "email=user-new1%40example.com", @fetcher.last_request.body + + assert_match response, @ui.output + end + + def test_add_owners_denied + response = "You don't have permission to push to this gem" + @fetcher.data["https://rubygems.org/api/v1/gems/freewill/owners"] = [response, 403, 'Forbidden'] + + assert_raises MockGemUi::TermError do + use_ui @ui do + @cmd.add_owners("freewill", ["user-new1@example.com"]) + end + end + + assert_match response, @ui.output + end + + def test_remove_owners + response = "Owner removed successfully." + @fetcher.data["https://rubygems.org/api/v1/gems/freewill/owners"] = [response, 200, 'OK'] + + use_ui @ui do + @cmd.remove_owners("freewill", ["user-remove1@example.com"]) + end + + assert_equal Net::HTTP::Delete, @fetcher.last_request.class + assert_equal Gem.configuration.rubygems_api_key, @fetcher.last_request["Authorization"] + assert_equal "email=user-remove1%40example.com", @fetcher.last_request.body + + assert_match response, @ui.output + end + + def test_remove_owners_denied + response = "You don't have permission to push to this gem" + @fetcher.data["https://rubygems.org/api/v1/gems/freewill/owners"] = [response, 403, 'Forbidden'] + + assert_raises MockGemUi::TermError do + use_ui @ui do + @cmd.remove_owners("freewill", ["user-remove1@example.com"]) + end + end + + assert_match response, @ui.output + end +end diff --git a/test/rubygems/test_gem_commands_pristine_command.rb b/test/rubygems/test_gem_commands_pristine_command.rb index e5cdbbc52f..06f43aa2b6 100644 --- a/test/rubygems/test_gem_commands_pristine_command.rb +++ b/test/rubygems/test_gem_commands_pristine_command.rb @@ -75,7 +75,7 @@ class TestGemCommandsPristineCommand < RubyGemTestCase install_gem a - FileUtils.rm File.join(@gemhome, 'cache', "#{a.full_name}.gem") + FileUtils.rm File.join(@gemhome, 'cache', a.file_name) @cmd.options[:args] = %w[a] diff --git a/test/rubygems/test_gem_commands_push_command.rb b/test/rubygems/test_gem_commands_push_command.rb new file mode 100644 index 0000000000..d461bd8af6 --- /dev/null +++ b/test/rubygems/test_gem_commands_push_command.rb @@ -0,0 +1,61 @@ +require_relative 'gemutilities' +require 'rubygems/commands/push_command' + +class TestGemCommandsPushCommand < RubyGemTestCase + + def setup + super + + @gems_dir = File.join @tempdir, 'gems' + @cache_dir = File.join @gemhome, 'cache' + FileUtils.mkdir @gems_dir + Gem.configuration.rubygems_api_key = "ed244fbf2b1a52e012da8616c512fa47f9aa5250" + @spec, @path = util_gem("freewill", "1.0.0") + + @fetcher = Gem::FakeFetcher.new + Gem::RemoteFetcher.fetcher = @fetcher + + @cmd = Gem::Commands::PushCommand.new + end + + def test_sending_gem + response = "Successfully registered gem: freewill (1.0.0)" + @fetcher.data["https://rubygems.org/api/v1/gems"] = [response, 200, 'OK'] + + use_ui @ui do + @cmd.send_gem(@path) + end + + assert_match %r{Pushing gem to RubyGems.org...}, @ui.output + + assert_equal Net::HTTP::Post, @fetcher.last_request.class + assert_equal Gem.read_binary(@path), @fetcher.last_request.body + assert_equal File.size(@path), @fetcher.last_request["Content-Length"].to_i + assert_equal "application/octet-stream", @fetcher.last_request["Content-Type"] + assert_equal Gem.configuration.rubygems_api_key, @fetcher.last_request["Authorization"] + + assert_match response, @ui.output + end + + def test_raises_error_with_no_arguments + def @cmd.sign_in; end + assert_raises Gem::CommandLineError do + @cmd.execute + end + end + + def test_sending_gem_denied + response = "You don't have permission to push to this gem" + @fetcher.data["https://rubygems.org/api/v1/gems"] = [response, 403, 'Forbidden'] + + assert_raises MockGemUi::TermError do + use_ui @ui do + @cmd.send_gem(@path) + end + end + + assert_match response, @ui.output + end + +end + diff --git a/test/rubygems/test_gem_commands_query_command.rb b/test/rubygems/test_gem_commands_query_command.rb index c47e5bf613..b56b33b639 100644 --- a/test/rubygems/test_gem_commands_query_command.rb +++ b/test/rubygems/test_gem_commands_query_command.rb @@ -58,6 +58,28 @@ pl (1) assert_equal '', @ui.error end + def test_execute_all_prerelease + a1_name = @a1.full_name + a2_name = @a2.full_name + + @cmd.handle_options %w[-r --all --prerelease] + + use_ui @ui do + @cmd.execute + end + + expected = <<-EOF + +*** REMOTE GEMS *** + +a (3.a, 2, 1) +pl (1) + EOF + + assert_equal expected, @ui.output + assert_equal '', @ui.error + end + def test_execute_details @a2.summary = 'This is a lot of text. ' * 4 @a2.authors = ['Abraham Lincoln', 'Hirohito'] @@ -216,61 +238,6 @@ pl (1) assert_equal 1, e.exit_code end - def test_execute_legacy - Gem::SpecFetcher.fetcher = nil - si = util_setup_source_info_cache @a1, @a2, @pl1 - - @fetcher.data["#{@gem_repo}yaml"] = YAML.dump si - @fetcher.data["#{@gem_repo}Marshal.#{Gem.marshal_version}"] = - si.dump - - @fetcher.data.delete "#{@gem_repo}latest_specs.#{Gem.marshal_version}.gz" - - @cmd.handle_options %w[-r] - - use_ui @ui do - @cmd.execute - end - - expected = <<-EOF - -*** REMOTE GEMS *** - -a (2) -pl (1) - EOF - - assert_equal expected, @ui.output - - expected = <<-EOF -WARNING: RubyGems 1.2+ index not found for: -\t#{@gem_repo} - -RubyGems will revert to legacy indexes degrading performance. - EOF - - assert_equal expected, @ui.error - end - - def test_execute_legacy_prerelease - Gem::SpecFetcher.fetcher = nil - si = util_setup_source_info_cache @a1, @a2, @pl1 - - @fetcher.data["#{@gem_repo}yaml"] = YAML.dump si - @fetcher.data["#{@gem_repo}Marshal.#{Gem.marshal_version}"] = - si.dump - - @fetcher.data.delete "#{@gem_repo}latest_specs.#{Gem.marshal_version}.gz" - - @cmd.handle_options %w[-r --prerelease] - - e = assert_raises Gem::OperationNotSupportedError do - @cmd.execute - end - - assert_equal 'Prereleases not supported on legacy repositories', e.message - end - def test_execute_local_details @a3a.summary = 'This is a lot of text. ' * 4 @a3a.authors = ['Abraham Lincoln', 'Hirohito'] diff --git a/test/rubygems/test_gem_commands_sources_command.rb b/test/rubygems/test_gem_commands_sources_command.rb index 77df59b16d..34632ea5f1 100644 --- a/test/rubygems/test_gem_commands_sources_command.rb +++ b/test/rubygems/test_gem_commands_sources_command.rb @@ -115,48 +115,9 @@ beta-gems.example.com is not a URI assert_equal '', @ui.error end - def test_execute_add_legacy - util_setup_fake_fetcher - util_setup_source_info_cache - - si = Gem::SourceIndex.new - si.add_spec @a1 - - @fetcher.data["#{@new_repo}/yaml"] = '' - - @cmd.handle_options %W[--add #{@new_repo}] - - use_ui @ui do - @cmd.execute - end - - assert_equal [@gem_repo], Gem.sources - - expected = <<-EOF -WARNING: RubyGems 1.2+ index not found for: -\t#{@new_repo} - -Will cause RubyGems to revert to legacy indexes, degrading performance. - EOF - - assert_equal "#{@new_repo} added to sources\n", @ui.output - assert_equal expected, @ui.error - end - def test_execute_clear_all @cmd.handle_options %w[--clear-all] - util_setup_source_info_cache - - cache = Gem::SourceInfoCache.cache - cache.update - cache.write_cache - - assert File.exist?(cache.system_cache_file), - 'system cache file' - assert File.exist?(cache.latest_system_cache_file), - 'latest system cache file' - util_setup_spec_fetcher fetcher = Gem::SpecFetcher.fetcher @@ -179,11 +140,6 @@ Will cause RubyGems to revert to legacy indexes, degrading performance. assert_equal expected, @ui.output assert_equal '', @ui.error - refute File.exist?(cache.system_cache_file), - 'system cache file' - refute File.exist?(cache.latest_system_cache_file), - 'latest system cache file' - refute File.exist?(fetcher.dir), 'cache dir removed' end @@ -249,30 +205,5 @@ Will cause RubyGems to revert to legacy indexes, degrading performance. assert_equal '', @ui.error end - def test_execute_update_legacy - @cmd.handle_options %w[--update] - - util_setup_fake_fetcher - util_setup_source_info_cache - Gem::SourceInfoCache.reset - - si = Gem::SourceIndex.new - si.add_spec @a1 - @fetcher.data["#{@gem_repo}yaml"] = YAML.dump si - @fetcher.data["#{@gem_repo}Marshal.#{@marshal_version}"] = si.dump - - use_ui @ui do - @cmd.execute - end - - expected = <<-EOF -Bulk updating Gem source index for: #{@gem_repo} -source cache successfully updated - EOF - - assert_equal expected, @ui.output - assert_equal '', @ui.error - end - end diff --git a/test/rubygems/test_gem_commands_specification_command.rb b/test/rubygems/test_gem_commands_specification_command.rb index 49b82f986a..6a43439969 100644 --- a/test/rubygems/test_gem_commands_specification_command.rb +++ b/test/rubygems/test_gem_commands_specification_command.rb @@ -80,7 +80,7 @@ class TestGemCommandsSpecificationCommand < RubyGemTestCase @cmd.execute end - assert_equal "--- foo\n\n", @ui.output + assert_equal "foo", YAML.load(@ui.output) end def test_execute_marshal @@ -106,8 +106,7 @@ class TestGemCommandsSpecificationCommand < RubyGemTestCase util_setup_spec_fetcher foo - FileUtils.rm File.join(@gemhome, 'specifications', - "#{foo.full_name}.gemspec") + FileUtils.rm File.join(@gemhome, 'specifications', foo.spec_name) @cmd.options[:args] = %w[foo] @cmd.options[:domain] = :remote diff --git a/test/rubygems/test_gem_commands_uninstall_command.rb b/test/rubygems/test_gem_commands_uninstall_command.rb index 092a9072c0..cd440f63ee 100644 --- a/test/rubygems/test_gem_commands_uninstall_command.rb +++ b/test/rubygems/test_gem_commands_uninstall_command.rb @@ -59,7 +59,7 @@ class TestGemCommandsUninstallCommand < GemInstallerTestCase def test_execute_prerelease @spec = quick_gem "pre", "2.b" - @gem = File.join @tempdir, "#{@spec.full_name}.gem" + @gem = File.join @tempdir, @spec.file_name FileUtils.touch @gem util_setup_gem diff --git a/test/rubygems/test_gem_commands_update_command.rb b/test/rubygems/test_gem_commands_update_command.rb index 8949897736..5264cd3955 100644 --- a/test/rubygems/test_gem_commands_update_command.rb +++ b/test/rubygems/test_gem_commands_update_command.rb @@ -13,14 +13,14 @@ class TestGemCommandsUpdateCommand < RubyGemTestCase util_setup_fake_fetcher - @a1_path = File.join @gemhome, 'cache', "#{@a1.full_name}.gem" - @a2_path = File.join @gemhome, 'cache', "#{@a2.full_name}.gem" + @a1_path = File.join @gemhome, 'cache', @a1.file_name + @a2_path = File.join @gemhome, 'cache', @a2.file_name util_setup_spec_fetcher @a1, @a2 - @fetcher.data["#{@gem_repo}gems/#{@a1.full_name}.gem"] = + @fetcher.data["#{@gem_repo}gems/#{@a1.file_name}"] = read_binary @a1_path - @fetcher.data["#{@gem_repo}gems/#{@a2.full_name}.gem"] = + @fetcher.data["#{@gem_repo}gems/#{@a2.file_name}"] = read_binary @a2_path end @@ -65,9 +65,9 @@ class TestGemCommandsUpdateCommand < RubyGemTestCase @a2.add_dependency 'c', '2' @a2.add_dependency 'b', '2' - @b2_path = File.join @gemhome, 'cache', "#{@b2.full_name}.gem" - @c1_2_path = File.join @gemhome, 'cache', "#{@c1_2.full_name}.gem" - @c2_path = File.join @gemhome, 'cache', "#{@c2.full_name}.gem" + @b2_path = File.join @gemhome, 'cache', @b2.file_name + @c1_2_path = File.join @gemhome, 'cache', @c1_2.file_name + @c2_path = File.join @gemhome, 'cache', @c2.file_name @source_index = Gem::SourceIndex.new @source_index.add_spec @a1 @@ -80,12 +80,12 @@ class TestGemCommandsUpdateCommand < RubyGemTestCase util_build_gem @a2 util_build_gem @c2 - @fetcher.data["#{@gem_repo}gems/#{@a1.full_name}.gem"] = read_binary @a1_path - @fetcher.data["#{@gem_repo}gems/#{@a2.full_name}.gem"] = read_binary @a2_path - @fetcher.data["#{@gem_repo}gems/#{@b2.full_name}.gem"] = read_binary @b2_path - @fetcher.data["#{@gem_repo}gems/#{@c1_2.full_name}.gem"] = + @fetcher.data["#{@gem_repo}gems/#{@a1.file_name}"] = read_binary @a1_path + @fetcher.data["#{@gem_repo}gems/#{@a2.file_name}"] = read_binary @a2_path + @fetcher.data["#{@gem_repo}gems/#{@b2.file_name}"] = read_binary @b2_path + @fetcher.data["#{@gem_repo}gems/#{@c1_2.file_name}"] = read_binary @c1_2_path - @fetcher.data["#{@gem_repo}gems/#{@c2.full_name}.gem"] = read_binary @c2_path + @fetcher.data["#{@gem_repo}gems/#{@c2.file_name}"] = read_binary @c2_path util_setup_spec_fetcher @a1, @a2, @b2, @c1_2, @c2 util_clear_gems diff --git a/test/rubygems/test_gem_commands_which_command.rb b/test/rubygems/test_gem_commands_which_command.rb new file mode 100644 index 0000000000..137f598378 --- /dev/null +++ b/test/rubygems/test_gem_commands_which_command.rb @@ -0,0 +1,66 @@ +require_relative 'gemutilities' +require 'rubygems/commands/which_command' + +class TestGemCommandsWhichCommand < RubyGemTestCase + + def setup + super + @cmd = Gem::Commands::WhichCommand.new + end + + def test_execute + util_foo_bar + + @cmd.handle_options %w[foo_bar] + + use_ui @ui do + @cmd.execute + end + + assert_equal "#{@foo_bar.full_gem_path}/lib/foo_bar.rb\n", @ui.output + assert_equal '', @ui.error + end + + def test_execute_one_missing + util_foo_bar + + @cmd.handle_options %w[foo_bar missing] + + use_ui @ui do + @cmd.execute + end + + assert_equal "#{@foo_bar.full_gem_path}/lib/foo_bar.rb\n", @ui.output + assert_match %r%Can't find ruby library file or shared library missing\n%, + @ui.error + end + + def test_execute_missing + @cmd.handle_options %w[missing] + + use_ui @ui do + assert_raises MockGemUi::TermError do + @cmd.execute + end + end + + assert_equal '', @ui.output + assert_match %r%Can't find ruby library file or shared library missing\n%, + @ui.error + end + + def util_foo_bar + files = %w[lib/foo_bar.rb Rakefile] + @foo_bar = quick_gem 'foo_bar' do |gem| + gem.files = files + end + + files.each do |file| + filename = @foo_bar.full_gem_path + "/#{file}" + FileUtils.mkdir_p File.dirname(filename) + FileUtils.touch filename + end + end + +end + diff --git a/test/rubygems/test_gem_config_file.rb b/test/rubygems/test_gem_config_file.rb index 1dd0d448ff..4cd0790b92 100644 --- a/test/rubygems/test_gem_config_file.rb +++ b/test/rubygems/test_gem_config_file.rb @@ -1,9 +1,3 @@ -#-- -# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. -# All rights reserved. -# See LICENSE.txt for permissions. -#++ - require_relative 'gemutilities' require 'rubygems/config_file' @@ -271,6 +265,18 @@ class TestGemConfigFile < RubyGemTestCase assert_equal %w[http://even-more-gems.example.com], Gem.sources end + def test_load_rubygems_api_key_from_credentials + temp_cred = File.join Gem.user_home, '.gem', 'credentials' + FileUtils.mkdir File.dirname(temp_cred) + File.open temp_cred, 'w' do |fp| + fp.puts ":rubygems_api_key: 701229f217cdf23b1344c7b4b54ca97" + end + + util_config_file + + assert_equal "701229f217cdf23b1344c7b4b54ca97", @cfg.rubygems_api_key + end + def util_config_file(args = @cfg_args) @cfg = Gem::ConfigFile.new args end diff --git a/test/rubygems/test_gem_dependency.rb b/test/rubygems/test_gem_dependency.rb index acaa3a8c4e..1f361229a4 100644 --- a/test/rubygems/test_gem_dependency.rb +++ b/test/rubygems/test_gem_dependency.rb @@ -1,189 +1,137 @@ -#-- -# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. -# All rights reserved. -# See LICENSE.txt for permissions. -#++ - require_relative 'gemutilities' -require 'rubygems/version' +require 'rubygems/dependency' class TestGemDependency < RubyGemTestCase - def setup - super - - @pkg1_0 = Gem::Dependency.new 'pkg', ['> 1.0'] - @pkg1_1 = Gem::Dependency.new 'pkg', ['> 1.1'] - - @oth1_0 = Gem::Dependency.new 'other', ['> 1.0'] + def test_subclass + sc = Class.new Gem::Dependency + def sc.requirement() bogus; end - @r1_0 = Gem::Requirement.new ['> 1.0'] - end + out, err = capture_io do + assert_equal Gem::Requirement.default, sc.new('a').version_requirement + end - def dep(name, version) - Gem::Dependency.new name, version + assert_match %r%deprecated%, err end def test_initialize - assert_equal "pkg", @pkg1_0.name - assert_equal @r1_0, @pkg1_0.version_requirements + d = dep "pkg", "> 1.0" + + assert_equal "pkg", d.name + assert_equal req("> 1.0"), d.requirement end def test_initialize_double - dep = Gem::Dependency.new("pkg", ["> 1.0", "< 2.0"]) - - assert_equal Gem::Requirement.new(["> 1.0", "< 2.0"]), - dep.version_requirements + d = dep "pkg", "> 1.0", "< 2.0" + assert_equal req("> 1.0", "< 2.0"), d.requirement end def test_initialize_empty - dep = Gem::Dependency.new("pkg", []) - req = @r1_0 - - req.instance_eval do - @version = ">= 1.0" - @op = ">=" - @nums = [1,0] - @requirements = nil - end - - dep.instance_eval do - @version_requirement = req - @version_requirements = nil - end - - assert_equal Gem::Requirement.new([">= 1.0"]), dep.version_requirements - end - - def test_initialize_version - dep = Gem::Dependency.new 'pkg', Gem::Version.new('2') - - assert_equal 'pkg', dep.name - - assert_equal Gem::Requirement.new('= 2'), dep.version_requirements + d = dep "pkg" + assert_equal req(">= 0"), d.requirement end - def test_initialize_with_type - dep = Gem::Dependency.new("pkg", [], :development) - assert_equal(:development, dep.type) - end + def test_initialize_type + assert_equal :runtime, dep("pkg").type + assert_equal :development, dep("pkg", [], :development).type - def test_type_is_runtime_by_default - assert_equal(:runtime, Gem::Dependency.new("pkg", []).type) - end - - def test_type_is_restricted assert_raises ArgumentError do - Gem::Dependency.new("pkg", [:sometimes]) + dep "pkg", :sometimes end end + def test_initialize_version + d = dep "pkg", v("2") + assert_equal req("= 2"), d.requirement + end + def test_equals2 - assert_equal @pkg1_0, @pkg1_0.dup - assert_equal @pkg1_0.dup, @pkg1_0 + o = dep "other" + d = dep "pkg", "> 1.0" + d1 = dep "pkg", "> 1.1" + + assert_equal d, d.dup + assert_equal d.dup, d - refute_equal @pkg1_0, @pkg1_1, "requirements different" - refute_equal @pkg1_1, @pkg1_0, "requirements different" + refute_equal d, d1 + refute_equal d1, d - refute_equal @pkg1_0, @oth1_0, "names different" - refute_equal @oth1_0, @pkg1_0, "names different" + refute_equal d, o + refute_equal o, d - refute_equal @pkg1_0, Object.new - refute_equal Object.new, @pkg1_0 + refute_equal d, Object.new + refute_equal Object.new, d end def test_equals2_type - runtime = Gem::Dependency.new("pkg", []) - development = Gem::Dependency.new("pkg", [], :development) - - refute_equal(runtime, development) + refute_equal dep("pkg", :runtime), dep("pkg", :development) end def test_equals_tilde - a0 = dep 'a', '0' - a1 = dep 'a', '1' - b0 = dep 'b', '0' - - pa0 = dep 'a', '>= 0' - pa0r = dep(/a/, '>= 0') - pab0r = dep(/a|b/, '>= 0') - - assert_match a0, a0, 'match self' - assert_match pa0, a0, 'match version exact' - assert_match pa0, a1, 'match version' - assert_match pa0r, a0, 'match regex simple' - assert_match pab0r, a0, 'match regex complex' - - refute_match pa0r, b0, 'fail match regex' - refute_match pa0r, Object.new, 'fail match Object' - end + d = dep "a", "0" - def test_equals_tilde_escape - a1 = Gem::Dependency.new 'a', '1' + assert_match d, d, "matche self" + assert_match dep("a", ">= 0"), d, "match version exact" + assert_match dep("a", ">= 0"), dep("a", "1"), "match version" + assert_match dep(/a/, ">= 0"), d, "match simple regexp" + assert_match dep(/a|b/, ">= 0"), d, "match scary regexp" - pab1 = Gem::Dependency.new 'a|b', '>= 1' - pab1r = Gem::Dependency.new(/a|b/, '>= 1') + refute_match dep(/a/), dep("b") + refute_match dep("a"), Object.new + end - refute_match pab1, a1, 'escaped' - assert_match pab1r, a1, 'exact regexp' + def test_equals_tilde_escape + refute_match dep("a|b"), dep("a", "1") + assert_match dep(/a|b/), dep("a", "1") end def test_equals_tilde_object - a0 = Object.new - - def a0.name() 'a' end - def a0.version() '0' end - - pa0 = Gem::Dependency.new 'a', '>= 0' + o = Object.new + def o.name ; 'a' end + def o.version ; '0' end - assert_match pa0, a0, 'match version exact' + assert_match dep("a"), o end def test_equals_tilde_spec - def spec(name, version) - Gem::Specification.new do |spec| - spec.name = name - spec.version = version - end - end + assert_match dep("a", ">= 0"), spec("a", "0") + assert_match dep("a", "1"), spec("a", "1") + assert_match dep(/a/, ">= 0"), spec("a", "0") + assert_match dep(/a|b/, ">= 0"), spec("b", "0") + refute_match dep(/a/, ">= 0"), spec("b", "0") + end - a0 = spec 'a', '0' - a1 = spec 'a', '1' - b0 = spec 'b', '0' + def test_hash + d = dep "pkg", "1.0" - pa0 = dep 'a', '>= 0' - pa0r = dep(/a/, '>= 0') - pab0r = dep(/a|b/, '>= 0') + assert_equal d.hash, d.dup.hash + assert_equal d.dup.hash, d.hash - assert_match pa0, a0, 'match version exact' - assert_match pa0, a1, 'match version' + refute_equal dep("pkg", "1.0").hash, dep("pkg", "2.0").hash, "requirement" + refute_equal dep("pkg", "1.0").hash, dep("abc", "1.0").hash, "name" + refute_equal dep("pkg", :development), dep("pkg", :runtime), "type" + end - assert_match pa0r, a0, 'match regex simple' - assert_match pa0r, a1, 'match regex simple' + def test_prerelease_eh + d = dep "pkg", "= 1" - assert_match pab0r, a0, 'match regex complex' - assert_match pab0r, b0, 'match regex complex' + refute d.prerelease? - refute_match pa0r, b0, 'fail match regex' - refute_match pa0r, Object.new, 'fail match Object' - end + d.prerelease = true - def test_hash - assert_equal @pkg1_0.hash, @pkg1_0.dup.hash - assert_equal @pkg1_0.dup.hash, @pkg1_0.hash + assert d.prerelease? - refute_equal @pkg1_0.hash, @pkg1_1.hash, "requirements different" - refute_equal @pkg1_1.hash, @pkg1_0.hash, "requirements different" + d = dep "pkg", "= 1.a" - refute_equal @pkg1_0.hash, @oth1_0.hash, "names different" - refute_equal @oth1_0.hash, @pkg1_0.hash, "names different" - end + assert d.prerelease? + + d.prerelease = false + + assert d.prerelease? - def test_hash_type - runtime = Gem::Dependency.new("pkg", []) - development = Gem::Dependency.new("pkg", [], :development) + d = dep "pkg", "> 1.a", "> 2" - refute_equal(runtime.hash, development.hash) + assert d.prerelease? end end diff --git a/test/rubygems/test_gem_dependency_installer.rb b/test/rubygems/test_gem_dependency_installer.rb index 76d541bb81..237c0a02a4 100644 --- a/test/rubygems/test_gem_dependency_installer.rb +++ b/test/rubygems/test_gem_dependency_installer.rb @@ -23,6 +23,16 @@ class TestGemDependencyInstaller < RubyGemTestCase s.add_development_dependency 'aa' end + @b1_pre, @b1_pre_gem = util_gem 'b', '1.a' do |s| + s.add_dependency 'a' + s.add_development_dependency 'aa' + end + + @c1_pre, @c1_pre_gem = util_gem 'c', '1.a' do |s| + s.add_dependency 'a', '1.a' + s.add_dependency 'b', '1' + end + @d1, @d1_gem = util_gem 'd', '1' @d2, @d2_gem = util_gem 'd', '2' @@ -46,8 +56,8 @@ class TestGemDependencyInstaller < RubyGemTestCase @fetcher = Gem::FakeFetcher.new Gem::RemoteFetcher.fetcher = @fetcher - si = util_setup_spec_fetcher(@a1, @a1_pre, @b1, @d1, @d2, @x1_m, @x1_o, @w1, @y1, - @y1_1_p, @z1) + si = util_setup_spec_fetcher(@a1, @a1_pre, @b1, @b1_pre, @c1_pre, @d1, @d2, + @x1_m, @x1_o, @w1, @y1, @y1_1_p, @z1) util_clear_gems end @@ -104,8 +114,8 @@ class TestGemDependencyInstaller < RubyGemTestCase assert_equal %w[a-1 b-1], inst.installed_gems.map { |s| s.full_name } - assert File.exist?(File.join(@tempdir, 'cache', "#{@a1.full_name}.gem")) - assert File.exist?(File.join(@tempdir, 'cache', "#{@b1.full_name}.gem")) + assert File.exist?(File.join(@tempdir, 'cache', @a1.file_name)) + assert File.exist?(File.join(@tempdir, 'cache', @b1.file_name)) end def test_install_dependencies_satisfied @@ -124,7 +134,7 @@ class TestGemDependencyInstaller < RubyGemTestCase inst.install 'a-2' end - FileUtils.rm File.join(@tempdir, "#{a2.full_name}.gem") + FileUtils.rm File.join(@tempdir, a2.file_name) Dir.chdir @tempdir do inst = Gem::DependencyInstaller.new @@ -259,7 +269,9 @@ class TestGemDependencyInstaller < RubyGemTestCase inst.install 'a' end - assert_match %r|\A#!/\S+/env #{Gem::ConfigMap[:ruby_install_name]}\n|, + env = "/\\S+/env" unless Gem.win_platform? + + assert_match %r|\A#!#{env} #{Gem::ConfigMap[:ruby_install_name]}\n|, File.read(File.join(@gemhome, 'bin', 'a_bin')) end @@ -302,10 +314,8 @@ class TestGemDependencyInstaller < RubyGemTestCase assert_equal %w[a-1], inst.installed_gems.map { |s| s.full_name } - assert File.exist?(File.join(gemhome2, 'specifications', - "#{@a1.full_name}.gemspec")) - assert File.exist?(File.join(gemhome2, 'cache', - "#{@a1.full_name}.gem")) + assert File.exist?(File.join(gemhome2, 'specifications', @a1.spec_name)) + assert File.exist?(File.join(gemhome2, 'cache', @a1.file_name)) end def test_install_domain_both @@ -327,10 +337,8 @@ class TestGemDependencyInstaller < RubyGemTestCase assert_equal %w[a-1 b-1], inst.installed_gems.map { |s| s.full_name } a1, b1 = inst.installed_gems - a1_expected = File.join(@gemhome, 'specifications', - "#{a1.full_name}.gemspec") - b1_expected = File.join(@gemhome, 'specifications', - "#{b1.full_name}.gemspec") + a1_expected = File.join(@gemhome, 'specifications', a1.spec_name) + b1_expected = File.join(@gemhome, 'specifications', b1.spec_name) assert_equal a1_expected, a1.loaded_from assert_equal b1_expected, b1.loaded_from @@ -463,9 +471,9 @@ class TestGemDependencyInstaller < RubyGemTestCase File.open @a1_gem, 'rb' do |fp| a1_data = fp.read end File.open a2_o_gem, 'rb' do |fp| a2_o_data = fp.read end - @fetcher.data["http://gems.example.com/gems/#{@a1.full_name}.gem"] = + @fetcher.data["http://gems.example.com/gems/#{@a1.file_name}"] = a1_data - @fetcher.data["http://gems.example.com/gems/#{a2_o.full_name}.gem"] = + @fetcher.data["http://gems.example.com/gems/#{a2_o.file_name}"] = a2_o_data inst = Gem::DependencyInstaller.new :domain => :remote @@ -576,10 +584,29 @@ class TestGemDependencyInstaller < RubyGemTestCase local = gems.last assert_equal 'a-1', local.first.full_name, 'local spec' - assert_equal File.join(@tempdir, "#{@a1.full_name}.gem"), + assert_equal File.join(@tempdir, @a1.file_name), local.last, 'local path' end + def test_find_gems_with_sources_prerelease + installer = Gem::DependencyInstaller.new + + dependency = Gem::Dependency.new('a', Gem::Requirement.default) + + releases = + installer.find_gems_with_sources(dependency).map { |gems, *| gems } + + assert releases.any? { |s| s.name == 'a' and s.version.to_s == '1' } + refute releases.any? { |s| s.name == 'a' and s.version.to_s == '1.a' } + + dependency.prerelease = true + + prereleases = + installer.find_gems_with_sources(dependency).map { |gems, *| gems } + + assert_equal [@a1_pre], prereleases + end + def test_gather_dependencies inst = Gem::DependencyInstaller.new inst.find_spec_by_name_and_version 'b' @@ -622,6 +649,15 @@ class TestGemDependencyInstaller < RubyGemTestCase assert_equal %w[y-1 z-1], inst.gems_to_install.map { |s| s.full_name } end + def test_gather_dependencies_prerelease + inst = Gem::DependencyInstaller.new :prerelease => true + inst.find_spec_by_name_and_version 'c', '1.a' + inst.gather_dependencies + + assert_equal %w[a-1.a b-1 c-1.a], + inst.gems_to_install.map { |s| s.full_name } + end + def test_gather_dependencies_old_required e1, = util_gem 'e', '1' do |s| s.add_dependency 'd', '= 1' end @@ -636,16 +672,5 @@ class TestGemDependencyInstaller < RubyGemTestCase assert_equal %w[d-1 e-1], inst.gems_to_install.map { |s| s.full_name } end - def test_prerelease_uses_pre_index - installer = Gem::DependencyInstaller.new - pre_installer = Gem::DependencyInstaller.new(:prerelease => true) - dependency = Gem::Dependency.new('a', Gem::Requirement.default) - - releases = installer.find_gems_with_sources(dependency).map{ |gems, *| gems } - prereleases = pre_installer.find_gems_with_sources(dependency).map{ |gems, *| gems } - - assert releases.select{ |s| s.name == 'a' and s.version.to_s == '1' }.first - assert releases.select{ |s| s.name == 'a' and s.version.to_s == '1.a' }.empty? - assert_equal [@a1_pre], prereleases - end end + diff --git a/test/rubygems/test_gem_dependency_list.rb b/test/rubygems/test_gem_dependency_list.rb index d8066c9238..eacd912f7a 100644 --- a/test/rubygems/test_gem_dependency_list.rb +++ b/test/rubygems/test_gem_dependency_list.rb @@ -1,9 +1,3 @@ -#-- -# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. -# All rights reserved. -# See LICENSE.txt for permissions. -#++ - require_relative 'gemutilities' require 'rubygems/dependency_list' @@ -71,6 +65,33 @@ class TestGemDependencyList < RubyGemTestCase assert_equal %w[b-1 c-1 a-1], order.map { |s| s.full_name } end + def test_dependency_order_development + e1 = quick_gem 'e', '1' + f1 = quick_gem 'f', '1' + g1 = quick_gem 'g', '1' + + @a1.add_dependency 'e' + @a1.add_dependency 'f' + @a1.add_dependency 'g' + g1.add_development_dependency 'a' + + deplist = Gem::DependencyList.new true + deplist.add @a1, e1, f1, g1 + + order = deplist.dependency_order + + assert_equal %w[g-1 a-1 f-1 e-1], order.map { |s| s.full_name }, + 'development on' + + deplist2 = Gem::DependencyList.new + deplist2.add @a1, e1, f1, g1 + + order = deplist2.dependency_order + + assert_equal %w[a-1 g-1 f-1 e-1], order.map { |s| s.full_name }, + 'development off' + end + def test_dependency_order_diamond util_diamond e1 = quick_gem 'e', '1' diff --git a/test/rubygems/test_gem_digest.rb b/test/rubygems/test_gem_digest.rb deleted file mode 100644 index 6bce4e4537..0000000000 --- a/test/rubygems/test_gem_digest.rb +++ /dev/null @@ -1,46 +0,0 @@ -#-- -# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. -# All rights reserved. -# See LICENSE.txt for permissions. -#++ - -require_relative 'gemutilities' -require "rubygems/digest/md5" -require "rubygems/digest/sha1" -require "rubygems/digest/sha2" - -class TestRubygemsGemDigest < RubyGemTestCase - - def test_sha256_hex_digest_works - digester = Gem::SHA256.new - assert_equal "b5d4045c3f466fa91fe2cc6abe79232a1a57cdf104f7a26e716e0a1e2789df78", digester.hexdigest("ABC") - end - - def test_sha256_digest_works - digester = Gem::SHA256.new - assert_equal "\265\324\004\\?Fo\251\037\342\314j\276y#*\032W\315\361\004\367\242nqn\n\036'\211\337x", - digester.digest("ABC") - end - - def test_sha1_hex_digest_works - digester = Gem::SHA1.new - assert_equal "3c01bdbb26f358bab27f267924aa2c9a03fcfdb8", digester.hexdigest("ABC") - end - - def test_sha1_digest_works - digester = Gem::SHA1.new - assert_equal "<\001\275\273&\363X\272\262\177&y$\252,\232\003\374\375\270", digester.digest("ABC") - end - - def test_md5_hex_digest_works - digester = Gem::MD5.new - assert_equal "902fbdd2b1df0c4f70b4a5d23525e932", digester.hexdigest("ABC") - end - - def test_md5_digest_works - digester = Gem::MD5.new - assert_equal "\220/\275\322\261\337\fOp\264\245\3225%\3512", digester.digest("ABC") - end - -end - diff --git a/test/rubygems/test_gem_doc_manager.rb b/test/rubygems/test_gem_doc_manager.rb index e3928ed2bc..46f425b9ba 100644 --- a/test/rubygems/test_gem_doc_manager.rb +++ b/test/rubygems/test_gem_doc_manager.rb @@ -1,9 +1,3 @@ -#-- -# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. -# All rights reserved. -# See LICENSE.txt for permissions. -#++ - require_relative 'gemutilities' require 'rubygems/doc_manager' diff --git a/test/rubygems/test_gem_format.rb b/test/rubygems/test_gem_format.rb index d9ddf0be92..555f98d77c 100644 --- a/test/rubygems/test_gem_format.rb +++ b/test/rubygems/test_gem_format.rb @@ -1,9 +1,3 @@ -#-- -# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. -# All rights reserved. -# See LICENSE.txt for permissions. -#++ - require_relative 'gemutilities' require_relative 'simple_gem' require 'rubygems/format' @@ -16,7 +10,7 @@ class TestGemFormat < RubyGemTestCase @simple_gem = SIMPLE_GEM end - def test_from_file_by_path + def test_class_from_file_by_path util_make_gems gems = Dir[File.join(@gemhome, 'cache', '*.gem')] @@ -34,13 +28,22 @@ class TestGemFormat < RubyGemTestCase end end - def test_from_file_by_path_nonexistent + def test_class_from_file_by_path_empty + util_make_gems + + empty_gem = File.join @tempdir, 'empty.gem' + FileUtils.touch empty_gem + + assert_nil Gem::Format.from_file_by_path(empty_gem) + end + + def test_class_from_file_by_path_nonexistent assert_raises Gem::Exception do Gem::Format.from_file_by_path '/nonexistent' end end - def test_from_io_garbled + def test_class_from_io_garbled e = assert_raises Gem::Package::FormatError do # subtly bogus input Gem::Format.from_io(StringIO.new(@simple_gem.upcase)) diff --git a/test/rubygems/test_gem_gem_path_searcher.rb b/test/rubygems/test_gem_gem_path_searcher.rb index 8a08ed8d06..3fb54d08f2 100644 --- a/test/rubygems/test_gem_gem_path_searcher.rb +++ b/test/rubygems/test_gem_gem_path_searcher.rb @@ -22,6 +22,9 @@ class TestGemGemPathSearcher < RubyGemTestCase @foo2 = quick_gem 'foo', '0.2' @bar1 = quick_gem 'bar', '0.1' @bar2 = quick_gem 'bar', '0.2' + @nrp = quick_gem 'nil_require_paths', '0.1' + @nrp.require_paths = nil + @fetcher = Gem::FakeFetcher.new Gem::RemoteFetcher.fetcher = @fetcher @@ -50,6 +53,10 @@ class TestGemGemPathSearcher < RubyGemTestCase assert_equal expected, lib_dirs end + def test_lib_dirs_for_nil_require_paths + assert_nil @gps.lib_dirs_for(@nrp) + end + def test_matching_file_eh refute @gps.matching_file?(@foo1, 'bar') assert @gps.matching_file?(@foo1, 'foo') @@ -63,5 +70,9 @@ class TestGemGemPathSearcher < RubyGemTestCase assert_equal [expected], @gps.matching_files(@foo1, 'foo') end + def test_matching_files_nil_require_paths + assert_empty @gps.matching_files(@nrp, 'foo') + end + end diff --git a/test/rubygems/test_gem_gemcutter_utilities.rb b/test/rubygems/test_gem_gemcutter_utilities.rb new file mode 100644 index 0000000000..f8306d583f --- /dev/null +++ b/test/rubygems/test_gem_gemcutter_utilities.rb @@ -0,0 +1,103 @@ +require_relative 'gemutilities' +require 'rubygems' +require 'rubygems/gemcutter_utilities' + +class TestGemGemcutterUtilities < RubyGemTestCase + + def setup + super + + ENV['RUBYGEMS_HOST'] = nil + Gem.configuration.rubygems_api_key = nil + + @cmd = Gem::Command.new '', 'summary' + @cmd.extend Gem::GemcutterUtilities + end + + def test_sign_in + api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903' + util_sign_in [api_key, 200, 'OK'] + + assert_match %r{Enter your RubyGems.org credentials.}, @sign_in_ui.output + assert @fetcher.last_request["authorization"] + assert_match %r{Signed in.}, @sign_in_ui.output + + credentials = YAML.load_file Gem.configuration.credentials_path + assert_equal api_key, credentials[:rubygems_api_key] + end + + def test_sign_in_with_host + api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903' + util_sign_in [api_key, 200, 'OK'], 'http://example.com' + + assert_match %r{Enter your RubyGems.org credentials.}, @sign_in_ui.output + assert @fetcher.last_request["authorization"] + assert_match %r{Signed in.}, @sign_in_ui.output + + credentials = YAML.load_file Gem.configuration.credentials_path + assert_equal api_key, credentials[:rubygems_api_key] + end + + def test_sign_in_skips_with_existing_credentials + api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903' + Gem.configuration.rubygems_api_key = api_key + + util_sign_in [api_key, 200, 'OK'] + + assert_equal "", @sign_in_ui.output + end + + def test_sign_in_with_other_credentials_doesnt_overwrite_other_keys + api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903' + other_api_key = 'f46dbb18bb6a9c97cdc61b5b85c186a17403cdcbf' + + FileUtils.mkdir_p File.dirname(Gem.configuration.credentials_path) + open Gem.configuration.credentials_path, 'w' do |f| + f.write Hash[:other_api_key, other_api_key].to_yaml + end + util_sign_in [api_key, 200, 'OK'] + + assert_match %r{Enter your RubyGems.org credentials.}, @sign_in_ui.output + assert_match %r{Signed in.}, @sign_in_ui.output + + credentials = YAML.load_file Gem.configuration.credentials_path + assert_equal api_key, credentials[:rubygems_api_key] + assert_equal other_api_key, credentials[:other_api_key] + end + + def test_sign_in_with_bad_credentials + skip 'Always uses $stdin on windows' if Gem.win_platform? + + assert_raises MockGemUi::TermError do + util_sign_in ['Access Denied.', 403, 'Forbidden'] + end + + assert_match %r{Enter your RubyGems.org credentials.}, @sign_in_ui.output + assert_match %r{Access Denied.}, @sign_in_ui.output + end + + def util_sign_in response, host = nil + skip 'Always uses $stdin on windows' if Gem.win_platform? + + email = 'you@example.com' + password = 'secret' + + if host + ENV['RUBYGEMS_HOST'] = host + else + host = "https://rubygems.org" + end + + @fetcher = Gem::FakeFetcher.new + @fetcher.data["#{host}/api/v1/api_key"] = response + Gem::RemoteFetcher.fetcher = @fetcher + + @sign_in_ui = MockGemUi.new "#{email}\n#{password}\n" + + use_ui @sign_in_ui do + @cmd.sign_in + end + end + +end + diff --git a/test/rubygems/test_gem_indexer.rb b/test/rubygems/test_gem_indexer.rb index e612a71d55..7bc4862d7b 100644 --- a/test/rubygems/test_gem_indexer.rb +++ b/test/rubygems/test_gem_indexer.rb @@ -1,9 +1,3 @@ -#-- -# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. -# All rights reserved. -# See LICENSE.txt for permissions. -#++ - require_relative 'gemutilities' require 'rubygems/indexer' @@ -145,19 +139,19 @@ pl-1-i386-linux assert_equal expected, latest_quick_index - assert_indexed quickdir, "#{@a1.full_name}.gemspec.rz" - assert_indexed quickdir, "#{@a2.full_name}.gemspec.rz" - assert_indexed quickdir, "#{@b2.full_name}.gemspec.rz" - assert_indexed quickdir, "#{@c1_2.full_name}.gemspec.rz" + assert_indexed quickdir, "#{@a1.spec_name}.rz" + assert_indexed quickdir, "#{@a2.spec_name}.rz" + assert_indexed quickdir, "#{@b2.spec_name}.rz" + assert_indexed quickdir, "#{@c1_2.spec_name}.rz" assert_indexed quickdir, "#{@pl1.original_name}.gemspec.rz" - refute_indexed quickdir, "#{@pl1.full_name}.gemspec.rz" + refute_indexed quickdir, "#{@pl1.spec_name}.rz" - assert_indexed marshal_quickdir, "#{@a1.full_name}.gemspec.rz" - assert_indexed marshal_quickdir, "#{@a2.full_name}.gemspec.rz" + assert_indexed marshal_quickdir, "#{@a1.spec_name}.rz" + assert_indexed marshal_quickdir, "#{@a2.spec_name}.rz" - refute_indexed quickdir, "#{@c1_2.full_name}.gemspec" - refute_indexed marshal_quickdir, "#{@c1_2.full_name}.gemspec" + refute_indexed quickdir, @c1_2.spec_name + refute_indexed marshal_quickdir, @c1_2.spec_name assert_indexed @tempdir, "specs.#{@marshal_version}" assert_indexed @tempdir, "specs.#{@marshal_version}.gz" @@ -172,7 +166,7 @@ pl-1-i386-linux <title>ExampleForge gems</title> <link>http://example.com</link> <description>Recently released gems from http://example.com</description> - <generator>RubyGems v1.3.4</generator> + <generator>RubyGems v#{Gem::RubyGemsVersion}</generator> <docs>http://cyber.law.harvard.edu/rss/rss.html</docs> <item> <title>a-2</title> @@ -325,19 +319,19 @@ eighty characters.</pre> assert_indexed quickdir, "latest_index" assert_indexed quickdir, "latest_index.rz" - assert_indexed quickdir, "#{@a1.full_name}.gemspec.rz" - assert_indexed quickdir, "#{@a2.full_name}.gemspec.rz" - assert_indexed quickdir, "#{@b2.full_name}.gemspec.rz" - assert_indexed quickdir, "#{@c1_2.full_name}.gemspec.rz" + assert_indexed quickdir, "#{@a1.spec_name}.rz" + assert_indexed quickdir, "#{@a2.spec_name}.rz" + assert_indexed quickdir, "#{@b2.spec_name}.rz" + assert_indexed quickdir, "#{@c1_2.spec_name}.rz" assert_indexed quickdir, "#{@pl1.original_name}.gemspec.rz" - refute_indexed quickdir, "#{@pl1.full_name}.gemspec.rz" + refute_indexed quickdir, "#{@pl1.spec_name}.rz" - assert_indexed marshal_quickdir, "#{@a1.full_name}.gemspec.rz" - assert_indexed marshal_quickdir, "#{@a2.full_name}.gemspec.rz" + assert_indexed marshal_quickdir, "#{@a1.spec_name}.rz" + assert_indexed marshal_quickdir, "#{@a2.spec_name}.rz" - refute_indexed quickdir, "#{@c1_2.full_name}.gemspec" - refute_indexed marshal_quickdir, "#{@c1_2.full_name}.gemspec" + refute_indexed quickdir, "#{@c1_2.spec_name}" + refute_indexed marshal_quickdir, "#{@c1_2.spec_name}" refute_indexed @tempdir, "specs.#{@marshal_version}" refute_indexed @tempdir, "specs.#{@marshal_version}.gz" @@ -379,15 +373,15 @@ eighty characters.</pre> assert_indexed quickdir, "latest_index" assert_indexed quickdir, "latest_index.rz" - assert_indexed quickdir, "#{@a1.full_name}.gemspec.rz" - assert_indexed quickdir, "#{@a2.full_name}.gemspec.rz" - assert_indexed quickdir, "#{@b2.full_name}.gemspec.rz" - assert_indexed quickdir, "#{@c1_2.full_name}.gemspec.rz" + assert_indexed quickdir, "#{@a1.spec_name}.rz" + assert_indexed quickdir, "#{@a2.spec_name}.rz" + assert_indexed quickdir, "#{@b2.spec_name}.rz" + assert_indexed quickdir, "#{@c1_2.spec_name}.rz" assert_indexed quickdir, "#{@pl1.original_name}.gemspec.rz" - assert_indexed marshal_quickdir, "#{@a1.full_name}.gemspec.rz" - assert_indexed marshal_quickdir, "#{@a2.full_name}.gemspec.rz" + assert_indexed marshal_quickdir, "#{@a1.spec_name}.rz" + assert_indexed marshal_quickdir, "#{@a2.spec_name}.rz" assert_indexed @tempdir, "specs.#{@marshal_version}" assert_indexed @tempdir, "specs.#{@marshal_version}.gz" @@ -421,19 +415,19 @@ eighty characters.</pre> refute_indexed quickdir, "latest_index" refute_indexed quickdir, "latest_index.rz" - refute_indexed quickdir, "#{@a1.full_name}.gemspec.rz" - refute_indexed quickdir, "#{@a2.full_name}.gemspec.rz" - refute_indexed quickdir, "#{@b2.full_name}.gemspec.rz" - refute_indexed quickdir, "#{@c1_2.full_name}.gemspec.rz" + refute_indexed quickdir, "#{@a1.spec_name}.rz" + refute_indexed quickdir, "#{@a2.spec_name}.rz" + refute_indexed quickdir, "#{@b2.spec_name}.rz" + refute_indexed quickdir, "#{@c1_2.spec_name}.rz" refute_indexed quickdir, "#{@pl1.original_name}.gemspec.rz" - refute_indexed quickdir, "#{@pl1.full_name}.gemspec.rz" + refute_indexed quickdir, "#{@pl1.spec_name}.rz" - assert_indexed marshal_quickdir, "#{@a1.full_name}.gemspec.rz" - assert_indexed marshal_quickdir, "#{@a2.full_name}.gemspec.rz" + assert_indexed marshal_quickdir, "#{@a1.spec_name}.rz" + assert_indexed marshal_quickdir, "#{@a2.spec_name}.rz" - refute_indexed quickdir, "#{@c1_2.full_name}.gemspec" - refute_indexed marshal_quickdir, "#{@c1_2.full_name}.gemspec" + refute_indexed quickdir, "#{@c1_2.spec_name}" + refute_indexed marshal_quickdir, "#{@c1_2.spec_name}" assert_indexed @tempdir, "specs.#{@marshal_version}" assert_indexed @tempdir, "specs.#{@marshal_version}.gz" @@ -475,15 +469,15 @@ eighty characters.</pre> assert_indexed quickdir, "latest_index" assert_indexed quickdir, "latest_index.rz" - assert_indexed quickdir, "#{@a1.full_name}.gemspec.rz" - assert_indexed quickdir, "#{@a2.full_name}.gemspec.rz" - assert_indexed quickdir, "#{@b2.full_name}.gemspec.rz" - assert_indexed quickdir, "#{@c1_2.full_name}.gemspec.rz" + assert_indexed quickdir, "#{@a1.spec_name}.rz" + assert_indexed quickdir, "#{@a2.spec_name}.rz" + assert_indexed quickdir, "#{@b2.spec_name}.rz" + assert_indexed quickdir, "#{@c1_2.spec_name}.rz" assert_indexed quickdir, "#{@pl1.original_name}.gemspec.rz" - assert_indexed marshal_quickdir, "#{@a1.full_name}.gemspec.rz" - assert_indexed marshal_quickdir, "#{@a2.full_name}.gemspec.rz" + assert_indexed marshal_quickdir, "#{@a1.spec_name}.rz" + assert_indexed marshal_quickdir, "#{@a2.spec_name}.rz" assert_indexed @tempdir, "specs.#{@marshal_version}" assert_indexed @tempdir, "specs.#{@marshal_version}.gz" @@ -637,14 +631,14 @@ eighty characters.</pre> @d2_1_a_tuple = [@d2_1_a.name, @d2_1_a.version, @d2_1_a.original_platform] gems = File.join @tempdir, 'gems' - FileUtils.mv File.join(@gemhome, 'cache', "#{@d2_1.full_name}.gem"), gems - FileUtils.mv File.join(@gemhome, 'cache', "#{@d2_1_a.full_name}.gem"), gems + FileUtils.mv File.join(@gemhome, 'cache', @d2_1.file_name), gems + FileUtils.mv File.join(@gemhome, 'cache', @d2_1_a.file_name), gems use_ui @ui do @indexer.update_index end - assert_indexed marshal_quickdir, "#{@d2_1.full_name}.gemspec.rz" + assert_indexed marshal_quickdir, "#{@d2_1.spec_name}.rz" specs_index = Marshal.load Gem.read_binary(@indexer.dest_specs_index) diff --git a/test/rubygems/test_gem_install_update_options.rb b/test/rubygems/test_gem_install_update_options.rb index 9be8cde7cf..385fd9d544 100644 --- a/test/rubygems/test_gem_install_update_options.rb +++ b/test/rubygems/test_gem_install_update_options.rb @@ -19,11 +19,6 @@ class TestGemInstallUpdateOptions < GemInstallerTestCase assert @cmd.handles?(args) end - def test_prerelease - @cmd.handle_options %w[--prerelease] - assert_equal true, @cmd.options[:prerelease] - end - def test_security_policy @cmd.handle_options %w[-P HighSecurity] diff --git a/test/rubygems/test_gem_installer.rb b/test/rubygems/test_gem_installer.rb index 76a7fc1d57..3fcfa4fedc 100644 --- a/test/rubygems/test_gem_installer.rb +++ b/test/rubygems/test_gem_installer.rb @@ -1,9 +1,3 @@ -#-- -# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. -# All rights reserved. -# See LICENSE.txt for permissions. -#++ - require_relative 'gem_installer_test_case' class TestGemInstaller < GemInstallerTestCase @@ -107,19 +101,6 @@ load Gem.bin_path('a', 'my_exec', version) assert_equal 'a requires b (> 2, runtime)', e.message end - def test_expand_and_validate_gem_dir - @installer.gem_dir = '/nonexistent' - expanded_gem_dir = @installer.send(:expand_and_validate_gem_dir) - if win_platform? - expected = File.expand_path('/nonexistent').downcase - expanded_gem_dir = expanded_gem_dir.downcase - else - expected = '/nonexistent' - end - - assert_equal expected, expanded_gem_dir - end - def test_extract_files format = Object.new def format.file_entries @@ -523,11 +504,11 @@ load Gem.bin_path('a', 'my_exec', version) def test_initialize spec = quick_gem 'a' do |s| s.platform = Gem::Platform.new 'mswin32' end - gem = File.join @tempdir, "#{spec.full_name}.gem" + gem = File.join @tempdir, spec.file_name Dir.mkdir util_inst_bindir util_build_gem spec - FileUtils.mv File.join(@gemhome, 'cache', "#{spec.full_name}.gem"), + FileUtils.mv File.join(@gemhome, 'cache', spec.file_name), @tempdir installer = Gem::Installer.new gem @@ -539,7 +520,7 @@ load Gem.bin_path('a', 'my_exec', version) Dir.mkdir util_inst_bindir util_setup_gem - cache_file = File.join @gemhome, 'cache', "#{@spec.full_name}.gem" + cache_file = File.join @gemhome, 'cache', @spec.file_name Gem.pre_install do |installer| refute File.exist?(cache_file), 'cache file should not exist yet' @@ -567,8 +548,7 @@ load Gem.bin_path('a', 'my_exec', version) assert File.exist?(File.join(gemdir, 'ext', 'a', 'Rakefile')) - spec_file = File.join(@gemhome, 'specifications', - "#{@spec.full_name}.gemspec") + spec_file = File.join(@gemhome, 'specifications', @spec.spec_name) assert_equal spec_file, @spec.loaded_from assert File.exist?(spec_file) @@ -582,7 +562,7 @@ load Gem.bin_path('a', 'my_exec', version) use_ui @ui do Dir.chdir @tempdir do Gem::Builder.new(@spec).build end - gem = File.join @tempdir, "#{@spec.full_name}.gem" + gem = File.join @tempdir, @spec.file_name end gem_data = File.open gem, 'rb' do |fp| fp.read 1024 end @@ -665,8 +645,7 @@ load Gem.bin_path('a', 'my_exec', version) assert_equal 0111, exe_mode, "0%o" % exe_mode unless win_platform? assert File.exist?(File.join(gemdir, 'lib', 'code.rb')) - assert File.exist?(File.join(@gemhome, 'specifications', - "#{@spec.full_name}.gemspec")) + assert File.exist?(File.join(@gemhome, 'specifications', @spec.spec_name)) end def test_install_missing_dirs @@ -676,7 +655,7 @@ load Gem.bin_path('a', 'my_exec', version) use_ui @ui do Dir.chdir @tempdir do Gem::Builder.new(@spec).build end - gem = File.join @tempdir, "#{@spec.full_name}.gem" + gem = File.join @tempdir, @spec.file_name @installer.install end @@ -685,50 +664,8 @@ load Gem.bin_path('a', 'my_exec', version) File.directory? File.join(Gem.dir, 'docs') File.directory? File.join(Gem.dir, 'specifications') - assert File.exist?(File.join(@gemhome, 'cache', "#{@spec.full_name}.gem")) - assert File.exist?(File.join(@gemhome, 'specifications', - "#{@spec.full_name}.gemspec")) - end - - unless win_platform? # File.chmod doesn't work - def test_install_user_local_fallback - Dir.mkdir util_inst_bindir - File.chmod 0755, @userhome - File.chmod 0000, util_inst_bindir - File.chmod 0000, Gem.dir - @spec.executables = ["executable"] - - build_rake_in do - use_ui @ui do - util_setup_gem - @installer.install - end - end - - assert File.exist?(File.join(Gem.user_dir, 'gems', - @spec.full_name, 'lib', 'code.rb')) - assert File.exist?(File.join(Gem.user_dir, 'bin', 'executable')) - ensure - File.chmod 0755, Gem.dir - File.chmod 0755, util_inst_bindir - end - - def test_install_bindir_read_only - Dir.mkdir util_inst_bindir - File.chmod 0755, @userhome - File.chmod 0000, util_inst_bindir - - build_rake_in do - use_ui @ui do - util_setup_gem - @installer.install - end - end - - assert File.exist?(File.join(Gem.user_dir, 'bin', 'executable')) - ensure - File.chmod 0755, util_inst_bindir - end + assert File.exist?(File.join(@gemhome, 'cache', @spec.file_name)) + assert File.exist?(File.join(@gemhome, 'specifications', @spec.spec_name)) end def test_install_with_message @@ -749,7 +686,7 @@ load Gem.bin_path('a', 'my_exec', version) e = assert_raises Gem::InstallError do installer.install end - assert_equal 'old_ruby_required requires Ruby version = 1.4.6', + assert_equal 'old_ruby_required requires Ruby version = 1.4.6.', e.message end end @@ -761,15 +698,15 @@ load Gem.bin_path('a', 'my_exec', version) util_build_gem spec - gem = File.join @gemhome, 'cache', "#{spec.full_name}.gem" + gem = File.join @gemhome, 'cache', spec.file_name use_ui @ui do @installer = Gem::Installer.new gem e = assert_raises Gem::InstallError do @installer.install end - assert_equal 'old_rubygems_required requires RubyGems version < 0', - e.message + assert_equal 'old_rubygems_required requires RubyGems version < 0. ' + + "Try 'gem update --system' to update RubyGems itself.", e.message end end @@ -825,7 +762,11 @@ load Gem.bin_path('a', 'my_exec', version) @installer.env_shebang = true shebang = @installer.shebang 'my_exec' - assert_equal "#!/usr/bin/env #{Gem::ConfigMap[:ruby_install_name]}", shebang + + env_shebang = "/usr/bin/env" unless Gem.win_platform? + + assert_equal("#!#{env_shebang} #{Gem::ConfigMap[:ruby_install_name]}", + shebang) end def test_shebang_nested @@ -889,7 +830,7 @@ load Gem.bin_path('a', 'my_exec', version) def test_write_spec spec_dir = File.join @gemhome, 'specifications' - spec_file = File.join spec_dir, "#{@spec.full_name}.gemspec" + spec_file = File.join spec_dir, @spec.spec_name FileUtils.rm spec_file refute File.exist?(spec_file) @@ -909,7 +850,7 @@ load Gem.bin_path('a', 'my_exec', version) util_build_gem spec - File.join @gemhome, 'cache', "#{spec.full_name}.gem" + File.join @gemhome, 'cache', spec.file_name end end diff --git a/test/rubygems/test_gem_package_tar_header.rb b/test/rubygems/test_gem_package_tar_header.rb index 16804452b7..cda3a0d663 100644 --- a/test/rubygems/test_gem_package_tar_header.rb +++ b/test/rubygems/test_gem_package_tar_header.rb @@ -1,9 +1,3 @@ -#-- -# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. -# All rights reserved. -# See LICENSE.txt for permissions. -#++ - require_relative 'gem_package_tar_test_case' require 'rubygems/package' diff --git a/test/rubygems/test_gem_package_tar_input.rb b/test/rubygems/test_gem_package_tar_input.rb index 7eea1826e0..6938e97eba 100644 --- a/test/rubygems/test_gem_package_tar_input.rb +++ b/test/rubygems/test_gem_package_tar_input.rb @@ -1,9 +1,3 @@ -#-- -# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. -# All rights reserved. -# See LICENSE.txt for permissions. -#++ - require_relative 'gem_package_tar_test_case' require 'rubygems/package/tar_input' diff --git a/test/rubygems/test_gem_package_tar_output.rb b/test/rubygems/test_gem_package_tar_output.rb index 4a07208368..0f2c0901ef 100644 --- a/test/rubygems/test_gem_package_tar_output.rb +++ b/test/rubygems/test_gem_package_tar_output.rb @@ -1,9 +1,3 @@ -#-- -# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. -# All rights reserved. -# See LICENSE.txt for permissions. -#++ - require_relative 'gem_package_tar_test_case' require 'rubygems/package/tar_output' diff --git a/test/rubygems/test_gem_package_tar_reader.rb b/test/rubygems/test_gem_package_tar_reader.rb index e5b7850e56..38ad48a94d 100644 --- a/test/rubygems/test_gem_package_tar_reader.rb +++ b/test/rubygems/test_gem_package_tar_reader.rb @@ -1,9 +1,3 @@ -#-- -# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. -# All rights reserved. -# See LICENSE.txt for permissions. -#++ - require_relative 'gem_package_tar_test_case' require 'rubygems/package' diff --git a/test/rubygems/test_gem_package_tar_reader_entry.rb b/test/rubygems/test_gem_package_tar_reader_entry.rb index bb154a7b6b..5323474541 100644 --- a/test/rubygems/test_gem_package_tar_reader_entry.rb +++ b/test/rubygems/test_gem_package_tar_reader_entry.rb @@ -1,9 +1,3 @@ -#-- -# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. -# All rights reserved. -# See LICENSE.txt for permissions. -#++ - require_relative 'gem_package_tar_test_case' require 'rubygems/package' diff --git a/test/rubygems/test_gem_package_tar_writer.rb b/test/rubygems/test_gem_package_tar_writer.rb index 0d691e45cd..d819065a41 100644 --- a/test/rubygems/test_gem_package_tar_writer.rb +++ b/test/rubygems/test_gem_package_tar_writer.rb @@ -1,9 +1,3 @@ -#-- -# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. -# All rights reserved. -# See LICENSE.txt for permissions. -#++ - require_relative 'gem_package_tar_test_case' require 'rubygems/package/tar_writer' diff --git a/test/rubygems/test_gem_package_task.rb b/test/rubygems/test_gem_package_task.rb index a8334ce4e8..2e6710f4ac 100644 --- a/test/rubygems/test_gem_package_task.rb +++ b/test/rubygems/test_gem_package_task.rb @@ -1,24 +1,3 @@ -# Copyright (c) 2003, 2004 Jim Weirich, 2009 Eric Hodel -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - require_relative 'gemutilities' require 'rubygems' require 'rubygems/package_task' @@ -35,7 +14,6 @@ class TestGemPackageTask < MiniTest::Unit::TestCase p.package_files << "y" end assert_equal ["x", "y"], pkg.package_files - assert_equal "pkgr-1.2.3.gem", pkg.gem_file end def test_gem_package_with_current_platform @@ -49,7 +27,6 @@ class TestGemPackageTask < MiniTest::Unit::TestCase p.package_files << "y" end assert_equal ["x", "y"], pkg.package_files - assert_match(/^pkgr-1\.2\.3-(\S+)\.gem$/, pkg.gem_file) end def test_gem_package_with_ruby_platform @@ -63,7 +40,6 @@ class TestGemPackageTask < MiniTest::Unit::TestCase p.package_files << "y" end assert_equal ["x", "y"], pkg.package_files - assert_equal "pkgr-1.2.3.gem", pkg.gem_file end end diff --git a/test/rubygems/test_gem_remote_fetcher.rb b/test/rubygems/test_gem_remote_fetcher.rb index e29fe60481..d6b78dc7cc 100644 --- a/test/rubygems/test_gem_remote_fetcher.rb +++ b/test/rubygems/test_gem_remote_fetcher.rb @@ -1,14 +1,8 @@ -#-- -# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. -# All rights reserved. -# See LICENSE.txt for permissions. -#++ - require_relative 'gemutilities' +require 'ostruct' require 'webrick' -require 'zlib' require 'rubygems/remote_fetcher' -require 'ostruct' +require 'rubygems/format' # = Testing Proxy Settings # @@ -208,7 +202,7 @@ gems: fetcher = util_fuck_with_fetcher a1_data - a1_cache_gem = File.join(@gemhome, 'cache', "#{@a1.full_name}.gem") + a1_cache_gem = File.join(@gemhome, 'cache', @a1.file_name) assert_equal a1_cache_gem, fetcher.download(@a1, 'http://gems.example.com') assert_equal("http://gems.example.com/gems/a-1.gem", fetcher.instance_variable_get(:@test_arg).to_s) @@ -220,20 +214,20 @@ gems: inst = Gem::RemoteFetcher.fetcher - assert_equal File.join(@gemhome, 'cache', "#{@a1.full_name}.gem"), + assert_equal File.join(@gemhome, 'cache', @a1.file_name), inst.download(@a1, 'http://gems.example.com') end def test_download_local FileUtils.mv @a1_gem, @tempdir - local_path = File.join @tempdir, "#{@a1.full_name}.gem" + local_path = File.join @tempdir, @a1.file_name inst = nil Dir.chdir @tempdir do inst = Gem::RemoteFetcher.fetcher end - assert_equal File.join(@gemhome, 'cache', "#{@a1.full_name}.gem"), + assert_equal File.join(@gemhome, 'cache', @a1.file_name), inst.download(@a1, local_path) end @@ -241,14 +235,14 @@ gems: space_path = File.join @tempdir, 'space path' FileUtils.mkdir space_path FileUtils.mv @a1_gem, space_path - local_path = File.join space_path, "#{@a1.full_name}.gem" + local_path = File.join space_path, @a1.file_name inst = nil Dir.chdir @tempdir do inst = Gem::RemoteFetcher.fetcher end - assert_equal File.join(@gemhome, 'cache', "#{@a1.full_name}.gem"), + assert_equal File.join(@gemhome, 'cache', @a1.file_name), inst.download(@a1, local_path) end @@ -262,7 +256,7 @@ gems: install_dir = File.join @tempdir, 'more_gems' - a1_cache_gem = File.join install_dir, 'cache', "#{@a1.full_name}.gem" + a1_cache_gem = File.join install_dir, 'cache', @a1.file_name FileUtils.mkdir_p(File.dirname(a1_cache_gem)) actual = fetcher.download(@a1, 'http://gems.example.com', install_dir) @@ -276,7 +270,7 @@ gems: unless win_platform? # File.chmod doesn't work def test_download_local_read_only FileUtils.mv @a1_gem, @tempdir - local_path = File.join @tempdir, "#{@a1.full_name}.gem" + local_path = File.join @tempdir, @a1.file_name inst = nil File.chmod 0555, File.join(@gemhome, 'cache') @@ -284,7 +278,7 @@ gems: inst = Gem::RemoteFetcher.fetcher end - assert_equal File.join(@tempdir, "#{@a1.full_name}.gem"), + assert_equal File.join(@tempdir, @a1.file_name), inst.download(@a1, local_path) ensure File.chmod 0755, File.join(@gemhome, 'cache') @@ -296,8 +290,7 @@ gems: fetcher = util_fuck_with_fetcher File.read(@a1_gem) fetcher.download(@a1, 'http://gems.example.com') - assert File.exist?(File.join(Gem.user_dir, 'cache', - "#{@a1.full_name}.gem")) + assert File.exist?(File.join(Gem.user_dir, 'cache', @a1.file_name)) ensure File.chmod 0755, File.join(@gemhome) File.chmod 0755, File.join(@gemhome, 'cache') @@ -319,7 +312,7 @@ gems: fetcher = util_fuck_with_fetcher e1_data, :blow_chunks - e1_cache_gem = File.join(@gemhome, 'cache', "#{e1.full_name}.gem") + e1_cache_gem = File.join(@gemhome, 'cache', e1.file_name) assert_equal e1_cache_gem, fetcher.download(e1, 'http://gems.example.com') @@ -328,6 +321,23 @@ gems: assert File.exist?(e1_cache_gem) end + def test_download_same_file + FileUtils.mv @a1_gem, @tempdir + local_path = File.join @tempdir, @a1.file_name + inst = nil + + Dir.chdir @tempdir do + inst = Gem::RemoteFetcher.fetcher + end + + cache_path = File.join @gemhome, 'cache', @a1.file_name + FileUtils.mv local_path, cache_path + + gem = Gem::Format.from_file_by_path cache_path + + assert_equal cache_path, inst.download(gem.spec, cache_path) + end + def test_download_unsupported inst = Gem::RemoteFetcher.fetcher diff --git a/test/rubygems/test_gem_requirement.rb b/test/rubygems/test_gem_requirement.rb index e64c90cb76..a70dd0fd8e 100644 --- a/test/rubygems/test_gem_requirement.rb +++ b/test/rubygems/test_gem_requirement.rb @@ -1,222 +1,292 @@ -#-- -# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. -# All rights reserved. -# See LICENSE.txt for permissions. -#++ - require_relative 'gemutilities' -require 'rubygems/version' +require "rubygems/requirement" class TestGemRequirement < RubyGemTestCase - def setup - super - - @r1_2 = Gem::Requirement.new '= 1.2' - @r1_3 = Gem::Requirement.new '= 1.3' - end - - def test_initialize - r = Gem::Requirement.new '2' - assert_equal '= 2', r.to_s, 'String' - - r = Gem::Requirement.new %w[2] - assert_equal '= 2', r.to_s, 'Array of Strings' - - r = Gem::Requirement.new Gem::Version.new('2') - assert_equal '= 2', r.to_s, 'Gem::Version' - end - def test_equals2 - assert_equal @r1_2, @r1_2.dup - assert_equal @r1_2.dup, @r1_2 + r = req "= 1.2" + assert_equal r, r.dup + assert_equal r.dup, r - refute_equal @r1_3, @r1_2 - refute_equal @r1_2, @r1_3 + refute_requirement_equal "= 1.2", "= 1.3" + refute_requirement_equal "= 1.3", "= 1.2" - refute_equal Object.new, @r1_2 - refute_equal @r1_2, Object.new + refute_equal Object.new, req("= 1.2") + refute_equal req("= 1.2"), Object.new end - def test_hash - assert_equal @r1_2.hash, @r1_2.dup.hash - assert_equal @r1_2.dup.hash, @r1_2.hash - - refute_equal @r1_2.hash, @r1_3.hash - refute_equal @r1_3.hash, @r1_2.hash + def test_initialize + assert_requirement_equal "= 2", "2" + assert_requirement_equal "= 2", ["2"] + assert_requirement_equal "= 2", v(2) end - # We may get some old gems that have requirements in old formats. - # We need to be able to handle those old requirements by normalizing - # them to the latest format. - def test_normalization - require 'yaml' - yamldep = %{--- !ruby/object:Gem::Requirement - nums: - - 1 - - 0 - - 4 - op: ">=" - version: ">= 1.0.4"} - dep = YAML.load(yamldep) - dep.normalize - assert_equal ">= 1.0.4", dep.to_s + def test_class_available_as_gem_version_requirement + assert_same Gem::Requirement, Gem::Version::Requirement, + "Gem::Version::Requirement is aliased for old YAML compatibility." end def test_parse - assert_equal ['=', Gem::Version.new(1)], @r1_2.parse(' 1') - - assert_equal ['=', Gem::Version.new(1)], @r1_2.parse('= 1') - assert_equal ['>', Gem::Version.new(1)], @r1_2.parse('> 1') + assert_equal ['=', Gem::Version.new(1)], Gem::Requirement.parse(' 1') + assert_equal ['=', Gem::Version.new(1)], Gem::Requirement.parse('= 1') + assert_equal ['>', Gem::Version.new(1)], Gem::Requirement.parse('> 1') + assert_equal ['=', Gem::Version.new(1)], Gem::Requirement.parse("=\n1") - assert_equal ['=', Gem::Version.new(0)], @r1_2.parse('=') - assert_equal ['>', Gem::Version.new(0)], @r1_2.parse('>') - - assert_equal ['=', Gem::Version.new(1)], @r1_2.parse("=\n1") - assert_equal ['=', Gem::Version.new(0)], @r1_2.parse("=\njunk") - - assert_equal ['=', Gem::Version.new(2)], @r1_2.parse(Gem::Version.new('2')) + assert_equal ['=', Gem::Version.new(2)], + Gem::Requirement.parse(Gem::Version.new('2')) end - def test_parse_illformed + def test_parse_bad e = assert_raises ArgumentError do - @r1_2.parse(nil) + Gem::Requirement.parse nil end assert_equal 'Illformed requirement [nil]', e.message e = assert_raises ArgumentError do - @r1_2.parse('') + Gem::Requirement.parse "" end assert_equal 'Illformed requirement [""]', e.message end + def test_prerelease_eh + r = req '= 1' + + refute r.prerelease? + + r = req '= 1.a' + + assert r.prerelease? + + r = req '> 1.a', '< 2' + + assert r.prerelease? + end + def test_satisfied_by_eh_bang_equal - r1_2 = Gem::Requirement.new '!= 1.2' - v1_1 = Gem::Version.new '1.1' - v1_2 = Gem::Version.new '1.2' - v1_3 = Gem::Version.new '1.3' + r = req '!= 1.2' - assert_equal true, r1_2.satisfied_by?(nil) - assert_equal true, r1_2.satisfied_by?(v1_1) - assert_equal false, r1_2.satisfied_by?(v1_2) - assert_equal true, r1_2.satisfied_by?(v1_3) + assert_satisfied_by nil, r + assert_satisfied_by "1.1", r + refute_satisfied_by "1.2", r + assert_satisfied_by "1.3", r end def test_satisfied_by_eh_blank - r1_2 = Gem::Requirement.new '1.2' - v1_1 = Gem::Version.new '1.1' - v1_2 = Gem::Version.new '1.2' - v1_3 = Gem::Version.new '1.3' + r = req "1.2" - assert_equal false, r1_2.satisfied_by?(nil) - assert_equal false, r1_2.satisfied_by?(v1_1) - assert_equal true, r1_2.satisfied_by?(v1_2) - assert_equal false, r1_2.satisfied_by?(v1_3) + refute_satisfied_by nil, r + refute_satisfied_by "1.1", r + assert_satisfied_by "1.2", r + refute_satisfied_by "1.3", r end def test_satisfied_by_eh_equal - r1_2 = @r1_2 - v1_1 = Gem::Version.new '1.1' - v1_2 = Gem::Version.new '1.2' - v1_3 = Gem::Version.new '1.3' + r = req "= 1.2" - assert_equal false, r1_2.satisfied_by?(nil) - assert_equal false, r1_2.satisfied_by?(v1_1) - assert_equal true, r1_2.satisfied_by?(v1_2) - assert_equal false, r1_2.satisfied_by?(v1_3) + refute_satisfied_by nil, r + refute_satisfied_by "1.1", r + assert_satisfied_by "1.2", r + refute_satisfied_by "1.3", r end def test_satisfied_by_eh_gt - r1_2 = Gem::Requirement.new '> 1.2' - v1_1 = Gem::Version.new '1.1' - v1_2 = Gem::Version.new '1.2' - v1_3 = Gem::Version.new '1.3' + r = req "> 1.2" - assert_equal false, r1_2.satisfied_by?(v1_1) - assert_equal false, r1_2.satisfied_by?(v1_2) - assert_equal true, r1_2.satisfied_by?(v1_3) + refute_satisfied_by "1.1", r + refute_satisfied_by "1.2", r + assert_satisfied_by "1.3", r assert_raises NoMethodError do - assert_equal true, r1_2.satisfied_by?(nil) + r.satisfied_by? nil end end def test_satisfied_by_eh_gte - r1_2 = Gem::Requirement.new '>= 1.2' - v1_1 = Gem::Version.new '1.1' - v1_2 = Gem::Version.new '1.2' - v1_3 = Gem::Version.new '1.3' + r = req ">= 1.2" - assert_equal false, r1_2.satisfied_by?(v1_1) - assert_equal true, r1_2.satisfied_by?(v1_2) - assert_equal true, r1_2.satisfied_by?(v1_3) + refute_satisfied_by "1.1", r + assert_satisfied_by "1.2", r + assert_satisfied_by "1.3", r assert_raises NoMethodError do - assert_equal true, r1_2.satisfied_by?(nil) + r.satisfied_by? nil end end def test_satisfied_by_eh_list - r = Gem::Requirement.create(['> 1.1', '< 1.3']) - v1_1 = Gem::Version.new '1.1' - v1_2 = Gem::Version.new '1.2' - v1_3 = Gem::Version.new '1.3' + r = req "> 1.1", "< 1.3" - assert_equal false, r.satisfied_by?(v1_1) - assert_equal true, r.satisfied_by?(v1_2) - assert_equal false, r.satisfied_by?(v1_3) + refute_satisfied_by "1.1", r + assert_satisfied_by "1.2", r + refute_satisfied_by "1.3", r assert_raises NoMethodError do - assert_equal true, r.satisfied_by?(nil) + r.satisfied_by? nil end end def test_satisfied_by_eh_lt - r1_2 = Gem::Requirement.new '< 1.2' - v1_1 = Gem::Version.new '1.1' - v1_2 = Gem::Version.new '1.2' - v1_3 = Gem::Version.new '1.3' + r = req "< 1.2" - assert_equal true, r1_2.satisfied_by?(v1_1) - assert_equal false, r1_2.satisfied_by?(v1_2) - assert_equal false, r1_2.satisfied_by?(v1_3) + assert_satisfied_by "1.1", r + refute_satisfied_by "1.2", r + refute_satisfied_by "1.3", r assert_raises NoMethodError do - assert_equal true, r1_2.satisfied_by?(nil) + r.satisfied_by? nil end end def test_satisfied_by_eh_lte - r1_2 = Gem::Requirement.new '<= 1.2' - v1_1 = Gem::Version.new '1.1' - v1_2 = Gem::Version.new '1.2' - v1_3 = Gem::Version.new '1.3' + r = req "<= 1.2" - assert_equal true, r1_2.satisfied_by?(v1_1) - assert_equal true, r1_2.satisfied_by?(v1_2) - assert_equal false, r1_2.satisfied_by?(v1_3) + assert_satisfied_by "1.1", r + assert_satisfied_by "1.2", r + refute_satisfied_by "1.3", r assert_raises NoMethodError do - assert_equal true, r1_2.satisfied_by?(nil) + r.satisfied_by? nil end end def test_satisfied_by_eh_tilde_gt - r1_2 = Gem::Requirement.new '~> 1.2' - v1_1 = Gem::Version.new '1.1' - v1_2 = Gem::Version.new '1.2' - v1_3 = Gem::Version.new '1.3' + r = req "~> 1.2" - assert_equal false, r1_2.satisfied_by?(v1_1) - assert_equal true, r1_2.satisfied_by?(v1_2) - assert_equal true, r1_2.satisfied_by?(v1_3) + refute_satisfied_by "1.1", r + assert_satisfied_by "1.2", r + assert_satisfied_by "1.3", r assert_raises NoMethodError do - assert_equal true, r1_2.satisfied_by?(nil) + r.satisfied_by? nil end end -end + def test_satisfied_by_eh_good + assert_satisfied_by "0.2.33", "= 0.2.33" + assert_satisfied_by "0.2.34", "> 0.2.33" + assert_satisfied_by "1.0", "= 1.0" + assert_satisfied_by "1.0", "1.0" + assert_satisfied_by "1.8.2", "> 1.8.0" + assert_satisfied_by "1.112", "> 1.111" + assert_satisfied_by "0.2", "> 0.0.0" + assert_satisfied_by "0.0.0.0.0.2", "> 0.0.0" + assert_satisfied_by "0.0.1.0", "> 0.0.0.1" + assert_satisfied_by "10.3.2", "> 9.3.2" + assert_satisfied_by "1.0.0.0", "= 1.0" + assert_satisfied_by "10.3.2", "!= 9.3.4" + assert_satisfied_by "10.3.2", "> 9.3.2" + assert_satisfied_by "10.3.2", "> 9.3.2" + assert_satisfied_by " 9.3.2", ">= 9.3.2" + assert_satisfied_by "9.3.2 ", ">= 9.3.2" + assert_satisfied_by "", "= 0" + assert_satisfied_by "", "< 0.1" + assert_satisfied_by " ", "< 0.1 " + assert_satisfied_by "", " < 0.1" + assert_satisfied_by " ", "> 0.a " + assert_satisfied_by "", " > 0.a" + assert_satisfied_by "3.1", "< 3.2.rc1" + assert_satisfied_by "3.2.0", "> 3.2.0.rc1" + assert_satisfied_by "3.2.0.rc2", "> 3.2.0.rc1" + assert_satisfied_by "3.0.rc2", "< 3.0" + assert_satisfied_by "3.0.rc2", "< 3.0.0" + assert_satisfied_by "3.0.rc2", "< 3.0.1" + end + def test_illformed_requirements + [ ">>> 1.3.5", "> blah" ].each do |rq| + assert_raises ArgumentError, "req [#{rq}] should fail" do + Gem::Requirement.new rq + end + end + end + + def test_satisfied_by_eh_boxed + refute_satisfied_by "1.3", "~> 1.4" + assert_satisfied_by "1.4", "~> 1.4" + assert_satisfied_by "1.5", "~> 1.4" + refute_satisfied_by "2.0", "~> 1.4" + + refute_satisfied_by "1.3", "~> 1.4.4" + refute_satisfied_by "1.4", "~> 1.4.4" + assert_satisfied_by "1.4.4", "~> 1.4.4" + assert_satisfied_by "1.4.5", "~> 1.4.4" + refute_satisfied_by "1.5", "~> 1.4.4" + refute_satisfied_by "2.0", "~> 1.4.4" + + refute_satisfied_by "1.1.pre", "~> 1.0.0" + assert_satisfied_by "1.1.pre", "~> 1.1" + refute_satisfied_by "2.0.a", "~> 1.0" + assert_satisfied_by "2.0.a", "~> 2.0" + end + + def test_satisfied_by_eh_multiple + req = [">= 1.4", "<= 1.6", "!= 1.5"] + + refute_satisfied_by "1.3", req + assert_satisfied_by "1.4", req + refute_satisfied_by "1.5", req + assert_satisfied_by "1.6", req + refute_satisfied_by "1.7", req + refute_satisfied_by "2.0", req + end + + def test_satisfied_by_boxed + refute_satisfied_by "1.3", "~> 1.4" + assert_satisfied_by "1.4", "~> 1.4" + assert_satisfied_by "1.5", "~> 1.4" + refute_satisfied_by "2.0", "~> 1.4" + + refute_satisfied_by "1.3", "~> 1.4.4" + refute_satisfied_by "1.4", "~> 1.4.4" + assert_satisfied_by "1.4.4", "~> 1.4.4" + assert_satisfied_by "1.4.5", "~> 1.4.4" + refute_satisfied_by "1.5", "~> 1.4.4" + refute_satisfied_by "2.0", "~> 1.4.4" + end + + def test_bad + refute_satisfied_by "", "> 0.1" + refute_satisfied_by "1.2.3", "!= 1.2.3" + refute_satisfied_by "1.2.003.0.0", "!= 1.02.3" + refute_satisfied_by "4.5.6", "< 1.2.3" + refute_satisfied_by "1.0", "> 1.1" + refute_satisfied_by "", "= 0.1" + refute_satisfied_by "1.1.1", "> 1.1.1" + refute_satisfied_by "1.2", "= 1.1" + refute_satisfied_by "1.40", "= 1.1" + refute_satisfied_by "1.3", "= 1.40" + refute_satisfied_by "9.3.3", "<= 9.3.2" + refute_satisfied_by "9.3.1", ">= 9.3.2" + refute_satisfied_by "9.3.03", "<= 9.3.2" + refute_satisfied_by "1.0.0.1", "= 1.0" + end + + # Assert that two requirements are equal. Handles Gem::Requirements, + # strings, arrays, numbers, and versions. + + def assert_requirement_equal expected, actual + assert_equal req(expected), req(actual) + end + + # Assert that +version+ satisfies +requirement+. + + def assert_satisfied_by version, requirement + assert req(requirement).satisfied_by?(v(version)), + "#{requirement} is satisfied by #{version}" + end + + # Refute the assumption that two requirements are equal. + + def refute_requirement_equal unexpected, actual + refute_equal req(unexpected), req(actual) + end + + # Refute the assumption that +version+ satisfies +requirement+. + + def refute_satisfied_by version, requirement + refute req(requirement).satisfied_by?(v(version)), + "#{requirement} is not satisfied by #{version}" + end +end diff --git a/test/rubygems/test_gem_server.rb b/test/rubygems/test_gem_server.rb index 5a380d008e..41c25fe7d9 100644 --- a/test/rubygems/test_gem_server.rb +++ b/test/rubygems/test_gem_server.rb @@ -78,6 +78,26 @@ class TestGemServer < RubyGemTestCase Marshal.load(Gem.gunzip(@res.body)) end + def test_listen + util_listen + + out, err = capture_io do + @server.listen + end + + assert_equal 1, @server.server.listeners.length + end + + def test_listen_addresses + util_listen + + out, err = capture_io do + @server.listen %w[a b] + end + + assert_equal 2, @server.server.listeners.length + end + def test_quick_a_1_gemspec_rz data = StringIO.new "GET /quick/a-1.gemspec.rz HTTP/1.0\r\n\r\n" @req.parse data @@ -306,5 +326,20 @@ class TestGemServer < RubyGemTestCase assert_equal si, YAML.load(Gem.inflate(@res.body)) end + def util_listen + webrick = Object.new + webrick.instance_variable_set :@listeners, [] + def webrick.listeners() @listeners end + def webrick.listen(host, port) + socket = Object.new + socket.instance_variable_set :@host, host + socket.instance_variable_set :@port, port + def socket.addr() [nil, @port, @host] end + @listeners << socket + end + + @server.instance_variable_set :@server, webrick + end + end diff --git a/test/rubygems/test_gem_source_index.rb b/test/rubygems/test_gem_source_index.rb index 40a9a85b27..acace09da9 100644 --- a/test/rubygems/test_gem_source_index.rb +++ b/test/rubygems/test_gem_source_index.rb @@ -1,9 +1,3 @@ -#-- -# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. -# All rights reserved. -# See LICENSE.txt for permissions. -#++ - require_relative 'gemutilities' require 'rubygems/source_index' require 'rubygems/config_file' @@ -31,7 +25,7 @@ class TestGemSourceIndex < RubyGemTestCase a1 = quick_gem 'a', '1' do |spec| spec.author = 'author 1' end - spec_file = File.join spec_dir, "#{a1.full_name}.gemspec" + spec_file = File.join spec_dir, a1.spec_name File.open spec_file, 'w' do |fp| fp.write a1.to_ruby @@ -52,7 +46,7 @@ class TestGemSourceIndex < RubyGemTestCase a1 = quick_gem 'a', '1' do |spec| spec.author = 'author 1' end - spec_file = File.join spec_dir, "#{a1.full_name}.gemspec" + spec_file = File.join spec_dir, a1.spec_name File.open spec_file, 'w' do |fp| fp.write a1.to_ruby @@ -298,11 +292,11 @@ WARNING: Invalid .gemspec format in '#{spec_file}' a1 = quick_gem 'a', '1' do |spec| spec.author = 'author 1' end a2 = quick_gem 'a', '1' do |spec| spec.author = 'author 2' end - File.open File.join(spec_dir1, "#{a1.full_name}.gemspec"), 'w' do |fp| + File.open File.join(spec_dir1, a1.spec_name), 'w' do |fp| fp.write a1.to_ruby end - File.open File.join(spec_dir2, "#{a2.full_name}.gemspec"), 'w' do |fp| + File.open File.join(spec_dir2, a2.spec_name), 'w' do |fp| fp.write a2.to_ruby end @@ -340,7 +334,7 @@ WARNING: Invalid .gemspec format in '#{spec_file}' end def test_refresh_bang - a1_spec = File.join @gemhome, "specifications", "#{@a1.full_name}.gemspec" + a1_spec = File.join @gemhome, "specifications", @a1.spec_name FileUtils.mv a1_spec, @tempdir @@ -348,7 +342,7 @@ WARNING: Invalid .gemspec format in '#{spec_file}' refute source_index.gems.include?(@a1.full_name) - FileUtils.mv File.join(@tempdir, "#{@a1.full_name}.gemspec"), a1_spec + FileUtils.mv File.join(@tempdir, @a1.spec_name), a1_spec source_index.refresh! diff --git a/test/rubygems/test_gem_source_info_cache.rb b/test/rubygems/test_gem_source_info_cache.rb deleted file mode 100644 index f712f138c1..0000000000 --- a/test/rubygems/test_gem_source_info_cache.rb +++ /dev/null @@ -1,447 +0,0 @@ -#-- -# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. -# All rights reserved. -# See LICENSE.txt for permissions. -#++ - -require_relative 'gemutilities' -require 'rubygems/source_info_cache' - -class Gem::SourceIndex - public :gems -end - -class TestGemSourceInfoCache < RubyGemTestCase - - def setup - @original_sources = Gem.sources - - super - - util_setup_fake_fetcher - - @sic = Gem::SourceInfoCache.new - @sic.instance_variable_set :@fetcher, @fetcher - - @si_new = Gem::SourceIndex.new - @sice_new = Gem::SourceInfoCacheEntry.new @si_new, 0 - - prep_cache_files @sic - - @sic.reset_cache_data - end - - def teardown - super - Gem.sources.replace @original_sources - Gem::SourceInfoCache.instance_variable_set :@cache, nil - end - - def test_self_cache_refreshes - Gem.configuration.update_sources = true #true by default - si = Gem::SourceIndex.new - si.add_spec @a1 - - @fetcher.data["#{@gem_repo}Marshal.#{@marshal_version}"] = si.dump - - Gem.sources.replace %W[#{@gem_repo}] - - use_ui @ui do - refute_nil Gem::SourceInfoCache.cache - assert_kind_of Gem::SourceInfoCache, Gem::SourceInfoCache.cache - assert_equal Gem::SourceInfoCache.cache.object_id, - Gem::SourceInfoCache.cache.object_id - end - - assert_match %r|Bulk updating|, @ui.output - end - - def test_self_cache_skips_refresh_based_on_configuration - Gem.configuration.update_sources = false - si = Gem::SourceIndex.new - si.add_spec @a1 - - @fetcher.data["#{@gem_repo}Marshal.#{@marshal_version}"] = si.dump - - Gem.sources.replace %w[#{@gem_repo}] - - use_ui @ui do - refute_nil Gem::SourceInfoCache.cache - assert_kind_of Gem::SourceInfoCache, Gem::SourceInfoCache.cache - assert_equal Gem::SourceInfoCache.cache.object_id, - Gem::SourceInfoCache.cache.object_id - refute_match %r|Bulk updating|, @ui.output - end - end - - def test_self_cache_data - si = Gem::SourceIndex.new - si.add_spec @a1 - - @fetcher.data["#{@gem_repo}Marshal.#{@marshal_version}"] = si.dump - - Gem::SourceInfoCache.instance_variable_set :@cache, nil - sice = Gem::SourceInfoCacheEntry.new si, 0 - - use_ui @ui do - gems = Gem::SourceInfoCache.cache_data[@gem_repo].source_index.gems - gem_names = gems.map { |_, spec| spec.full_name } - - assert_equal si.gems.map { |_,spec| spec.full_name }, gem_names - end - end - - def test_cache_data - assert_equal [[@gem_repo, @usr_sice]], @sic.cache_data.to_a.sort - end - - def test_cache_data_dirty - def @sic.dirty() @dirty; end - assert_equal false, @sic.dirty, 'clean on init' - @sic.cache_data - assert_equal false, @sic.dirty, 'clean on fetch' - @sic.update - @sic.cache_data - assert_equal true, @sic.dirty, 'still dirty' - end - - def test_cache_data_irreparable - @fetcher.data["#{@gem_repo}Marshal.#{@marshal_version}"] = @source_index.dump - - data = { @gem_repo => { 'totally' => 'borked' } } - - cache_files = [ - @sic.system_cache_file, - @sic.latest_system_cache_file, - @sic.user_cache_file, - @sic.latest_user_cache_file - ] - - cache_files.each do |fn| - FileUtils.mkdir_p File.dirname(fn) - open(fn, "wb") { |f| f.write Marshal.dump(data) } - end - - @sic.instance_eval { @cache_data = nil } - - fetched = use_ui @ui do @sic.cache_data end - - fetched_si = fetched["#{@gem_repo}"].source_index - - assert_equal @source_index.index_signature, fetched_si.index_signature - end - - def test_cache_data_none_readable - FileUtils.chmod 0222, @sic.system_cache_file - FileUtils.chmod 0222, @sic.latest_system_cache_file - FileUtils.chmod 0222, @sic.user_cache_file - FileUtils.chmod 0222, @sic.latest_user_cache_file - return if (File.stat(@sic.system_cache_file).mode & 0222) != 0222 - return if (File.stat(@sic.user_cache_file).mode & 0222) != 0222 - # HACK for systems that don't support chmod - assert_equal({}, @sic.cache_data) - end - - def test_cache_data_none_writable - FileUtils.chmod 0444, @sic.system_cache_file - FileUtils.chmod 0444, @sic.user_cache_file - e = assert_raises RuntimeError do - @sic.cache_data - end - assert_equal 'unable to locate a writable cache file', e.message - end - - def test_cache_data_nonexistent - FileUtils.rm @sic.system_cache_file - FileUtils.rm @sic.latest_system_cache_file - FileUtils.rm @sic.user_cache_file - FileUtils.rm @sic.latest_user_cache_file - - # TODO test verbose output - assert_equal [], @sic.cache_data.to_a.sort - end - - def test_cache_data_repair - data = { - @gem_repo => { - 'cache' => Gem::SourceIndex.new, - 'size' => 0, - } - } - [@sic.system_cache_file, @sic.user_cache_file].each do |fn| - FileUtils.mkdir_p File.dirname(fn) - open(fn, "wb") { |f| f.write Marshal.dump(data) } - end - - @sic.instance_eval { @cache_data = nil } - - expected = { - @gem_repo => - Gem::SourceInfoCacheEntry.new(Gem::SourceIndex.new, 0) - } - assert_equal expected, @sic.cache_data - end - - def test_cache_data_user_fallback - FileUtils.chmod 0444, @sic.system_cache_file - - assert_equal [[@gem_repo, @usr_sice]], @sic.cache_data.to_a.sort - end - - def test_cache_file - assert_equal @gemcache, @sic.cache_file - end - - def test_cache_file_user_fallback - FileUtils.chmod 0444, @sic.system_cache_file - assert_equal @usrcache, @sic.cache_file - end - - def test_cache_file_none_writable - FileUtils.chmod 0444, @sic.system_cache_file - FileUtils.chmod 0444, @sic.user_cache_file - e = assert_raises RuntimeError do - @sic.cache_file - end - assert_equal 'unable to locate a writable cache file', e.message - end - - def test_flush - @sic.cache_data[@gem_repo] = @sice_new - @sic.update - @sic.flush - - assert_equal [[@gem_repo, @sice_new]], - read_cache(@sic.system_cache_file).to_a.sort - end - - def test_latest_cache_data - util_make_gems - - sice = Gem::SourceInfoCacheEntry.new @source_index, 0 - - @sic.set_cache_data @gem_repo => sice - latest = @sic.latest_cache_data - beginning_with_a = Gem::Dependency.new(/^a/, Gem::Requirement.default) - gems = latest[@gem_repo].source_index.search(beginning_with_a).map { |s| s.full_name } - - assert_equal %w[a-2 a_evil-9], gems - end - - def test_latest_cache_file - latest_cache_file = File.join File.dirname(@gemcache), - "latest_#{File.basename @gemcache}" - assert_equal latest_cache_file, @sic.latest_cache_file - end - - def test_latest_system_cache_file - assert_equal File.join(Gem.dir, "latest_source_cache"), - @sic.latest_system_cache_file - end - - def test_latest_user_cache_file - assert_equal @latest_usrcache, @sic.latest_user_cache_file - end - - def test_read_system_cache - assert_equal [[@gem_repo, @sys_sice]], @sic.cache_data.to_a.sort - end - - def test_read_user_cache - FileUtils.chmod 0444, @sic.user_cache_file - FileUtils.chmod 0444, @sic.latest_user_cache_file - - @si = Gem::SourceIndex.new - @si.add_specs @a1, @a2 - - @sice = Gem::SourceInfoCacheEntry.new @si, 0 - - @sic.set_cache_data({ @gem_repo => @sice }) - @sic.update - @sic.write_cache - @sic.reset_cache_data - - user_cache_data = @sic.cache_data.to_a.sort - - assert_equal 1, user_cache_data.length - user_cache_data = user_cache_data.first - - assert_equal @gem_repo, user_cache_data.first - - gems = user_cache_data.last.source_index.map { |_,spec| spec.full_name } - assert_equal [@a2.full_name], gems - end - - def test_search - si = Gem::SourceIndex.new - si.add_spec @a1 - cache_data = { @gem_repo => Gem::SourceInfoCacheEntry.new(si, nil) } - @sic.instance_variable_set :@cache_data, cache_data - - assert_equal [@a1], @sic.search(//) - end - - def test_search_all - util_make_gems - - sice = Gem::SourceInfoCacheEntry.new @source_index, 0 - - @sic.set_cache_data @gem_repo => sice - @sic.update - @sic.instance_variable_set :@only_latest, false - @sic.write_cache - @sic.reset_cache_data - - gem_names = @sic.search(//, false, true).map { |spec| spec.full_name } - - assert_equal %w[a-1 a-2 a-3.a a_evil-9 c-1.2], gem_names - end - - def test_search_dependency - si = Gem::SourceIndex.new - si.add_spec @a1 - cache_data = { @gem_repo => Gem::SourceInfoCacheEntry.new(si, nil) } - @sic.instance_variable_set :@cache_data, cache_data - - dep = Gem::Dependency.new @a1.name, @a1.version - - assert_equal [@a1], @sic.search(dep) - end - - def test_search_no_matches - si = Gem::SourceIndex.new - si.add_spec @a1 - cache_data = { @gem_repo => Gem::SourceInfoCacheEntry.new(si, nil) } - @sic.instance_variable_set :@cache_data, cache_data - - assert_equal [], @sic.search(/nonexistent/) - end - - def test_search_no_matches_in_source - si = Gem::SourceIndex.new - si.add_spec @a1 - cache_data = { @gem_repo => Gem::SourceInfoCacheEntry.new(si, nil) } - @sic.instance_variable_set :@cache_data, cache_data - Gem.sources.replace %w[more-gems.example.com] - - assert_equal [], @sic.search(/nonexistent/) - end - - def test_search_with_source - si = Gem::SourceIndex.new - si.add_spec @a1 - cache_data = { @gem_repo => Gem::SourceInfoCacheEntry.new(si, nil) } - @sic.instance_variable_set :@cache_data, cache_data - - assert_equal [[@a1, @gem_repo]], - @sic.search_with_source(//) - end - - def test_system_cache_file - assert_equal File.join(Gem.dir, "source_cache"), @sic.system_cache_file - end - - def test_user_cache_file - assert_equal @usrcache, @sic.user_cache_file - end - - def test_write_cache - @sic.cache_data[@gem_repo] = @sice_new - @sic.write_cache - - assert_equal [[@gem_repo, @sice_new]], - read_cache(@sic.system_cache_file).to_a.sort - assert_equal [[@gem_repo, @usr_sice]], - read_cache(@sic.user_cache_file).to_a.sort - end - - def test_write_cache_user - FileUtils.chmod 0444, @sic.system_cache_file - @sic.set_cache_data({@gem_repo => @sice_new}) - @sic.update - @sic.write_cache - @sic.instance_variable_set :@only_latest, false - - assert File.exist?(@sic.user_cache_file), 'user_cache_file' - assert File.exist?(@sic.latest_user_cache_file), - 'latest_user_cache_file exists' - - assert_equal [[@gem_repo, @sys_sice]], - read_cache(@sic.system_cache_file).to_a.sort - assert_equal [[@gem_repo, @sice_new]], - read_cache(@sic.user_cache_file).to_a.sort - end - - def test_write_cache_user_from_scratch - FileUtils.rm_rf @sic.user_cache_file - FileUtils.rm_rf @sic.latest_user_cache_file - - FileUtils.chmod 0444, @sic.system_cache_file - FileUtils.chmod 0444, @sic.latest_system_cache_file - - @si = Gem::SourceIndex.new - @si.add_specs @a1, @a2 - - @sice = Gem::SourceInfoCacheEntry.new @si, 0 - - @sic.set_cache_data({ @gem_repo => @sice }) - @sic.update - - @sic.write_cache - - assert File.exist?(@sic.user_cache_file), 'system_cache_file' - assert File.exist?(@sic.latest_user_cache_file), - 'latest_system_cache_file' - - user_cache_data = read_cache(@sic.user_cache_file).to_a.sort - assert_equal 1, user_cache_data.length, 'user_cache_data length' - user_cache_data = user_cache_data.first - - assert_equal @gem_repo, user_cache_data.first - - gems = user_cache_data.last.source_index.map { |_,spec| spec.full_name } - assert_equal [@a1.full_name, @a2.full_name], gems.sort - - user_cache_data = read_cache(@sic.latest_user_cache_file).to_a.sort - assert_equal 1, user_cache_data.length - user_cache_data = user_cache_data.first - - assert_equal @gem_repo, user_cache_data.first - - gems = user_cache_data.last.source_index.map { |_,spec| spec.full_name } - assert_equal [@a2.full_name], gems - end - - def test_write_cache_user_no_directory - FileUtils.rm_rf File.dirname(@sic.user_cache_file) - FileUtils.chmod 0444, @sic.system_cache_file - @sic.set_cache_data({ @gem_repo => @sice_new }) - @sic.update - @sic.write_cache - - assert_equal [[@gem_repo, @sys_sice]], - read_cache(@sic.system_cache_file).to_a.sort - assert_equal [[@gem_repo, @sys_sice]], - read_cache(@sic.user_cache_file).to_a.sort - assert_equal [[@gem_repo, @sice_new]], - read_cache(@sic.latest_user_cache_file).to_a.sort - end - - def test_write_cache_user_only_latest - FileUtils.chmod 0444, @sic.system_cache_file - @sic.set_cache_data({@gem_repo => @sice_new}) - @sic.update - @sic.write_cache - - assert File.exist?(@sic.user_cache_file), 'user_cache_file' - assert File.exist?(@sic.latest_user_cache_file), - 'latest_user_cache_file exists' - - assert_equal [[@gem_repo, @sys_sice]], - read_cache(@sic.system_cache_file).to_a.sort - assert_equal [[@gem_repo, @sice_new]], - read_cache(@sic.user_cache_file).to_a.sort - end - -end - diff --git a/test/rubygems/test_gem_source_info_cache_entry.rb b/test/rubygems/test_gem_source_info_cache_entry.rb deleted file mode 100644 index e05a05f69c..0000000000 --- a/test/rubygems/test_gem_source_info_cache_entry.rb +++ /dev/null @@ -1,78 +0,0 @@ -require_relative 'gemutilities' -require 'rubygems/source_info_cache_entry' - -class TestGemSourceInfoCacheEntry < RubyGemTestCase - - def setup - super - - util_setup_fake_fetcher - - @si = Gem::SourceIndex.new - @si.add_spec @a1 - @sic_e = Gem::SourceInfoCacheEntry.new @si, @si.dump.size - end - - def test_refresh - @fetcher.data["#{@gem_repo}Marshal.#{@marshal_version}.Z"] = - proc { raise } - @fetcher.data["#{@gem_repo}Marshal.#{@marshal_version}"] = @si.dump - - use_ui @ui do - @sic_e.refresh @gem_repo, true - end - end - - def test_refresh_all - @si.add_spec @a2 - - a1_name = @a1.full_name - a2_name = @a2.full_name - - @fetcher.data["#{@gem_repo}quick/index.rz"] = - util_zip [a1_name, a2_name].join("\n") - @fetcher.data["#{@gem_repo}quick/latest_index.rz"] = util_zip a2_name - @fetcher.data["#{@gem_repo}quick/Marshal.#{Gem.marshal_version}/#{a1_name}.gemspec.rz"] = util_zip Marshal.dump(@a1) - @fetcher.data["#{@gem_repo}quick/Marshal.#{Gem.marshal_version}/#{a2_name}.gemspec.rz"] = util_zip Marshal.dump(@a2) - @fetcher.data["#{@gem_repo}Marshal.#{Gem.marshal_version}"] = - Marshal.dump @si - - sic_e = Gem::SourceInfoCacheEntry.new Gem::SourceIndex.new, 0 - - assert_equal [], sic_e.source_index.map { |n,| n } - - use_ui @ui do - assert sic_e.refresh(@gem_repo, false) - end - - assert_equal [a2_name], sic_e.source_index.map { |n,| n }.sort - - use_ui @ui do - sic_e.refresh @gem_repo, true - end - - assert_equal [a1_name, a2_name], sic_e.source_index.map { |n,| n }.sort - end - - def test_refresh_bad_uri - assert_raises URI::BadURIError do - @sic_e.refresh 'gems.example.com', true - end - end - - def test_refresh_update - si = Gem::SourceIndex.new - si.add_spec @a1 - si.add_spec @b2 - @fetcher.data["#{@gem_repo}Marshal.#{@marshal_version}"] = si.dump - - use_ui @ui do - @sic_e.refresh @gem_repo, true - end - - new_gem = @sic_e.source_index.specification(@b2.full_name) - assert_equal @b2.full_name, new_gem.full_name - end - -end - diff --git a/test/rubygems/test_gem_spec_fetcher.rb b/test/rubygems/test_gem_spec_fetcher.rb index 4a6f22bafd..6864fd3beb 100644 --- a/test/rubygems/test_gem_spec_fetcher.rb +++ b/test/rubygems/test_gem_spec_fetcher.rb @@ -39,16 +39,17 @@ class TestGemSpecFetcher < RubyGemTestCase end def test_fetch_all - @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a1.full_name}.gemspec.rz"] = + @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a1.spec_name}.rz"] = util_zip(Marshal.dump(@a1)) - @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a2.full_name}.gemspec.rz"] = + @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a2.spec_name}.rz"] = util_zip(Marshal.dump(@a2)) - @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a_pre.full_name}.gemspec.rz"] = + @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a_pre.spec_name}.rz"] = util_zip(Marshal.dump(@a_pre)) - @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a3a.full_name}.gemspec.rz"] = + @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a3a.spec_name}.rz"] = util_zip(Marshal.dump(@a3a)) dep = Gem::Dependency.new 'a', 1 + specs_and_sources = @sf.fetch dep, true spec_names = specs_and_sources.map do |spec, source_uri| @@ -63,11 +64,11 @@ class TestGemSpecFetcher < RubyGemTestCase end def test_fetch_latest - @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a1.full_name}.gemspec.rz"] = + @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a1.spec_name}.rz"] = util_zip(Marshal.dump(@a1)) - @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a2.full_name}.gemspec.rz"] = + @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a2.spec_name}.rz"] = util_zip(Marshal.dump(@a2)) - @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a_pre.full_name}.gemspec.rz"] = + @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a_pre.spec_name}.rz"] = util_zip(Marshal.dump(@a_pre)) dep = Gem::Dependency.new 'a', 1 @@ -81,11 +82,11 @@ class TestGemSpecFetcher < RubyGemTestCase end def test_fetch_prerelease - @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a1.full_name}.gemspec.rz"] = + @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a1.spec_name}.rz"] = util_zip(Marshal.dump(@a1)) - @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a2.full_name}.gemspec.rz"] = + @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a2.spec_name}.rz"] = util_zip(Marshal.dump(@a2)) - @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a_pre.full_name}.gemspec.rz"] = + @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a_pre.spec_name}.rz"] = util_zip(Marshal.dump(@a_pre)) dep = Gem::Dependency.new 'a', '1.a' @@ -98,37 +99,6 @@ class TestGemSpecFetcher < RubyGemTestCase assert_equal [[@a_pre.full_name, @gem_repo]], spec_names end - def test_fetch_legacy_repo - @fetcher.data.delete "#{@gem_repo}specs.#{Gem.marshal_version}.gz" - @fetcher.data["#{@gem_repo}yaml"] = '' - util_setup_source_info_cache @a1, @a2 - - dep = Gem::Dependency.new 'a', 1 - specs = nil - - use_ui @ui do - specs = @sf.fetch dep, true - end - - expected = <<-EOF -WARNING: RubyGems 1.2+ index not found for: -\thttp://gems.example.com/ - -RubyGems will revert to legacy indexes degrading performance. - EOF - - assert_equal expected, @ui.error - - specs = specs.map { |spec, source_uri| [spec.full_name, source_uri] } - - expected = [ - [@a1.full_name, @gem_repo], - [@a2.full_name, @gem_repo], - ] - - assert_equal expected, specs - end - def test_fetch_platform util_set_arch 'i386-linux' @@ -146,7 +116,7 @@ RubyGems will revert to legacy indexes degrading performance. end def test_fetch_spec - spec_uri = "#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a1.full_name}.gemspec" + spec_uri = "#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a1.spec_name}" @fetcher.data["#{spec_uri}.rz"] = util_zip(Marshal.dump(@a1)) spec = @sf.fetch_spec ['a', Gem::Version.new(1), 'ruby'], @uri @@ -154,19 +124,19 @@ RubyGems will revert to legacy indexes degrading performance. cache_dir = @sf.cache_dir URI.parse(spec_uri) - cache_file = File.join cache_dir, "#{@a1.full_name}.gemspec" + cache_file = File.join cache_dir, @a1.spec_name assert File.exist?(cache_file) end def test_fetch_spec_cached - spec_uri = "#{@gem_repo}/#{Gem::MARSHAL_SPEC_DIR}#{@a1.full_name}.gemspec" + spec_uri = "#{@gem_repo}/#{Gem::MARSHAL_SPEC_DIR}#{@a1.spec_name}" @fetcher.data["#{spec_uri}.rz"] = nil cache_dir = @sf.cache_dir URI.parse(spec_uri) FileUtils.mkdir_p cache_dir - cache_file = File.join cache_dir, "#{@a1.full_name}.gemspec" + cache_file = File.join cache_dir, @a1.spec_name open cache_file, 'wb' do |io| Marshal.dump @a1, io @@ -186,7 +156,7 @@ RubyGems will revert to legacy indexes degrading performance. end def test_fetch_spec_platform_ruby - @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a1.full_name}.gemspec.rz"] = + @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a1.spec_name}.rz"] = util_zip(Marshal.dump(@a1)) spec = @sf.fetch_spec ['a', Gem::Version.new(1), nil], @uri diff --git a/test/rubygems/test_gem_specification.rb b/test/rubygems/test_gem_specification.rb index fb5cf67461..5979890aeb 100644 --- a/test/rubygems/test_gem_specification.rb +++ b/test/rubygems/test_gem_specification.rb @@ -1,11 +1,5 @@ -#-- -# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. -# All rights reserved. -# See LICENSE.txt for permissions. -#++ - -require 'stringio' require_relative 'gemutilities' +require 'stringio' require 'rubygems/specification' class TestGemSpecification < RubyGemTestCase @@ -129,7 +123,7 @@ end end def test_self_load - spec = File.join @gemhome, 'specifications', "#{@a2.full_name}.gemspec" + spec = File.join @gemhome, 'specifications', @a2.spec_name gs = Gem::Specification.load spec assert_equal @a2, gs @@ -145,16 +139,6 @@ end assert_equal false, spec.has_unit_tests? end - def test_self_load_legacy_yaml - s = YAML.load StringIO.new(LEGACY_YAML_SPEC) - assert_equal 'keyedlist', s.name - assert_equal '0.4.0', s.version.to_s - assert_equal true, s.has_rdoc? - #assert_equal Date.today, s.date - #assert s.required_ruby_version.satisfied_by?(Gem::Version.new('1')) - assert_equal false, s.has_unit_tests? - end - def test_self_normalize_yaml_input_with_183_yaml input = "!ruby/object:Gem::Specification " assert_equal "--- #{input}", Gem::Specification.normalize_yaml_input(input) @@ -538,8 +522,7 @@ end def test_full_gem_path_double_slash gemhome = @gemhome.sub(/\w\//, '\&/') - @a1.loaded_from = File.join gemhome, 'specifications', - "#{@a1.full_name}.gemspec" + @a1.loaded_from = File.join gemhome, 'specifications', @a1.spec_name assert_equal File.join(@gemhome, 'gems', @a1.full_name), @a1.full_gem_path @@ -730,6 +713,10 @@ end assert_equal( 1, (s2 <=> s1)) end + def test_spec_name + assert_equal 'a-1.gemspec', @a1.spec_name + end + def test_summary assert_equal 'this is a summary', @a1.summary end diff --git a/test/rubygems/test_gem_stream_ui.rb b/test/rubygems/test_gem_stream_ui.rb index 886f53a60d..395dbda9e1 100644 --- a/test/rubygems/test_gem_stream_ui.rb +++ b/test/rubygems/test_gem_stream_ui.rb @@ -46,6 +46,26 @@ class TestGemStreamUI < RubyGemTestCase end end + def test_ask_for_password + skip 'Always uses $stdin on windows' if Gem.win_platform? + + timeout(1) do + expected_answer = "Arthur, King of the Britons" + @in.string = "#{expected_answer}\n" + actual_answer = @sui.ask_for_password("What is your name?") + assert_equal expected_answer, actual_answer + end + end + + def test_ask_for_password_no_tty + @in.tty = false + + timeout(0.1) do + answer = @sui.ask_for_password("what is the airspeed velocity of an unladen swallow?") + assert_equal nil, answer + end + end + def test_ask_yes_no_no_tty_with_default @in.tty = false diff --git a/test/rubygems/test_gem_validator.rb b/test/rubygems/test_gem_validator.rb index 529c93ae1a..51dad524f3 100644 --- a/test/rubygems/test_gem_validator.rb +++ b/test/rubygems/test_gem_validator.rb @@ -1,9 +1,3 @@ -#-- -# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. -# All rights reserved. -# See LICENSE.txt for permissions. -#++ - require_relative 'gemutilities' require_relative 'simple_gem' require 'rubygems/validator' diff --git a/test/rubygems/test_gem_version.rb b/test/rubygems/test_gem_version.rb index f2b0280f3d..f3692682b6 100644 --- a/test/rubygems/test_gem_version.rb +++ b/test/rubygems/test_gem_version.rb @@ -1,316 +1,172 @@ -#-- -# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. -# All rights reserved. -# See LICENSE.txt for permissions. -#++ - require_relative 'gemutilities' require 'rubygems/version' class TestGemVersion < RubyGemTestCase - def setup - super - - version = Object.new - def version.to_s() '1.4.0' end - - @v1_0 = Gem::Version.new '1.0' - @v1_2 = Gem::Version.new '1.2' - @v1_3 = Gem::Version.new '1.3' - @v1_4_0 = Gem::Version.new version - end - - def test_class_create - assert_version Gem::Version.create('1.0') - assert_version Gem::Version.create("1.0 ") - assert_version Gem::Version.create(" 1.0 ") - assert_version Gem::Version.create("1.0\n") - assert_version Gem::Version.create("\n1.0\n") - - assert_equal Gem::Version.create('1'), Gem::Version.create(1) - end - - def test_class_create_malformed - e = assert_raises ArgumentError do Gem::Version.create("junk") end - assert_equal "Malformed version number string junk", e.message - - e = assert_raises ArgumentError do Gem::Version.create("1.0\n2.0") end - assert_equal "Malformed version number string 1.0\n2.0", e.message + def test_bump + assert_bumped_version_equal "5.3", "5.2.4" end - def test_bad - assert_inadequate( "", "> 0.1") - assert_inadequate( "1.2.3", "!= 1.2.3") - assert_inadequate( "1.2.003.0.0", "!= 1.02.3") - assert_inadequate( "4.5.6", "< 1.2.3") - assert_inadequate( "1.0", "> 1.1") - assert_inadequate( "0", ">") - assert_inadequate( "0", "<") - assert_inadequate( "", "= 0.1") - assert_inadequate( "1.1.1", "> 1.1.1") - assert_inadequate( "1.2", "= 1.1") - assert_inadequate( "1.40", "= 1.1") - assert_inadequate( "1.3", "= 1.40") - assert_inadequate( "9.3.3", "<= 9.3.2") - assert_inadequate( "9.3.1", ">= 9.3.2") - assert_inadequate( "9.3.03", "<= 9.3.2") - assert_inadequate( "1.0.0.1", "= 1.0") + def test_bump_alpha + assert_bumped_version_equal "5.3", "5.2.4.a" end def test_bump_trailing_zeros - v = Gem::Version.new("5.0.0") - assert_equal "5.1", v.bump.to_s - end - - def test_bump - v = Gem::Version.new("5.2.4") - assert_equal "5.3", v.bump.to_s - end - - def test_bump_alpha - v = Gem::Version.new("5.2.4.a") - assert_equal "5.3", v.bump.to_s + assert_bumped_version_equal "5.1", "5.0.0" end def test_bump_one_level - v = Gem::Version.new("5") - assert_equal "6", v.bump.to_s + assert_bumped_version_equal "6", "5" end - def test_eql_eh - v1_2 = Gem::Version.new '1.2' - v1_2_0 = Gem::Version.new '1.2.0' - - assert_equal true, v1_2.eql?(@v1_2) - assert_equal true, @v1_2.eql?(v1_2) + # FIX: For "legacy reasons," any object that responds to +version+ + # is returned unchanged. I'm not certain why. - assert_equal false, v1_2_0.eql?(@v1_2) - assert_equal false, @v1_2.eql?(v1_2_0) + def test_class_create + fake = Object.new + def fake.version; "1.0" end - assert_equal false, @v1_2.eql?(@v1_3) - assert_equal false, @v1_3.eql?(@v1_2) + assert_same fake, Gem::Version.create(fake) + assert_nil Gem::Version.create(nil) + assert_equal v("5.1"), Gem::Version.create("5.1") end - def test_eql_eh4 - v1_4 = Gem::Version.new '1.4' - v1_4_0 = Gem::Version.new "1.4.0" - - assert_equal true, v1_4_0.eql?(@v1_4_0) - assert_equal true, @v1_4_0.eql?(v1_4_0) - - assert_equal false, v1_4.eql?(@v1_4_0) - assert_equal false, @v1_4_0.eql?(v1_4) - - assert_equal false, @v1_4_0.eql?(@v1_3) - assert_equal false, @v1_3.eql?(@v1_4_0) + def test_eql_eh + assert_version_eql "1.2", "1.2" + refute_version_eql "1.2", "1.2.0" + refute_version_eql "1.2", "1.3" end - def test_equals2 - v = Gem::Version.new("1.2") - - assert_equal v, @v1_2 - assert_equal @v1_2, v - - refute_equal @v1_2, @v1_3 - refute_equal @v1_3, @v1_2 + def test_equals + assert_version_equal "1.2", "1.2" + refute_version_equal "1.2", "1.3" end + # REVISIT: consider removing as too impl-bound def test_hash - v1_2 = Gem::Version.new "1.2" - v1_2_0 = Gem::Version.new "1.2.0" - v1_4_0 = Gem::Version.new "1.4.0" - - assert_equal v1_2.hash, @v1_2.hash - - refute_equal v1_2_0.hash, @v1_2.hash - - assert_equal v1_4_0.hash, @v1_4_0.hash - - refute_equal @v1_2.hash, @v1_3.hash - - refute_equal @v1_2.hash, @v1_4_0.hash + assert_equal v("1.2").hash, v("1.2").hash + refute_equal v("1.2").hash, v("1.3").hash + refute_equal v("1.2").hash, v("1.2.0").hash end - def test_illformed_requirements - [ ">>> 1.3.5", "> blah" ].each do |rq| - assert_raises ArgumentError, "req [#{rq}] should fail" do - Gem::Version::Requirement.new rq - end + def test_initialize + ["1.0", "1.0 ", " 1.0 ", "1.0\n", "\n1.0\n"].each do |good| + assert_version_equal "1.0", good end - end - def test_normalize - assert_equal [0], Gem::Version.new("").normalize.map { |part| part.value } - assert_equal [0], Gem::Version.new("0").normalize.map { |part| part.value } - assert_equal [1], Gem::Version.new("1").normalize.map { |part| part.value } - assert_equal [1], Gem::Version.new("1.0").normalize.map { |part| part.value } - assert_equal [1, 1], Gem::Version.new("1.1").normalize.map { |part| part.value } - assert_equal [1, 1, "a"], Gem::Version.new("1.1.a").normalize.map { |part| part.value } + assert_version_equal "1", 1 end - def test_ok - assert_adequate( "0.2.33", "= 0.2.33") - assert_adequate( "0.2.34", "> 0.2.33") - assert_adequate( "1.0", "= 1.0") - assert_adequate( "1.0", "1.0") - assert_adequate( "1.8.2", "> 1.8.0") - assert_adequate( "1.112", "> 1.111") - assert_adequate( "0.2", "> 0.0.0") - assert_adequate( "0.0.0.0.0.2", "> 0.0.0") - assert_adequate( "0.0.1.0", "> 0.0.0.1") - assert_adequate( "10.3.2", "> 9.3.2") - assert_adequate( "1.0.0.0", "= 1.0") - assert_adequate( "10.3.2", "!= 9.3.4") - assert_adequate( "10.3.2", "> 9.3.2") - assert_adequate( "10.3.2", "> 9.3.2") - assert_adequate( " 9.3.2", ">= 9.3.2") - assert_adequate( "9.3.2 ", ">= 9.3.2") - assert_adequate( "", "= 0") - assert_adequate( "", "< 0.1") - assert_adequate( " ", "< 0.1 ") - assert_adequate( "", " < 0.1") - assert_adequate( " ", "> 0.a ") - assert_adequate( "", " > 0.a") - assert_adequate( "0", "=") - assert_adequate( "0", ">=") - assert_adequate( "0", "<=") - assert_adequate( "3.1", "< 3.2.rc1") - assert_adequate( "3.2.0", "> 3.2.0.rc1") - assert_adequate( "3.2.0.rc2", "> 3.2.0.rc1") - assert_adequate( "3.0.rc2", "< 3.0") - assert_adequate( "3.0.rc2", "< 3.0.0") - assert_adequate( "3.0.rc2", "< 3.0.1") - end + def test_initialize_bad + ["junk", "1.0\n2.0"].each do |bad| + e = assert_raises ArgumentError do + Gem::Version.new bad + end - def test_parse_parts_from_version_string - assert_equal [], part_values(Gem::Version.new("").parse_parts_from_version_string) - assert_equal [1], part_values(Gem::Version.new("1").parse_parts_from_version_string) - assert_equal [1, 0], part_values(Gem::Version.new("1.0").parse_parts_from_version_string) - assert_equal [1, 0, "a"], part_values(Gem::Version.new("1.0.a").parse_parts_from_version_string) + assert_equal "Malformed version number string #{bad}", e.message + end end def test_prerelease - assert Gem::Version.new('1.2.0.a').prerelease? - assert Gem::Version.new('2.9.b').prerelease? - assert Gem::Version.new('22.1.50.0.d').prerelease? + assert_prerelease "1.2.0.a" + assert_prerelease "2.9.b" + assert_prerelease "22.1.50.0.d" + assert_prerelease "1.2.d.42" + + assert_prerelease '1.A' - refute Gem::Version.new('1.2.0').prerelease? - refute Gem::Version.new('2.9').prerelease? - refute Gem::Version.new('22.1.50.0').prerelease? + refute_prerelease "1.2.0" + refute_prerelease "2.9" + refute_prerelease "22.1.50.0" end def test_release - assert_equal Gem::Version.new('1.2.0'), Gem::Version.new('1.2.0.a').release - assert_equal Gem::Version.new('1.1'), Gem::Version.new('1.1.rc10').release - assert_equal Gem::Version.new('1.9.3'), Gem::Version.new('1.9.3.alpha.5').release - assert_equal Gem::Version.new('1.9.3'), Gem::Version.new('1.9.3').release + assert_release_equal "1.2.0", "1.2.0.a" + assert_release_equal "1.1", "1.1.rc10" + assert_release_equal "1.9.3", "1.9.3.alpha.5" + assert_release_equal "1.9.3", "1.9.3" end - def test_satisfied_by_eh_boxed - assert_inadequate("1.3", "~> 1.4") - assert_adequate( "1.4", "~> 1.4") - assert_adequate( "1.5", "~> 1.4") - assert_inadequate("2.0", "~> 1.4") - - assert_inadequate("1.3", "~> 1.4.4") - assert_inadequate("1.4", "~> 1.4.4") - assert_adequate( "1.4.4", "~> 1.4.4") - assert_adequate( "1.4.5", "~> 1.4.4") - assert_inadequate("1.5", "~> 1.4.4") - assert_inadequate("2.0", "~> 1.4.4") - - assert_inadequate("1.1.pre", "~> 1.0.0") - assert_adequate( "1.1.pre", "~> 1.1") - assert_inadequate("2.0.a", "~> 1.0") - assert_adequate( "2.0.a", "~> 2.0") + def test_spaceship + assert_equal( 0, v("1.0") <=> v("1.0.0")) + assert_equal( 1, v("1.0") <=> v("1.0.a")) + assert_equal( 1, v("1.8.2") <=> v("0.0.0")) + assert_equal( 1, v("1.8.2") <=> v("1.8.2.a")) + assert_equal( 1, v("1.8.2.b") <=> v("1.8.2.a")) + assert_equal(-1, v("1.8.2.a") <=> v("1.8.2")) + assert_equal( 0, v("") <=> v("0")) end - def test_satisfied_by_eh_multiple - req = [">= 1.4", "<= 1.6", "!= 1.5"] - assert_inadequate("1.3", req) - assert_adequate( "1.4", req) - assert_inadequate("1.5", req) - assert_adequate( "1.6", req) - assert_inadequate("1.7", req) - assert_inadequate("2.0", req) + def test_spermy_recommendation + assert_spermy_equal "~> 1.0", "1" + assert_spermy_equal "~> 1.0", "1.0" + assert_spermy_equal "~> 1.2", "1.2" + assert_spermy_equal "~> 1.2", "1.2.0" + assert_spermy_equal "~> 1.2", "1.2.3" + assert_spermy_equal "~> 1.2", "1.2.3.a.4" end - def test_spaceship - assert_equal 0, Gem::Version.new('1.0') <=> Gem::Version.new('1.0.0') - assert_equal 1, Gem::Version.new('1.0') <=> Gem::Version.new('1.0.a') - assert_equal 1, Gem::Version.new('1.8.2') <=> Gem::Version.new('0.0.0') - assert_equal 1, Gem::Version.new('1.8.2') <=> Gem::Version.new('1.8.2.a') - assert_equal 1, Gem::Version.new('1.8.2.b') <=> Gem::Version.new('1.8.2.a') - assert_equal 0, Gem::Version.new('') <=> Gem::Version.new('0') + def test_to_s + assert_equal "5.2.4", v("5.2.4").to_s end - def test_boxed - assert_inadequate("1.3", "~> 1.4") - assert_adequate( "1.4", "~> 1.4") - assert_adequate( "1.5", "~> 1.4") - assert_inadequate("2.0", "~> 1.4") - - assert_inadequate("1.3", "~> 1.4.4") - assert_inadequate("1.4", "~> 1.4.4") - assert_adequate( "1.4.4", "~> 1.4.4") - assert_adequate( "1.4.5", "~> 1.4.4") - assert_inadequate("1.5", "~> 1.4.4") - assert_inadequate("2.0", "~> 1.4.4") - end + # Asserts that +version+ is a prerelease. - def test_to_s - v = Gem::Version.new("5.2.4") - assert_equal "5.2.4", v.to_s + def assert_prerelease version + assert v(version).prerelease?, "#{version} is a prerelease" end - def assert_adequate(version, requirement) - ver = Gem::Version.new(version) - req = Gem::Requirement.new(requirement) - assert req.satisfied_by?(ver), - "Version #{version} should be adequate for Requirement #{requirement}" + # Assert that +expected+ is the "spermy" recommendation for +version". + + def assert_spermy_equal expected, version + assert_equal expected, v(version).spermy_recommendation end - def assert_inadequate(version, requirement) - ver = Gem::Version.new(version) - req = Gem::Version::Requirement.new(requirement) - refute req.satisfied_by?(ver), - "Version #{version} should not be adequate for Requirement #{requirement}" + # Assert that bumping the +unbumped+ version yields the +expected+. + + def assert_bumped_version_equal expected, unbumped + assert_version_equal expected, v(unbumped).bump end - def assert_version(actual) - assert_equal @v1_0, actual - assert_equal @v1_0.version, actual.version + # Assert that +release+ is the correct non-prerelease +version+. + + def assert_release_equal release, version + assert_version_equal release, v(version).release end - def part_values(*parts) - parts.flatten.map { |part| part.value } + # Assert that two versions are equal. Handles strings or + # Gem::Version instances. + + def assert_version_equal expected, actual + assert_equal v(expected), v(actual) end -end -class TestGemVersionPart < RubyGemTestCase - def test_initialize - assert_equal 1, Gem::Version::Part.new(1).value - assert_equal 1, Gem::Version::Part.new("1").value - assert_equal "a", Gem::Version::Part.new("a").value + # Assert that two versions are eql?. Checks both directions. + + def assert_version_eql first, second + first, second = v(first), v(second) + assert first.eql?(second), "#{first} is eql? #{second}" + assert second.eql?(first), "#{second} is eql? #{first}" end - def test_spaceship - assert_equal(-1, Gem::Version::Part.new(1) <=> Gem::Version::Part.new(2)) - assert_equal( 0, Gem::Version::Part.new(2) <=> Gem::Version::Part.new(2)) - assert_equal( 1, Gem::Version::Part.new(2) <=> Gem::Version::Part.new(1)) + # Refute the assumption that +version+ is a prerelease. - assert_equal(-1, Gem::Version::Part.new("a") <=> Gem::Version::Part.new("b")) - assert_equal( 0, Gem::Version::Part.new("b") <=> Gem::Version::Part.new("b")) - assert_equal( 1, Gem::Version::Part.new("b") <=> Gem::Version::Part.new("a")) + def refute_prerelease version + refute v(version).prerelease?, "#{version} is NOT a prerelease" + end - assert_equal(-1, Gem::Version::Part.new("a") <=> Gem::Version::Part.new(1)) - assert_equal( 1, Gem::Version::Part.new(1) <=> Gem::Version::Part.new("a")) + # Refute the assumption that two versions are eql?. Checks both + # directions. + + def refute_version_eql first, second + first, second = v(first), v(second) + refute first.eql?(second), "#{first} is NOT eql? #{second}" + refute second.eql?(first), "#{second} is NOT eql? #{first}" end - def test_succ - assert_equal 2, Gem::Version::Part.new(1).succ.value - assert_equal "b", Gem::Version::Part.new("a").succ.value + # Refute the assumption that the two versions are equal?. + + def refute_version_equal unexpected, actual + refute_equal v(unexpected), v(actual) end end - diff --git a/test/rubygems/test_kernel.rb b/test/rubygems/test_kernel.rb index 0b2e8026a8..524b20d82b 100644 --- a/test/rubygems/test_kernel.rb +++ b/test/rubygems/test_kernel.rb @@ -1,9 +1,3 @@ -#-- -# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. -# All rights reserved. -# See LICENSE.txt for permissions. -#++ - require_relative 'gemutilities' require 'rubygems/package' diff --git a/test/socket/test_socket.rb b/test/socket/test_socket.rb index ae29ae1ed5..a2c0baf1e4 100644 --- a/test/socket/test_socket.rb +++ b/test/socket/test_socket.rb @@ -191,7 +191,7 @@ class TestSocket < Test::Unit::TestCase assert_equal(clients.length, accepted.length) ensure tcp_servers.each {|s| s.close if !s.closed? } - unix_server.close if !unix_server.closed? + unix_server.close if unix_server && !unix_server.closed? clients.each {|s| s.close if !s.closed? } accepted.each {|s| s.close if !s.closed? } end diff --git a/tool/mkconfig.rb b/tool/mkconfig.rb index df3c35fb80..ac24821829 100755 --- a/tool/mkconfig.rb +++ b/tool/mkconfig.rb @@ -111,7 +111,10 @@ File.foreach "config.status" do |line| end end end - val.gsub!(/ +(?!-)/, "=") if name == "configure_args" && /mswin32/ =~ RUBY_PLATFORM + if name == "configure_args" + val.gsub!(/ +(?!-)/, "=") if /mswin32/ =~ RUBY_PLATFORM + val.gsub!(/--with-out-ext/, "--without-ext") + end val = val.gsub(/\$(?:\$|\{?(\w+)\}?)/) {$1 ? "$(#{$1})" : $&}.dump if /^prefix$/ =~ name val = "(TOPDIR || DESTDIR + #{val})" @@ -1,5 +1,5 @@ #define RUBY_VERSION "1.9.2" -#define RUBY_RELEASE_DATE "2010-02-17" +#define RUBY_RELEASE_DATE "2010-02-24" #define RUBY_PATCHLEVEL -1 #define RUBY_BRANCH_NAME "mvm" @@ -8,7 +8,7 @@ #define RUBY_VERSION_TEENY 1 #define RUBY_RELEASE_YEAR 2010 #define RUBY_RELEASE_MONTH 2 -#define RUBY_RELEASE_DAY 17 +#define RUBY_RELEASE_DAY 24 #include "ruby/version.h" @@ -723,8 +723,14 @@ vm_backtrace_each(rb_thread_t *th, int lev, rb_backtrace_iter_func *iter, void * } } else if (RUBYVM_CFUNC_FRAME_P(cfp)) { + ID id; + if (NIL_P(file)) file = rb_str_new_cstr("ruby"); - if ((*iter)(arg, file, line_no, rb_id2str(cfp->me->def->original_id))) break; + if (cfp->me->def) + id = cfp->me->def->original_id; + else + id = cfp->me->called_id; + if ((*iter)(arg, file, line_no, rb_id2str(id))) break; } cfp = RUBY_VM_NEXT_CONTROL_FRAME(cfp); } |