Skip to content

Instantly share code, notes, and snippets.

@rfns
Created July 19, 2017 14:20
Show Gist options
  • Save rfns/24be127c3db27d1e84d0a75f222b46d4 to your computer and use it in GitHub Desktop.
Save rfns/24be127c3db27d1e84d0a75f222b46d4 to your computer and use it in GitHub Desktop.
Git extension backup
Class Port.SourceControl.Extension.Git Extends Port.SourceControl.Extension.VCS
{
Parameter NAME = "Git";
Parameter PATHS = "cls inc int mac web";
Method %OnNew(repositoryPath As %String) As %Status
{
do ##super(repositoryPath)
if '##class(%File).DirectoryExists(repositoryPath_"/.git") {
quit $$$ERROR("Directory is not a git repository.")
}
quit $$$OK
}
ClassMethod Install() As %Status
{
set input = ""
set validated = 0
write !!, "This setup will help you to configure a git integration."
write !, "Please fill out fields when asked:", !
// git-diff tool configuration
set defaults(2) = "{VCS} --work-tree={P1} --git-dir={P1}{SLASH}.git diff --name-status --diff-filter={P2} {P3} -- {P4} 2> ""{P5}"" > ""{P6}"""
set defaults(3) = "{VCS} --work-tree={P1} --git-dir={P1}{SLASH}.git add {P2}"
set defaults(4) = "{VCS} --work-tree={P1} --git-dir={P1}{SLASH}.git log --pretty=format:""%H||%an||%ae||%ad||at"" --date=relative 2> ""{P2}"" > ""{P3}"""
while 1 {
if input = -1 write !, "Aborted." quit
if '$get(validated(1), 0) {
set input(1) = ""
write !, "git.exe full path: "
read input(1)
if input(1) = -1 set input = 1
set validated(1) = (##class(%File).Exists(input(1)) && (##class(%File).GetFilename(input(1)) = "git.exe"))
if 'validated(1) {
write !, "Invalid path, you must specify the path for your git.exe."
continue
}
}
if '$get(validated(2), 0) {
set input(2) = ""
write !, "diff command (or empty to use default): "
read input(2)
if input(2) = -1 set input = 1
if input(2) = "" set input(2) = defaults(2)
set validated(2) = 1
}
if '$get(validated(3), 0) {
set input(3) = ""
write !, "add command (or empty to use default):"
read input(3)
if input(3) = -1 set input = 1
if input(3) = "" set input(3) = defaults(3)
set validated(3) = 1
}
if validated(1) && validated(2) && validated(3) quit
}
do ##class(Port.SourceControl.Config).SetVCSPath(input(1))
do ##class(Port.SourceControl.Config).SetVCSCommand("diff", input(2))
do ##class(Port.SourceControl.Config).SetVCSCommand("add", input(3))
do ##class(Port.SourceControl.Config).SetVCSCommand("log", defaults(4))
do ##class(Port.SourceControl.Config).RegisterVCSHandler($classname($this))
do ##class(Port.SourceControl.Config).EnableVCS()
write !!, "Done. Git is now integrated with the source control hook."
quit $$$OK
}
Method add(file As %String) As %Status
{
set sc = $$$OK
set params = 2
set params(1) = ..RepositoryPath
set params(2) = file
set command = ##class(Port.SourceControl.Config).GetVCSCommand("add", params...)
do $zf(-1, command)
quit $$$OK
}
Method diff(
paths As %String = ".",
filter As %String = "AMD",
commit As %String = "HEAD",
consoleOutput As %Stream.GlobalCharacter,
consoleError As %Stream.GlobalCharacter) As %Status
{
set sc = $$$OK
set params = 6
set params(1) = ..RepositoryPath
set params(2) = filter
set params(3) = commit
set params(4) = paths
set params(5) = ..ErrorFilePath
set params(6) = ..OutputFilePath
set command = ##class(Port.SourceControl.Config).GetVCSCommand("diff", params...)
set ^mtempPort = command
do $zf(-1, command)
set outputFile = ##class(%FileCharacterStream).%New()
set errorFile = ##class(%FileCharacterStream).%New()
set outputFile.Filename = ..OutputFilePath
set errorFile.Filename = ..ErrorFilePath
set consoleOutput = ##class(%Stream.GlobalCharacter).%New()
set consoleError = ##class(%Stream.GlobalCharacter).%New()
$$$QuitOnError(consoleOutput.CopyFrom(outputFile))
$$$QuitOnError(consoleError.CopyFrom(errorFile))
set consoleOutput.LineTerminator = $char(10)
set consoleError.LineTerminator = $char(10)
do outputFile.Clear()
do errorFile.Clear()
if consoleOutput.Size = 0 && (consoleError.Size > 0) {
do consoleError.Rewind()
set sc = $$$ERROR(5001, "Unable to diff targets, command returned the error: "_consoleError.Read())
do consoleError.Rewind()
}
quit sc
}
Method log(Output logList As %Stream.Object) As %Status
{
set sc = $$$OK
set params = 3
set params(1) = ..RepositoryPath
set params(2) = ..ErrorFilePath
set params(3) = ..OutputFilePath
set command = ##class(Port.SourceControl.Config).GetVCSCommand("log", params...)
do $zf(-1, command)
set outputBuffer = ##class(%FileCharacterStream).%New()
set outputBuffer.Filename = ..OutputFilePath
set errorBuffer = ##class(%FileCharacterStream).%New()
set errorBuffer.Filename = ..ErrorFilePath
set logList = ##class(%Stream.GlobalCharacter).%New()
$$$QuitOnError(logList.CopyFrom(outputBuffer))
set logList.LineTerminator = $char(10)
do outputBuffer.Clear()
do errorBuffer.Clear()
if logList.Size = 0 && (logList.Size > 0) {
do errorBuffer.Rewind()
set sc = $$$ERROR(5001, "Unable to show git log: "_errorBuffer.Read())
do errorBuffer.Rewind()
}
quit $$$OK
}
Query Diff(
repositoryPath As %String,
paths As %String,
filter As %String = "AMD",
commit As %String = "HEAD") As %Query(ROWSPEC = "Type:%String,Path:%String") [ SqlProc ]
{
}
ClassMethod DiffFetch(
ByRef QHandle As %Binary,
ByRef Row As %List,
ByRef AtEnd As %Integer = 0) As %Status [ Internal, PlaceAfter = DiffExecute ]
{
set index = $list(QHandle, 1)
set index = $order(^||Port.Git.Diff(index))
if index = "" {
set Row = ""
set AtEnd = 1
} else {
set Row = ^||Port.Git.Diff(index)
set $list(Row, 1) = $listget(^||Port.Git.Diff(index), 1)
set $list(Row, 2) = $listget(^||Port.Git.Diff(index), 2)
}
set QHandle = $listbuild(index)
quit $$$OK
}
ClassMethod DiffClose(ByRef QHandle As %Binary) As %Status [ Internal, PlaceAfter = DiffExecute ]
{
set QHandle = ""
kill ^||Port.Git.Diff
quit $$$OK
}
ClassMethod DiffExecute(
ByRef QHandle As %Binary,
repositoryPath As %String,
paths As %String = ".",
filter As %String = "AMD",
commit As %String = "HEAD") As %Status
{
set sc = $$$OK
set git = ..%New(repositoryPath)
set diffs = ""
kill ^||Port.Git.Diff
$$$QuitOnError(git.diff(paths,filter, commit, .output, .error))
if $isobject(output) && output.%IsA("%Stream.Object") && (output.Size > 0) {
while 'output.AtEnd {
set line = output.ReadLine()
set status = $piece(line, $char(9), 1)
set file = $piece(line, $char(9), 2)
set ^||Port.Git.Diff($increment(i)) = $listbuild(status, file)
}
}
set QHandle = $listbuild("")
quit sc
}
Query Log(repositoryPath As %String = "") As %Query(ROWSPEC = "Commit:%String,Author:%String,Email:%String,Date:%String,Message:%String") [ SqlProc ]
{
}
ClassMethod LogFetch(
ByRef QHandle As %Binary,
ByRef Row As %List,
ByRef AtEnd As %Integer = 0) As %Status [ Internal, PlaceAfter = DiffExecute ]
{
set index = $list(QHandle, 1)
set index = $order(^||Port.Git.Log(index), -1)
if index = "" {
set Row = ""
set AtEnd = 1
} else {
set Row = ^||Port.Git.Log(index)
set $list(Row, 1) = $listget(^||Port.Git.Log(index), 1)
set $list(Row, 2) = $listget(^||Port.Git.Log(index), 2)
}
set QHandle = $listbuild(index)
quit $$$OK
}
ClassMethod LogExecute(
ByRef QHandle As %Binary,
repositoryPath As %String) As %Status
{
set sc = $$$OK
set git = ..%New(repositoryPath)
set diffs = ""
kill ^||Port.Git.Log
$$$QuitOnError(git.log(.commits))
if $isobject(commits) && commits.%IsA("%Stream.Object") && (commits.Size > 0) {
while 'commits.AtEnd {
set line = commits.ReadLine()
set commit = $piece(line, "||", 1)
set author = $piece(line, "||", 2)
set email = $piece(line, "||", 3)
set authorDate = $piece(line, "||", 4)
set authorUNIXDate = $piece(line, "||", 5)
set subject = $piece(line, "||", 6)
set ^||Port.Git.Log(authorUNIXDate) = $listbuild(commit, author, email, authorDate, subject)
}
}
set QHandle = $listbuild("")
quit sc
}
ClassMethod LogClose(ByRef QHandle As %Binary) As %Status [ Internal, PlaceAfter = DiffExecute ]
{
set QHandle = ""
kill ^||Port.Git.Log
quit $$$OK
}
Method OnExport(file As %String) As %Status
{
$$$QuitOnError(..add(file))
quit $$$OK
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment