Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Uses common lib for Cloud SDK detection. #335

Merged
merged 12 commits into from
Jul 19, 2016
Merged

Conversation

joaoandremartins
Copy link
Contributor

@googlebot
Copy link

Thanks for your pull request. It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

📝 Please visit https://cla.developers.google.com/ to sign.

Once you've signed, please reply here (e.g. I signed it!) and we'll verify. Thanks.


  • If you've already signed a CLA, it's possible we don't have your GitHub username or you're using a different email address. Check your existing CLA data and verify that your email is set on your git commits.
  • If you signed the CLA as a corporation, please let us know the company's name.

@@ -79,7 +79,7 @@
<!-- bundle: com.google.cloud.tools.app.lib -->
<groupId>com.google.cloud.tools</groupId>
<artifactId>appengine-plugins-core</artifactId>
<version>0.1.1-SNAPSHOT</version>
<version>0.1.2-SNAPSHOT</version>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#332 was just merged.

@elharo
Copy link
Contributor

elharo commented Jul 11, 2016

Please resolve conflicts and repush.

@elharo elharo self-assigned this Jul 11, 2016
@googlebot
Copy link

CLAs look good, thanks!

@joaoandremartins
Copy link
Contributor Author

@elharo I think the conflicts are resolved. Let me know if you want me to walk you through what I've done so far. Might be faster that way!

@@ -146,7 +146,7 @@ public void widgetSelected(SelectionEvent event) {
}
});

File location = new CloudSdkProvider(null).getCloudSdkLocation();
File location = new CloudSdkProvider().getCloudSdk().getJavaAppEngineSdkPath().toFile();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need toFile here? If getJavaAppEngineSdkPath returns a Path we can just declare location to be that instead, I expect.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be the CLOUD_SDK instance?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because there is already a Path class imported, this was my shortcut to having less readable java.nio.file.Path. I'll change to Path, though.

@briandealwis because we're only using this once in this class, I didn't factor this to a static variable. Let me know if there is anything I'm missing.

@briandealwis
Copy link
Member

@joaoandremartins my thought was that we should ideally make the Cloud SDK discovery more pluggable, so this preference-based code can be just another resolver that complements the existing PATH and fixed-location resolvers. Perhaps configured with the JDK's IServiceLocator.

I don't think we should treat the resolution as being a cheap. Certainly doing lots of filesystem checks in the PATH isn't that cheap for non-SSD, and many corporate developers are still on underpowered hardware.

// TODO should be changed once app-tools-lib can provide the directory
// https://github.com/GoogleCloudPlatform/app-tools-lib-for-java/issues/134
private static final String SDK_JAR = "platform/google_appengine/google/appengine/tools/java/lib/appengine-tools-api.jar";
private static final CloudSdk CLOUD_SDK = new CloudSdkProvider().getCloudSdk();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shouldn't be a static. Actually, AppEngineSdkClasspathContainer should accept being provided with a CloudSdk instance.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed static.

I suspect you want to pass in a CloudSdk instance so we always get the freshest Cloud SDK we have. In that case, could it make sense to just call CloudSdkProvider every time we want it? Or are you worried this will incur in unnecessary FS checks?

@elharo
Copy link
Contributor

elharo commented Jul 12, 2016

Please put this on hold for the moment. It's starting to look like we may need to back out some of the changes this depends on first, for reasons unrelated to this PR.

@elharo elharo removed the blocked label Jul 12, 2016
@elharo
Copy link
Contributor

elharo commented Jul 13, 2016

