Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support dry-running generators #1028

Merged
merged 1 commit into from
Jul 18, 2023
Merged
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
13 changes: 11 additions & 2 deletions libs/rtemodel/include/RteGenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,17 +130,19 @@ class RteGenerator : public RteItem
* @brief get all arguments as vector for the given host type
* @param target pointer to RteTarget
* @param hostType host type, empty to match current host
* @param dryRun include dry-run arguments
* @return vector of arguments consisting of switch and value in pairs
*/
std::vector<std::pair<std::string, std::string> > GetExpandedArguments(RteTarget* target, const std::string& hostType = EMPTY_STRING) const;
std::vector<std::pair<std::string, std::string> > GetExpandedArguments(RteTarget* target, const std::string& hostType = EMPTY_STRING, bool dryRun = false) const;

/**
* @brief get full command line with arguments and expanded key sequences for specified target
* @param target pointer to RteTarget
* @param hostType host type, empty to match current host
* @param dryRun include dry-run arguments
* @return expanded command line with arguments, properly quoted
*/
std::string GetExpandedCommandLine(RteTarget* target, const std::string& hostType = EMPTY_STRING) const;
std::string GetExpandedCommandLine(RteTarget* target, const std::string& hostType = EMPTY_STRING, bool dryRun = false) const;

/**
* @brief get absolute path to gpdsc file for specified target
Expand Down Expand Up @@ -208,6 +210,13 @@ class RteGenerator : public RteItem
*/
RteItem* CreateItem(const std::string& tag) override;

/**
* @brief check whether the generator can be run in dry-run mode
* @param hostType host type, empty to match current host
* @return true if the generator is dry-run capable, false otherwise
*/
bool IsDryRunCapable(const std::string& hostType = EMPTY_STRING) const;

