@@ -44,6 +44,11 @@ def version_tuple(version):
4444 RC_OFFSET = - 100
4545 version_parts = re .split (r'\.|-' , version [0 ])
4646
47+ if version_parts [- 1 ] == "pre" :
48+ # Prior to improvements for how the version string is managed within the server
49+ # (SERVER-17782), the binary archives would contain a trailing "-pre".
50+ version_parts .pop ()
51+
4752 if version_parts [- 1 ].startswith ("rc" ):
4853 rc_part = version_parts .pop ()
4954 rc_part = rc_part .split ('rc' )[1 ]
@@ -52,12 +57,17 @@ def version_tuple(version):
5257 # releases to be sorted in ascending order (e.g., 2.6.0-rc1,
5358 # 2.6.0-rc2, 2.6.0).
5459 version_parts .append (int (rc_part ) + RC_OFFSET )
60+ elif version_parts [0 ].startswith ("v" ) and version_parts [- 1 ] == "latest" :
61+ version_parts [0 ] = version_parts [0 ][1 :]
62+ # The "<branchname>-latest" versions are weighted the highest when a particular major
63+ # release is requested.
64+ version_parts [- 1 ] = float ("inf" )
5565 else :
5666 # Non-RC releases have an extra 0 appended so version tuples like
5767 # (2, 6, 0, -100) and (2, 6, 0, 0) sort in ascending order.
5868 version_parts .append (0 )
5969
60- return tuple (map (int , version_parts ))
70+ return tuple (map (float , version_parts ))
6171
6272class MultiVersionDownloader :
6373
@@ -116,13 +126,16 @@ def download_version(self, version):
116126
117127 urls = []
118128 for link_version , link_url in self .links .iteritems ():
119- if link_version .startswith (version ):
120- # If we have a "-" in our version, exact match only
121- if version .find ("-" ) >= 0 :
122- if link_version != version : continue
123- elif link_version .find ("-" ) >= 0 :
124- continue
125-
129+ if link_version .startswith (version ) or link_version == "v%s-latest" % (version ):
130+ # The 'link_version' is a candidate for the requested 'version' if
131+ # (a) it is a prefix of the requested version, or if
132+ # (b) it is the "<branchname>-latest" version and the requested version is for a
133+ # particular major release.
134+ if "-" in version :
135+ # The requested 'version' contains a hyphen, so we only consider exact matches
136+ # to that version.
137+ if link_version != version :
138+ continue
126139 urls .append ((link_version , link_url ))
127140
128141 if len (urls ) == 0 :
@@ -156,17 +169,32 @@ def download_version(self, version):
156169 if file_suffix == ".zip" :
157170 # Support .zip downloads, used for Windows binaries.
158171 with zipfile .ZipFile (temp_file ) as zf :
172+ # Use the name of the root directory in the archive as the name of the directory
173+ # to extract the binaries into inside 'self.install_dir'. The name of the root
174+ # directory nearly always matches the parsed URL text, with the exception of
175+ # versions such as "v3.2-latest" that instead contain the githash.
176+ extract_dir = os .path .dirname (zf .namelist ()[0 ])
159177 zf .extractall (temp_dir )
160178 elif file_suffix == ".tgz" :
161179 # Support .tgz downloads, used for Linux binaries.
162180 with closing (tarfile .open (temp_file , 'r:gz' )) as tf :
181+ # Use the name of the root directory in the archive as the name of the directory
182+ # to extract the binaries into inside 'self.install_dir'. The name of the root
183+ # directory nearly always matches the parsed URL text, with the exception of
184+ # versions such as "v3.2-latest" that instead contain the githash.
185+ extract_dir = os .path .dirname (tf .getnames ()[0 ])
163186 tf .extractall (path = temp_dir )
164187 else :
165188 raise Exception ("Unsupported file extension %s" % file_suffix )
166189
167190 temp_install_dir = os .path .join (temp_dir , extract_dir )
168191
169- shutil .move (temp_install_dir , self .install_dir )
192+ # We may not have been able to determine whether we already downloaded the requested
193+ # version due to the ambiguity in the parsed URL text, so we check for it again using
194+ # the adjusted 'extract_dir' value.
195+ already_downloaded = os .path .isdir (os .path .join (self .install_dir , extract_dir ))
196+ if not already_downloaded :
197+ shutil .move (temp_install_dir , self .install_dir )
170198
171199 shutil .rmtree (temp_dir )
172200 os .remove (temp_file )
0 commit comments