Skip to content
Draft
9 changes: 6 additions & 3 deletions io/io/src/TDirectoryFile.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -1258,7 +1258,9 @@ TFile *TDirectoryFile::OpenFile(const char *name, Option_t *option,const char *f
/// Create a sub-directory "a" or a hierarchy of sub-directories "a/b/c/...".
///
/// @param name the name or hierarchy of the subdirectory ("a" or "a/b/c")
/// @param title the title
/// @param title the title of the directory. For hierarchies, this is only applied
/// to the innermost directory (so if `name == "a/b/c"` and `title == "my dir"`,
/// only `c` will have the title `"my dir"`).
/// @param returnExistingDirectory if key-name is already existing, the returned
/// value points to preexisting sub-directory if true and to `nullptr` if false.
/// @return a pointer to the created sub-directory, not to the top sub-directory
Expand All @@ -1284,10 +1286,11 @@ TDirectory *TDirectoryFile::mkdir(const char *name, const char *title, Bool_t re
TDirectoryFile *tmpdir = nullptr;
GetObject(workname.Data(), tmpdir);
if (!tmpdir) {
tmpdir = (TDirectoryFile*)mkdir(workname.Data(),title);
// We give all intermediate directories a default title, as `title` is only given to the innermost dir.
tmpdir = (TDirectoryFile *)mkdir(workname.Data(), workname.Data());
if (!tmpdir) return nullptr;
}
return tmpdir->mkdir(slash + 1);
return tmpdir->mkdir(slash + 1, title, returnExistingDirectory);
}

TDirectory::TContext ctxt(this);
Expand Down
24 changes: 24 additions & 0 deletions io/io/test/TFileTests.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

#include "gtest/gtest.h"

#include <ROOT/TestSupport.hxx>

#include "TFile.h"
#include "TMemFile.h"
#include "TDirectory.h"
Expand Down Expand Up @@ -280,6 +282,28 @@ TEST(TDirectoryFile, SeekParent)
EXPECT_EQ(dir11->GetSeekParent(), 239);
}

TEST(TDirectoryFile, RecursiveMkdir)
{
TMemFile f("mkdirtest.root", "RECREATE");
auto dir1 = f.mkdir("a/b/c", "my dir");
EXPECT_NE(dir1, nullptr);
{
ROOT::TestSupport::CheckDiagsRAII diags;
diags.requiredDiag(kError, "TDirectoryFile::mkdir","An object with name c exists already");
auto dir2 = f.mkdir("a/b/c", "", /* returnExisting = */ false);
EXPECT_EQ(dir2, nullptr);
}
auto dir3 = f.mkdir("a/b/c", "foobar", /* returnExisting = */ true);
EXPECT_EQ(dir3, dir1);
EXPECT_STREQ(dir3->GetTitle(), "my dir");
auto dirB = dir3->GetMotherDir();
ASSERT_NE(dirB, nullptr);
EXPECT_STREQ(dirB->GetTitle(), "b");
auto dirA = dirB->GetMotherDir();
ASSERT_NE(dirA, nullptr);
EXPECT_STREQ(dirA->GetTitle(), "a");
}

