diff --git a/pom.xml b/pom.xml index 2db1ab3..a44f8cc 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ istlab.KisoJikkenNWP KisoJikkenNWP jar - 0.75 + 0.76 KisoJikkenNWP http://maven.apache.org diff --git a/src/main/java/istlab/KisoJikken/App.java b/src/main/java/istlab/KisoJikken/App.java index b8c0675..a3f8179 100644 --- a/src/main/java/istlab/KisoJikken/App.java +++ b/src/main/java/istlab/KisoJikken/App.java @@ -3,7 +3,6 @@ import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; -import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URI; @@ -22,6 +21,9 @@ import javax.swing.SwingUtilities; import javax.swing.UIManager; +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.errors.GitAPIException; + /** * Hello world! * @@ -51,7 +53,8 @@ System.out.println("Different! " + latestVersion + " from " + execPath.getFileName().toString()); String pathfile = download(); if (pathfile != null) { - int res = JOptionPane.showConfirmDialog(null, "最新版をダウンロードしました。最新版を起動しますか?", "アプリ更新", JOptionPane.YES_NO_OPTION); + int res = JOptionPane.showConfirmDialog(null, "最新版をダウンロードしました。最新版を起動しますか?", "アプリ更新", + JOptionPane.YES_NO_OPTION); if (res == JOptionPane.YES_OPTION) { reboot(pathfile); } @@ -60,7 +63,8 @@ // ファイルがあるかチェック userhome = System.getProperty("user.home"); - userhome_escaped = App.userhome.replaceAll("\\\\","\\\\\\\\"); //なんじゃこの意味不明なエスケープは https://stackoverflow.com/questions/1701839/string-replaceall-single-backslashes-with-double-backslashes + userhome_escaped = App.userhome.replaceAll("\\\\", "\\\\\\\\"); // なんじゃこの意味不明なエスケープは + // https://stackoverflow.com/questions/1701839/string-replaceall-single-backslashes-with-double-backslashes getNWPifnotexist(false); @@ -69,7 +73,8 @@ String laf = UIManager.getSystemLookAndFeelClassName(); // System.out.println(laf); // Linuxの場合 - if (laf.endsWith("GTKLookAndFeel")) laf = "javax.swing.plaf.metal.MetalLookAndFeel"; + if (laf.endsWith("GTKLookAndFeel")) + laf = "javax.swing.plaf.metal.MetalLookAndFeel"; UIManager.setLookAndFeel(laf); } catch (Exception e) { /* Never happens */ } @@ -143,7 +148,7 @@ try { processBuilder.start(); System.exit(0); - }catch(Exception ex){ + } catch (Exception ex) { } } @@ -153,17 +158,27 @@ int res = JOptionPane.showConfirmDialog(Launcher.theapp, "NWP実験用のファイルが " + userhome + nwpsrc + " にありません。ダウンロードしますか?"); if (res == JOptionPane.YES_OPTION) { - System.out.println("cd ; git clone " + gitrepos + " を実行。"); - ProcessBuilder processBuilder = new ProcessBuilder("git", "clone", gitrepos); - processBuilder.directory(new File(userhome)); - processBuilder.inheritIO(); + // JGitをもちいる try { - Process process; - process = processBuilder.start(); - process.waitFor(); - } catch (IOException | InterruptedException e1) { - e1.printStackTrace(); + Git git = Git.cloneRepository() + .setURI(gitrepos) + .setDirectory(new File(userhome)) + .call(); + } catch (GitAPIException e) { + JOptionPane.showMessageDialog(Launcher.theapp, "NWP実験用ファイルのダウンロード失敗しました。\n\n講義中であれば、教員を呼んでください。"); + e.printStackTrace(); } + // System.out.println("cd ; git clone " + gitrepos + " を実行。"); + // ProcessBuilder processBuilder = new ProcessBuilder("git", "clone", gitrepos); + // processBuilder.directory(new File(userhome)); + // processBuilder.inheritIO(); + // try { + // Process process; + // process = processBuilder.start(); + // process.waitFor(); + // } catch (IOException | InterruptedException e1) { + // e1.printStackTrace(); + // } } else { System.out.println("cd ; git clone " + gitrepos + " を実行してください。"); System.exit(0); diff --git a/src/main/java/istlab/KisoJikken/ConfigManager.java b/src/main/java/istlab/KisoJikken/ConfigManager.java new file mode 100644 index 0000000..ccd6877 --- /dev/null +++ b/src/main/java/istlab/KisoJikken/ConfigManager.java @@ -0,0 +1,63 @@ +package istlab.KisoJikken; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; + +public class ConfigManager { + + File userdir; + + public ConfigManager(String dir) { + if (dir == null) { + userdir = new File(System.getProperty("user.home")); + } else { + userdir = new File(dir); + } + } + + public String getDate(int plusday){ + // 現在の日付を取得 + LocalDate today = LocalDate.now(); + // plusday日後の日付を計算 + LocalDate futureDate = today.plusDays(plusday); + // 日付文字列のフォーマットを指定 + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + // フォーマットに従って日付文字列を生成 + return futureDate.format(formatter); + } + + // 10日先の日付を設定する + public void write() { + try { + File file = new File(userdir.getAbsolutePath() + File.separator + ".nwp.conf"); + FileWriter fw = new FileWriter(file); + fw.write(getDate(10)); + fw.close(); + } catch (IOException e) { + System.out.println(e); + } + } + + public boolean readAndCheckDate(){ + BufferedReader br; + try { + File file = new File(userdir.getAbsolutePath() + File.separator + ".nwp.conf"); + FileReader fr = new FileReader(file); + br = new BufferedReader(fr); + String today = getDate(0); + String line = br.readLine(); + System.out.println(line+" "+today+" "+line.compareTo(today)); + if (br != null) br.close(); + return (line.compareTo(today)>0); + } catch (IOException e) { + // System.out.println(e); + return false; + } + } + +} diff --git a/src/main/java/istlab/KisoJikken/GitManager.java b/src/main/java/istlab/KisoJikken/GitManager.java new file mode 100644 index 0000000..248f1f4 --- /dev/null +++ b/src/main/java/istlab/KisoJikken/GitManager.java @@ -0,0 +1,124 @@ + +package istlab.KisoJikken; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Set; + +import javax.swing.JOptionPane; + +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.StashCreateCommand; +import org.eclipse.jgit.api.Status; +import org.eclipse.jgit.api.StatusCommand; +import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.errors.NoWorkTreeException; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.revwalk.RevCommit; + +public class GitManager { + + Git git = null; + Repository repository; + ConfigManager configman; + + public GitManager(File root) throws IOException { + repository = Git.open(new File(root.getParentFile().getAbsolutePath() + File.separator + ".git")) + .getRepository(); + configman = new ConfigManager(App.userhome); + } + + /** + * Gitのリポジトリ状況を確認する + * + * @throws NoWorkTreeException + * @throws GitAPIException + */ + public void checkClean() throws NoWorkTreeException, GitAPIException { + + git = new Git(repository); + + StatusCommand statusCommand = git.status(); + Status status = statusCommand.call(); + + if (!status.isClean()) { + // もし、延期ファイルがあって、延期ファイルの日付よりも今日の日付のほうが早いなら、チェックをスキップする(イコールのときはスキップしない) + if (configman.readAndCheckDate()) + return; + + System.out.println("Gitのローカルリポジトリに変更点があります。"); + Set changedFiles = status.getModified(); + Set untrackedFiles = status.getUntracked(); + + System.out.println("変更されたファイル:"); + for (String filePath : changedFiles) { + System.out.println(filePath); + } + System.out.println("まだGit管理下にないファイル:"); + for (String filePath : untrackedFiles) { + System.out.println(filePath); + } + int res = JOptionPane.showConfirmDialog(Launcher.theapp, "教員提供のSampleSrcが修正されています。\n\n" + // + "あなたの作業を消して,初期状態に戻しますか?\n\n" + // + "「はい」を押すと,修正を削除して初期状態に戻します。\n" + // + "「いいえ」「取消」を押すと,なにもしません。\n\n" + // + "あなたがまだ何も作業しておらず,これから実験を\n" + // + "始めるときだけ「はい」を押してください。\n作業の続きを行うときは「いいえ」を押してください。\n(「いいえ」で回答すると、次は10日後までチェックしません。)", + "教員が提供するサンプルソースコードが修正されています", + JOptionPane.YES_NO_CANCEL_OPTION); + if (res == JOptionPane.YES_OPTION) { + int res2 = JOptionPane.showConfirmDialog(Launcher.theapp, "あなたの編集したファイルが消えます。\n本当に消してよいですか?", "ファイルが消えます", + JOptionPane.YES_NO_CANCEL_OPTION); + if (res2 == JOptionPane.YES_OPTION) { + stash(); + JOptionPane.showMessageDialog(Launcher.theapp, "初期状態に戻しました。\n\n誤って削除してしまった場合は、\n $ cd ~/NWP\nをしたあとで\n" + // + " $ git stash list (退避情報の一覧)\n"+ // + " $ git stash pop (直前の退避情報を復活)\n"+// + " $ git stash pop stash@{1} (指定した退避情報を復活)\n"+// + "などを行ってください。"); + } + } else { + if (res == JOptionPane.NO_OPTION) + configman.write(); + } + } else { + System.out.println("No uncommitted changes in the local repository."); + } + if (git != null) + git.close(); + // showNotice(); + } + + public void stash() throws GitAPIException { + git = new Git(repository); + + StashCreateCommand stashCreateCommand = git.stashCreate(); + stashCreateCommand.setIncludeUntracked(true); + + SimpleDateFormat sdf = new SimpleDateFormat("yy/MM/dd HH:mm:ss"); + + stashCreateCommand.setWorkingDirectoryMessage(sdf.format(new Date()) + " に退避した作業"); + RevCommit stashCommit = stashCreateCommand.call(); + + if (stashCommit != null) { + System.out.println("Stash created. Stash commit ID: " + stashCommit.getName()); + } else { + System.out.println("No local changes to stash."); + } + } + + public void showNotice() { + JOptionPane.showMessageDialog(Launcher.theapp, "(1) デバイスを認識すると,タイトルバーに COM3 のように表示します。\n" + // + " 複数みえるときはWindowsのデバイスマネージャ>ポートでM5Stickのポート番号を調べたうえで,\n" + // + " このプログラムの Serialメニュー から,書き込み先ポートを選んでください。\n\n" + // + "(2) デバイスを認識しないときは,このプログラムを再起動してみてください。\n" + // + " (Appメニュー>このプログラムを再起動する)\n\n" + // + "(3) デバイスを返却するときは,FactoryTest を書き込んでおいてください。\n" + // + " (Fileメニュー>FactoryTestを書き込む)\n\n" + // + " デバイスは充電した状態で返却してください。"// + , "IoTP実験における大事な注意点です。たくさんありますがしっかり読んでください。", JOptionPane.WARNING_MESSAGE); + + } +} diff --git a/src/main/java/istlab/KisoJikken/Launcher.java b/src/main/java/istlab/KisoJikken/Launcher.java index 1c402d3..98cf9d0 100644 --- a/src/main/java/istlab/KisoJikken/Launcher.java +++ b/src/main/java/istlab/KisoJikken/Launcher.java @@ -29,7 +29,7 @@ public class Launcher extends JFrame implements MouseInputListener, KeyListener { public static Launcher theapp; - public static String version = "0.75"; + public static String version = "0.76"; // JPanel mainP; File root; JTree tree; @@ -143,6 +143,10 @@ mi.addActionListener(ae -> openURL("https://ss.istlab.info/presens/dview/383/")); menu.add(mi); + mi = new JMenuItem(isEnglish ? "LMS Login" : "講義システム ログイン"); + mi.addActionListener(ae -> openURL("https://ss.istlab.info/users/login")); + menu.add(mi); + setJMenuBar(menuBar); // getContentPane().add(mainP, BorderLayout.WEST);