Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [0.10.7] - Unreleased

### Added
- #945: The `load` command will unpack the tarball (or copy the non-tarball source) into the standard unpacking directory `$System.Util.DataDirectory()/ipm/<packagename>/<version>/` just like the install command
- #992: Implement automatic history purge logic
- #973: Enables CORS and JWT configuration for WebApplications in module.xml
- #1110: Add `iriscli` and `ipm` container utility scripts that are auto-installed to `~/.local/bin/` and `~/bin/` so they work both inside and outside of containers (Unix/Linux only)
Expand Down
5 changes: 2 additions & 3 deletions src/cls/IPM/General/Archive.cls
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,8 @@ ClassMethod Extract(
quit
}
if '##class(%File).DirectoryExists(pTargetDirectory) {
set tResult = ##class(%File).CreateDirectoryChain(pTargetDirectory,.tReturn)
if 'tResult {
set tSC = $$$ERROR($$$GeneralError,$$$FormatText("Error creating directory chain %1: %2",pTargetDirectory,tReturn))
set tSC = ##class(%IPM.Utils.File).CreateDirectoryChain(pTargetDirectory)
if $$$ISERR(tSC) {
quit
}
}
Expand Down
16 changes: 4 additions & 12 deletions src/cls/IPM/Lifecycle/Base.cls
Original file line number Diff line number Diff line change
Expand Up @@ -1153,11 +1153,8 @@ Method %Export(
}

