/*
* Copyright (c) 2013, the Dart project authors.
*
* Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.dart.tools.ui.actions;
import com.google.dart.engine.sdk.DirectoryBasedDartSdk;
import com.google.dart.tools.core.DartCore;
import com.google.dart.tools.core.MessageConsole;
import com.google.dart.tools.core.model.DartSdkManager;
import com.google.dart.tools.core.pub.PubMessages;
import com.google.dart.tools.core.pub.RunPubJob;
import com.google.dart.tools.ui.internal.util.ExternalBrowserUtil;
import org.eclipse.core.resources.IContainer;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Link;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IWorkbenchWindow;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Action that runs the pub lish command for the selected package
*/
public class RunPublishAction extends RunPubAction {
private class MissingReqsDialog extends MessageDialog {
public MissingReqsDialog(Shell parentShell) {
super(
parentShell,
ActionMessages.RunPubAction_publish_dialog_title,
null,
ActionMessages.RunPubAction_publish_missing_requirements,
MessageDialog.INFORMATION,
new String[] {IDialogConstants.OK_LABEL},
0);
}
@Override
protected Control createCustomArea(Composite parent) {
Composite composite = new Composite(parent, SWT.NONE);
Link link = new Link(composite, SWT.NONE);
String message = "\nMore information at <a href=\"http://pub.dartlang.org/doc/pub-lish.html\">"
+ "http://pub.dartlang.org/doc/pub-lish.html</a>.";
link.setText(message);
link.setSize(400, 100);
link.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
ExternalBrowserUtil.openInExternalBrowser(e.text);
}
});
composite.pack();
return composite;
}
@Override
protected boolean customShouldTakeFocus() {
return false;
}
}
private class PubMessageDialog extends MessageDialog {
public PubMessageDialog(Shell parentShell, String dialogTitle, String dialogMessage) {
super(parentShell, dialogTitle, null, dialogMessage, MessageDialog.CONFIRM, new String[] {
IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL}, 0);
}
@Override
protected Control createCustomArea(Composite parent) {
Composite composite = new Composite(parent, SWT.NONE);
GridLayout layout = new GridLayout();
layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
composite.setLayout(layout);
composite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
Text textArea = new Text(composite, SWT.MULTI | SWT.V_SCROLL | SWT.WRAP | SWT.BORDER);
textArea.setEditable(false);
textArea.setText(stringBuilder.toString());
return composite;
}
@Override
protected boolean customShouldTakeFocus() {
return false;
}
}
private static final String WARNINGS_REGEX = "Package has [0-9]+ warning(s)?."; //$NON-NLS-1$
private static final String ERRORS_STRING = "Missing requirements:"; //$NON-NLS-1$
private static final String ZERO_WARNINGS = "Package has 0 warnings."; //$NON-NLS-1$
public static RunPublishAction createPubPublishAction(IWorkbenchWindow window) {
RunPublishAction action = new RunPublishAction(window);
action.setText(NLS.bind(ActionMessages.RunPubAction_commandText, "Publish..."));
action.setDescription(NLS.bind(
ActionMessages.RunPubAction_commandDesc,
RunPubJob.PUBLISH_COMMAND));
return action;
}
private RunPublishAction(IWorkbenchWindow window) {
super(window, RunPubJob.PUBLISH_COMMAND);
}
@Override
protected void runPubJob(IContainer container) {
if (container.findMember(DartCore.PUBSPEC_FILE_NAME) != null) {
MessageConsole console = DartCore.getConsole();
console.printSeparator(NLS.bind(
PubMessages.RunPubJob_running,
RunPubJob.PUBLISH_COMMAND,
container.getLocation().toOSString()));
// use publish --dry-run to do just validation on the package and do not upload.
List<String> args = buildPublishCommand("--dry-run"); //$NON-NLS-1$
runPub(container, console, args, true);
// check if we can publish - no errors and user confirms
if (!confirmPackageUpload(stringBuilder.toString())) {
console.println(ActionMessages.RunPubAction_publish_upload_cancel);
return;
}
// use publish --force upload package without asking for user confirmation - the editor has done so.
args = buildPublishCommand("--force"); //$NON-NLS-1$
runPub(container, console, args, false);
} else {
MessageDialog.openError(
getShell(),
ActionMessages.RunPubAction_fail,
ActionMessages.RunPubAction_fileNotFound);
}
}
@Override
protected void runPubJob(IContainer container, IContainer sourceFolder) {
// publish does not need source folder
runPubJob(container);
}
private List<String> buildPublishCommand(String arg) {
DirectoryBasedDartSdk sdk = DartSdkManager.getManager().getSdk();
File pubFile = sdk.getPubExecutable();
List<String> args = new ArrayList<String>();
args.add(pubFile.getAbsolutePath());
args.add(RunPubJob.PUBLISH_COMMAND);
args.add(arg);
return args;
}
private boolean confirmPackageUpload(String output) {
if (output.indexOf(ERRORS_STRING) != -1) { // missing requirements, cannot publish
new MissingReqsDialog(getShell()).open();
return false;
}
Pattern warningsPattern = Pattern.compile(WARNINGS_REGEX);
Matcher m = warningsPattern.matcher(output);
String message = "";
if (m.find()) {
if (!m.group(0).equals(ZERO_WARNINGS)) {
message = m.group(0);
}
}
int returnCode = new PubMessageDialog(
getShell(),
ActionMessages.RunPubAction_publish_dialog_title,
ActionMessages.RunPubAction_publish_upload_message + "\n" + message).open();
return (returnCode == 0);
}
}