protected:
/**
* @brief construct generator ID
Expand Down
22 changes: 19 additions & 3 deletions libs/rtemodel/src/RteGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,23 +142,25 @@ string RteGenerator::GetExecutable(RteTarget* target, const std::string& hostTyp
}


vector<pair<string, string> > RteGenerator::GetExpandedArguments(RteTarget* target, const string& hostType) const
vector<pair<string, string> > RteGenerator::GetExpandedArguments(RteTarget* target, const string& hostType, bool dryRun) const
{
vector<pair<string, string> > args;
RteItem* argsItem = GetArgumentsItem("exe");
if (argsItem) {
for (auto arg : argsItem->GetChildren()) {
if (arg->GetTag() != "argument" || !arg->MatchesHost(hostType))
continue;
if (!dryRun && arg->GetAttribute("mode") == "dry-run")
continue;
args.push_back({arg->GetAttribute("switch"), ExpandString(arg->GetText())});
}
}
return args;
}

string RteGenerator::GetExpandedCommandLine(RteTarget* target, const string& hostType) const
string RteGenerator::GetExpandedCommandLine(RteTarget* target, const string& hostType, bool dryRun) const
{
const vector<pair<string, string> > args = GetExpandedArguments(target, hostType);
const vector<pair<string, string> > args = GetExpandedArguments(target, hostType, dryRun);
string fullCmd = GetExecutable(target, hostType);
for (size_t i = 0; i < args.size(); i++) {
fullCmd += ' ' + RteUtils::AddQuotesIfSpace(args[i].first + args[i].second);
Expand Down Expand Up @@ -265,6 +267,20 @@ RteItem* RteGenerator::CreateItem(const std::string& tag)
}


bool RteGenerator::IsDryRunCapable(const std::string& hostType) const
{
RteItem* argsItem = GetArgumentsItem("exe");
if (argsItem) {
for (auto arg : argsItem->GetChildren()) {
if (arg->GetTag() != "argument" || !arg->MatchesHost(hostType))
continue;
if (arg->GetAttribute("mode") == "dry-run")
return true;
}
}
return false;
}

RteGeneratorContainer::RteGeneratorContainer(RteItem* parent) :
RteItem(parent)
{
Expand Down
6 changes: 3 additions & 3 deletions libs/rtemodel/test/src/RteChkTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ Generic: 1\n\
DFP: 3\n\
BSP: 1\n\
\n\
Components: 51\n\
Components: 52\n\
From generic packs: 31\n\
From DFP: 20\n\
From DFP: 21\n\
From BSP: 0\n\
\n\
Devices: 10\n\
Expand All @@ -51,7 +51,7 @@ completed\n";
int res = rteChk.RunCheckRte();
EXPECT_EQ(res, 0);
EXPECT_EQ(rteChk.GetPackCount(), 5);
EXPECT_EQ(rteChk.GetComponentCount(), 51);
EXPECT_EQ(rteChk.GetComponentCount(), 52);
EXPECT_EQ(rteChk.GetDeviceCount(), 10);
EXPECT_EQ(rteChk.GetBoardCount(), 13);

Expand Down
27 changes: 27 additions & 0 deletions test/packs/ARM/RteTestGenerator/0.1.0/ARM.RteTestGenerator.pdsc
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
<argument>$S</argument>
<!-- absolute path to the generator input file -->
<argument>$G</argument>
<argument mode="dry-run">--dry-run</argument>
<argument host="win" switch="/foo=">bar</argument>
<argument host="linux" switch="--foo=">bar</argument>
<argument host="mac" switch="--foo=">bar</argument>
Expand Down Expand Up @@ -105,6 +106,29 @@
<gpdsc name="$PRTE/Device/$D/RteTest.gpdsc"/>
</generator>

<!-- This generator is for testing of dry-running without "dry-run" support -->
<generator id="RteTestGeneratorNoDryRun">
<description>RteTest Generator Description</description>
<!-- path is specified either absolute or relative to PDSC or GPDSC file -->
<workingDir>$PRTE/Device</workingDir>
<exe>
<command host="win">Generator/script.bat</command>
<command host="linux">Generator/script.sh</command>
<command host="mac">Generator/script.sh</command>
<!-- path is specified either absolute or relative to PDSC or GPDSC file. If not specified it is the project directory configured by the environment -->
<!-- D = Device (Dname/Dvariant as configured by environment) -->
<argument>$D</argument>
<!-- Project path and project name (as configured by environment) -->
<argument>#P</argument>
<!-- absolute or relative to workingDir. $S = Device Family Pack base folder -->
<argument>$S</argument>
<!-- absolute path to the generator input file -->
<argument>$G</argument>
</exe>
<!-- path is either absolute or relative to working directory -->
<gpdsc name="$PRTE/Device/$D/RteTest.gpdsc"/>
</generator>

</generators>

<components>
Expand Down Expand Up @@ -157,6 +181,9 @@
<file category="genAsset" name="Templates/RteTest.gpdsc.template" version ="1.0.0"/>
</files>
</component>
<component generator="RteTestGeneratorNoDryRun" Cclass="Device" Cgroup="RteTest Generated Component" Csub="RteTestNoDryRun" Cversion="1.1.0">
<description>Configuration via RteTest script</description>
</component>
<bundle Cbundle="RteTestBundle" Cclass="Device" Cversion="1.0.0">
<component generator="RteTestGeneratorIdentifier" Cgroup="RteTest Generated Component" Cversion="1.1.0">
<description>Configuration via RteTest script</description>
Expand Down
13 changes: 10 additions & 3 deletions test/packs/ARM/RteTestGenerator/0.1.0/Generator/script.bat
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,14 @@ echo %1
echo %2
echo %3
echo %4
echo %5

mkdir %1
copy "%3\Templates\RteTest.gpdsc.template" "%1\RteTest.gpdsc"
copy "%3\Templates\RteTest_Generated_Component.c.template" "%1\RteTest_Generated_Component.c"
if "%5" == "--dry-run" (
echo -----BEGIN GPDSC-----
type "%3\Templates\RteTest.gpdsc.template"
echo -----END GPDSC-----
) else (
mkdir %1
copy "%3\Templates\RteTest.gpdsc.template" "%1\RteTest.gpdsc"
copy "%3\Templates\RteTest_Generated_Component.c.template" "%1\RteTest_Generated_Component.c"
)
13 changes: 10 additions & 3 deletions test/packs/ARM/RteTestGenerator/0.1.0/Generator/script.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,14 @@ echo $1
echo $2
echo $3
echo $4
echo $5

mkdir $1
cp "$3/Templates/RteTest.gpdsc.template" "$1/RteTest.gpdsc"
cp "$3/Templates/RteTest_Generated_Component.c.template" "$1/RteTest_Generated_Component.c"
if [ "$5" = "--dry-run" ]; then
echo "-----BEGIN GPDSC-----"
cat "$3/Templates/RteTest.gpdsc.template"
echo "-----END GPDSC-----"
else
mkdir $1
cp "$3/Templates/RteTest.gpdsc.template" "$1/RteTest.gpdsc"
cp "$3/Templates/RteTest_Generated_Component.c.template" "$1/RteTest_Generated_Component.c"
fi
1 change: 1 addition & 0 deletions tools/projmgr/include/ProjMgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ class ProjMgr {
bool m_updateRteFiles;
bool m_verbose;
bool m_debug;
bool m_dryRun;
bool m_ymlOrder;
GroupNode m_files;
std::vector<ContextItem*> m_processedContexts;
Expand Down
7 changes: 7 additions & 0 deletions tools/projmgr/include/ProjMgrWorker.h
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,12 @@ class ProjMgrWorker {
*/
void SetDebug(bool debug);

