Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: doublefint/cache-udl
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: master
Choose a base ref
...
head repository: objectscript/cache-udl
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref
Can’t automatically merge. Don’t worry, you can still create the pull request.
  • 14 commits
  • 6 files changed
  • 2 contributors

Commits on Jan 23, 2018

  1. Copy the full SHA
    1c502a1 View commit details

Commits on Jan 24, 2018

  1. dash bug fixed

    gevorg95 committed Jan 24, 2018
    Copy the full SHA
    4187158 View commit details

Commits on Feb 9, 2018

  1. Copy the full SHA
    5795251 View commit details
  2. Copy the full SHA
    f35c992 View commit details

Commits on Feb 18, 2018

  1. dfi bug fixed

    gevorg95 committed Feb 18, 2018
    Copy the full SHA
    8011cdf View commit details
  2. Copy the full SHA
    435d56d View commit details

Commits on Feb 27, 2018

  1. Update README.md

    evshvarov authored Feb 27, 2018

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    b5dda85 View commit details
  2. dfi export bug fixed

    gevorg95 committed Feb 27, 2018
    Copy the full SHA
    e46074b View commit details

Commits on Mar 5, 2018

  1. Copy the full SHA
    a115333 View commit details
  2. Update README.md

    gevorg95 authored Mar 5, 2018

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    cc2f99d View commit details

Commits on Mar 7, 2018

  1. [FIX] xml extension bug

    gevorg95 committed Mar 7, 2018
    Copy the full SHA
    6fbd24e View commit details
  2. Copy the full SHA
    37225ca View commit details

Commits on Mar 8, 2018

  1. [FIX] XML line

    gevorg95 committed Mar 8, 2018
    Copy the full SHA
    15055ac View commit details

Commits on Mar 9, 2018

  1. Fix Readme

    evshvarov committed Mar 9, 2018
    Copy the full SHA
    69422ea View commit details
Showing with 415 additions and 30 deletions.
  1. +1 −0 .gitignore
  2. +24 −5 README.md
  3. +113 −25 sc.code.cls → cls/sc/code.cls
  4. +108 −0 cls/sc/diff/gitHub.cls
  5. +133 −0 cls/sc/diff/gitLocal.cls
  6. +36 −0 cls/sc/diff/utils.cls
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.DS*
.vscode

dev.md

