<commit_before>(ns nightcode.git
  (:require [clojure.java.io :as io]
            [clojure.string :as string]
            [hiccup.core :as h]
            [nightcode.dialogs :as dialogs]
            [nightcode.editors :as editors]
            [nightcode.shortcuts :as shortcuts]
            [nightcode.ui :as ui]
            [nightcode.utils :as utils]
            [seesaw.core :as s])
  (:import [java.io ByteArrayOutputStream]
           [javax.swing JTree]
           [javax.swing.event HyperlinkEvent$EventType TreeSelectionListener]
           [javax.swing.text.html HTMLEditorKit StyleSheet]
           [javax.swing.tree DefaultMutableTreeNode DefaultTreeModel
            TreeSelectionModel]
           [org.eclipse.jgit.api Git]
           [org.eclipse.jgit.diff DiffEntry DiffFormatter]
           [org.eclipse.jgit.dircache DirCacheIterator]
           [org.eclipse.jgit.internal.storage.file FileRepository]
           [org.eclipse.jgit.lib PersonIdent ProgressMonitor Repository]
           [org.eclipse.jgit.revwalk RevCommit]
           [org.eclipse.jgit.transport CredentialItem$CharArrayType
            CredentialItem$StringType CredentialsProvider
            CredentialsProviderUserInfo URIish]
           [org.eclipse.jgit.treewalk CanonicalTreeParser EmptyTreeIterator
            FileTreeIterator]))

(def ^:const git-name "Git")
(def ^:const max-commits 50)

; commands

(defn address->name
  [s]
  (when (.endsWith s ".git")
    (-> s URIish. .getHumanishName)))

(defn remote-url
  [^FileRepository repo]
  (-> repo .getConfig (.getString "remote" "origin" "url")))

(defn creds
  []
  (proxy [CredentialsProvider] []
    (isInteractive [] false)
    (supports [& items] true)
    (get [uri items]
      (let [success? (promise)]
        (s/invoke-later
          (doseq [item items]
            (when-not (realized? success?)
              (if-let [s (dialogs/show-input-dialog! (.getPromptText item)
                                                     (.isValueSecure item))]
                (cond
                  (isa? (type item) CredentialItem$CharArrayType)
                  (.setValue item (char-array s))
                  (isa? (type item) CredentialItem$StringType)
                  (.setValue item s))
                (deliver success? false))))
          (deliver success? true))
        @success?))))

(defn progress-monitor
  [dialog cancelled?]
  (reify ProgressMonitor
    (beginTask [this title total-work])
    (endTask [this]
      (s/invoke-later
        (s/dispose! dialog)))
    (isCancelled [this] @cancelled?)
    (start [this total-tasks])
    (update [this completed])))

(defn clone!
  [^String uri f progress]
  (-> (Git/cloneRepository)
      (.setURI uri)
      (.setDirectory f)
      (.setCredentialsProvider (creds))
      (.setProgressMonitor progress)
      .call
      .close))

(defn clone-with-dialog!
  [^String uri f]
  (let [cancelled? (atom false)
        exception (atom nil)
        path (promise)
        d (dialogs/cancel-dialog (str (utils/get-string :cloning-project)
                                      \newline
                                      \newline
                                      (format (utils/get-string :from) uri)
                                      \newline
                                      (format (utils/get-string :to)
                                              (.getCanonicalPath f))))]
    (future (try (clone! uri f (progress-monitor d cancelled?))
              (catch Exception e
                (when-not @cancelled?
                  (reset! exception e)
                  (s/invoke-later
                    (s/dispose! d)
                    (dialogs/show-simple-dialog! (.getMessage e)))))
              (finally
                (if (or @cancelled? @exception)
                  (do
                    (deliver path nil)
                    (utils/delete-children-recursively! f))
                  (deliver path (.getCanonicalPath f))))))
    (reset! cancelled? (some? (s/show! d)))
    @path))

(defn do-with-dialog!
  [git-fn! repo dialog-text]
  (let [cancelled? (atom false)
        exception (atom nil)
        d (dialogs/cancel-dialog dialog-text)]
    (future (try (git-fn! repo (progress-monitor d cancelled?))
              (catch Exception e
                (when-not @cancelled?
                  (reset! exception e)
                  (s/invoke-later
                    (s/dispose! d)
                    (dialogs/show-simple-dialog! (.getMessage e)))))))
    (reset! cancelled? (some? (s/show! d)))))

(defn pull!
  [^FileRepository repo ^ProgressMonitor progress]
  (-> repo Git. .pull
      (.setCredentialsProvider (creds))
      (.setProgressMonitor progress)
      .call))

(defn push!
  [^FileRepository repo ^ProgressMonitor progress]
  (-> repo Git. .push
      (.setCredentialsProvider (creds))
      (.setProgressMonitor progress)
      .call))

; ui