// https://its.cern.ch/jira/browse/ROOT-10581
TEST(TFile, PersistTObjectStdArray)
{
Expand Down
1 change: 1 addition & 0 deletions main/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ add_dependencies(rootcint rootcint)
if (TARGET Gui)
ROOT_EXECUTABLE(rootbrowse src/rootbrowse.cxx LIBRARIES RIO Core Rint Gui)
endif()
ROOT_EXECUTABLE(rootcp src/rootcp.cxx LIBRARIES RIO Tree Core Rint)
ROOT_EXECUTABLE(rootls src/rootls.cxx LIBRARIES RIO Tree Core Rint ROOTNTuple)

ROOT_ADD_TEST_SUBDIRECTORY(test)
46 changes: 0 additions & 46 deletions main/python/cmdLineUtils.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@
# http://stackoverflow.com/questions/4675728/redirect-stdout-to-a-file-in-python/22434262#22434262
# Thanks J.F. Sebastian !!

from contextlib import contextmanager
import os
import sys
from time import sleep

Check failure on line 19 in main/python/cmdLineUtils.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (F401)

main/python/cmdLineUtils.py:19:18: F401 `time.sleep` imported but unused
from itertools import zip_longest

Check failure on line 20 in main/python/cmdLineUtils.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (F401)

main/python/cmdLineUtils.py:20:23: F401 `itertools.zip_longest` imported but unused

Check failure on line 20 in main/python/cmdLineUtils.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (I001)

main/python/cmdLineUtils.py:16:1: I001 Import block is un-sorted or un-formatted

def fileno(file_or_fd):
"""
Expand Down Expand Up @@ -81,10 +81,10 @@
ROOT.PyConfig.IgnoreCommandLineOptions = True
ROOT.gROOT.GetVersion()

import argparse

Check failure on line 84 in main/python/cmdLineUtils.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (E402)

main/python/cmdLineUtils.py:84:1: E402 Module level import not at top of file
import glob

Check failure on line 85 in main/python/cmdLineUtils.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (E402)

main/python/cmdLineUtils.py:85:1: E402 Module level import not at top of file
import fnmatch

Check failure on line 86 in main/python/cmdLineUtils.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (E402)

main/python/cmdLineUtils.py:86:1: E402 Module level import not at top of file
import logging

Check failure on line 87 in main/python/cmdLineUtils.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (E402)

main/python/cmdLineUtils.py:87:1: E402 Module level import not at top of file

Check failure on line 87 in main/python/cmdLineUtils.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (I001)

main/python/cmdLineUtils.py:84:1: I001 Import block is un-sorted or un-formatted

LOG_FORMAT = "%(levelname)s: %(message)s"
logging.basicConfig(format=LOG_FORMAT)
Expand Down Expand Up @@ -328,12 +328,12 @@
Open a ROOT file (like openROOTFile) with the possibility
to change compression settings
"""
if compress != None and os.path.isfile(fileName):

Check failure on line 331 in main/python/cmdLineUtils.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (E711)

main/python/cmdLineUtils.py:331:20: E711 Comparison to `None` should be `cond is not None`
logging.warning("can't change compression settings on existing file")
return None
mode = "recreate" if recreate else "update"
theFile = openROOTFile(fileName, mode)
if compress != None:

Check failure on line 336 in main/python/cmdLineUtils.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (E711)

main/python/cmdLineUtils.py:336:20: E711 Comparison to `None` should be `cond is not None`
theFile.SetCompressionSettings(compress)
return theFile

Expand Down Expand Up @@ -783,52 +783,6 @@
# End of help strings
##########

##########
# ROOTCP


def _copyObjects(fileName, pathSplitList, destFile, destPathSplit, oneFile, recursive, replace):
retcode = 0
destFileName = destFile.GetName()
rootFile = openROOTFile(fileName) if fileName != destFileName else destFile
if not rootFile:
return 1
ROOT.gROOT.GetListOfFiles().Remove(rootFile) # Fast copy necessity
for pathSplit in pathSplitList:
oneSource = oneFile and len(pathSplitList) == 1
retcode += copyRootObject(rootFile, pathSplit, destFile, destPathSplit, oneSource, recursive, replace)
if fileName != destFileName:
rootFile.Close()
return retcode


def rootCp(sourceList, destFileName, destPathSplit, compress=None, recreate=False, recursive=False, replace=False):
# Check arguments
if sourceList == [] or destFileName == "":
return 1
if recreate and destFileName in [n[0] for n in sourceList]:
logging.error("cannot recreate destination file if this is also a source file")
return 1

# Open destination file
destFile = openROOTFileCompress(destFileName, compress, recreate)
if not destFile:
return 1
ROOT.gROOT.GetListOfFiles().Remove(destFile) # Fast copy necessity

# Loop on the root files
retcode = 0
for fileName, pathSplitList in sourceList:
retcode += _copyObjects(
fileName, pathSplitList, destFile, destPathSplit, len(sourceList) == 1, recursive, replace
)
destFile.Close()
return retcode


# End of ROOTCP
##########

##########
# ROOTEVENTSELECTOR

Expand Down
66 changes: 0 additions & 66 deletions main/python/rootcp.py

This file was deleted.

Loading
Loading