29 changes: 24 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -4,7 +4,8 @@ Export/Import sources in UDL format for [ISC Caché 2016.2](http://www.intersyst
# Installation
Download code and run
```
do $System.OBJ.ImportDir("/dir/cache-udl","*.xml;*.cls;*.mac;*.int;*.inc;*.dfi","ck",,1)
set dir="/dir/cache-udl
do $System.OBJ.ImportDir(dir,"*.xml;*.cls;*.mac;*.int;*.inc;*.dfi","ck",,1)
```
or
import the [release](https://github.com/intersystems-ru/cache-udl/releases) to the namespace.
@@ -26,13 +27,23 @@ NS> d ##class(sc.code).export()
NS> d ##class(sc.code).import()
```

## Compile and Release:
## Compile, Release and Patch:

Introduce cos.json file in the source root directory with settings for the code mask and for the name of the project. e.g.
Introduce isc.json file in the source root directory with settings for the code mask, for the name of the project and for get the patch form local git or GitHub. e.g.
```
cos.json
"git": 0 - files diff from local git
"git": 1 - files diff from GitHub
```

```
isc.json
"compileList": "Classes*.INC,classes*.CLS,*.DFI",
"projectName": "myproject"
"projectName": "myproject",
"git": 0,
"owner": "owner",
"repository": "repository",
"user": "user",
"password": "password"
```
Run init method to initialize project settings:
```
@@ -46,6 +57,14 @@ Or compile it whenever you want to compile all the proejct related resources.
```
NS> d ##class(sc.code).compile()
```
Get last changes from github or local git. Run patch to export the classes in comileList into one "patch.xml" patch file. It will export it into the default for current Namespace directory or you can choose where export. By default, makes a patch from the last commit if you do not specify `commitFrom` and `commitTo` e.g.
```
NS> s filename = "c:\patch.xml"
NS> s commitFrom = 1
NS> s commitTo = 5
NS> d ##class(sc.code).patch(filename,commitFrom,commitTo)
```




138 changes: 113 additions & 25 deletions sc.code.cls → cls/sc/code.cls
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@ Class sc.code [ Abstract ]
{

/// export all available code
ClassMethod export(generated = 0, system = 0, percent = 0, mapped = 0, mask = "")
ClassMethod export(generated = 0, system = 0, percent = 0, mapped = 0, mask = "", dfi = 0)
{

#define export(%code, %file) s sc = $system.OBJ.ExportUDL(%code, %file,"/diffexport") ##continue
@@ -52,6 +52,7 @@ ClassMethod export(generated = 0, system = 0, percent = 0, mapped = 0, mask = ""
while rs.%Next() {

s code = rs.Name
w code,!
if ( 'generated && $$$isGenerated( code ) ) continue
if ( 'percent && $$$isPercented( code ) ) continue
if ( 'mapped && $$$isMapped( code ) ) continue
@@ -67,17 +68,29 @@ ClassMethod export(generated = 0, system = 0, percent = 0, mapped = 0, mask = ""


#; dfi
do ..fixDashIntoName()
#define export(%code,%file) s sc = ##class(%DeepSee.UserLibrary.Utils).%Export( %code, %file, 0 )

s sql = "Select fullName as Name From %DeepSee_UserLibrary.FolderItem"
s sql = "Select id, fullName as Name, documentName From %DeepSee_UserLibrary.FolderItem"
s rs = ##class(%SQL.Statement).%ExecDirect( .stm, sql )
while rs.%Next() {
s code = rs.Name, filename = ..filename( code_".dfi" )
if ( '$find( code, mask ) ) continue
set code = rs.Name
set filename = ..filename( code_".dfi" )
set documentName = rs.documentName

if ( '$find($zcvt(documentName,"l"), mask ) ) continue
if ($L(code,"$TRASH")>1) continue
$$$mkdir( filename )
$$$log
$$$export(code,filename)

if dfi{
$$$log
$$$export( code, filename)
}
elseif ('dfi){
set documentName = $replace(documentName,"/","-")
set filename = $extract(filename,1,*-4)
do ..fixXMLLine(documentName,filename_".xml")
}

} s rs=""

@@ -111,10 +124,11 @@ ClassMethod import(filemask = "*.xml;*.cls;*.mac;*.int;*.inc;*.dfi", qspec = "ck
// check file filter
if ..inFilter(.fm,filename) continue

s ext = $p( filename, ".", * )
s ext = $zcvt($p( filename, ".", * ),"l")

if $zcvt( ext, "l" ) = "dfi" {
if (ext = "dfi") {
s sc = ##class(%DeepSee.UserLibrary.Utils).%Import( filename, 1, 0, 0, "", .dsloaded )

} else {
// load classes only
s sc = $system.OBJ.Load( filename, "k-d", .err, .loaded)
@@ -143,7 +157,53 @@ ClassMethod import(filemask = "*.xml;*.cls;*.mac;*.int;*.inc;*.dfi", qspec = "ck
Q sc
}

ClassMethod inFilter(ByRef filtermask,filename) as %Boolean
ClassMethod patch(filename = "", commitFrom = "", commitTo = "") As %Status
{
s gln = ..gln()
s git = @gln@("git")

set:commitTo="" commitTo=1
if (git = 0) {
set:(commitFrom="")||(commitFrom=1) commitFrom=0
set sc = ##class(sc.diff.gitLocal).buildDiff(..workdir(), "HEAD~"_commitTo, "HEAD~"_commitFrom, .items)
return:$$$ISERR(sc) sc
}elseif(git = 1) {
set owner = @gln@("owner")
set repository = @gln@("repository")
set user = @gln@("user")
set password = @gln@("password")
set:commitFrom="" commitFrom=1

set sc = ##class(sc.diff.gitHub).Get(.items, owner, repository, user, password, commitFrom, commitTo)
return:$$$ISERR(sc) sc
}

if (filename="") {
set filename=$G(@gln@("projectName"),"patch")
set filename=filename_$p($zdt($h,8)," ")_$tr($p($p($zdt($h)," ",2),":",1,2),":")_".xml"
}
zw filename
set sc = $system.OBJ.Export(.items,filename)

return sc
}

ClassMethod fixXMLLine(documentName, filename) As %Status
{
set stream = ##class(%Stream.FileBinary).%New()
do stream.LinkToFile(filename)
do $system.OBJ.ExportToStream(documentName, .stream)

set matcher=##class(%Regex.Matcher).%New("<Export generator=.+>")
set matcher.Text = stream.Read(stream.Size)
set data = matcher.ReplaceFirst("<Export generator=""Cache"">")

do stream.Clear()
do stream.Write(data)
return stream.%Save()
}

ClassMethod inFilter(ByRef filtermask, filename) As %Boolean
{
s result=0
for
@@ -158,7 +218,7 @@ ClassMethod inFilter(ByRef filtermask,filename) as %Boolean

/// get the filtermask for the repository.
/// looks for .gitignore file and applies all the lines to filters
ClassMethod setIgnore(ByRef filtermask)
ClassMethod setIgnore(ByRef filtermask)
{

// working with .gitignore file
@@ -176,10 +236,9 @@ ClassMethod setIgnore(ByRef filtermask)
{
s filtermask($I(filtermask))=file.ReadLine()
}
quit
quit
}


/// get or set working directory for export/import source
ClassMethod workdir(workdir)
{
@@ -195,23 +254,36 @@ ClassMethod gln() [ CodeMode = expression, Private ]
"^"_$classname()
}



ClassMethod init()
ClassMethod init(confile = "isc.json")
{
#define confile "/cos.json"
set stream=##class(%Stream.FileCharacter).%New()
set sc=stream.LinkToFile(..workdir()_$$$confile)
set sc=stream.LinkToFile(..workdir()_"/"_confile)
s conf={}.%FromJSON(stream.Read($$$MaxCacheInt))

s gln=..gln()

s @gln@("compileList")=conf.compileList
s @gln@("projectName")=conf.projectName
s @gln@("owner")=conf.owner
s @gln@("repository")=conf.repository
s @gln@("user")=conf.user
s @gln@("password")=conf.password
s @gln@("git")=conf.git

w "compileList="_conf.compileList,!
w "projectName="_conf.projectName
w "projectName="_conf.projectName,!
w "owner="_conf.owner,!
w "repository="_conf.repository,!
w "user="_conf.user,!
w "password="_conf.password,!
w "git="_conf.git,!

quit $$$OK
}

/// export release file for list and project settings
ClassMethod release() {
ClassMethod release()
{
s gln=..gln()
s list=$G(@gln@("compileList"))
if list="" w "Nothing to release. Run init method first" quit
@@ -222,7 +294,8 @@ ClassMethod release() {
w "All objects with mask "_list_" has been exported to "_release
}

ClassMethod compile() {
ClassMethod compile()
{
s gln=..gln()
s list=$G(@gln@("compileList"))
if list="" w "Nothing to compile. Run init method first" quit
@@ -303,10 +376,8 @@ ClassMethod importUpdated(filemask = "*.*", qspec = "cku-d", ByRef err = "", rec

if ( filets '] codets ) continue

if ext = "dfi" {

s sc = ##class(%DeepSee.UserLibrary.Utils).%Import( filename, 1, 0, 0, "", .loaded )

if (ext = "dfi"){
s sc = ##class(%DeepSee.UserLibrary.Utils).%Import( filename, 1, 0, 0, "", .dsloaded )
} else {

#; drop existing code before import ( purge DateModified )
@@ -354,6 +425,23 @@ ClassMethod codets(codename, ext)
Q $p( ts, "." ) ;remove ms
}

// fix "-" into dfi files

ClassMethod fixDashIntoName()
{
s sql = "Select id, fullName as Name, documentName From %DeepSee_UserLibrary.FolderItem"
s rs = ##class(%SQL.Statement).%ExecDirect( .stm, sql )
while rs.%Next() {
if $find(rs.Name, "-"){
w rs.Name," -> "
set item = ##class(%DeepSee.UserLibrary.FolderItem).%OpenId(rs.id)
set item.name = $replace(item.name,"-"," ")
w item.name,!
do item.%Save()
}
}
k rs
}

}

108 changes: 108 additions & 0 deletions cls/sc/diff/gitHub.cls
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
Class sc.diff.gitHub
{

ClassMethod Get(Output items, Owner As %String = "", Repository As %String = "", Username As %String = "clminstaller", Password As %String = "clminstaller2016", CommitFrom As %Integer = "", CommitTo As %Integer = "") As %Status
{
#dim req As %Net.HttpRequest
set req = ..CreateRequest(Username, Password)
set req.Location = "repos/" _ Owner _ "/" _ Repository _ "/commits" // as described in https://developer.github.com/v3/repos/

set links = ##class(%ListOfDataTypes).%New()
set sc = ..GetSHAs(.req, CommitFrom, CommitTo, .items)

return sc
}

ClassMethod GetSHAs(Request As %Net.HttpRequest, CommitFrom As %Integer, CommitTo As %Integer, Output Items) As %Status
{
set st = Request.Get()

return:$$$ISERR(st) st
return:(Request.HttpResponse.StatusCode = 404) $$$ERROR($$$GeneralError,"Repository doesn't exist OR you don't have access")
return:((Request.HttpResponse.StatusCode = 403) && (Request.HttpResponse.GetHeader("X-RATELIMIT-REMAINING")=0)) $$$ERROR($$$GeneralError,"API rate limit exceeded. Try logging in.")
return:(Request.HttpResponse.StatusCode '= 200) $$$ERROR($$$GeneralError,"Received " _ Request.HttpResponse.StatusCode _ " expected 200")

#dim objects As List of %ZEN.proxyObject
set st = ##class(%ZEN.Auxiliary.jsonProvider).%ConvertJSONToObject(Request.HttpResponse.Data,,.objects,1)

if ((CommitFrom >= 1) && (CommitTo <= objects.Size)) {
set list = ""
for i=CommitFrom:1:CommitTo
{
set sha = objects.GetAt(i).%data("sha")
set list = list _ $lb(sha)
}
}else {
w "CommitTo can't be more than 30"
return $$$NO
}

do ..GetFileNameForReleaseBySHAs(Request,list,.Items)

return $$$OK
}

ClassMethod GetFileNameForReleaseBySHAs(Request As %Net.HttpRequest, SHAsList, Output filesForRelease) As %Status
{
#dim objects As List of %ZEN.proxyObject
#dim files As List of %ZEN.proxyObject
set location = Request.Location
for i=1:1:$ll(SHAsList)
{
set Request.Location = location_"/"_$lg(SHAsList, i)

set st = Request.Get()
Return:$$$ISERR(st) st

set st = ##class(%ZEN.Auxiliary.jsonProvider).%ConvertJSONToObject(Request.HttpResponse.Data,,.objects,1)
return:$$$ISERR(st) st

set files = objects.%data("files")

for j=1:1:files.Size
{
set fileStatus = files.GetAt(j).%data("status")
continue:(fileStatus'="modified")&&(fileStatus'="added")
set fileName = files.GetAt(j).%data("filename")
set:$L(fileName,".xml")'=1 fileName = $extract(fileName,1,*-4)
continue:..IsCacheFile(fileName)=0
do ##class(sc.diff.utils).ToCacheName(.fileName)
set filesForRelease(fileName) = ""
}
}
}

ClassMethod CreateRequest(Username As %String, Password As %String) As %Net.HttpRequest
{
set namespace = $Namespace
set SSLConfig = "GitHub"

zn "%SYS"
do:'##class(Security.SSLConfigs).Exists(SSLConfig) ##class(Security.SSLConfigs).Create(SSLConfig)
zn namespace

set req=##class(%Net.HttpRequest).%New()
set req.Https=1
set req.SSLConfiguration=SSLConfig
set req.Server="api.github.com"
do req.SetHeader("Accept","application/vnd.github.v3+json") // we want 3rd version of api

if ($d(Username) && $d(Password) && (Username'="") && (Password'="")) { // supply Username and Password, if both are provided. GitHub accept Basic Auth
set req.Username = Username // https://developer.github.com/v3/auth/
set req.Password = Password
}

return req
}

/// Check that incoming file is the one you need.
ClassMethod IsCacheFile(FileName As %String) As %Boolean
{
set extensions = "xml,cls,csp,csr,mac,int,bas,inc,gbl,prj,obj,pkg,gof,dfi,pivot,dashboard," //html,css,js,ts,scss,"
return:($L(FileName,".")=1) 0 //no extension
set fileExtension = $P(FileName,".",*)
return $F(extensions,","_$ZCVT(fileExtension,"l")_",")
}

}

133 changes: 133 additions & 0 deletions cls/sc/diff/gitLocal.cls
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
Class sc.diff.gitLocal
{

/// Get diff between two points in repository
/// repo - repository root directory
/// sha1, sha2 - poins of history in repository
///
/// Internal diff statuses:
/// M modified - File has been modified
/// C copy-edit - File has been copied and modified //3
/// R rename-edit - File has been renamed and modified //3
/// A added - File has been added
/// D deleted - File has been deleted
/// U unmerged - File has conflicts after a merge
///
/// do ##class(isc.diff.gitLocal).buildDiff("C:\\temp\cache-udl\", "HEAD~10", "HEAD", release)
ClassMethod buildDiff(repo As %String, sha1 As %String, sha2 As %String, Output items) As %Status
{
$$$TOE(sc, ..createFile(.tempFile))
do $system.Process.CurrentDirectory(repo)
$$$TOE(sc, ..execute($$$FormatText("git diff --name-status %1 %2 > %3 2>&3", sha1, sha2, tempFile)))
$$$TOE(sc, ..fileToString(tempFile, .diffRaw))

for i=1:1:$length(diffRaw, $c(10))
{
set element = $piece(diffRaw, $c(10), i)
set status = $e($piece(element, $c(9)))
set file = $piece(element, $c(9), 2)

if ($l(file,"src/") < 2) continue

set isRelevantFile = ##class(sc.diff.utils).isRelevantFile(file)
if ((element="") || ('isRelevantFile)) continue

if $length(element, $c(9))=2
{
if ((status="M") || (status="U")) || (status="A")
{
do ##class(sc.diff.utils).ToCacheName(.file)
set items(file) = ""
}
}elseif $length(element, $c(9))=3
{
set file = $piece(element, $c(9), 3)
if ($l(file,"src/") < 2) continue
if ((status="C") || (status="R"))
{
do ##class(sc.diff.utils).ToCacheName(.newFile)
set items(file) = ""
}
}
}
return sc
}

/// Create file name.
/// Если name не задан, то возвращается имя созданного файла (в папке Temp).
/// Если name - расширение, то возвращается имя созданного файла (в папке Temp) с заданным расширением.
/// stream - стрим файла
/// content - строка или stream который записывается в файл
ClassMethod createFile(ByRef name As %String = "", Output stream As %Stream.FileBinary, content As %String) As %Status
{
#dim sc As %Status = $$$OK

if name="" {
set name = ##class(%File).TempFilename()
} elseif $length(name, ".")=1 {
set name = ##class(%File).TempFilename(name)
}

set stream = ##class(%Stream.FileBinary).%New()
set sc = stream.LinkToFile(name)

if $data(content) {
if $isObject(content) {
set sc = stream.CopyFrom(content)
} else {
set sc = stream.Write(content)
}
quit:$$$ISERR(sc) sc
set sc = stream.%Save()
do stream.Rewind()
}

quit sc
}

/// Прочитать файл в строку
ClassMethod fileToString(name As %String, Output content As %String, delete As %Boolean = {$$$YES}) As %Status
{
#dim sc As %Status = $$$OK
set stream = ##class(%Stream.FileBinary).%New()
set sc = stream.LinkToFile(name)

set content = stream.Read($$$MaxStringLength)

if delete {
kill stream
set sc = ..deleteFile(name)
}

quit sc
}

/// Удалить файл
ClassMethod deleteFile(name As %String) As %Status
{
#dim sc As %Status = $$$OK
set success = ##class(%File).Delete(name, .code)
set:success'=$$$YES sc = $$$ERROR($$$GeneralError, $$$FormatText("Error deleting file %1 with code %2", name, code))
quit sc
}

/// Выполнить команду ОС
ClassMethod execute(cmd, debug As %Boolean = {$$$NO}) As %Status
{
#dim sc As %Status = $$$OK
set code = ""
//set out = ""
write:debug !, "cmd: ", cmd
//set sc = ##class(%Net.Remote.Utility).RunCommandViaZF(cmd, , .out, timeout, $$$YES, .code)
set code = $zf(-1, cmd)
write:debug !,"code: ", code

if code'=0 {
set sc1 = $$$ERROR($$$GeneralError, $$$FormatText("Комманда ОС: `%1` завершилась с кодом: `%2`", cmd, code))
set sc = $$$ADDSC(sc, sc1)
}
return sc
}

}

36 changes: 36 additions & 0 deletions cls/sc/diff/utils.cls
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
Class sc.diff.utils
{

Parameter TRACKEDEXT As List = {$lb("xml", "cls", "csp", "csr", "mac", "int", "bas", "inc", "gbl", "prj", "obj", "pkg", "gof", "dfi", "pivot", "dashboard")};

ClassMethod ToCacheName(ByRef filename)
{
do:$L(filename,".xml")>1 ..getExtension(.filename)
set str = $Select(
$L(filename,"cls/")>1:$Replace($P(filename,"cls/",2),"/","."),
$L(filename,"csp/")>1:$Replace($P(filename,"csp/",2),"/","."),
$L(filename,"dfi/")>1:$Replace($P(filename,"dfi/",2),"/","-"),
$L(filename,"inc/")>1:$Replace($P(filename,"inc/",2),"/","."),
$L(filename,"web/")>1:$Replace($P(filename,"web/",2),"/","."),
1:$Replace(filename,"/",".")
)
set filename = $P(str,".",1,*-1)_"."_ $ZCVT($P(str,".",*),"U")
}

ClassMethod isRelevantFile(file As %String) As %Boolean
{
set ext = $select($length(file, ".")=1:"", 1:$piece(file, ".", *))
quit $lf(..#TRACKEDEXT, ext)>0
}

ClassMethod getExtension(ByRef filename)
{
if ($L(filename,"dfi/") > 1) {
set filename = $extract(filename,1,*-4)_".DFI"
}elseif ($L(filename,"cls/") > 1) {
set filename = $extract(filename,1,*-4)_".CLS"
}
}

}