(defn git-file<commit_msg>Don't request credentials every time<commit_after>(ns nightcode.git
  (:require [clojure.java.io :as io]
            [clojure.string :as string]
            [hiccup.core :as h]
            [nightcode.dialogs :as dialogs]
            [nightcode.editors :as editors]
            [nightcode.shortcuts :as shortcuts]
            [nightcode.ui :as ui]
            [nightcode.utils :as utils]
            [seesaw.core :as s])
  (:import [java.io ByteArrayOutputStream]
           [javax.swing JTree]
           [javax.swing.event HyperlinkEvent$EventType TreeSelectionListener]
           [javax.swing.text.html HTMLEditorKit StyleSheet]
           [javax.swing.tree DefaultMutableTreeNode DefaultTreeModel
            TreeSelectionModel]
           [org.eclipse.jgit.api Git]
           [org.eclipse.jgit.diff DiffEntry DiffFormatter]
           [org.eclipse.jgit.dircache DirCacheIterator]
           [org.eclipse.jgit.internal.storage.file FileRepository]
           [org.eclipse.jgit.lib PersonIdent ProgressMonitor Repository]
           [org.eclipse.jgit.revwalk RevCommit]
           [org.eclipse.jgit.transport CredentialItem$CharArrayType
            CredentialItem$StringType CredentialsProvider
            CredentialsProviderUserInfo URIish]
           [org.eclipse.jgit.treewalk CanonicalTreeParser EmptyTreeIterator
            FileTreeIterator]))

(def ^:const git-name "Git")
(def ^:const max-commits 50)

; utils

(defn address->name
  [s]
  (when (.endsWith s ".git")
    (-> s URIish. .getHumanishName)))

(defn remote-url
  [^FileRepository repo]
  (-> repo .getConfig (.getString "remote" "origin" "url")))

(def creds
  (delay
    (proxy [CredentialsProvider] []
      (isInteractive [] false)
      (supports [& items] true)
      (get [uri items]
        (let [success? (promise)]
          (s/invoke-later
            (doseq [item items]
              (when-not (realized? success?)
                (if-let [s (dialogs/show-input-dialog! (.getPromptText item)
                                                       (.isValueSecure item))]
                  (cond
                    (isa? (type item) CredentialItem$CharArrayType)
                    (.setValue item (char-array s))
                    (isa? (type item) CredentialItem$StringType)
                    (.setValue item s))
                  (deliver success? false))))
            (deliver success? true))
          @success?)))))

(defn progress-monitor
  [dialog cancelled?]
  (reify ProgressMonitor
    (beginTask [this title total-work])
    (endTask [this]
      (s/invoke-later
        (s/dispose! dialog)))
    (isCancelled [this] @cancelled?)
    (start [this total-tasks])
    (update [this completed])))

; commands

(defn clone!
  [^String uri f progress]
  (-> (Git/cloneRepository)
      (.setURI uri)
      (.setDirectory f)
      (.setCredentialsProvider @creds)
      (.setProgressMonitor progress)
      .call
      .close))

(defn clone-with-dialog!
  [^String uri f]
  (let [cancelled? (atom false)
        exception (atom nil)
        path (promise)
        d (dialogs/cancel-dialog (str (utils/get-string :cloning-project)
                                      \newline
                                      \newline
                                      (format (utils/get-string :from) uri)
                                      \newline
                                      (format (utils/get-string :to)
                                              (.getCanonicalPath f))))]
    (future (try (clone! uri f (progress-monitor d cancelled?))
              (catch Exception e
                (when-not @cancelled?
                  (reset! exception e)
                  (s/invoke-later
                    (s/dispose! d)
                    (dialogs/show-simple-dialog! (.getMessage e)))))
              (finally
                (if (or @cancelled? @exception)
                  (do
                    (deliver path nil)
                    (utils/delete-children-recursively! f))
                  (deliver path (.getCanonicalPath f))))))
    (reset! cancelled? (some? (s/show! d)))
    @path))

(defn do-with-dialog!
  [git-fn! repo dialog-text]
  (let [cancelled? (atom false)
        exception (atom nil)
        d (dialogs/cancel-dialog dialog-text)]
    (future (try (git-fn! repo (progress-monitor d cancelled?))
              (catch Exception e
                (when-not @cancelled?
                  (reset! exception e)
                  (s/invoke-later
                    (s/dispose! d)
                    (dialogs/show-simple-dialog! (.getMessage e)))))))
    (reset! cancelled? (some? (s/show! d)))))

(defn pull!
  [^FileRepository repo ^ProgressMonitor progress]
  (-> repo Git. .pull
      (.setCredentialsProvider @creds)
      (.setProgressMonitor progress)
      .call))

(defn push!
  [^FileRepository repo ^ProgressMonitor progress]
  (-> repo Git. .push
      (.setCredentialsProvider @creds)
      (.setProgressMonitor progress)
      .call))

; ui

(defn git-file
{'fraction_non_alphanumeric': 0.11554346731137302, 'fraction_numerical': 0.0004029414727510829, 'mean_word_length': 1.7516629711751663, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 18, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6693302', 'n_tokens_mistral': 2917, 'n_tokens_neox': 2799, 'n_words': 681}