diff --git a/app/src/cc/arduino/view/git/GitCommit.form b/app/src/cc/arduino/view/git/GitCommit.form new file mode 100644 index 00000000000..592679bbaf9 --- /dev/null +++ b/app/src/cc/arduino/view/git/GitCommit.form @@ -0,0 +1,103 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/app/src/cc/arduino/view/git/GitCommit.java b/app/src/cc/arduino/view/git/GitCommit.java new file mode 100644 index 00000000000..f2e4b219e0d --- /dev/null +++ b/app/src/cc/arduino/view/git/GitCommit.java @@ -0,0 +1,224 @@ +/* + * This file is part of Arduino. + * + * Copyright 2015 Arduino LLC (http://www.arduino.cc/) + * + * Arduino is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * As a special exception, you may use this file as part of a free software + * library without restriction. Specifically, if other files instantiate + * templates or use macros or inline functions from this file, or you compile + * this file and link it with other files to produce an executable, this + * file does not by itself cause the resulting executable to be covered by + * the GNU General Public License. This exception does not however + * invalidate any other reasons why the executable file might be covered by + * the GNU General Public License. + */ + +package cc.arduino.view.git; + +import processing.app.Base; +import processing.app.Editor; +import processing.app.Sketch; +import processing.app.helpers.OSUtils; +import processing.app.syntax.SketchTextArea; + +import java.awt.event.WindowEvent; +import java.io.*; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; + +import static processing.app.I18n.tr; + +public class GitCommit extends javax.swing.JFrame { + private final static Logger LOG = Logger.getLogger(SketchTextArea.class.getName()); + private final Editor editor; + + + public GitCommit(Editor editor, Map state) { + this.editor = editor; + + initComponents(); + + Base.setIcon(this); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + javax.swing.JLabel commitMessageLabel = new javax.swing.JLabel(); + commitMessageField = new javax.swing.JTextField(); + buttonsContainer = new javax.swing.JPanel(); + cancelButton = new javax.swing.JButton(); + okButton = new javax.swing.JButton(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setTitle(tr("Commit")); + setResizable(false); + + commitMessageLabel.setText(tr("Message:")); + + commitMessageField.setColumns(20); + + cancelButton.setText(tr("Cancel")); + cancelButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + cancelButtonActionPerformed(evt); + } + }); + buttonsContainer.add(cancelButton); + + okButton.setText(tr("Ok")); + okButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + okButtonActionPerformed(evt); + } + }); + buttonsContainer.add(okButton); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(commitMessageLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(commitMessageField, javax.swing.GroupLayout.DEFAULT_SIZE, 513, Short.MAX_VALUE)) + .addComponent(buttonsContainer, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(commitMessageLabel) + .addComponent(commitMessageField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(0, 0, 0) + .addComponent(buttonsContainer, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + + pack(); + }// //GEN-END:initComponents + + private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed + dispatchEvent(new WindowEvent(this, WindowEvent.WINDOW_CLOSING)); + }//GEN-LAST:event_cancelButtonActionPerformed + + private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed + commit(); + dispatchEvent(new WindowEvent(this, WindowEvent.WINDOW_CLOSING)); + }//GEN-LAST:event_okButtonActionPerformed + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel buttonsContainer; + private javax.swing.JButton cancelButton; + private javax.swing.JTextField commitMessageField; + private javax.swing.JButton okButton; + // End of variables declaration//GEN-END:variables + + private String[] getArgsForProcess(String command) { + String[] args = new String[3]; + if (OSUtils.isWindows()) { + args[0] = "cmd.exe"; + args[1] = "/c"; + } else { //For Mac and Linux + args[0] = "/bin/bash"; + args[1] = "-cl"; + } + + args[2] = command; + + return args; + } + + private void setSystemEnvironment(Map environment) { + environment.put("HOME", System.getProperty("user.home")); + environment.put("LANG", "en_US.UTF-8"); + environment.put("GDM_LANG", "en_US.UTF-8"); + environment.put("LANGUAGE", "us"); + } + + private void runCommand(String command, File dir) { + ProcessBuilder processBuilder = new ProcessBuilder(getArgsForProcess(command)); + processBuilder.redirectErrorStream(true); + + setSystemEnvironment(processBuilder.environment()); + + processBuilder.directory(dir); + + try { + Process process = processBuilder.start(); + try (BufferedReader errStream = new BufferedReader(new InputStreamReader(process.getErrorStream())); + BufferedReader cin = new BufferedReader(new InputStreamReader(process.getInputStream()))) { + process.waitFor(); + + String line; + while ((line = errStream.readLine()) != null) { + System.out.println(line); + LOG.log(Level.WARNING, line); + } + + while ((line = cin.readLine()) != null) { + System.out.println(line); + LOG.log(Level.WARNING, line); + } + + if (process.exitValue() == 0) { + System.out.println("Git command successful!"); + LOG.log(Level.FINE, "Git command successful!"); + } + + } catch (InterruptedException e) { + System.out.println(e.getMessage()); + LOG.log(Level.WARNING, e.getMessage()); + } + + } catch (IOException e) { + System.out.println(e.getMessage()); + LOG.log(Level.WARNING, e.getMessage()); + } + } + + private void commit() { + String filePath = editor.getSketch().getMainFilePath(); + StringBuilder command = new StringBuilder(String.format("git add %s && git commit %s ", filePath, filePath)); + + String message = commitMessageField.getText(); + if (!message.isEmpty()) { + command.append(" -m \"") + .append(message) + .append('\"'); + } else { + System.out.println("Commit Failed! Git message wasn't set!"); + LOG.log(Level.WARNING, "Commit Failed! Git message wasn't set!"); + return; + } + + runCommand(command.toString(), editor.getSketch().getFolder()); + } +} diff --git a/app/src/processing/app/Editor.java b/app/src/processing/app/Editor.java index 566cabf1c3f..5938e4dff67 100644 --- a/app/src/processing/app/Editor.java +++ b/app/src/processing/app/Editor.java @@ -29,6 +29,7 @@ import cc.arduino.view.GoToLineNumber; import cc.arduino.view.StubMenuListener; import cc.arduino.view.findreplace.FindReplace; +import cc.arduino.view.git.GitCommit; import com.jcraft.jsch.JSchException; import jssc.SerialPortException; import org.fife.ui.rsyntaxtextarea.RSyntaxDocument; @@ -189,6 +190,7 @@ public boolean test(Sketch sketch) { protected RedoAction redoAction; private FindReplace find; + private GitCommit gitCommit; Runnable runHandler; Runnable presentHandler; @@ -1502,6 +1504,14 @@ public void actionPerformed(ActionEvent e) { }); menu.add(findPreviousItem); + JMenuItem commitItem = newJMenuItem(tr("Commit..."), 'C'); + commitItem.addActionListener(e -> { + gitCommit = new GitCommit(Editor.this, Collections.emptyMap()); + gitCommit.setLocationRelativeTo(Editor.this); + gitCommit.setVisible(true); + }); + menu.add(commitItem); + if (OSUtils.isMacOS()) { JMenuItem useSelectionForFindItem = newJMenuItem(tr("Use Selection For Find"), 'E'); useSelectionForFindItem.addActionListener(new ActionListener() {