if '##class(%File).DirectoryExists(pTargetDirectory) {
kill %objlasterror
set tCreated = ##class(%File).CreateDirectoryChain(pTargetDirectory,.tReturnValue)
if 'tCreated {
set tLastErr = $get(%objlasterror)
set tSC = $$$EMBEDSC($$$ERROR($$$GeneralError,$$$FormatText("Error creating directory %1: %2",pTargetDirectory,tReturnValue)),tLastErr)
set tSC = ##class(%IPM.Utils.File).CreateDirectoryChain(pTargetDirectory)
if $$$ISERR(tSC) {
quit
}
}
Expand Down Expand Up @@ -1956,12 +1953,7 @@ Method ExportSingleModule(
set tSC = $$$OK
set tDirectory = ##class(%File).GetDirectory(tExportPath,1)
if '##class(%File).DirectoryExists(tDirectory) {
set tGood = ##class(%File).CreateDirectoryChain(tDirectory,.tReturn)
if 'tGood {
set tLastErr = $get(%objlasterror)
set tSC = $$$EMBEDSC($$$ERROR($$$GeneralError,$$$FormatText("Error creating directory '%1': %2",tDirectory,tReturn)),tLastErr)
$$$ThrowOnError(tSC)
}
$$$ThrowOnError(##class(%IPM.Utils.File).CreateDirectoryChain(tDirectory))
write:pVerbose !,"Created ",tDirectory
}
if ##class(%File).DirectoryExists(tSourcePath) {
Expand All @@ -1981,7 +1973,7 @@ Method ExportSingleModule(
}
} elseif (tExt = "CLS") || (tExt = "DFI") || (tExt = "PRJ") || ($zconvert($extract(tFullPath,$length(tFullPath)-2,*),"l")="xml") || (##class(%RoutineMgr).UserType(tFullResourceName)) {
if '##class(%File).Exists(tFullPath) {
do ##class(%File).CreateDirectoryChain(##class(%File).GetDirectory(tFullPath))
$$$ThrowOnError(##class(%IPM.Utils.File).CreateDirectoryChain(##class(%File).GetDirectory(tFullPath)))
}
set tSC = $$Export^%occXMLExport(tFullPath,"-d /diffexport/createdirs",tFullResourceName)
$$$ThrowOnError(tSC)
Expand Down
4 changes: 2 additions & 2 deletions src/cls/IPM/Lifecycle/Module.cls
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,8 @@ Method %Package(ByRef pParams) As %Status
// create temporary subdirectory to prevent clashes
set randomDir = $translate($system.Encryption.Base64Encode($system.Encryption.GenCryptRand(6)),"+/=")
set tExportSubDirectory = ##class(%Library.File).NormalizeDirectory(tExportDirectory) _ randomDir _ "/"
if '##class(%File).CreateDirectoryChain(tExportSubDirectory,.tReturn) {
set tSC = $$$ERROR($$$GeneralError,$$$FormatText("Error creating directory chain %1: %2",tExportSubDirectory,tReturn))
set tSC = ##class(%IPM.Utils.File).CreateDirectoryChain(tExportSubDirectory)
if $$$ISERR(tSC) {
quit
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/cls/IPM/Lifecycle/StudioProject/XDataArchive.cls
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ ClassMethod CreateDirectoryChain(pName As %String) As %Status
{
set tSC = $$$OK
if '##class(%Library.File).CreateDirectoryChain(pName,.tReturn) {
set tSC = $$$ERROR($$$GeneralError,$$$FormatText("Error creating directory chain %1: %2",pName,$zutil(209,tReturn)))
set tSC = $$$ERROR($$$GeneralError,$$$FormatText("Error creating directory chain %1: %2",pName,$zutil(209,$select(tReturn<0:-tReturn,1:tReturn))))
}
quit tSC
}
Expand Down
23 changes: 21 additions & 2 deletions src/cls/IPM/Main.cls
Original file line number Diff line number Diff line change
Expand Up @@ -2274,7 +2274,7 @@ ClassMethod LoadFromRepo(
{
set slash=$select($zversion(1)=3:"/",1:"\")
set TempDir = ##class(%File).GetDirectory(##class(%File).GetDirectory($zutil(86))_"mgr"_slash_"Temp"_slash_$translate($ztimestamp,".,")_slash)
$$$ThrowOnError(##class(%File).CreateDirectoryChain(TempDir))
$$$ThrowOnError(##class(%IPM.Utils.File).CreateDirectoryChain(TempDir))
set:$extract(tDirectoryName,*)="/" tDirectoryName=$extract(tDirectoryName,1,*-1)
set RepoName=$piece($piece($piece(tDirectoryName,"/",*),".git")," ")
set tCmd="cd "_TempDir_" && git clone "_tDirectoryName
Expand Down Expand Up @@ -2350,7 +2350,8 @@ ClassMethod LoadInternal(
}
set extension = $$$lcase($piece(tDirectoryName,".",*))
if ##class(%File).Exists(tDirectoryName) && ((extension="tgz") || (extension="tar.gz")) {
set tTargetDirectory = $$$FileTempDirSys
set tTempExtractionRoot = $$$FileTempDirSys
set tTargetDirectory = tTempExtractionRoot
if $get(pCommandInfo("data", "Verbose")) {
write !,"Extracting archive to ",tTargetDirectory
}
Expand Down Expand Up @@ -2382,6 +2383,24 @@ ClassMethod LoadInternal(
// When loading a module from a local folder, there might be a <mod root>/.modules/ folder containining dependencies.
// It's easier to configure a temporary repository than to handle this case in the dependency resolution code.
set tTargetDirectory = $get(tTargetDirectory, tDirectoryName)

// Copy source to the standard module location (DataDirectory/ipm/<name>/<version>/) unless in developer mode,
// where the developer works on files in-place.
if '$get(tParams("DeveloperMode"), 0) {
set tModuleObj = ##class(%IPM.Utils.Module).GetModuleObjectFromPath(tTargetDirectory, .tFound)
set tFinalDirectory = ##class(%Library.File).NormalizeDirectory(
##class(%SYSTEM.Util).DataDirectory() _ "ipm/" _ tModuleObj.Name _ "/" _ tModuleObj.VersionString)
if ##class(%File).DirectoryExists(tFinalDirectory) {
$$$ThrowOnError(##class(%IPM.Utils.File).RemoveDirectoryTree(tFinalDirectory))
}
$$$ThrowOnError(##class(%IPM.Utils.File).CreateDirectoryChain(tFinalDirectory))
$$$ThrowOnError(##class(%IPM.Utils.File).CopyDir(tTargetDirectory, tFinalDirectory, 0))
if $get(tTempExtractionRoot) '= "" {
$$$ThrowOnError(##class(%IPM.Utils.File).RemoveDirectoryTree(tTempExtractionRoot))
}
set tTargetDirectory = tFinalDirectory
}

set dotModules = ##class(%File).NormalizeDirectory(".modules", tTargetDirectory)
set tmpRepoMgr = ##class(%IPM.General.TempLocalRepoManager).%New(dotModules, 1)
set tSC = ##class(%IPM.Utils.Module).LoadNewModule(tTargetDirectory, .tParams, , pLog)
Expand Down
5 changes: 1 addition & 4 deletions src/cls/IPM/Repo/Oras/PublishService.cls
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,7 @@ Method PublishModule(pModule As %IPM.Repo.Remote.ModuleInfo) As %Status
set tempDirectory = ##class(%File).NormalizeDirectory(tDir _ "/" _ repo _ "/" _ tag _ "/")

#; Create temp directory
set tCreated = ##class(%File).CreateDirectoryChain(tempDirectory,.tReturnValue)
if 'tCreated {
$$$ThrowStatus($$$ERROR($$$GeneralError, $$$FormatText("Error creating directory %1: %2", tempDirectory, tReturnValue)))
}
$$$ThrowOnError(##class(%IPM.Utils.File).CreateDirectoryChain(tempDirectory))

#; Create tgz file in temp directory
set tFileBinStream = ##class(%Stream.FileBinary).%New()
Expand Down
4 changes: 1 addition & 3 deletions src/cls/IPM/ResourceProcessor/ArtifactoryTarball.cls
Original file line number Diff line number Diff line change
Expand Up @@ -267,9 +267,7 @@ ClassMethod RetrieveArtifact(

// Create directory if it doesn't exist
if '##class(%File).DirectoryExists(downloadDirectory) {
if '##class(%File).CreateDirectoryChain(downloadDirectory) {
$$$ThrowStatus($$$ERROR($$$GeneralError, "Unable to create destination directory: "_downloadDirectory))
}
$$$ThrowOnError(##class(%IPM.Utils.File).CreateDirectoryChain(downloadDirectory))
}

set localPath = ##class(%File).NormalizeFilename(artifactName, downloadDirectory)
Expand Down
4 changes: 2 additions & 2 deletions src/cls/IPM/ResourceProcessor/FileCopy.cls
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,8 @@ Method DoCopy(
do ..NormalizeNames(.tSource, .tTarget, .tTargetDir, .copyAsFile)

if '##class(%File).DirectoryExists(tTargetDir) {
if '##class(%File).CreateDirectoryChain(tTargetDir,.tReturn) {
set tSC = $$$ERROR($$$GeneralError,$$$FormatText("Error creating directory %1: %2",tTargetDir,$zutil(209,tReturn)))
set tSC = ##class(%IPM.Utils.File).CreateDirectoryChain(tTargetDir)
if $$$ISERR(tSC) {
quit
}
}
Expand Down
5 changes: 3 additions & 2 deletions src/cls/IPM/ResourceProcessor/PythonWheel.cls
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,9 @@ Method OnExportItem(
return $$$ERROR($$$GeneralError, "File """_dir_""" exists and is not a directory. Failed to export item: "_..Name)
}
if '##class(%File).DirectoryExists(dir) {
if '##class(%File).CreateDirectoryChain(dir, .return) {
return $$$ERROR($$$GeneralError, "Failed to create directory "_dir_", OS returned code: "_-return)
set sc = ##class(%IPM.Utils.File).CreateDirectoryChain(dir)
if $$$ISERR(sc) {
return sc
}
}
if verbose {
Expand Down
2 changes: 1 addition & 1 deletion src/cls/IPM/ResourceProcessor/Test.cls
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ Method OnPhase(
}
set outputDir = ##class(%File).GetDirectory(outputFile)
if outputDir '= "" {
$$$ThrowOnError(##class(%File).CreateDirectoryChain(outputDir))
$$$ThrowOnError(##class(%IPM.Utils.File).CreateDirectoryChain(outputDir))
}
set tSC = $classmethod(outputClass,"ToFile",outputFile)
$$$ThrowOnError(tSC)
Expand Down
2 changes: 1 addition & 1 deletion src/cls/IPM/Utils/File.cls
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ ClassMethod CreateDirectoryChain(pName As %String) As %Status
{
set tSC = $$$OK
if '##class(%Library.File).CreateDirectoryChain(pName,.tReturn) {
set tSC = $$$ERROR($$$GeneralError,$$$FormatText("Error creating directory chain %1: %2",pName,$zutil(209,tReturn)))
set tSC = $$$ERROR($$$GeneralError,$$$FormatText("Error creating directory chain %1: %2",pName,$zutil(209,$select(tReturn<0:-tReturn,1:tReturn))))
}
quit tSC
}
Expand Down
7 changes: 4 additions & 3 deletions src/cls/IPM/Utils/FileBinaryTar.cls
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ Method ExtractTo(pDest As %String) As %Status
if ..name'="" {
if ..typeflag=5 {
set fullPath = ##class(%File).NormalizeDirectory(..name, pDest)
set sc = ##class(%File).CreateDirectoryChain(fullPath)
set sc = ##class(%IPM.Utils.File).CreateDirectoryChain(fullPath)
if $$$ISERR(sc) {
return sc
}
Expand All @@ -164,8 +164,9 @@ Method ExtractTo(pDest As %String) As %Status
set path = pDest_..name
set directory = ##class(%File).GetDirectory(path)
if '##class(%File).DirectoryExists(directory) {
if '##class(%File).CreateDirectoryChain(directory, .ret) {
return $$$ERROR($$$GeneralError, $$$FormatText("Error creating directory chain %1: %2", directory, ret))
set sc = ##class(%IPM.Utils.File).CreateDirectoryChain(directory)
if $$$ISERR(sc) {
return sc
}
}
#; no idea, why it's needed, but IRIS.DAT filename not allowed
Expand Down
5 changes: 2 additions & 3 deletions src/cls/IPM/Utils/Module.cls
Original file line number Diff line number Diff line change
Expand Up @@ -235,9 +235,8 @@ ClassMethod LoadModuleFromArchive(
quit
}
}
set tCreated = ##class(%File).CreateDirectoryChain(tTargetDirectory,.tReturnValue)
if 'tCreated {
set tSC = $$$ERROR($$$GeneralError,$$$FormatText("Error creating directory %1: %2",tTargetDirectory,tReturnValue))
set tSC = ##class(%IPM.Utils.File).CreateDirectoryChain(tTargetDirectory)
if $$$ISERR(tSC) {
quit
}
set tTargetDirectory = ##class(%File).NormalizeFilenameWithSpaces(tTargetDirectory)
Expand Down
113 changes: 83 additions & 30 deletions tests/integration_tests/Test/PM/Integration/FileBinaryTar.cls
Original file line number Diff line number Diff line change
Expand Up @@ -5,36 +5,89 @@ Class Test.PM.Integration.FileBinaryTar Extends %UnitTest.TestCase

Method TestPackageAndExtract()
{
Set tSC = $$$OK
Try {
Set tTestRoot = ##class(%File).NormalizeDirectory($Get(^UnitTestRoot))

Set tModuleDir = ##class(%File).NormalizeDirectory(##class(%File).GetDirectory(tTestRoot)_"/_data/simple-module/")
Set tSC = ##class(%IPM.Main).Shell("load "_tModuleDir)
Do $$$AssertStatusOK(tSC,"Loaded SimpleModule module successfully.")

Set tempDir = ##class(%Library.File).TempFilename()_"dir"
Set tSC = ##class(%IPM.Main).Shell("simplemodule package -only -DPath="_tempDir)
Do $$$AssertStatusOK(tSC,"Packaged SimpleModule successfully.")

Set outFile = ##class(%Library.File).TempFilename()
Set outDir = ##class(%Library.File).NormalizeDirectory(##class(%Library.File).TempFilename()_"dir-out")
Do ##class(%Library.File).CreateDirectoryChain(outDir)
Do $$$AssertEquals($zf(-100,"/STDOUT="""_outFile_"""/STDERR="""_outFile_"""","tar","-xvf",tempDir_".tgz","-C",outDir),0)

Do $$$AssertNotTrue(##class(%File).DirectoryExists(outDir_"src/cls/Test/Test"))
Do $$$AssertNotTrue(##class(%File).DirectoryExists(outDir_"src/src"))
Do $$$AssertNotTrue(##class(%File).DirectoryExists(outDir_"simplemodule"))
Do $$$AssertTrue(##class(%File).Exists(outDir_"src/cls/Test/Test.cls"))
Do $$$AssertTrue(##class(%File).Exists(outDir_"module.xml"))

Set tSC = ##class(%IPM.Main).Shell("load "_tempDir_".tgz")
Do $$$AssertStatusOK(tSC,"Loaded SimpleModule module successfully from .tgz file.")

Set tSC = ##class(%IPM.Main).Shell("load "_outDir)
Do $$$AssertStatusOK(tSC,"Loaded SimpleModule module successfully from package directory.")
} Catch e {
Do $$$AssertStatusOK(e.AsStatus(),"An exception occurred.")
set sc = $$$OK
try {
set tTestRoot = ##class(%File).NormalizeDirectory($get(^UnitTestRoot))

set tModuleDir = ##class(%File).NormalizeDirectory(##class(%File).GetDirectory(tTestRoot)_"/_data/simple-module/")
set sc = ##class(%IPM.Main).Shell("load "_tModuleDir)
do $$$AssertStatusOK(sc,"Loaded SimpleModule module successfully.")

set tempDir = ##class(%Library.File).TempFilename()_"dir"
set sc = ##class(%IPM.Main).Shell("simplemodule package -only -DPath="_tempDir)
do $$$AssertStatusOK(sc,"Packaged SimpleModule successfully.")

set outFile = ##class(%Library.File).TempFilename()
set outDir = ##class(%Library.File).NormalizeDirectory(##class(%Library.File).TempFilename()_"dir-out")
do ##class(%Library.File).CreateDirectoryChain(outDir)
do $$$AssertEquals($zf(-100,"/STDOUT="""_outFile_"""/STDERR="""_outFile_"""","tar","-xvf",tempDir_".tgz","-C",outDir),0)

do $$$AssertNotTrue(##class(%File).DirectoryExists(outDir_"src/cls/Test/Test"))
do $$$AssertNotTrue(##class(%File).DirectoryExists(outDir_"src/src"))
do $$$AssertNotTrue(##class(%File).DirectoryExists(outDir_"simplemodule"))
do $$$AssertTrue(##class(%File).Exists(outDir_"src/cls/Test/Test.cls"))
do $$$AssertTrue(##class(%File).Exists(outDir_"module.xml"))

set sc = ##class(%IPM.Main).Shell("load "_tempDir_".tgz")
do $$$AssertStatusOK(sc,"Loaded SimpleModule module successfully from .tgz file.")

set sc = ##class(%IPM.Main).Shell("load "_outDir)
do $$$AssertStatusOK(sc,"Loaded SimpleModule module successfully from package directory.")
} catch e {
do $$$AssertStatusOK(e.AsStatus(),"An exception occurred.")
}
}

Method TestLoadDestinationDirectory()
{
set sc = $$$OK
try {
set tTestRoot = ##class(%File).NormalizeDirectory($get(^UnitTestRoot))
set tModuleDir = ##class(%File).NormalizeDirectory(##class(%File).GetDirectory(tTestRoot)_"/_data/simple-module/")

// Load from directory — files should land in DataDirectory/ipm/<name>/<version>/
set sc = ##class(%IPM.Main).Shell("load "_tModuleDir)
do $$$AssertStatusOK(sc,"Loaded SimpleModule from directory.")
set tModule = ##class(%IPM.Storage.Module).NameOpen("simplemodule",,.sc)
do $$$AssertStatusOK(sc,"Opened module after directory load.")
set tExpectedDir = ##class(%Library.File).NormalizeDirectory(
##class(%SYSTEM.Util).DataDirectory()_"ipm/"_tModule.Name_"/"_tModule.VersionString)
do $$$AssertTrue(##class(%File).DirectoryExists(tExpectedDir),"Module directory exists at standard path after load from directory.")
do $$$AssertTrue(##class(%File).Exists(tExpectedDir_"module.xml"),"module.xml present at standard path after load from directory.")
set sc = ##class(%IPM.Main).Shell("uninstall simplemodule")
do $$$AssertStatusOK(sc,"Uninstalled SimpleModule.")
$$$ThrowOnError(##class(%IPM.Utils.File).RemoveDirectoryTree(tExpectedDir))

// Load from tarball — files should also land in DataDirectory/ipm/<name>/<version>/
set tempDir = ##class(%Library.File).TempFilename()_"dir"
set sc = ##class(%IPM.Main).Shell("load "_tModuleDir)
do $$$AssertStatusOK(sc,"Loaded SimpleModule from directory to enable packaging.")
set sc = ##class(%IPM.Main).Shell("simplemodule package -only -DPath="_tempDir)
do $$$AssertStatusOK(sc,"Packaged SimpleModule.")
set sc = ##class(%IPM.Main).Shell("uninstall simplemodule")
do $$$AssertStatusOK(sc,"Uninstalled SimpleModule before tarball load.")
set sc = ##class(%IPM.Main).Shell("load "_tempDir_".tgz")
do $$$AssertStatusOK(sc,"Loaded SimpleModule from tarball.")
set tModule = ##class(%IPM.Storage.Module).NameOpen("simplemodule",,.sc)
do $$$AssertStatusOK(sc,"Opened module after tarball load.")
set tExpectedDir = ##class(%Library.File).NormalizeDirectory(
##class(%SYSTEM.Util).DataDirectory()_"ipm/"_tModule.Name_"/"_tModule.VersionString)
do $$$AssertTrue(##class(%File).DirectoryExists(tExpectedDir),"Module directory exists at standard path after load from tarball.")
set sc = ##class(%IPM.Main).Shell("uninstall simplemodule")
do $$$AssertStatusOK(sc,"Uninstalled SimpleModule.")

// Load -dev from directory — module Root should point to the original path, not DataDirectory
$$$ThrowOnError(##class(%IPM.Utils.File).RemoveDirectoryTree(tExpectedDir))
set sc = ##class(%IPM.Main).Shell("load -dev "_tModuleDir)
do $$$AssertStatusOK(sc,"Loaded SimpleModule in dev mode.")
set tModule = ##class(%IPM.Storage.Module).NameOpen("simplemodule",,.sc)
do $$$AssertStatusOK(sc,"Opened module after dev mode load.")
do $$$AssertEquals(tModule.Root, tModuleDir, "Module Root points to original directory in dev mode.")
do $$$AssertNotTrue(##class(%File).DirectoryExists(tExpectedDir),"Module NOT copied to standard path in dev mode.")
set sc = ##class(%IPM.Main).Shell("uninstall simplemodule")
do $$$AssertStatusOK(sc,"Uninstalled SimpleModule.")
} catch e {
do $$$AssertStatusOK(e.AsStatus(),"An exception occurred.")
}
}

Expand Down
Loading