Skip to content

Commit f3722ad

Browse files
jblomerdpiparo
authored andcommitted
[core] fix saving TEnv with ROOTENV_USER_PATH set
(cherry picked from commit caf87c6)
1 parent 952d7be commit f3722ad

4 files changed

Lines changed: 70 additions & 14 deletions

File tree

core/base/inc/TEnv.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ class TEnv : public TObject {
8787
TEnv& operator=(const TEnv&) = delete;
8888

8989
const char *Getvalue(const char *name) const;
90+
const char *GetUserDirectory() const;
9091

9192
public:
9293
TEnv(const char *name="");

core/base/src/TEnv.cxx

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,16 @@ TString TEnvRec::ExpandValue(const char *value)
389389
return val;
390390
}
391391

392+
////////////////////////////////////////////////////////////////////////////////
393+
/// Returns the home directory or, if set, the value of the environment variable
394+
/// ROOTENV_USER_PATH.
395+
const char *TEnv::GetUserDirectory() const
396+
{
397+
const auto customPath = gSystem->Getenv("ROOTENV_USER_PATH");
398+
if (customPath)
399+
return customPath;
400+
return gSystem->HomeDirectory();
401+
}
392402

393403
////////////////////////////////////////////////////////////////////////////////
394404
/// Create a resource table and read the (possibly) three resource files,
@@ -422,16 +432,10 @@ TEnv::TEnv(const char *name)
422432
const char *s = gSystem->PrependPathName(TROOT::GetEtcDir(), sname);
423433
ReadFile(s, kEnvGlobal);
424434
if (!gSystem->Getenv("ROOTENV_NO_HOME")) {
425-
if (const auto rootrcPath = gSystem->Getenv("ROOTENV_USER_PATH")) {
426-
TString temp(name);
427-
const char *s1 = gSystem->PrependPathName(rootrcPath, temp);
428-
ReadFile(s1, kEnvUser);
429-
} else {
430-
TString temp(name);
431-
const char *s1 = gSystem->PrependPathName(gSystem->HomeDirectory(), temp);
432-
ReadFile(s1, kEnvUser);
433-
}
434-
if (strcmp(gSystem->HomeDirectory(), gSystem->WorkingDirectory())) {
435+
TString temp(name);
436+
gSystem->PrependPathName(GetUserDirectory(), temp);
437+
ReadFile(temp.Data(), kEnvUser);
438+
if (strcmp(GetUserDirectory(), gSystem->WorkingDirectory())) {
435439
ReadFile(name, kEnvLocal);
436440
}
437441
} else {
@@ -693,16 +697,16 @@ void TEnv::SaveLevel(EEnvLevel level)
693697
FILE *ifp, *ofp;
694698

695699
if (level == kEnvGlobal) {
696-
697700
TString sname = "system";
698701
sname += fRcName;
699702
rootrcdir = gSystem->PrependPathName(TROOT::GetEtcDir(), sname);
700703
} else if (level == kEnvUser) {
701-
rootrcdir = gSystem->PrependPathName(gSystem->HomeDirectory(), fRcName);
702-
} else if (level == kEnvLocal)
704+
rootrcdir = gSystem->PrependPathName(GetUserDirectory(), fRcName);
705+
} else if (level == kEnvLocal) {
703706
rootrcdir = fRcName;
704-
else
707+
} else {
705708
return;
709+
}
706710

707711
if ((ofp = fopen(TString::Format("%s.new", rootrcdir.Data()).Data(), "w"))) {
708712
ifp = fopen(rootrcdir.Data(), "r");

core/base/test/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ endif()
2222
target_compile_options(CoreBaseTests PRIVATE -DEXPECTED_SHARED_LIBRARY_DIR="${localruntimedir}")
2323
target_compile_options(CoreBaseTests PRIVATE -DEXPECTED_INCLUDE_DIR="${CMAKE_BINARY_DIR}/include")
2424

25+
ROOT_ADD_GTEST(CoreEnvTests TEnvTests.cxx LIBRARIES Core)
26+
2527
ROOT_ADD_GTEST(CoreErrorTests TErrorTests.cxx LIBRARIES Core)
2628

2729
ROOT_ADD_GTEST(CoreSystemTests TSystemTests.cxx LIBRARIES Core)

core/base/test/TEnvTests.cxx

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#include "gtest/gtest.h"
2+
3+
#include "TEnv.h"
4+
#include "TString.h"
5+
#include "TSystem.h"
6+
#include "TUUID.h"
7+
8+
#include <string>
9+
10+
TEST(TEnv, ROOTENV_USER_PATH)
11+
{
12+
auto uuid = TUUID::UUIDv4();
13+
14+
// Create directories structure <UUID>/local with user-level config in <UUID> and local-level config
15+
// in <UUID>/local
16+
const TString rcname = "testenv";
17+
const TString userDir = uuid.AsString();
18+
TString userConfig = rcname;
19+
gSystem->PrependPathName(userDir.Data(), userConfig);
20+
const TString userBak = userConfig + ".bak";
21+
TString localDir = "local";
22+
gSystem->PrependPathName(userDir, localDir);
23+
TString localConfig = rcname;
24+
gSystem->PrependPathName(localDir.Data(), localConfig);
25+
TString homeConfig = rcname;
26+
gSystem->PrependPathName(gSystem->HomeDirectory(), homeConfig);
27+
28+
localDir.ReplaceAll("\\", "\\\\");
29+
ASSERT_EQ(0, gSystem->mkdir(localDir.Data(), /*recursive=*/true));
30+
31+
gSystem->Setenv("ROOTENV_USER_PATH", userDir.Data());
32+
EXPECT_TRUE(gSystem->AccessPathName(localConfig.Data()));
33+
EXPECT_TRUE(gSystem->AccessPathName(userConfig.Data()));
34+
35+
TEnv env("testenv");
36+
env.SetValue("EnvRec");
37+
EXPECT_EQ(1, env.GetValue("EnvRec", 0));
38+
env.SaveLevel(kEnvUser);
39+
40+
EXPECT_TRUE(gSystem->AccessPathName(localConfig.Data()));
41+
EXPECT_FALSE(gSystem->AccessPathName(userConfig.Data()));
42+
EXPECT_TRUE(gSystem->AccessPathName(homeConfig.Data()));
43+
44+
EXPECT_EQ(0, gSystem->Unlink(localDir.Data()));
45+
EXPECT_EQ(0, gSystem->Unlink(userConfig.Data()));
46+
EXPECT_EQ(0, gSystem->Unlink(userBak.Data()));
47+
EXPECT_EQ(0, gSystem->Unlink(userDir.Data()));
48+
gSystem->Unsetenv("ROOTENV_USER_PATH");
49+
}

0 commit comments

Comments
 (0)