|
| 1 | +Class sc.diff.gitLocal |
| 2 | +{ |
| 3 | + |
| 4 | +/// Get diff between two points in repository |
| 5 | +/// repo - repository root directory |
| 6 | +/// sha1, sha2 - poins of history in repository |
| 7 | +/// |
| 8 | +/// Internal diff statuses: |
| 9 | +/// M modified - File has been modified |
| 10 | +/// C copy-edit - File has been copied and modified //3 |
| 11 | +/// R rename-edit - File has been renamed and modified //3 |
| 12 | +/// A added - File has been added |
| 13 | +/// D deleted - File has been deleted |
| 14 | +/// U unmerged - File has conflicts after a merge |
| 15 | +/// |
| 16 | +/// do ##class(isc.diff.gitLocal).buildDiff("C:\\temp\cache-udl\", "HEAD~10", "HEAD", release) |
| 17 | +ClassMethod buildDiff(repo As %String, sha1 As %String, sha2 As %String, Output items) As %Status |
| 18 | +{ |
| 19 | + $$$TOE(sc, ..createFile(.tempFile)) |
| 20 | + do $system.Process.CurrentDirectory(repo) |
| 21 | + $$$TOE(sc, ..execute($$$FormatText("git diff --name-status %1 %2 > %3 2>&3", sha1, sha2, tempFile))) |
| 22 | + $$$TOE(sc, ..fileToString(tempFile, .diffRaw)) |
| 23 | + |
| 24 | + for i=1:1:$length(diffRaw, $c(10)) |
| 25 | + { |
| 26 | + set element = $piece(diffRaw, $c(10), i) |
| 27 | + set status = $e($piece(element, $c(9))) |
| 28 | + set file = $piece(element, $c(9), 2) |
| 29 | + |
| 30 | + if ($l(file,"src/") '= 2) continue |
| 31 | + |
| 32 | + set isRelevantFile = ##class(sc.diff.utils).isRelevantFile(file) |
| 33 | + if ((element="") || ('isRelevantFile)) continue |
| 34 | + |
| 35 | + if $length(element, $c(9))=2 |
| 36 | + { |
| 37 | + if ((status="M") || (status="U")) || (status="A") |
| 38 | + { |
| 39 | + do ##class(sc.diff.utils).ToCacheName(.file) |
| 40 | + set items(file) = "" |
| 41 | + } |
| 42 | + }elseif $length(element, $c(9))=3 |
| 43 | + { |
| 44 | + set file = $piece(element, $c(9), 3) |
| 45 | + if ($l(file,"src/") '= 2) continue |
| 46 | + if ((status="C") || (status="R")) |
| 47 | + { |
| 48 | + do ##class(sc.diff.utils).ToCacheName(.newFile) |
| 49 | + set items(file) = "" |
| 50 | + } |
| 51 | + } |
| 52 | + } |
| 53 | + return sc |
| 54 | +} |
| 55 | + |
| 56 | +/// Create file name. |
| 57 | +/// Если name не задан, то возвращается имя созданного файла (в папке Temp). |
| 58 | +/// Если name - расширение, то возвращается имя созданного файла (в папке Temp) с заданным расширением. |
| 59 | +/// stream - стрим файла |
| 60 | +/// content - строка или stream который записывается в файл |
| 61 | +ClassMethod createFile(ByRef name As %String = "", Output stream As %Stream.FileBinary, content As %String) As %Status |
| 62 | +{ |
| 63 | + #dim sc As %Status = $$$OK |
| 64 | + |
| 65 | + if name="" { |
| 66 | + set name = ##class(%File).TempFilename() |
| 67 | + } elseif $length(name, ".")=1 { |
| 68 | + set name = ##class(%File).TempFilename(name) |
| 69 | + } |
| 70 | + |
| 71 | + set stream = ##class(%Stream.FileBinary).%New() |
| 72 | + set sc = stream.LinkToFile(name) |
| 73 | + |
| 74 | + if $data(content) { |
| 75 | + if $isObject(content) { |
| 76 | + set sc = stream.CopyFrom(content) |
| 77 | + } else { |
| 78 | + set sc = stream.Write(content) |
| 79 | + } |
| 80 | + quit:$$$ISERR(sc) sc |
| 81 | + set sc = stream.%Save() |
| 82 | + do stream.Rewind() |
| 83 | + } |
| 84 | + |
| 85 | + quit sc |
| 86 | +} |
| 87 | + |
| 88 | +/// Прочитать файл в строку |
| 89 | +ClassMethod fileToString(name As %String, Output content As %String, delete As %Boolean = {$$$YES}) As %Status |
| 90 | +{ |
| 91 | + #dim sc As %Status = $$$OK |
| 92 | + set stream = ##class(%Stream.FileBinary).%New() |
| 93 | + set sc = stream.LinkToFile(name) |
| 94 | + |
| 95 | + set content = stream.Read($$$MaxStringLength) |
| 96 | + |
| 97 | + if delete { |
| 98 | + kill stream |
| 99 | + set sc = ..deleteFile(name) |
| 100 | + } |
| 101 | + |
| 102 | + quit sc |
| 103 | +} |
| 104 | + |
| 105 | +/// Удалить файл |
| 106 | +ClassMethod deleteFile(name As %String) As %Status |
| 107 | +{ |
| 108 | + #dim sc As %Status = $$$OK |
| 109 | + set success = ##class(%File).Delete(name, .code) |
| 110 | + set:success'=$$$YES sc = $$$ERROR($$$GeneralError, $$$FormatText("Error deleting file %1 with code %2", name, code)) |
| 111 | + quit sc |
| 112 | +} |
| 113 | + |
| 114 | +/// Выполнить команду ОС |
| 115 | +ClassMethod execute(cmd, debug As %Boolean = {$$$NO}) As %Status |
| 116 | +{ |
| 117 | + #dim sc As %Status = $$$OK |
| 118 | + set code = "" |
| 119 | + //set out = "" |
| 120 | + write:debug !, "cmd: ", cmd |
| 121 | + //set sc = ##class(%Net.Remote.Utility).RunCommandViaZF(cmd, , .out, timeout, $$$YES, .code) |
| 122 | + set code = $zf(-1, cmd) |
| 123 | + write:debug !,"code: ", code |
| 124 | + |
| 125 | + if code'=0 { |
| 126 | + set sc1 = $$$ERROR($$$GeneralError, $$$FormatText("Комманда ОС: `%1` завершилась с кодом: `%2`", cmd, code)) |
| 127 | + set sc = $$$ADDSC(sc, sc1) |
| 128 | + } |
| 129 | + return sc |
| 130 | +} |
| 131 | + |
| 132 | +} |
| 133 | + |
0 commit comments