5555import java .util .Arrays ;
5656import java .util .List ;
5757import java .util .Locale ;
58+ import java .util .Objects ;
5859import java .util .UUID ;
5960import java .util .logging .Level ;
6061import java .util .logging .Logger ;
62+ import java .util .regex .Matcher ;
6163import java .util .regex .Pattern ;
6264import java .util .zip .ZipEntry ;
6365import java .util .zip .ZipInputStream ;
6769 */
6870public class LocalDatastoreHelper {
6971 private static final Logger log = Logger .getLogger (LocalDatastoreHelper .class .getName ());
70- private static final String GCD_VERSION = "1.2.0" ;
72+ private static final Version GCD_VERSION = Version . fromString ( "1.2.0" ) ;
7173 private static final double DEFAULT_CONSISTENCY = 0.9 ;
7274 private static final String GCD_BASENAME = "cloud-datastore-emulator-" + GCD_VERSION ;
7375 private static final String GCD_FILENAME = GCD_BASENAME + ".zip" ;
@@ -120,8 +122,8 @@ private static Path installedGcdPath() {
120122 Path installedGcdPath = gcloudPath .resolve ("platform" ).resolve ("cloud-datastore-emulator" );
121123 if (Files .exists (installedGcdPath )) {
122124 try {
123- String installedVersion = installedGcdVersion ();
124- if (installedVersion != null && installedVersion .startsWith (GCD_VERSION )) {
125+ Version installedVersion = installedGcdVersion ();
126+ if (installedVersion != null && installedVersion .compareTo (GCD_VERSION ) >= 0 ) {
125127 if (log .isLoggable (Level .FINE )) {
126128 log .fine ("SDK datastore emulator found" );
127129 }
@@ -131,14 +133,14 @@ private static Path installedGcdPath() {
131133 log .fine ("SDK datastore emulator found but version mismatch" );
132134 }
133135 }
134- } catch (IOException | InterruptedException ignore ) {
136+ } catch (IOException | InterruptedException | IllegalArgumentException ignore ) {
135137 // ignore
136138 }
137139 }
138140 return null ;
139141 }
140142
141- private static String installedGcdVersion () throws IOException , InterruptedException {
143+ private static Version installedGcdVersion () throws IOException , InterruptedException {
142144 Process process =
143145 CommandWrapper .create ().command ("gcloud" , "version" ).redirectErrorStream ().start ();
144146 process .waitFor ();
@@ -148,7 +150,7 @@ private static String installedGcdVersion() throws IOException, InterruptedExcep
148150 if (line .startsWith (GCD_VERSION_PREFIX )) {
149151 String [] lineComponents = line .split (" " );
150152 if (lineComponents .length > 1 ) {
151- return lineComponents [1 ];
153+ return Version . fromString ( lineComponents [1 ]) ;
152154 }
153155 }
154156 }
@@ -171,6 +173,59 @@ private static Path executablePath(String cmd) {
171173 return null ;
172174 }
173175
176+ private static class Version implements Comparable <Version > {
177+
178+ private static final Pattern VERSION_PATTERN = Pattern .compile ("(\\ d+).(\\ d+).(\\ d+)" );
179+
180+ final int major ;
181+ final int minor ;
182+ final int patch ;
183+
184+ Version (int major , int minor , int patch ) {
185+ this .major = major ;
186+ this .minor = minor ;
187+ this .patch = patch ;
188+ }
189+
190+ @ Override
191+ public int compareTo (Version version ) {
192+ int result = major - version .major ;
193+ if (result == 0 ) {
194+ result = minor - version .minor ;
195+ if (result == 0 ) {
196+ result = patch - version .patch ;
197+ }
198+ }
199+ return result ;
200+ }
201+
202+ @ Override
203+ public String toString () {
204+ return String .format ("%d.%d.%d" , major , minor , patch );
205+ }
206+
207+ @ Override
208+ public boolean equals (Object other ) {
209+ return this == other || other instanceof Version && compareTo ((Version ) other ) == 0 ;
210+ }
211+
212+ @ Override
213+ public int hashCode () {
214+ return Objects .hash (major , minor , patch );
215+ }
216+
217+ static Version fromString (String version ) {
218+ Matcher matcher = VERSION_PATTERN .matcher (version );
219+ if (matcher .matches ()) {
220+ return new Version (
221+ Integer .valueOf (matcher .group (1 )),
222+ Integer .valueOf (matcher .group (2 )),
223+ Integer .valueOf (matcher .group (3 )));
224+ }
225+ throw new IllegalArgumentException ("Invalid version format" );
226+ }
227+ }
228+
174229 private static class ProcessStreamReader extends Thread {
175230 private final BufferedReader reader ;
176231 private volatile boolean terminated ;
0 commit comments