This can move forward again. We've resolved the issues that were blocking it. Though I'm afraid you have to merge again. :-(

// Let's use the configured path, if there is one. Otherwise, the lib will try to discover the
// path.
if (configuredPath != null && !configuredPath.isEmpty()) {
// TODO(joaomartins): What happens when the provided path is invalid? Tools lib isn't
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We allow it in case the SDK distribution has changed so the validate() code is now out-of-date. We show a warning in the preference page.

@briandealwis
Copy link
Member

CloudSdkProvider was only needed because the Cloud SDK resolving mechanism is not sufficiently flexible. We could happily get rid of CloudSdkProvider entirely if we could instead configure the CloudSdk.Builder with an alternative PathResolver-like instance that knew to first look at the relevant Eclipse preference. We could do this via java.util.ServiceLoader, for example.

I don't think we can completely get rid of CloudSdkPrompter: I don't think it's safe to push UI-prompting into the path resolving code since we don't really know the UI situation.

@@ -61,11 +61,9 @@ public Object compute(IEclipseContext context, String contextKey) {

Object path = context.get(PreferenceConstants.CLOUDSDK_PATH);
File location = toFile(path);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

location is no longer used. Remove it?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think location should be unused, I think there's value in being able to specify an alternative path this way — it certainly doesn't hurt.

The background here is that context functions are only re-evaluated (which we'll want to do if the preference changed) when some input used by the function is changed. We trigger the re-evaluation here by retrieving the SDK Path from the referencing contexts, and then setting the SDK Path on those contexts when the preference changes (see further above to the referencedContexts, which is used by the Activator's IPreferenceChangeListener and CloudSdkContextFunction#sdkPathChanged()).

That said, there's a logic error here in that a path value explicitly set in the context will be overwritten when the preference is next changed, and compute() should be:

    Object path = context.get(PreferenceConstants.CLOUDSDK_PATH);
    if(path == null) {
      // record this context as using the preference value
      referencedContexts.add(context);
    }

But if you strongly believe there should only be a single SDK Path, then we should use a different context key name than PreferenceConstants.CLOUDSDK_PATH, like "sdkPathChanged".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CloudSdkProvider now takes an additional location that can come from the context. If there is no context location, it uses the one in the preference store. If none there either, it then delegates SDK discovery to the library. If the library can't find it, then null is returned and later on the user is prompted to set a valid one.

if (jarFile.exists()) {
String appEngineToolsApiJar = jarFile.getPath();
CloudSdk cloudSdk = new CloudSdkProvider().getCloudSdk();
if (cloudSdk.getJavaAppEngineSdkPath() != null) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is weird. You're checking to see if getJavaAppEngineSdkPath is null but then calling a different method.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I fixed this locally but didn't push yet.

@@ -6,5 +6,5 @@ CloudSdkPreferencePage_4=Cannot launch a browser
CloudSdkPreferencePage_5=&SDK location:
CloudSdkPreferencePage_6=No SDK found: {0}
CloudSdkPrompter_0=Google Cloud SDK Not Configured
CloudSdkPrompter_1=The Google Cloud SDK cannot be found\! Would you like to configure it now?
CloudSdkPrompter_1=Invalid or no Google Cloud SDK specified. Do you want to configure Google Cloud SDK now?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is an improvement: the first part sounds awkward.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted a message that enforces the user must either specify a valid Cloud SDK or the operation will fail, which the first message didn't convey very well IMO.
I agree the first part doesn't sound great, feel free to provide an alternative.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about:

The Google Cloud SDK is required but cannot be found! Would you like to configure it now?

@briandealwis
Copy link
Member

LGTM

@joaoandremartins
Copy link
Contributor Author

Waiting for changes from GoogleCloudPlatform/appengine-plugins#164 to be pushed to Maven central so tests can succeed.

import com.google.cloud.tools.appengine.cloudsdk.CloudSdk;
import com.google.cloud.tools.eclipse.sdk.CloudSdkProvider;

@RunWith(MockitoJUnitRunner.class)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@elharo @briandealwis PTAL. I made a few more changes so the unit/integration tests pass. After these changes, I think this is ready for submission.

@@ -28,7 +27,8 @@
* <li>stage project for deploy</li>
* <li>deploy staged project</li>
* </ol>
* It uses a work directory where it will create separate directory for the exploded WAR and the staging results.
* It uses a work directory where it will create separate directory for the exploded WAR and the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

separate directories

@elharo
Copy link
Contributor

elharo commented Jul 19, 2016

LGTM

@joaoandremartins joaoandremartins merged commit b2bff4a into master Jul 19, 2016
@joaoandremartins joaoandremartins deleted the get-tools-jar branch July 19, 2016 13:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants