1577 lines
52 KiB
Plaintext
1577 lines
52 KiB
Plaintext
; PBIDE-GitTool.pb — Outil externe Git pour l’IDE PureBasic
|
||
; - Init, Status, Add+Commit (sélectif), Push/Pull
|
||
; - UI : liste avec cases à cocher + actions Inclure/Exclure/Tout
|
||
; - Fenêtre "Avancé…" : switch/restore de branche
|
||
; - Assistant d’installation IDE si lancé sans paramètre
|
||
; Contraintes respectées : pas d'underscore dans nos identifiants,
|
||
; Protected uniquement dans les procédures, pas de IIf, déclarations = implémentations,
|
||
; comparaisons uniquement dans If/While/Until/For, etc.
|
||
|
||
EnableExplicit
|
||
#EnableDebug = #True
|
||
|
||
; ====== Séparateur de chemin (portable) ======
|
||
CompilerIf #PB_Compiler_OS = #PB_OS_Windows
|
||
#PathSep$ = "\"
|
||
; Chemin Git forcé pour Windows :
|
||
#GitExe$ = "C:\Program Files\Git\cmd\git.exe"
|
||
CompilerElse
|
||
#PathSep$ = "/"
|
||
; Sur macOS/Linux on garde 'git' dans le PATH :
|
||
#GitExe$ = "git"
|
||
CompilerEndIf
|
||
|
||
; ====== IDs UI (placer ce bloc AVANT toutes les procédures) ======
|
||
; Fenêtre principale
|
||
#GWindow = 1
|
||
#GLabelRepo = 10
|
||
#GStringRepo = 11
|
||
#GButtonBrowse = 12
|
||
#GListStatus = 13
|
||
#GRefresh = 14
|
||
#GLabelMsg = 15
|
||
#GStringMsg = 16
|
||
#GCheckPush = 17
|
||
#GLabelRemote = 18
|
||
#GStringRemote = 19
|
||
#GLabelBranch = 20
|
||
#GComboBranch = 21
|
||
#GSavePrefs = 22
|
||
#GInit = 23
|
||
#GCommit = 24
|
||
#GPull = 25
|
||
#GPush = 26
|
||
#GInclude = 27
|
||
#GExclude = 28
|
||
#GIncludeAll = 29
|
||
#GExcludeAll = 30
|
||
#GAdvanced = 31
|
||
|
||
; Fenêtre avancée (branches)
|
||
#WAdv = 200
|
||
#GAdvLabel = 210
|
||
#GAdvCombo = 211
|
||
#GAdvSwitch = 212
|
||
#GAdvRestore = 213
|
||
#GAdvClose = 214
|
||
|
||
; Assistant d’installation
|
||
#WInstall = 100
|
||
#GLabelIde = 110
|
||
#GStringIde = 111
|
||
#GButtonIde = 112
|
||
#GLabelTools = 113
|
||
#GStringTools = 114
|
||
#GButtonTools = 115
|
||
#GLabelTheme = 116
|
||
#GStringTheme = 117
|
||
#GButtonTheme = 118
|
||
#GInstallGo = 119
|
||
#GInstallCancel = 120
|
||
#GInstallNote = 121
|
||
|
||
; --- Nouveaux gadgets ---
|
||
#GDiff = 32
|
||
#GMakeIgnore = 33
|
||
#GConfig = 34
|
||
#GGuide = 35
|
||
|
||
; --- Fenêtre Diff ---
|
||
#WDiff = 300
|
||
#GDiffText = 301
|
||
#GDiffClose = 302
|
||
|
||
; Fenêtre de sortie Git
|
||
#WOut = 400
|
||
#GOutText = 401
|
||
#GOutCopy = 402
|
||
#GOutClose = 403
|
||
|
||
; --- Bouton "Restaurer fichier…" dans la fenêtre principale ---
|
||
#GRestoreFile = 36
|
||
|
||
; --- Fenêtre de restauration d’un fichier vers un commit ---
|
||
#WRestore = 500
|
||
#GRestList = 501
|
||
#GRestOK = 502
|
||
#GRestCancel = 503
|
||
#GRestInfo = 504
|
||
|
||
|
||
; ====== Structures ======
|
||
Structure GitCall
|
||
args.s
|
||
workdir.s
|
||
output.s
|
||
errors.s
|
||
exitcode.i
|
||
EndStructure
|
||
|
||
Structure FileRow
|
||
stat.s ; 2 lettres porcelain (" M", "A ", "??", etc.)
|
||
file.s ; chemin relatif
|
||
include.i ; 1=coché (inclus), 0=exclu
|
||
EndStructure
|
||
|
||
; ====== Déclarations ======
|
||
Declare.s TrimNewlines(text$)
|
||
Declare.i RunGit(*call.GitCall)
|
||
Declare.s DetectRepoRoot(startDir$)
|
||
Declare.i LoadPrefs(prefsPath$, remote$, branch$)
|
||
Declare.i SavePrefs(prefsPath$, remote$, branch$)
|
||
Declare.i EnsureGitAvailable()
|
||
Declare.i OpenGUI(initialDir$, prefsPath$)
|
||
Declare.s DirFromArgOrFallback()
|
||
Declare.i DoInitRepo(repoDir$)
|
||
Declare.i DoStatus(repoDir$, out$)
|
||
Declare.i DoCommit(repoDir$, message$, doPush.i, remote$, branch$)
|
||
Declare.i DoPush(repoDir$, remote$, branch$)
|
||
Declare.i DoPull(repoDir$, remote$, branch$)
|
||
Declare.i ListBranches(repoDir$, List branchesList.s())
|
||
Declare.i LoadStatusRows(repoDir$, List rows.FileRow())
|
||
Declare.i FillStatusList(List rows.FileRow())
|
||
Declare.i ToggleIncludeAt(index.i, List rows.FileRow())
|
||
Declare.i CollectIncludedFiles(List rows.FileRow(), List files.s())
|
||
Declare.i DoCommitSelected(repoDir$, message$, doPush.i, remote$, branch$, List files.s())
|
||
Declare.i OpenAdvancedWindow(repoDir$)
|
||
Declare.i SwitchToBranch(repoDir$, branch$)
|
||
Declare.i RestoreFromBranch(repoDir$, branch$)
|
||
Declare.i InstallPBGitInIDE(ideExe$, toolsPrefs$, themeZip$)
|
||
Declare.i OpenInstallWizard()
|
||
Declare.s PorcelainToLabel(code$)
|
||
Declare.i OpenDiffWindow(repoDir$, List rows.FileRow())
|
||
Declare.i ConfigIdentityWizard(repoDir$)
|
||
Declare.i MakeDefaultGitignore(repoDir$)
|
||
Declare.i UpdateGuide(repoDir$, List rows.FileRow(), branch$, remote$)
|
||
Declare.s GetLocalConfig(repoDir$, key$)
|
||
Declare.i IsGitRepo(dir$)
|
||
Declare.i UpdateGuide(repoDir$, List rows.FileRow(), branch$, remote$)
|
||
Declare.i OpenRestoreFileWindow(repoDir$, List rows.FileRow())
|
||
Declare.i RestoreFileFromCommit(repoDir$, file$, commit$)
|
||
|
||
; ====== Utils ======
|
||
Procedure.s TrimNewlines(text$)
|
||
Protected s$ = text$
|
||
While Right(s$, 1) = #LF$ Or Right(s$, 1) = #CR$
|
||
s$ = Left(s$, Len(s$)-1)
|
||
Wend
|
||
ProcedureReturn s$
|
||
EndProcedure
|
||
|
||
|
||
; Détecte si 'remote$' ressemble à une URL (http(s):// ou git@…)
|
||
Procedure.i IsUrlRemote(remote$)
|
||
If FindString(remote$, "://", 1) Or FindString(remote$, "@", 1)
|
||
ProcedureReturn 1
|
||
EndIf
|
||
ProcedureReturn 0
|
||
EndProcedure
|
||
|
||
; Récupère le nom de branche courante (HEAD → renvoie "" si détachée)
|
||
Procedure.s GetCurrentBranch(repoDir$)
|
||
Protected gc.GitCall
|
||
gc\workdir = repoDir$
|
||
gc\args = "rev-parse --abbrev-ref HEAD"
|
||
If RunGit(@gc) = 0
|
||
Protected b$ = TrimNewlines(gc\output)
|
||
If b$ <> "" And LCase(b$) <> "head"
|
||
ProcedureReturn b$
|
||
EndIf
|
||
EndIf
|
||
ProcedureReturn ""
|
||
EndProcedure
|
||
|
||
; Teste si un remote nommé existe
|
||
Procedure.i RemoteExists(repoDir$, remoteName$)
|
||
Protected gc.GitCall, out$, i.i, n.i, line$
|
||
gc\workdir = repoDir$
|
||
gc\args = "remote"
|
||
If RunGit(@gc) <> 0
|
||
ProcedureReturn 0
|
||
EndIf
|
||
out$ = gc\output
|
||
n = CountString(out$, #LF$) + 1
|
||
For i = 1 To n
|
||
line$ = Trim(StringField(out$, i, #LF$))
|
||
If line$ <> "" And LCase(line$) = LCase(remoteName$)
|
||
ProcedureReturn 1
|
||
EndIf
|
||
Next
|
||
ProcedureReturn 0
|
||
EndProcedure
|
||
|
||
Procedure.i ShowGitOutput(title$, stdOut$, stdErr$)
|
||
Protected full$
|
||
full$ + "=== STDOUT ===" + #LF$ + stdOut$ + #LF$ + "=== STDERR ===" + #LF$ + stdErr$
|
||
|
||
If OpenWindow(#WOut, 0, 0, 820, 520, title$, #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
|
||
EditorGadget(#GOutText, 10, 10, 800, 460)
|
||
ButtonGadget(#GOutCopy, 600, 480, 100, 28, "Copier")
|
||
ButtonGadget(#GOutClose, 710, 480, 100, 28, "Fermer")
|
||
SetGadgetText(#GOutText, full$)
|
||
Repeat
|
||
Protected ev.i = WaitWindowEvent()
|
||
If ev = #PB_Event_Gadget
|
||
Select EventGadget()
|
||
Case #GOutCopy
|
||
SetClipboardText(full$)
|
||
Case #GOutClose
|
||
CloseWindow(#WOut)
|
||
Break
|
||
EndSelect
|
||
EndIf
|
||
Until ev = #PB_Event_CloseWindow
|
||
EndIf
|
||
ProcedureReturn 1
|
||
EndProcedure
|
||
|
||
; Ajoute un remote
|
||
Procedure.i AddRemote(repoDir$, remoteName$, remoteUrl$)
|
||
Protected gc.GitCall
|
||
gc\workdir = repoDir$
|
||
gc\args = "remote add " + remoteName$ + " " + Chr(34) + remoteUrl$ + Chr(34)
|
||
If RunGit(@gc) = 0
|
||
ProcedureReturn 1
|
||
EndIf
|
||
ShowGitOutput("Git remote add — erreur", "", gc\errors)
|
||
ProcedureReturn 0
|
||
EndProcedure
|
||
|
||
; Exécute git avec capture stdout/stderr (structure passée par pointeur)
|
||
Procedure.i RunGit(*call.GitCall)
|
||
Protected prg.i, line$,lineError$, out$, err$
|
||
If #EnableDebug
|
||
Debug "[RunGit] " + #GitExe$ + " " + *call\args + " (wd=" + *call\workdir + ")"
|
||
EndIf
|
||
|
||
prg = RunProgram(#GitExe$, *call\args, *call\workdir, #PB_Program_Open | #PB_Program_Read | #PB_Program_Error | #PB_Program_Hide)
|
||
If prg = 0
|
||
*call\output = ""
|
||
*call\errors = "Impossible de lancer '" + #GitExe$ + "'."
|
||
*call\exitcode = -1
|
||
ProcedureReturn *call\exitcode
|
||
EndIf
|
||
|
||
While ProgramRunning(prg)
|
||
While AvailableProgramOutput(prg)
|
||
line$ = ReadProgramString(prg)
|
||
If line$ <> "" : out$ + line$ + #LF$ : EndIf
|
||
lineError$ = ReadProgramError(prg) ; renvoie "" si rien à lire (non bloquant)
|
||
If lineError$ <> "" : err$ + lineError$ + #LF$ : EndIf
|
||
Wend
|
||
Delay(5)
|
||
Wend
|
||
|
||
While AvailableProgramOutput(prg)
|
||
line$ = ReadProgramString(prg)
|
||
If line$ <> "" : out$ + line$ + #LF$ : EndIf
|
||
Wend
|
||
Repeat
|
||
line$ = ReadProgramError(prg)
|
||
If line$ = "" : Break : EndIf
|
||
err$ + line$ + #LF$
|
||
ForEver
|
||
|
||
*call\output = out$
|
||
*call\errors = err$
|
||
*call\exitcode = ProgramExitCode(prg)
|
||
CloseProgram(prg)
|
||
|
||
If #EnableDebug
|
||
Debug "[RunGit] code=" + Str(*call\exitcode)
|
||
If *call\output <> "" : Debug *call\output : EndIf
|
||
If *call\errors <> "" : Debug "[stderr] " + *call\errors : EndIf
|
||
EndIf
|
||
|
||
ProcedureReturn *call\exitcode
|
||
EndProcedure
|
||
|
||
Procedure.s DetectRepoRoot(startDir$)
|
||
Protected gc.GitCall
|
||
gc\args = "rev-parse --show-toplevel"
|
||
gc\workdir = startDir$
|
||
If RunGit(@gc) = 0
|
||
ProcedureReturn TrimNewlines(gc\output)
|
||
EndIf
|
||
ProcedureReturn startDir$
|
||
EndProcedure
|
||
|
||
Procedure.i LoadPrefs(prefsPath$, remote$, branch$)
|
||
If OpenPreferences(prefsPath$)
|
||
PreferenceGroup("git")
|
||
remote$ = ReadPreferenceString("remote", "origin")
|
||
branch$ = ReadPreferenceString("branch", "main")
|
||
ClosePreferences()
|
||
If #EnableDebug
|
||
Debug "[LoadPrefs] " + prefsPath$ + " remote=" + remote$ + " branch=" + branch$
|
||
EndIf
|
||
ProcedureReturn 1
|
||
EndIf
|
||
remote$ = "origin"
|
||
branch$ = "main"
|
||
ProcedureReturn 0
|
||
EndProcedure
|
||
|
||
Procedure.i SavePrefs(prefsPath$, remote$, branch$)
|
||
If CreatePreferences(prefsPath$)
|
||
PreferenceGroup("git")
|
||
WritePreferenceString("remote", remote$)
|
||
WritePreferenceString("branch", branch$)
|
||
ClosePreferences()
|
||
If #EnableDebug
|
||
Debug "[SavePrefs] " + prefsPath$ + " remote=" + remote$ + " branch=" + branch$
|
||
EndIf
|
||
ProcedureReturn 1
|
||
EndIf
|
||
ProcedureReturn 0
|
||
EndProcedure
|
||
|
||
Procedure.i EnsureGitAvailable()
|
||
Protected gc.GitCall
|
||
gc\args = "--version"
|
||
If RunGit(@gc) = 0 And FindString(LCase(gc\output), "git version", 1)
|
||
ProcedureReturn 1
|
||
EndIf
|
||
MessageRequester("PBIDE-GitTool", "Git n'est pas détecté à l’emplacement prévu : " + #GitExe$, #PB_MessageRequester_Warning)
|
||
ProcedureReturn 0
|
||
EndProcedure
|
||
|
||
; Détermine un répertoire pertinent (project → env → --repo → exe)
|
||
Procedure.s DirFromArgOrFallback()
|
||
Protected n.i = CountProgramParameters()
|
||
Protected gotNextProject.i = 0
|
||
Protected gotNextRepo.i = 0
|
||
Protected dir$ = "", i.i, p$
|
||
|
||
For i = 0 To n - 1
|
||
p$ = ProgramParameter(i)
|
||
If gotNextProject
|
||
dir$ = p$
|
||
gotNextProject = 0
|
||
ElseIf gotNextRepo
|
||
dir$ = p$
|
||
gotNextRepo = 0
|
||
ElseIf LCase(p$) = "--project"
|
||
gotNextProject = 1
|
||
ElseIf LCase(p$) = "--repo"
|
||
gotNextRepo = 1
|
||
ElseIf Left(p$, 1) <> "-"
|
||
If dir$ = "" : dir$ = p$ : EndIf
|
||
EndIf
|
||
Next
|
||
|
||
If dir$ <> ""
|
||
If #EnableDebug : Debug "[Dir] from args: " + dir$ : EndIf
|
||
ProcedureReturn dir$
|
||
EndIf
|
||
|
||
Protected projFile$ = GetEnvironmentVariable("PB_TOOL_Project")
|
||
If projFile$ <> ""
|
||
Protected projDir$ = GetPathPart(projFile$)
|
||
If projDir$ <> ""
|
||
If #EnableDebug : Debug "[Dir] from PB_TOOL_Project: " + projDir$ : EndIf
|
||
ProcedureReturn projDir$
|
||
EndIf
|
||
EndIf
|
||
|
||
dir$ = GetPathPart(ProgramFilename())
|
||
If #EnableDebug : Debug "[Dir] fallback exe dir: " + dir$ : EndIf
|
||
ProcedureReturn dir$
|
||
EndProcedure
|
||
|
||
; ====== Opérations Git de base ======
|
||
Procedure.i DoInitRepo(repoDir$)
|
||
Protected gc.GitCall
|
||
gc\args = "init"
|
||
gc\workdir = repoDir$
|
||
If RunGit(@gc) = 0
|
||
MessageRequester("Git init", "Répertoire initialisé." + #LF$ + TrimNewlines(gc\output), #PB_MessageRequester_Info)
|
||
ProcedureReturn 1
|
||
EndIf
|
||
MessageRequester("Git init", "Échec: " + #LF$ + TrimNewlines(gc\errors), #PB_MessageRequester_Error)
|
||
ProcedureReturn 0
|
||
EndProcedure
|
||
|
||
Procedure.i DoStatus(repoDir$, out$)
|
||
Protected gc.GitCall
|
||
gc\args = "status --porcelain"
|
||
gc\workdir = repoDir$
|
||
If RunGit(@gc) <> 0
|
||
out$ = ""
|
||
MessageRequester("Git status", "Échec: " + #LF$ + TrimNewlines(gc\errors), #PB_MessageRequester_Error)
|
||
ProcedureReturn 0
|
||
EndIf
|
||
out$ = gc\output
|
||
ProcedureReturn 1
|
||
EndProcedure
|
||
|
||
Procedure.i DoCommit(repoDir$, message$, doPush.i, remote$, branch$)
|
||
Protected gc.GitCall, code.i
|
||
gc\workdir = repoDir$
|
||
|
||
gc\args = "add -A"
|
||
code = RunGit(@gc)
|
||
If code <> 0
|
||
MessageRequester("Git add", "Échec: " + #LF$ + TrimNewlines(gc\errors), #PB_MessageRequester_Error)
|
||
ProcedureReturn 0
|
||
EndIf
|
||
|
||
gc\args = "commit -m " + Chr(34) + message$ + Chr(34)
|
||
code = RunGit(@gc)
|
||
If code <> 0
|
||
MessageRequester("Git commit", "Échec ou rien à valider: " + #LF$ + TrimNewlines(gc\errors) + #LF$ + TrimNewlines(gc\output), #PB_MessageRequester_Warning)
|
||
If doPush = 0 : ProcedureReturn 0 : EndIf
|
||
Else
|
||
MessageRequester("Git commit", "OK:" + #LF$ + TrimNewlines(gc\output), #PB_MessageRequester_Info)
|
||
EndIf
|
||
|
||
If doPush
|
||
ProcedureReturn DoPush(repoDir$, remote$, branch$)
|
||
EndIf
|
||
ProcedureReturn 1
|
||
EndProcedure
|
||
|
||
; Push amélioré :
|
||
; - Accepte 'Remote' comme URL : crée/emploie 'origin' automatiquement
|
||
; - Si pas d'upstream : retente avec 'push -u <remote> <branch>'
|
||
; - Affiche sorties complètes en cas d'erreur
|
||
Procedure.i DoPush(repoDir$, remote$, branch$)
|
||
Protected gc.GitCall, code.i
|
||
Protected remoteName$ = remote$
|
||
Protected remoteUrl$ = ""
|
||
Protected curBranch$
|
||
|
||
; Remote vide → suppose 'origin'
|
||
If Trim(remoteName$) = ""
|
||
remoteName$ = "origin"
|
||
EndIf
|
||
|
||
; Si l'utilisateur a saisi une URL comme 'remote', crée/emploie 'origin'
|
||
If IsUrlRemote(remoteName$)
|
||
remoteUrl$ = remoteName$
|
||
remoteName$ = "origin"
|
||
If RemoteExists(repoDir$, remoteName$) = 0
|
||
If AddRemote(repoDir$, remoteName$, remoteUrl$) = 0
|
||
ProcedureReturn 0
|
||
EndIf
|
||
EndIf
|
||
EndIf
|
||
|
||
; Branche à utiliser : champ ou branche courante
|
||
If Trim(branch$) = ""
|
||
curBranch$ = GetCurrentBranch(repoDir$)
|
||
Else
|
||
curBranch$ = branch$
|
||
EndIf
|
||
|
||
If curBranch$ = ""
|
||
MessageRequester("Git push", "Branche courante introuvable (HEAD détachée ?). Sélectionnez une branche.", #PB_MessageRequester_Warning)
|
||
ProcedureReturn 0
|
||
EndIf
|
||
|
||
; Tentative de push normal
|
||
gc\workdir = repoDir$
|
||
gc\args = "push " + remoteName$ + " " + curBranch$
|
||
code = RunGit(@gc)
|
||
If code = 0
|
||
MessageRequester("Git push", "OK:" + #LF$ + TrimNewlines(gc\output), #PB_MessageRequester_Info)
|
||
ProcedureReturn 1
|
||
EndIf
|
||
|
||
; Si pas d'upstream, retente avec -u (premier push)
|
||
If FindString(LCase(gc\errors), "no upstream branch", 1) Or FindString(LCase(gc\errors), "set the remote as upstream", 1)
|
||
gc\args = "push -u " + remoteName$ + " " + curBranch$
|
||
code = RunGit(@gc)
|
||
If code = 0
|
||
MessageRequester("Git push (premier envoi)", "Upstream configuré et push effectué." + #LF$ + TrimNewlines(gc\output), #PB_MessageRequester_Info)
|
||
ProcedureReturn 1
|
||
EndIf
|
||
EndIf
|
||
|
||
; Autre erreur → fenêtre complète
|
||
ShowGitOutput("Git push — erreur", gc\output, gc\errors)
|
||
ProcedureReturn 0
|
||
EndProcedure
|
||
|
||
|
||
Procedure.i DoPull(repoDir$, remote$, branch$)
|
||
Protected gc.GitCall
|
||
gc\args = "pull " + remote$ + " " + branch$
|
||
gc\workdir = repoDir$
|
||
If RunGit(@gc) = 0
|
||
MessageRequester("Git pull", "OK:" + #LF$ + TrimNewlines(gc\output), #PB_MessageRequester_Info)
|
||
ProcedureReturn 1
|
||
EndIf
|
||
MessageRequester("Git pull", "Échec: " + #LF$ + TrimNewlines(gc\errors), #PB_MessageRequester_Error)
|
||
ProcedureReturn 0
|
||
EndProcedure
|
||
|
||
Procedure.i ListBranches(repoDir$, List branchesList.s())
|
||
ClearList(branchesList())
|
||
Protected gc.GitCall
|
||
gc\args = "branch --list --format='%(refname:short)'"
|
||
gc\workdir = repoDir$
|
||
|
||
If RunGit(@gc) <> 0
|
||
AddElement(branchesList()) : branchesList() = "main"
|
||
AddElement(branchesList()) : branchesList() = "master"
|
||
ProcedureReturn 0
|
||
EndIf
|
||
|
||
Protected out$ = ReplaceString(gc\output, "'", "")
|
||
Protected i.i, n.i = CountString(out$, #LF$) + 1
|
||
For i = 1 To n
|
||
Protected b$ = Trim(StringField(out$, i, #LF$))
|
||
If b$ <> ""
|
||
AddElement(branchesList())
|
||
branchesList() = b$
|
||
EndIf
|
||
Next i
|
||
ProcedureReturn 1
|
||
EndProcedure
|
||
|
||
; ====== Status → lignes et gestion des coches ======
|
||
Procedure.i LoadStatusRows(repoDir$, List rows.FileRow())
|
||
Protected gc.GitCall, text$, line$, n.i, i.i
|
||
gc\args = "status --porcelain"
|
||
gc\workdir = repoDir$
|
||
If RunGit(@gc) <> 0
|
||
MessageRequester("Git status", "Échec: " + #LF$ + TrimNewlines(gc\errors), #PB_MessageRequester_Error)
|
||
ProcedureReturn 0
|
||
EndIf
|
||
|
||
text$ = gc\output
|
||
n = CountString(text$, #LF$) + 1
|
||
For i = 1 To n
|
||
line$ = Trim(StringField(text$, i, #LF$))
|
||
If line$ <> ""
|
||
AddElement(rows())
|
||
rows()\stat = Left(line$, 2)
|
||
rows()\file = Trim(Mid(line$, 4))
|
||
rows()\include = 0
|
||
EndIf
|
||
Next i
|
||
ProcedureReturn ListSize(rows())
|
||
EndProcedure
|
||
|
||
Procedure.i FillStatusList(List rows.FileRow())
|
||
ClearGadgetItems(#GListStatus)
|
||
Protected idx.i = 0
|
||
Protected label$
|
||
ForEach rows()
|
||
label$ = PorcelainToLabel(rows()\stat)
|
||
AddGadgetItem(#GListStatus, -1, label$ + #LF$ + rows()\file)
|
||
If rows()\include
|
||
SetGadgetItemState(#GListStatus, idx, #PB_ListIcon_Checked)
|
||
Else
|
||
SetGadgetItemState(#GListStatus, idx, 0)
|
||
EndIf
|
||
idx + 1
|
||
Next
|
||
ProcedureReturn CountGadgetItems(#GListStatus)
|
||
EndProcedure
|
||
|
||
|
||
Procedure.i ToggleIncludeAt(index.i, List rows.FileRow())
|
||
If index < 0 : ProcedureReturn 0 : EndIf
|
||
Protected c.i = CountGadgetItems(#GListStatus)
|
||
If index >= c : ProcedureReturn 0 : EndIf
|
||
|
||
Protected state.i = GetGadgetItemState(#GListStatus, index)
|
||
Protected want.i
|
||
If state & #PB_ListIcon_Checked : want = 1 : Else : want = 0 : EndIf
|
||
|
||
Protected j.i = 0
|
||
ForEach rows()
|
||
If j = index
|
||
rows()\include = want
|
||
Break
|
||
EndIf
|
||
j + 1
|
||
Next
|
||
ProcedureReturn 1
|
||
EndProcedure
|
||
|
||
Procedure.i CollectIncludedFiles(List rows.FileRow(), List files.s())
|
||
ClearList(files())
|
||
ForEach rows()
|
||
If rows()\include
|
||
AddElement(files())
|
||
files() = rows()\file
|
||
EndIf
|
||
Next
|
||
ProcedureReturn ListSize(files())
|
||
EndProcedure
|
||
|
||
; Commit sélectif si des fichiers sont cochés
|
||
Procedure.i DoCommitSelected(repoDir$, message$, doPush.i, remote$, branch$, List files.s())
|
||
If ListSize(files()) = 0
|
||
ProcedureReturn DoCommit(repoDir$, message$, doPush, remote$, branch$)
|
||
EndIf
|
||
|
||
Protected gc.GitCall, code.i, argsAdd$, q$
|
||
gc\workdir = repoDir$
|
||
q$ = Chr(34)
|
||
|
||
argsAdd$ = "add"
|
||
ForEach files()
|
||
argsAdd$ + " " + q$ + files() + q$
|
||
Next
|
||
gc\args = argsAdd$
|
||
code = RunGit(@gc)
|
||
If code <> 0
|
||
MessageRequester("Git add", "Échec: " + #LF$ + TrimNewlines(gc\errors), #PB_MessageRequester_Error)
|
||
ProcedureReturn 0
|
||
EndIf
|
||
|
||
gc\args = "commit -m " + Chr(34) + message$ + Chr(34)
|
||
code = RunGit(@gc)
|
||
If code <> 0
|
||
MessageRequester("Git commit", "Échec ou rien à valider: " + #LF$ + TrimNewlines(gc\errors) + #LF$ + TrimNewlines(gc\output), #PB_MessageRequester_Warning)
|
||
If doPush = 0 : ProcedureReturn 0 : EndIf
|
||
Else
|
||
MessageRequester("Git commit", "OK:" + #LF$ + TrimNewlines(gc\output), #PB_MessageRequester_Info)
|
||
EndIf
|
||
|
||
If doPush
|
||
ProcedureReturn DoPush(repoDir$, remote$, branch$)
|
||
EndIf
|
||
ProcedureReturn 1
|
||
EndProcedure
|
||
|
||
; ====== Fenêtre Avancé… (branches) ======
|
||
#WAdv = 200
|
||
#GAdvLabel = 210
|
||
#GAdvCombo = 211
|
||
#GAdvSwitch = 212
|
||
#GAdvRestore = 213
|
||
#GAdvClose = 214
|
||
|
||
Procedure.i OpenAdvancedWindow(repoDir$)
|
||
Protected b$
|
||
NewList blist.s()
|
||
ListBranches(repoDir$, blist())
|
||
|
||
If OpenWindow(#WAdv, 0, 0, 440, 160, "Actions avancées — Branches", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
|
||
TextGadget(#GAdvLabel, 10, 14, 140, 24, "Branche :")
|
||
ComboBoxGadget(#GAdvCombo, 160, 12, 270, 24)
|
||
ForEach blist() : AddGadgetItem(#GAdvCombo, -1, blist()) : Next
|
||
GadgetToolTip(#GAdvCombo, "Sélectionnez la branche cible.")
|
||
|
||
ButtonGadget(#GAdvSwitch, 10, 60, 170, 30, "Basculer sur la branche")
|
||
GadgetToolTip(#GAdvSwitch, "git switch <branche> (ou git checkout).")
|
||
|
||
ButtonGadget(#GAdvRestore, 190, 60, 170, 30, "Restaurer depuis la branche")
|
||
GadgetToolTip(#GAdvRestore, "git restore --source <branche> -- . (remplace le contenu de travail).")
|
||
|
||
ButtonGadget(#GAdvClose, 370, 60, 60, 30, "Fermer")
|
||
|
||
Repeat
|
||
Protected ev.i = WaitWindowEvent()
|
||
If ev = #PB_Event_Gadget
|
||
Select EventGadget()
|
||
Case #GAdvSwitch
|
||
b$ = GetGadgetText(#GAdvCombo)
|
||
If b$ <> ""
|
||
If SwitchToBranch(repoDir$, b$)
|
||
MessageRequester("Branche", "Basculé sur '" + b$ + "'.", #PB_MessageRequester_Info)
|
||
EndIf
|
||
EndIf
|
||
|
||
Case #GAdvRestore
|
||
b$ = GetGadgetText(#GAdvCombo)
|
||
If b$ <> ""
|
||
If MessageRequester("Restauration", "Cette action va restaurer le contenu depuis '" + b$ + "'." + #LF$ + "Continuer ?", #PB_MessageRequester_YesNo) = #PB_MessageRequester_Yes
|
||
If RestoreFromBranch(repoDir$, b$)
|
||
MessageRequester("Restauration", "Contenu restauré depuis '" + b$ + "'.", #PB_MessageRequester_Info)
|
||
EndIf
|
||
EndIf
|
||
EndIf
|
||
|
||
Case #GAdvClose
|
||
CloseWindow(#WAdv)
|
||
ProcedureReturn 1
|
||
EndSelect
|
||
EndIf
|
||
Until ev = #PB_Event_CloseWindow
|
||
|
||
ProcedureReturn 1
|
||
EndIf
|
||
ProcedureReturn 0
|
||
EndProcedure
|
||
|
||
Procedure.i SwitchToBranch(repoDir$, branch$)
|
||
Protected gc.GitCall
|
||
gc\workdir = repoDir$
|
||
gc\args = "switch " + Chr(34) + branch$ + Chr(34)
|
||
If RunGit(@gc) = 0 : ProcedureReturn 1 : EndIf
|
||
gc\args = "checkout " + Chr(34) + branch$ + Chr(34) ; fallback versions anciennes
|
||
If RunGit(@gc) = 0 : ProcedureReturn 1 : EndIf
|
||
MessageRequester("Branche", "Échec: " + #LF$ + TrimNewlines(gc\errors), #PB_MessageRequester_Error)
|
||
ProcedureReturn 0
|
||
EndProcedure
|
||
|
||
Procedure.i RestoreFromBranch(repoDir$, branch$)
|
||
Protected gc.GitCall
|
||
gc\workdir = repoDir$
|
||
gc\args = "restore --source " + Chr(34) + branch$ + Chr(34) + " -- ."
|
||
If RunGit(@gc) = 0 : ProcedureReturn 1 : EndIf
|
||
MessageRequester("Restauration", "Échec: " + #LF$ + TrimNewlines(gc\errors), #PB_MessageRequester_Error)
|
||
ProcedureReturn 0
|
||
EndProcedure
|
||
|
||
Procedure.s PorcelainToLabel(code$)
|
||
Protected x$ = Left(code$, 1)
|
||
Protected y$ = Right(code$, 1)
|
||
|
||
If code$ = "??"
|
||
ProcedureReturn "Nouveau (non suivi)"
|
||
EndIf
|
||
If code$ = "!!"
|
||
ProcedureReturn "Ignoré"
|
||
EndIf
|
||
|
||
; Colonne X = indexé (staged)
|
||
If x$ = "M" : ProcedureReturn "Modifié (indexé)" : EndIf
|
||
If x$ = "A" : ProcedureReturn "Ajouté (indexé)" : EndIf
|
||
If x$ = "D" : ProcedureReturn "Supprimé (indexé)" : EndIf
|
||
If x$ = "R" : ProcedureReturn "Renommé (indexé)" : EndIf
|
||
If x$ = "C" : ProcedureReturn "Copié (indexé)" : EndIf
|
||
|
||
; Colonne Y = non indexé (worktree)
|
||
If y$ = "M" : ProcedureReturn "Modifié (non indexé)" : EndIf
|
||
If y$ = "A" : ProcedureReturn "Ajouté (non indexé)" : EndIf
|
||
If y$ = "D" : ProcedureReturn "Supprimé (non indexé)" : EndIf
|
||
|
||
ProcedureReturn "Changement"
|
||
EndProcedure
|
||
|
||
Procedure.i OpenDiffWindow(repoDir$, List rows.FileRow())
|
||
Protected idx.i = GetGadgetState(#GListStatus)
|
||
If idx < 0
|
||
MessageRequester("Diff", "Sélectionnez un fichier dans la liste.", #PB_MessageRequester_Info)
|
||
ProcedureReturn 0
|
||
EndIf
|
||
|
||
Protected j.i = 0, target$
|
||
ForEach rows()
|
||
If j = idx
|
||
target$ = rows()\file
|
||
Break
|
||
EndIf
|
||
j + 1
|
||
Next
|
||
|
||
If target$ = ""
|
||
MessageRequester("Diff", "Aucun fichier sélectionné.", #PB_MessageRequester_Info)
|
||
ProcedureReturn 0
|
||
EndIf
|
||
|
||
Protected gc.GitCall
|
||
gc\workdir = repoDir$
|
||
gc\args = "diff -- " + Chr(34) + target$ + Chr(34)
|
||
If RunGit(@gc) <> 0
|
||
MessageRequester("Diff", "Échec: " + #LF$ + TrimNewlines(gc\errors), #PB_MessageRequester_Error)
|
||
ProcedureReturn 0
|
||
EndIf
|
||
|
||
If OpenWindow(#WDiff, 0, 0, 800, 500, "Diff — " + target$, #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
|
||
EditorGadget(#GDiffText, 10, 10, 780, 440)
|
||
ButtonGadget(#GDiffClose, 690, 460, 100, 28, "Fermer")
|
||
SetGadgetText(#GDiffText, gc\output)
|
||
Repeat
|
||
Protected ev.i = WaitWindowEvent()
|
||
If ev = #PB_Event_Gadget And EventGadget() = #GDiffClose
|
||
CloseWindow(#WDiff)
|
||
Break
|
||
EndIf
|
||
Until ev = #PB_Event_CloseWindow
|
||
EndIf
|
||
|
||
ProcedureReturn 1
|
||
EndProcedure
|
||
|
||
Procedure.s GetLocalConfig(repoDir$, key$)
|
||
Protected gc.GitCall
|
||
gc\workdir = repoDir$
|
||
gc\args = "config --get " + key$
|
||
If RunGit(@gc) = 0
|
||
ProcedureReturn TrimNewlines(gc\output)
|
||
EndIf
|
||
ProcedureReturn ""
|
||
EndProcedure
|
||
|
||
Procedure.i ConfigIdentityWizard(repoDir$)
|
||
Protected curName$ = GetLocalConfig(repoDir$, "user.name")
|
||
Protected curMail$ = GetLocalConfig(repoDir$, "user.email")
|
||
Protected name$ = InputRequester("Identité Git", "Nom d’auteur (user.name)", curName$)
|
||
If name$ = "" : ProcedureReturn 0 : EndIf
|
||
Protected mail$ = InputRequester("Identité Git", "Email (user.email)", curMail$)
|
||
If mail$ = "" Or FindString(mail$, "@", 1) = 0
|
||
MessageRequester("Identité Git", "Email invalide.", #PB_MessageRequester_Warning)
|
||
ProcedureReturn 0
|
||
EndIf
|
||
|
||
Protected gc.GitCall
|
||
gc\workdir = repoDir$
|
||
gc\args = "config user.name " + Chr(34) + name$ + Chr(34)
|
||
If RunGit(@gc) <> 0
|
||
MessageRequester("Git config", "Échec user.name: " + #LF$ + TrimNewlines(gc\errors), #PB_MessageRequester_Error)
|
||
ProcedureReturn 0
|
||
EndIf
|
||
|
||
gc\args = "config user.email " + Chr(34) + mail$ + Chr(34)
|
||
If RunGit(@gc) <> 0
|
||
MessageRequester("Git config", "Échec user.email: " + #LF$ + TrimNewlines(gc\errors), #PB_MessageRequester_Error)
|
||
ProcedureReturn 0
|
||
EndIf
|
||
|
||
MessageRequester("Identité Git", "Identité locale configurée.", #PB_MessageRequester_Info)
|
||
ProcedureReturn 1
|
||
EndProcedure
|
||
|
||
Procedure.i MakeDefaultGitignore(repoDir$)
|
||
Protected base$ = repoDir$
|
||
If Right(base$, 1) <> #PathSep$ : base$ + #PathSep$ : EndIf
|
||
Protected path$ = base$ + ".gitignore"
|
||
|
||
If FileSize(path$) > 0
|
||
If MessageRequester(".gitignore", "Un .gitignore existe déjà. Le remplacer ?", #PB_MessageRequester_YesNo) = #PB_MessageRequester_No
|
||
ProcedureReturn 0
|
||
EndIf
|
||
EndIf
|
||
|
||
Protected txt$ = ""
|
||
txt$ + "# PureBasic / build artefacts" + #LF$
|
||
txt$ + "*.exe" + #LF$
|
||
txt$ + "*.dll" + #LF$
|
||
txt$ + "*.so" + #LF$
|
||
txt$ + "*.dylib" + #LF$
|
||
txt$ + "*.o" + #LF$
|
||
txt$ + "*.obj" + #LF$
|
||
txt$ + "*.pdb" + #LF$
|
||
txt$ + "*.res" + #LF$
|
||
txt$ + "*.a" + #LF$
|
||
txt$ + "*.lib" + #LF$
|
||
txt$ + "*.d" + #LF$
|
||
txt$ + "*.map" + #LF$
|
||
txt$ + "*.dbg" + #LF$
|
||
txt$ + "*.log" + #LF$
|
||
txt$ + "*.temp" + #LF$
|
||
txt$ + "*.bak" + #LF$
|
||
txt$ + "*.cache" + #LF$
|
||
txt$ + #LF$
|
||
txt$ + "# IDE / OS" + #LF$
|
||
txt$ + ".DS_Store" + #LF$
|
||
txt$ + "Thumbs.db" + #LF$
|
||
txt$ + ".idea" + #LF$
|
||
txt$ + ".vscode" + #LF$
|
||
|
||
Protected ok.i
|
||
If CreateFile(0, path$)
|
||
WriteString(0, txt$) : CloseFile(0) : ok = 1
|
||
EndIf
|
||
|
||
If ok
|
||
MessageRequester(".gitignore", "Fichier .gitignore créé.", #PB_MessageRequester_Info)
|
||
ProcedureReturn 1
|
||
EndIf
|
||
|
||
MessageRequester(".gitignore", "Échec de création.", #PB_MessageRequester_Error)
|
||
ProcedureReturn 0
|
||
EndProcedure
|
||
|
||
; Vérifie si 'dir$' est un dépôt Git
|
||
; - essaie via 'git rev-parse --is-inside-work-tree'
|
||
; - fallback: présence du dossier .git
|
||
Procedure.i IsGitRepo(dir$)
|
||
Protected gc.GitCall
|
||
Protected isRepo.i = 0
|
||
Protected dotGitDir$ = dir$
|
||
|
||
If Right(dotGitDir$, 1) <> #PathSep$
|
||
dotGitDir$ + #PathSep$
|
||
EndIf
|
||
dotGitDir$ + ".git"
|
||
|
||
gc\workdir = dir$
|
||
gc\args = "rev-parse --is-inside-work-tree"
|
||
If RunGit(@gc) = 0
|
||
If FindString(LCase(TrimNewlines(gc\output)), "true", 1)
|
||
isRepo = 1
|
||
EndIf
|
||
Else
|
||
; Fallback : dossier .git présent ?
|
||
If FileSize(dotGitDir$) = -2
|
||
isRepo = 1
|
||
EndIf
|
||
EndIf
|
||
|
||
If #EnableDebug
|
||
Debug "[IsGitRepo] " + dir$ + " -> " + Str(isRepo)
|
||
EndIf
|
||
|
||
ProcedureReturn isRepo
|
||
EndProcedure
|
||
|
||
; Restaure un fichier à l’état d’un commit précis
|
||
; - Essaye 'git restore --source <commit> -- <file>'
|
||
; - Fallback 'git checkout <commit> -- <file>' (pour Git anciens)
|
||
Procedure.i RestoreFileFromCommit(repoDir$, file$, commit$)
|
||
Protected gc.GitCall
|
||
gc\workdir = repoDir$
|
||
gc\args = "restore --source " + Chr(34) + commit$ + Chr(34) + " -- " + Chr(34) + file$ + Chr(34)
|
||
|
||
If #EnableDebug
|
||
Debug "[RestoreFile] " + gc\args + " (wd=" + repoDir$ + ")"
|
||
EndIf
|
||
|
||
If RunGit(@gc) = 0
|
||
MessageRequester("Restaurer", "Le fichier a été restauré depuis le commit " + commit$ + ".", #PB_MessageRequester_Info)
|
||
ProcedureReturn 1
|
||
EndIf
|
||
|
||
; Fallback pour compatibilité
|
||
gc\args = "checkout " + Chr(34) + commit$ + Chr(34) + " -- " + Chr(34) + file$ + Chr(34)
|
||
If RunGit(@gc) = 0
|
||
MessageRequester("Restaurer", "Le fichier a été restauré (fallback checkout) depuis " + commit$ + ".", #PB_MessageRequester_Info)
|
||
ProcedureReturn 1
|
||
EndIf
|
||
|
||
MessageRequester("Restaurer", "Échec : " + #LF$ + TrimNewlines(gc\errors), #PB_MessageRequester_Error)
|
||
ProcedureReturn 0
|
||
EndProcedure
|
||
|
||
; Ouvre une fenêtre listant les commits du fichier sélectionné,
|
||
; puis restaure le fichier vers le commit choisi.
|
||
Procedure.i OpenRestoreFileWindow(repoDir$, List rows.FileRow())
|
||
Protected idx.i = GetGadgetState(#GListStatus)
|
||
If idx < 0
|
||
MessageRequester("Restaurer", "Sélectionnez d'abord un fichier dans la liste.", #PB_MessageRequester_Info)
|
||
ProcedureReturn 0
|
||
EndIf
|
||
|
||
; Récupère le chemin du fichier choisi dans rows()
|
||
Protected j.i = 0, target$
|
||
ForEach rows()
|
||
If j = idx
|
||
target$ = rows()\file
|
||
Break
|
||
EndIf
|
||
j + 1
|
||
Next
|
||
|
||
If target$ = ""
|
||
MessageRequester("Restaurer", "Aucun fichier sélectionné.", #PB_MessageRequester_Info)
|
||
ProcedureReturn 0
|
||
EndIf
|
||
|
||
; Récupère l’historique des commits de ce fichier (50 derniers)
|
||
Protected gc.GitCall, out$, line$, n.i, i.i
|
||
gc\workdir = repoDir$
|
||
gc\args = "log --date=short --pretty=format:%h%x09%ad%x09%s -n 50 -- " + Chr(34) + target$ + Chr(34)
|
||
|
||
If RunGit(@gc) <> 0
|
||
MessageRequester("Restaurer", "Échec du log : " + #LF$ + TrimNewlines(gc\errors), #PB_MessageRequester_Error)
|
||
ProcedureReturn 0
|
||
EndIf
|
||
|
||
out$ = gc\output
|
||
If Trim(out$) = ""
|
||
MessageRequester("Restaurer", "Aucun commit trouvé pour ce fichier.", #PB_MessageRequester_Info)
|
||
ProcedureReturn 0
|
||
EndIf
|
||
|
||
; Prépare une liste parallèle des hash pour retrouver le commit sélectionné
|
||
NewList hashes.s()
|
||
|
||
; Fenêtre de sélection
|
||
If OpenWindow(#WRestore, 0, 0, 760, 420, "Restaurer : " + target$, #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
|
||
TextGadget(#GRestInfo, 10, 10, 740, 22, "Choisissez le commit vers lequel restaurer le fichier.")
|
||
ListIconGadget(#GRestList, 10, 40, 740, 330, "Commit", 100, #PB_ListIcon_FullRowSelect)
|
||
AddGadgetColumn(#GRestList, 1, "Date", 90)
|
||
AddGadgetColumn(#GRestList, 2, "Message", 520)
|
||
ButtonGadget(#GRestOK, 540, 380, 100, 28, "Restaurer")
|
||
ButtonGadget(#GRestCancel, 650, 380, 100, 28, "Annuler")
|
||
|
||
; Remplit la liste
|
||
n = CountString(out$, #LF$) + 1
|
||
For i = 1 To n
|
||
line$ = StringField(out$, i, #LF$)
|
||
If Trim(line$) <> ""
|
||
; Format: %h<TAB>%ad<TAB>%s
|
||
Protected h$ = StringField(line$, 1, #TAB$)
|
||
Protected d$ = StringField(line$, 2, #TAB$)
|
||
Protected s$ = StringField(line$, 3, #TAB$)
|
||
AddGadgetItem(#GRestList, -1, h$ + #LF$ + d$ + #LF$ + s$)
|
||
AddElement(hashes()) : hashes() = h$
|
||
EndIf
|
||
Next
|
||
|
||
; Boucle fenêtre
|
||
Repeat
|
||
Protected ev.i = WaitWindowEvent()
|
||
If ev = #PB_Event_Gadget
|
||
Select EventGadget()
|
||
Case #GRestOK
|
||
idx = GetGadgetState(#GRestList)
|
||
If idx < 0
|
||
MessageRequester("Restaurer", "Sélectionnez un commit.", #PB_MessageRequester_Warning)
|
||
Else
|
||
; Récupère le hash à l’index idx
|
||
j = 0
|
||
Protected chosen$
|
||
ForEach hashes()
|
||
If j = idx : chosen$ = hashes() : Break : EndIf
|
||
j + 1
|
||
Next
|
||
If chosen$ <> ""
|
||
If RestoreFileFromCommit(repoDir$, target$, chosen$)
|
||
CloseWindow(#WRestore)
|
||
ProcedureReturn 1
|
||
EndIf
|
||
EndIf
|
||
EndIf
|
||
|
||
Case #GRestCancel
|
||
CloseWindow(#WRestore)
|
||
ProcedureReturn 0
|
||
EndSelect
|
||
EndIf
|
||
Until ev = #PB_Event_CloseWindow
|
||
|
||
ProcedureReturn 0
|
||
EndIf
|
||
|
||
ProcedureReturn 0
|
||
EndProcedure
|
||
|
||
|
||
|
||
; Met à jour le panneau "Guide" avec un pas-à-pas adapté
|
||
; - Inclut l’étape “Init repo” si le dossier n’est pas encore un dépôt
|
||
; - Rappelle la différence Commit / Push pour débutants
|
||
Procedure.i UpdateGuide(repoDir$, List rows.FileRow(), branch$, remote$)
|
||
Protected tips$ = ""
|
||
Protected hasChanges.i = 0
|
||
Protected name$ = GetLocalConfig(repoDir$, "user.name")
|
||
Protected mail$ = GetLocalConfig(repoDir$, "user.email")
|
||
Protected repoReady.i = IsGitRepo(repoDir$)
|
||
|
||
; Y a-t-il des lignes dans le status ?
|
||
ForEach rows()
|
||
hasChanges = 1
|
||
Break
|
||
Next
|
||
|
||
tips$ + "Bienvenue !" + #LF$
|
||
tips$ + "- Ce panneau vous guide pas à pas." + #LF$ + #LF$
|
||
|
||
If repoReady = 0
|
||
; ---- Dépôt non initialisé : on commence par git init ----
|
||
tips$ + "Étapes de départ :" + #LF$
|
||
tips$ + "1) " + Chr(149) + " Cliquez sur le bouton 'Init repo' pour INITIALISER le dépôt dans ce dossier." + #LF$
|
||
tips$ + "2) " + Chr(149) + " (Recommandé) Créez un '.gitignore' avec le bouton dédié, pour ignorer les binaires/artefacts." + #LF$
|
||
tips$ + "3) " + Chr(149) + " Configurez votre identité (bouton 'Configurer identité…')." + #LF$
|
||
tips$ + "4) " + Chr(149) + " Cochez les fichiers à inclure, saisissez un message, puis 'Add + Commit'." + #LF$
|
||
tips$ + "5) " + Chr(149) + " Pour partager en ligne : créez un dépôt distant (GitHub/GitLab…) puis utilisez 'Push'." + #LF$ + #LF$
|
||
|
||
Else
|
||
; ---- Dépôt déjà prêt ----
|
||
tips$ + "Étapes :" + #LF$
|
||
tips$ + "1) " + Chr(149) + " (Optionnel) Créez/complétez un '.gitignore' si nécessaire." + #LF$
|
||
tips$ + "2) " + Chr(149) + " Vérifiez l’identité Git locale." + #LF$
|
||
If name$ = "" Or mail$ = ""
|
||
tips$ + " → Identité : INCOMPLÈTE (utilisez 'Configurer identité…')." + #LF$
|
||
Else
|
||
tips$ + " → Identité : " + name$ + " <" + mail$ + ">" + #LF$
|
||
EndIf
|
||
tips$ + "3) " + Chr(149) + " Cochez les fichiers à inclure au prochain commit (bouton 'Diff…' pour voir les détails)." + #LF$
|
||
If hasChanges
|
||
tips$ + " → Des modifications sont détectées ci-dessus." + #LF$
|
||
Else
|
||
tips$ + " → Aucune modification détectée pour l’instant." + #LF$
|
||
EndIf
|
||
tips$ + "4) " + Chr(149) + " Saisissez un message, cliquez 'Add + Commit' (et cochez 'Pousser après' si vous voulez envoyer au serveur)." + #LF$
|
||
tips$ + "5) " + Chr(149) + " Pour changer/restaurer une branche : 'Avancé…'." + #LF$ + #LF$
|
||
EndIf
|
||
|
||
tips$ + "Infos :" + #LF$
|
||
tips$ + "• Remote : " + remote$ + " • Branche : " + branch$ + #LF$
|
||
tips$ + "• 'Diff…' affiche le détail d’un fichier sélectionné." + #LF$ + #LF$
|
||
|
||
; Rappel pédagogique (commit vs push)
|
||
tips$ + "Rappel : différence entre Commit et Push" + #LF$
|
||
tips$ + "• Commit : enregistre localement un instantané de vos fichiers (dans l’historique du dépôt sur votre machine)." + #LF$
|
||
tips$ + "• Push : envoie vos commits locaux vers un serveur distant (GitHub, GitLab, etc.)." + #LF$
|
||
tips$ + "→ On peut faire des commits hors-ligne ; le push nécessite un dépôt distant configuré (ex. 'origin') et une branche (ex. 'main')." + #LF$
|
||
|
||
SetGadgetText(#GGuide, tips$)
|
||
|
||
If #EnableDebug
|
||
Debug "[UpdateGuide] repoReady=" + Str(repoReady) + " changes=" + Str(hasChanges)
|
||
EndIf
|
||
|
||
ProcedureReturn 1
|
||
EndProcedure
|
||
|
||
; Affiche stdout + stderr dans une fenêtre (évite le texte tronqué)
|
||
|
||
|
||
|
||
|
||
; ====== UI principale ======
|
||
; Gadgets IDs (inclut les NOUVEAUX boutons)
|
||
#GWindow = 1
|
||
#GLabelRepo = 10
|
||
#GStringRepo = 11
|
||
#GButtonBrowse = 12
|
||
#GListStatus = 13
|
||
#GRefresh = 14
|
||
#GLabelMsg = 15
|
||
#GStringMsg = 16
|
||
#GCheckPush = 17
|
||
#GLabelRemote = 18
|
||
#GStringRemote = 19
|
||
#GLabelBranch = 20
|
||
#GComboBranch = 21
|
||
#GSavePrefs = 22
|
||
#GInit = 23
|
||
#GCommit = 24
|
||
#GPull = 25
|
||
#GPush = 26
|
||
#GInclude = 27
|
||
#GExclude = 28
|
||
#GIncludeAll = 29
|
||
#GExcludeAll = 30
|
||
#GAdvanced = 31
|
||
|
||
Procedure.i OpenGUI(initialDir$, prefsPath$)
|
||
Protected repoDir$ = DetectRepoRoot(initialDir$)
|
||
Protected remote$ = "", branch$ = ""
|
||
LoadPrefs(prefsPath$, remote$, branch$)
|
||
|
||
; On élargit légèrement pour caser le nouveau bouton
|
||
If OpenWindow(#GWindow, 0, 0, 900, 640, "PBIDE-GitTool — Git (mode simplifié)", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
|
||
TextGadget(#GLabelRepo, 10, 12, 60, 22, "Dépôt :")
|
||
StringGadget(#GStringRepo, 80, 10, 720, 24, repoDir$)
|
||
ButtonGadget(#GButtonBrowse, 810, 10, 80, 24, "Parcourir…")
|
||
|
||
; Liste avec cases à cocher
|
||
ListIconGadget(#GListStatus, 10, 46, 880, 300, "Statut", 180, #PB_ListIcon_CheckBoxes | #PB_ListIcon_FullRowSelect)
|
||
AddGadgetColumn(#GListStatus, 1, "Fichier", 680)
|
||
|
||
; Ligne actions liste
|
||
ButtonGadget(#GRefresh, 10, 352, 90, 26, "Rafraîchir")
|
||
ButtonGadget(#GInit, 110, 352, 90, 26, "Init repo")
|
||
ButtonGadget(#GInclude, 210, 352, 90, 26, "Inclure")
|
||
ButtonGadget(#GExclude, 310, 352, 90, 26, "Exclure")
|
||
ButtonGadget(#GIncludeAll, 410, 352, 110, 26, "Tout inclure")
|
||
ButtonGadget(#GExcludeAll, 530, 352, 110, 26, "Tout exclure")
|
||
ButtonGadget(#GDiff, 650, 352, 80, 26, "Diff…")
|
||
ButtonGadget(#GRestoreFile,740, 352, 150, 26, "Restaurer fichier…")
|
||
|
||
; Zone commit / push
|
||
TextGadget(#GLabelMsg, 10, 388, 100, 22, "Message :")
|
||
StringGadget(#GStringMsg, 110, 386, 620, 24, "")
|
||
CheckBoxGadget(#GCheckPush, 10, 418, 140, 22, "Pousser après")
|
||
SetGadgetState(#GCheckPush, #True)
|
||
|
||
TextGadget(#GLabelRemote, 160, 418, 60, 22, "Remote :")
|
||
StringGadget(#GStringRemote, 220, 416, 120, 24, remote$)
|
||
TextGadget(#GLabelBranch, 350, 418, 60, 22, "Branche :")
|
||
ComboBoxGadget(#GComboBranch, 410, 416, 170, 24)
|
||
ButtonGadget(#GSavePrefs, 590, 416, 220, 24, "Sauver défauts")
|
||
ButtonGadget(#GAdvanced, 820, 416, 70, 24, "Avancé…")
|
||
|
||
ButtonGadget(#GCommit, 10, 450, 120, 30, "Add + Commit")
|
||
ButtonGadget(#GPush, 140, 450, 120, 30, "Push")
|
||
ButtonGadget(#GPull, 270, 450, 120, 30, "Pull")
|
||
ButtonGadget(#GConfig, 400, 450, 170, 30, "Configurer identité…")
|
||
ButtonGadget(#GMakeIgnore, 580, 450, 230, 30, "Créer .gitignore (recommandé)")
|
||
|
||
; Panneau Guide
|
||
EditorGadget(#GGuide, 10, 490, 880, 140)
|
||
DisableGadget(#GGuide, 1)
|
||
|
||
; Infobulles utiles
|
||
GadgetToolTip(#GRestoreFile, "Restaurer le fichier sélectionné à un commit précis (historique).")
|
||
GadgetToolTip(#GDiff, "Afficher les différences du fichier sélectionné.")
|
||
|
||
; Branches
|
||
NewList branchItems.s()
|
||
ListBranches(repoDir$, branchItems())
|
||
ClearGadgetItems(#GComboBranch)
|
||
ForEach branchItems() : AddGadgetItem(#GComboBranch, -1, branchItems()) : Next
|
||
If branch$ <> "" : SetGadgetText(#GComboBranch, branch$) : EndIf
|
||
|
||
; Status
|
||
NewList rows.FileRow()
|
||
LoadStatusRows(repoDir$, rows())
|
||
FillStatusList(rows())
|
||
UpdateGuide(repoDir$, rows(), GetGadgetText(#GComboBranch), GetGadgetText(#GStringRemote))
|
||
|
||
; Boucle
|
||
Repeat
|
||
Protected ev.i = WaitWindowEvent()
|
||
Select ev
|
||
Case #PB_Event_Gadget
|
||
Select EventGadget()
|
||
|
||
Case #GButtonBrowse
|
||
Protected newDir$ = PathRequester("Choisir le répertoire du dépôt", repoDir$)
|
||
If newDir$ <> ""
|
||
repoDir$ = newDir$
|
||
SetGadgetText(#GStringRepo, repoDir$)
|
||
ClearList(branchItems())
|
||
ListBranches(repoDir$, branchItems())
|
||
ClearGadgetItems(#GComboBranch)
|
||
ForEach branchItems() : AddGadgetItem(#GComboBranch, -1, branchItems()) : Next
|
||
ClearList(rows())
|
||
LoadStatusRows(repoDir$, rows())
|
||
FillStatusList(rows())
|
||
UpdateGuide(repoDir$, rows(), GetGadgetText(#GComboBranch), GetGadgetText(#GStringRemote))
|
||
EndIf
|
||
|
||
Case #GRefresh
|
||
repoDir$ = GetGadgetText(#GStringRepo)
|
||
ClearList(rows())
|
||
LoadStatusRows(repoDir$, rows())
|
||
FillStatusList(rows())
|
||
UpdateGuide(repoDir$, rows(), GetGadgetText(#GComboBranch), GetGadgetText(#GStringRemote))
|
||
|
||
Case #GInit
|
||
repoDir$ = GetGadgetText(#GStringRepo)
|
||
DoInitRepo(repoDir$)
|
||
ClearList(rows())
|
||
LoadStatusRows(repoDir$, rows())
|
||
FillStatusList(rows())
|
||
UpdateGuide(repoDir$, rows(), GetGadgetText(#GComboBranch), GetGadgetText(#GStringRemote))
|
||
|
||
Case #GInclude
|
||
Protected idx.i = GetGadgetState(#GListStatus)
|
||
If idx >= 0
|
||
SetGadgetItemState(#GListStatus, idx, #PB_ListIcon_Checked)
|
||
ToggleIncludeAt(idx, rows())
|
||
EndIf
|
||
UpdateGuide(repoDir$, rows(), GetGadgetText(#GComboBranch), GetGadgetText(#GStringRemote))
|
||
|
||
Case #GExclude
|
||
idx = GetGadgetState(#GListStatus)
|
||
If idx >= 0
|
||
SetGadgetItemState(#GListStatus, idx, 0)
|
||
ToggleIncludeAt(idx, rows())
|
||
EndIf
|
||
UpdateGuide(repoDir$, rows(), GetGadgetText(#GComboBranch), GetGadgetText(#GStringRemote))
|
||
|
||
Case #GIncludeAll
|
||
Protected c.i = CountGadgetItems(#GListStatus)
|
||
For idx = 0 To c - 1 : SetGadgetItemState(#GListStatus, idx, #PB_ListIcon_Checked) : Next
|
||
ForEach rows() : rows()\include = 1 : Next
|
||
UpdateGuide(repoDir$, rows(), GetGadgetText(#GComboBranch), GetGadgetText(#GStringRemote))
|
||
|
||
Case #GExcludeAll
|
||
c = CountGadgetItems(#GListStatus)
|
||
For idx = 0 To c - 1 : SetGadgetItemState(#GListStatus, idx, 0) : Next
|
||
ForEach rows() : rows()\include = 0 : Next
|
||
UpdateGuide(repoDir$, rows(), GetGadgetText(#GComboBranch), GetGadgetText(#GStringRemote))
|
||
|
||
Case #GDiff
|
||
repoDir$ = GetGadgetText(#GStringRepo)
|
||
OpenDiffWindow(repoDir$, rows())
|
||
|
||
Case #GRestoreFile
|
||
repoDir$ = GetGadgetText(#GStringRepo)
|
||
If OpenRestoreFileWindow(repoDir$, rows())
|
||
; Après restauration : rafraîchir l’état
|
||
ClearList(rows())
|
||
LoadStatusRows(repoDir$, rows())
|
||
FillStatusList(rows())
|
||
UpdateGuide(repoDir$, rows(), GetGadgetText(#GComboBranch), GetGadgetText(#GStringRemote))
|
||
EndIf
|
||
|
||
Case #GAdvanced
|
||
repoDir$ = GetGadgetText(#GStringRepo)
|
||
OpenAdvancedWindow(repoDir$)
|
||
ClearList(rows())
|
||
LoadStatusRows(repoDir$, rows())
|
||
FillStatusList(rows())
|
||
UpdateGuide(repoDir$, rows(), GetGadgetText(#GComboBranch), GetGadgetText(#GStringRemote))
|
||
|
||
Case #GSavePrefs
|
||
remote$ = GetGadgetText(#GStringRemote)
|
||
branch$ = GetGadgetText(#GComboBranch)
|
||
If SavePrefs(prefsPath$, remote$, branch$)
|
||
MessageRequester("Préférences", "Valeurs par défaut enregistrées.", #PB_MessageRequester_Info)
|
||
Else
|
||
MessageRequester("Préférences", "Échec d'enregistrement.", #PB_MessageRequester_Error)
|
||
EndIf
|
||
UpdateGuide(repoDir$, rows(), branch$, remote$)
|
||
|
||
Case #GConfig
|
||
repoDir$ = GetGadgetText(#GStringRepo)
|
||
If ConfigIdentityWizard(repoDir$)
|
||
UpdateGuide(repoDir$, rows(), GetGadgetText(#GComboBranch), GetGadgetText(#GStringRemote))
|
||
EndIf
|
||
|
||
Case #GMakeIgnore
|
||
repoDir$ = GetGadgetText(#GStringRepo)
|
||
If MakeDefaultGitignore(repoDir$)
|
||
ClearList(rows())
|
||
LoadStatusRows(repoDir$, rows())
|
||
FillStatusList(rows())
|
||
EndIf
|
||
|
||
Case #GCommit
|
||
repoDir$ = GetGadgetText(#GStringRepo)
|
||
remote$ = GetGadgetText(#GStringRemote)
|
||
branch$ = GetGadgetText(#GComboBranch)
|
||
Protected msg$ = GetGadgetText(#GStringMsg)
|
||
If Trim(msg$) = ""
|
||
MessageRequester("Commit", "Merci de saisir un message.", #PB_MessageRequester_Warning)
|
||
Else
|
||
NewList files.s()
|
||
CollectIncludedFiles(rows(), files())
|
||
If ListSize(files()) > 0
|
||
DoCommitSelected(repoDir$, msg$, GetGadgetState(#GCheckPush), remote$, branch$, files())
|
||
Else
|
||
DoCommit(repoDir$, msg$, GetGadgetState(#GCheckPush), remote$, branch$)
|
||
EndIf
|
||
ClearList(rows())
|
||
LoadStatusRows(repoDir$, rows())
|
||
FillStatusList(rows())
|
||
UpdateGuide(repoDir$, rows(), GetGadgetText(#GComboBranch), GetGadgetText(#GStringRemote))
|
||
EndIf
|
||
|
||
Case #GPush
|
||
repoDir$ = GetGadgetText(#GStringRepo)
|
||
remote$ = GetGadgetText(#GStringRemote)
|
||
branch$ = GetGadgetText(#GComboBranch)
|
||
DoPush(repoDir$, remote$, branch$)
|
||
|
||
Case #GPull
|
||
repoDir$ = GetGadgetText(#GStringRepo)
|
||
remote$ = GetGadgetText(#GStringRemote)
|
||
branch$ = GetGadgetText(#GComboBranch)
|
||
DoPull(repoDir$, remote$, branch$)
|
||
|
||
Case #GListStatus
|
||
idx = GetGadgetState(#GListStatus)
|
||
If idx >= 0 : ToggleIncludeAt(idx, rows()) : EndIf
|
||
UpdateGuide(repoDir$, rows(), GetGadgetText(#GComboBranch), GetGadgetText(#GStringRemote))
|
||
|
||
EndSelect
|
||
EndSelect
|
||
Until ev = #PB_Event_CloseWindow
|
||
|
||
ProcedureReturn 1
|
||
EndIf
|
||
ProcedureReturn 0
|
||
EndProcedure
|
||
|
||
; ====== Installation IDE ======
|
||
; Fenêtre assistant
|
||
#WInstall = 100
|
||
#GLabelIde = 110
|
||
#GStringIde = 111
|
||
#GButtonIde = 112
|
||
#GLabelTools = 113
|
||
#GStringTools = 114
|
||
#GButtonTools = 115
|
||
#GLabelTheme = 116
|
||
#GStringTheme = 117
|
||
#GButtonTheme = 118
|
||
#GInstallGo = 119
|
||
#GInstallCancel = 120
|
||
#GInstallNote = 121
|
||
|
||
Procedure.i InstallPBGitInIDE(ideExe$, toolsPrefs$, themeZip$)
|
||
Protected ok.i = 1, ideHome$, themesDir$, destZip$, args$, prg.i, copyok.i
|
||
|
||
If FileSize(ideExe$) <= 0 Or FileSize(toolsPrefs$) <= 0 Or FileSize(themeZip$) <= 0
|
||
MessageRequester("Installation", "Chemins invalides. Sélectionnez PureBasic.exe, le fichier d’outils et le thème.", #PB_MessageRequester_Error)
|
||
ProcedureReturn 0
|
||
EndIf
|
||
|
||
ideHome$ = GetPathPart(ideExe$)
|
||
themesDir$ = ideHome$ + "Themes" + #PathSep$
|
||
destZip$ = themesDir$ + GetFilePart(themeZip$)
|
||
|
||
If FileSize(themesDir$) <> -2
|
||
If CreateDirectory(themesDir$) = 0
|
||
MessageRequester("Installation", "Impossible de créer le dossier Themes : " + themesDir$, #PB_MessageRequester_Error)
|
||
ProcedureReturn 0
|
||
EndIf
|
||
EndIf
|
||
|
||
copyok = CopyFile(themeZip$, destZip$)
|
||
If copyok = 0
|
||
MessageRequester("Installation", "Échec de copie du thème vers : " + destZip$, #PB_MessageRequester_Error)
|
||
ok = 0
|
||
EndIf
|
||
|
||
If ok
|
||
args$ = "/A " + Chr(34) + toolsPrefs$ + Chr(34)
|
||
prg = RunProgram(ideExe$, args$, "", #PB_Program_Hide | #PB_Program_Wait)
|
||
If prg = 0
|
||
MessageRequester("Installation", "Échec de l’import des outils (/A).", #PB_MessageRequester_Error)
|
||
ok = 0
|
||
EndIf
|
||
EndIf
|
||
|
||
If ok
|
||
MessageRequester("Installation", "Intégration importée !" + #LF$ +
|
||
"- Thème copié : " + destZip$ + #LF$ +
|
||
"- Outils importés via /A", #PB_MessageRequester_Info)
|
||
EndIf
|
||
ProcedureReturn ok
|
||
EndProcedure
|
||
|
||
Procedure.i OpenInstallWizard()
|
||
Protected exeDefault$ = ""
|
||
Protected dirExe$ = GetPathPart(ProgramFilename())
|
||
Protected prefsDefault$ = dirExe$ + "git_tools.prefs"
|
||
Protected themeDefault$ = dirExe$ + "PBGitTheme.zip"
|
||
|
||
If OpenWindow(#WInstall, 0, 0, 680, 240, "PBIDE-GitTool — Assistant d’installation IDE", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
|
||
TextGadget(#GLabelIde, 10, 16, 140, 22, "PureBasic.exe :")
|
||
StringGadget(#GStringIde,160, 14, 420, 24, exeDefault$)
|
||
ButtonGadget(#GButtonIde,590, 14, 80, 24, "Parcourir…")
|
||
|
||
TextGadget(#GLabelTools, 10, 56, 140, 22, "Fichier outils :")
|
||
StringGadget(#GStringTools,160, 54, 420, 24, prefsDefault$)
|
||
ButtonGadget(#GButtonTools,590, 54, 80, 24, "Parcourir…")
|
||
|
||
TextGadget(#GLabelTheme, 10, 96, 140, 22, "Thème icônes :")
|
||
StringGadget(#GStringTheme,160, 94, 420, 24, themeDefault$)
|
||
ButtonGadget(#GButtonTheme,590, 94, 80, 24, "Parcourir…")
|
||
|
||
ButtonGadget(#GInstallGo, 380, 150, 140, 30, "Installer")
|
||
ButtonGadget(#GInstallCancel, 530, 150, 140, 30, "Annuler")
|
||
|
||
TextGadget(#GInstallNote, 10, 190, 660, 40,
|
||
"Astuce : placez 'git_tools.prefs' et 'PBGitTheme.zip' à côté de PBIDE-GitTool.exe pour auto-renseignement." + #LF$ +
|
||
"Ensuite choisissez le thème (Préférences → Themes) et ajoutez les boutons 'Run tool' dans la Toolbar.")
|
||
|
||
GadgetToolTip(#GStringIde, "Chemin de PureBasic.exe (IDE).")
|
||
GadgetToolTip(#GButtonIde, "Parcourir pour sélectionner l’exécutable de l’IDE PureBasic.")
|
||
GadgetToolTip(#GStringTools, "Fichier d’outils externes à importer (/A).")
|
||
GadgetToolTip(#GButtonTools, "Parcourir le fichier 'git_tools.prefs'.")
|
||
GadgetToolTip(#GStringTheme, "Archive ZIP du thème d’icônes pour la Toolbar.")
|
||
GadgetToolTip(#GButtonTheme, "Parcourir le fichier 'PBGitTheme.zip'.")
|
||
GadgetToolTip(#GInstallGo, "Lancer l’installation (copie du thème + import des outils).")
|
||
GadgetToolTip(#GInstallCancel, "Fermer l’assistant sans rien modifier.")
|
||
|
||
Repeat
|
||
Protected ev.i = WaitWindowEvent()
|
||
If ev = #PB_Event_Gadget
|
||
Select EventGadget()
|
||
Case #GButtonIde
|
||
Protected pickExe$ = OpenFileRequester("Choisir PureBasic.exe", GetPathPart(GetGadgetText(#GStringIde)), "Exécutable|*.exe;*|Tous|*.*", 0)
|
||
If pickExe$ <> "" : SetGadgetText(#GStringIde, pickExe$) : EndIf
|
||
|
||
Case #GButtonTools
|
||
Protected pickPrefs$ = OpenFileRequester("Choisir le fichier d'outils", GetGadgetText(#GStringTools), "Prefs|*.prefs;*.txt|Tous|*.*", 0)
|
||
If pickPrefs$ <> "" : SetGadgetText(#GStringTools, pickPrefs$) : EndIf
|
||
|
||
Case #GButtonTheme
|
||
Protected pickZip$ = OpenFileRequester("Choisir le thème (zip)", GetGadgetText(#GStringTheme), "Zip|*.zip|Tous|*.*", 0)
|
||
If pickZip$ <> "" : SetGadgetText(#GStringTheme, pickZip$) : EndIf
|
||
|
||
Case #GInstallGo
|
||
Protected ok.i = InstallPBGitInIDE(GetGadgetText(#GStringIde), GetGadgetText(#GStringTools), GetGadgetText(#GStringTheme))
|
||
If ok : CloseWindow(#WInstall) : ProcedureReturn 1 : EndIf
|
||
|
||
Case #GInstallCancel
|
||
CloseWindow(#WInstall)
|
||
ProcedureReturn 0
|
||
EndSelect
|
||
EndIf
|
||
Until ev = #PB_Event_CloseWindow
|
||
|
||
ProcedureReturn 0
|
||
EndIf
|
||
ProcedureReturn 0
|
||
EndProcedure
|
||
|
||
; ====== Entrée ======
|
||
; On ne coupe pas si Git manque, pour permettre l’assistant d’installation
|
||
If EnsureGitAvailable() = 0
|
||
; Averti, mais continue.
|
||
EndIf
|
||
|
||
; Préférences locales de l’outil
|
||
Define baseDoc$ = GetUserDirectory(#PB_Directory_Documents)
|
||
If Right(baseDoc$, 1) <> #PathSep$ : baseDoc$ + #PathSep$ : EndIf
|
||
Define prefsDir$ = baseDoc$ + "PBIDE-GitTool" + #PathSep$
|
||
If FileSize(prefsDir$) <> -2 : CreateDirectory(prefsDir$) : EndIf
|
||
Define prefsPath$ = prefsDir$ + "settings.prefs"
|
||
|
||
; Paramètres CLI
|
||
Define argCount.i = CountProgramParameters()
|
||
Define useGui.i = 1
|
||
Define repoArg$ = "", msgArg$ = "", remoteArg$ = "", branchArg$ = ""
|
||
Define wantStatus.i = 0, wantInit.i = 0, wantCommit.i = 0, wantPush.i = 0, wantPull.i = 0
|
||
Define w.i
|
||
|
||
; Si aucun paramètre : proposer l’installation IDE
|
||
If argCount = 0
|
||
If MessageRequester("PBIDE-GitTool", "Aucun paramètre détecté." + #LF$ + "Souhaitez-vous installer l’intégration IDE (outils + thème) maintenant ?", #PB_MessageRequester_YesNo) = #PB_MessageRequester_Yes
|
||
OpenInstallWizard()
|
||
End
|
||
EndIf
|
||
EndIf
|
||
|
||
For w = 0 To argCount - 1
|
||
Define a$ = ProgramParameter(w)
|
||
Select LCase(a$)
|
||
Case "--project" : If w + 1 < argCount : repoArg$ = ProgramParameter(w + 1) : EndIf
|
||
Case "--repo" : If w + 1 < argCount : repoArg$ = ProgramParameter(w + 1) : EndIf
|
||
Case "--status" : wantStatus = 1 : useGui = 0
|
||
Case "--init" : wantInit = 1 : useGui = 0
|
||
Case "--commit" : wantCommit = 1 : useGui = 0 : If w + 1 < argCount : msgArg$ = ProgramParameter(w + 1) : EndIf
|
||
Case "--push" : wantPush = 1 : useGui = 0
|
||
Case "--pull" : wantPull = 1 : useGui = 0
|
||
Case "--remote" : If w + 1 < argCount : remoteArg$ = ProgramParameter(w + 1) : EndIf
|
||
Case "--branch" : If w + 1 < argCount : branchArg$ = ProgramParameter(w + 1) : EndIf
|
||
EndSelect
|
||
Next w
|
||
|
||
If useGui
|
||
Define dir$ = repoArg$
|
||
If dir$ = "" : dir$ = DirFromArgOrFallback() : EndIf
|
||
OpenGUI(dir$, prefsPath$)
|
||
Else
|
||
; Mode non interactif
|
||
Define remote$ = "", branch$ = ""
|
||
LoadPrefs(prefsPath$, remote$, branch$)
|
||
If remoteArg$ <> "" : remote$ = remoteArg$ : EndIf
|
||
If branchArg$ <> "" : branch$ = branchArg$ : EndIf
|
||
|
||
Define baseDir$ = repoArg$
|
||
If baseDir$ = "" : baseDir$ = DirFromArgOrFallback() : EndIf
|
||
baseDir$ = DetectRepoRoot(baseDir$)
|
||
|
||
If wantStatus
|
||
Define st$, okstat.i = DoStatus(baseDir$, st$)
|
||
If okstat : PrintN(st$) : EndIf
|
||
ElseIf wantInit
|
||
DoInitRepo(baseDir$)
|
||
ElseIf wantCommit
|
||
If msgArg$ = "" : msgArg$ = "update" : EndIf
|
||
DoCommit(baseDir$, msgArg$, wantPush, remote$, branch$)
|
||
ElseIf wantPush
|
||
DoPush(baseDir$, remote$, branch$)
|
||
ElseIf wantPull
|
||
DoPull(baseDir$, remote$, branch$)
|
||
EndIf
|
||
EndIf
|
||
|
||
; IDE Options = PureBasic 6.21 (Windows - x64)
|
||
; CursorPosition = 1370
|
||
; FirstLine = 1329
|
||
; Folding = -------
|
||
; EnableXP
|
||
; DPIAware
|
||
; Executable = ..\PBIDE-GitTool.exe
|
||
; CompileSourceDirectory |