/**
* @brief set dry-run mode
* @param boolean dryRun
*/
void SetDryRun(bool dryRun);

/**
* @brief set load packs policy
* @param reference to load packs policy
Expand Down Expand Up @@ -562,6 +568,7 @@ class ProjMgrWorker {
bool m_checkSchema;
bool m_verbose;
bool m_debug;
bool m_dryRun;

bool LoadPacks(ContextItem& context);
bool GetRequiredPdscFiles(ContextItem& context, const std::string& packRoot, std::set<std::string>& errMsgs);
Expand Down
8 changes: 6 additions & 2 deletions tools/projmgr/src/ProjMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ Commands:\n\
Options:\n\
-c, --context arg [...] Input context names [<project-name>][.<build-type>][+<target-type>]\n\
-d, --debug Enable debug messages\n\
-D, --dry-run Enable dry-run\n\
-e, --export arg Set suffix for exporting <context><suffix>.cprj retaining only specified versions\n\
-f, --filter arg Filter words\n\
-g, --generator arg Code generator identifier\n\
Expand Down Expand Up @@ -130,6 +131,7 @@ int ProjMgr::RunProjMgr(int argc, char **argv, char** envp) {
cxxopts::Option version("V,version", "Print version");
cxxopts::Option verbose("v,verbose", "Enable verbose messages", cxxopts::value<bool>()->default_value("false"));
cxxopts::Option debug("d,debug", "Enable debug messages", cxxopts::value<bool>()->default_value("false"));
cxxopts::Option dryRun("D,dry-run", "Enable dry-run", cxxopts::value<bool>()->default_value("false"));
cxxopts::Option exportSuffix("e,export", "Set suffix for exporting <context><suffix>.cprj retaining only specified versions", cxxopts::value<string>());
cxxopts::Option toolchain("t,toolchain","Selection of the toolchain used in the project optionally with version", cxxopts::value<string>());
cxxopts::Option ymlOrder("yml-order", "Preserve order as specified in input yml", cxxopts::value<bool>()->default_value("false"));
Expand All @@ -139,7 +141,7 @@ int ProjMgr::RunProjMgr(int argc, char **argv, char** envp) {
// command, optional args, options
{"update-rte", { false, {context, debug, load, schemaCheck, toolchain, verbose}}},
{"convert", { false, {context, debug, exportSuffix, load, schemaCheck, noUpdateRte, output, toolchain, verbose}}},
{"run", { false, {context, debug, generator, load, schemaCheck, verbose}}},
{"run", { false, {context, debug, generator, load, schemaCheck, verbose, dryRun}}},
{"list packs", { true, {context, debug, filter, load, missing, schemaCheck, toolchain, verbose}}},
{"list boards", { true, {context, debug, filter, load, schemaCheck, toolchain, verbose}}},
{"list devices", { true, {context, debug, filter, load, schemaCheck, toolchain, verbose}}},
Expand All @@ -157,7 +159,7 @@ int ProjMgr::RunProjMgr(int argc, char **argv, char** envp) {
{"positional", "", cxxopts::value<vector<string>>()},
solution, context, filter, generator,
load, clayerSearchPath, missing, schemaCheck, noUpdateRte, output,
help, version, verbose, debug, exportSuffix, toolchain, ymlOrder
help, version, verbose, debug, dryRun, exportSuffix, toolchain, ymlOrder
});
options.parse_positional({ "positional" });

Expand All @@ -169,7 +171,9 @@ int ProjMgr::RunProjMgr(int argc, char **argv, char** envp) {
manager.m_verbose = parseResult.count("v");
manager.m_worker.SetVerbose(manager.m_verbose);
manager.m_debug = parseResult.count("d");
manager.m_dryRun = parseResult.count("D");
manager.m_worker.SetDebug(manager.m_debug);
manager.m_worker.SetDryRun(manager.m_dryRun);
manager.m_ymlOrder = parseResult.count("yml-order");

vector<string> positionalArguments;
Expand Down
21 changes: 17 additions & 4 deletions tools/projmgr/src/ProjMgrWorker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,13 @@ static const map<const string, tuple<const string, const string, const string>>
{ "IAR", {ProjMgrUtils::IAR_ELF_SUFFIX , ProjMgrUtils::IAR_LIB_PREFIX , ProjMgrUtils::IAR_LIB_SUFFIX }},
};

ProjMgrWorker::ProjMgrWorker(void) {
m_loadPacksPolicy = LoadPacksPolicy::DEFAULT;
ProjMgrWorker::ProjMgrWorker(void) :
m_loadPacksPolicy(LoadPacksPolicy::DEFAULT),
m_checkSchema(false),
m_verbose(false),
m_debug(false),
m_dryRun(false)
{
RteCondition::SetVerboseFlags(0);
}

Expand Down Expand Up @@ -206,6 +211,10 @@ void ProjMgrWorker::SetDebug(bool debug) {
m_debug = debug;
}

void ProjMgrWorker::SetDryRun(bool dryRun) {
m_dryRun = dryRun;
}

void ProjMgrWorker::SetLoadPacksPolicy(const LoadPacksPolicy& policy) {
m_loadPacksPolicy = policy;
}
Expand Down Expand Up @@ -3190,7 +3199,11 @@ bool ProjMgrWorker::ExecuteGenerator(std::string& generatorId) {
ProjMgrLogger::Error("generator file '" + generatorExe + "' cannot be executed, check permissions");
return false;
}
const string generatorCommand = generator->GetExpandedCommandLine(context.rteActiveTarget);
if (m_dryRun && !generator->IsDryRunCapable(generatorExe)) {
ProjMgrLogger::Error("generator '" + generatorId + "' is not dry-run capable");
return false;
}
const string generatorCommand = generator->GetExpandedCommandLine(context.rteActiveTarget, RteUtils::EMPTY_STRING, m_dryRun);

error_code ec;
const auto& workingDir = fs::current_path(ec);
Expand Down Expand Up @@ -3638,4 +3651,4 @@ bool ProjMgrWorker::ListConfigFiles(vector<string>& configFiles) {
}
}
return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/Open-CMSIS-Pack/devtools/main/tools/projmgr/schemas/cproject.schema.json

project:
description: Project 3_3
components:
- component: Startup
- component: CORE
- component: Device:RteTest Generated Component:RteTestNoDryRun
16 changes: 16 additions & 0 deletions tools/projmgr/test/data/TestSolution/gen_nodryrun.csolution.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/Open-CMSIS-Pack/devtools/main/tools/projmgr/schemas/csolution.schema.json

solution:
target-types:
- type: TypeA
device: RteTestGen_ARMCM0

build-types:
- type: Debug
compiler: [email protected]

projects:
- project: ./TestProject3_3/TestProject3_3.cproject.yml

output-dirs:
outdir: $Project$/outdir/
Loading
Loading