Skip to content
Snippets Groups Projects
Commit cae3ae12 authored by Bensong Liu's avatar Bensong Liu
Browse files

Merge branch 'allow_explicit_arg' into 'master'

Allow explicit arg

See merge request bensl/cis-workflow-gen!1
parents 816e66b2 741e4231
No related branches found
No related tags found
1 merge request!1Allow explicit arg
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
#include <queue> #include <queue>
#include <algorithm> #include <algorithm>
#include "uuid.hpp" #include "utility.hpp"
#include "xaml-template.hpp" #include "xaml-template.hpp"
#include <rlib/string.hpp> #include <rlib/string.hpp>
#include <rlib/require/cxx14> #include <rlib/require/cxx14>
...@@ -24,39 +24,61 @@ namespace CIS { ...@@ -24,39 +24,61 @@ namespace CIS {
class Activity { class Activity {
public: public:
friend Flow; friend Flow;
// All `Name` should not contain QuotationMark(")
Activity(string displayName, string className, string entityName = "") Activity(string displayName, string className, string entityName = "")
: displayName(displayName), className(className), entityName(entityName), taskId(GenUUID()) {} : displayName(Utility::HtmlEscapeString(displayName)), className(className), entityName(entityName), taskId(Utility::GenUUID()) {}
Flow operator>>(const Flow &seqNext) const; Flow operator>>(const Flow &seqNext) const;
Flow operator|(const Flow &seqNext) const; Flow operator|(const Flow &seqNext) const;
void addInputSetting(string k, string v) { void addInputSetting(string k, string v) {
inputSettings[k] = v; inputSettings[k] = v;
} }
void addRawActivityArgument(string xamlTypeString, string csharpValueCode) { void explicitSetRawArgument(string argTypeInXaml, string argValueInCSharp) {
throw std::invalid_argument("Not implemented yet."); throw std::runtime_error("NotSupported! Activity seems doesn't support custom type inputSettings at all. Refer to commit 7fd539d6d5f6b102337da9591217b781cb71ced9 if we get new info and want to support it again. ");
} }
private: private:
string displayName, className, entityName; string displayName, className, entityName;
string taskId; string taskId;
std::unordered_map<string, string> inputSettings; std::unordered_map<string, string> inputSettings;
auto inputSettingsToCodelines() const {
// Convert InputSettings Dictionary to C# code.
std::list<string> inputSettingStrings;
std::transform(this->inputSettings.begin(), this->inputSettings.end(), std::back_inserter(inputSettingStrings), [](auto &&kv) {
return " {\"{}\", \"{}\"}"_rs.format(kv.first, kv.second);
});
auto inputSettingsString = ",\n"_rs.join(inputSettingStrings);
return rlib::string(templates::ACTIVITY_DICT_TEMPLATE_UNESCAPED).replace_once("__TEMPLATE_ARG_DictLines", inputSettingsString);
}
auto generateXaml() const {
rlib::string xamlCode;
if(inputSettings.empty()) {
// Also no inputSettings.
xamlCode = templates::ACTIVITY_XAML_TEMPLATE_WITHOUT_INPUTSETTINGS;
}
else {
// Generate inputSettings.
xamlCode = templates::ACTIVITY_XAML_TEMPLATE;
xamlCode.replace("__TEMPLATE_ARG_TypeName", templates::ACTIVITY_DICT_TYPENAME);
xamlCode.replace_once("__TEMPLATE_ARG_TypeValue", Utility::HtmlEscapeString(inputSettingsToCodelines()));
}
xamlCode.replace_once("__TEMPLATE_ARG_ClassName", this->className);
xamlCode.replace_once("__TEMPLATE_ARG_DisplayName", this->displayName);
xamlCode.replace_once("__TEMPLATE_ARG_TaskId", this->taskId);
auto entityXaml = this->entityName == "" ? "" : rlib::string(templates::ENTITY_DEF_TEMPLATE).replace("__TEMPLATE_ARG_EntityName", this->entityName);
xamlCode.replace_once("__TEMPLATE_ARG_EntityDefPlaceholder", entityXaml);
return xamlCode;
}
}; };
class Flow { class Flow {
public: public:
Flow(const Activity &activity) { Flow(const Activity &activity) {
xamlCode = templates::ACTIVITY_XAML_TEMPLATE; xamlCode = activity.generateXaml();
xamlCode.replace_once("__TEMPLATE_ARG_ClassName", activity.className);
xamlCode.replace_once("__TEMPLATE_ARG_DisplayName", activity.displayName);
xamlCode.replace_once("__TEMPLATE_ARG_TaskId", activity.taskId);
auto entityXaml = activity.entityName == "" ? "" : rlib::string(templates::ENTITY_DEF_TEMPLATE).replace("__TEMPLATE_ARG_EntityName", activity.entityName);
xamlCode.replace_once("__TEMPLATE_ARG_EntityDefPlaceholder", entityXaml);
std::list<string> inputSettingStrings;
std::transform(activity.inputSettings.begin(), activity.inputSettings.end(), std::back_inserter(inputSettingStrings), [](auto &&kv) {
return "{\"{}\", \"{}\"}"_rs.format(kv.first, kv.second);
});
auto inputSettingsString = ",\n "_rs.join(inputSettingStrings);
xamlCode.replace_once("__TEMPLATE_ARG_DictLines", inputSettingsString);
} }
Flow(rlib::string xamlCode) : xamlCode(xamlCode) {} Flow(rlib::string xamlCode) : xamlCode(xamlCode) {}
Flow(const Flow &another) : queued(another.queued), xamlCode(another.xamlCode), prevOperationIsSequential(another.prevOperationIsSequential) {} Flow(const Flow &another) : queued(another.queued), xamlCode(another.xamlCode), prevOperationIsSequential(another.prevOperationIsSequential) {}
......
...@@ -3,8 +3,12 @@ ...@@ -3,8 +3,12 @@
#include <random> #include <random>
#include <string> #include <string>
#include <rlib/string.hpp>
inline static std::string GenUUID() { namespace Utility {
inline static auto GenUUID() {
static std::random_device dev; static std::random_device dev;
static std::mt19937 rng(dev()); static std::mt19937 rng(dev());
...@@ -22,4 +26,10 @@ inline static std::string GenUUID() { ...@@ -22,4 +26,10 @@ inline static std::string GenUUID() {
return res; return res;
} }
inline static auto HtmlEscapeString(rlib::string s) {
return s.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;");
}
}
#endif #endif
\ No newline at end of file
...@@ -12,17 +12,26 @@ namespace templates { ...@@ -12,17 +12,26 @@ namespace templates {
constexpr auto ACTIVITY_XAML_TEMPLATE = constexpr auto ACTIVITY_XAML_TEMPLATE =
R"XAMLTL( <mwcwa:ControlledActivity ClassName="__TEMPLATE_ARG_ClassName" DisplayName="__TEMPLATE_ARG_DisplayName" TaskId="__TEMPLATE_ARG_TaskId" __TEMPLATE_ARG_EntityDefPlaceholder> R"XAMLTL( <mwcwa:ControlledActivity ClassName="__TEMPLATE_ARG_ClassName" DisplayName="__TEMPLATE_ARG_DisplayName" TaskId="__TEMPLATE_ARG_TaskId" __TEMPLATE_ARG_EntityDefPlaceholder>
<mwcwa:ControlledActivity.InputSettings> <mwcwa:ControlledActivity.InputSettings>
<InArgument x:TypeArguments="scg:Dictionary(x:String, x:String)"> <InArgument x:TypeArguments="__TEMPLATE_ARG_TypeName">
<mca:CSharpValue x:TypeArguments="scg:Dictionary(x:String, x:String)" xml:space="preserve"> <mca:CSharpValue x:TypeArguments="__TEMPLATE_ARG_TypeName" xml:space="preserve">
new Dictionary&lt;string, string&gt;() __TEMPLATE_ARG_TypeValue </mca:CSharpValue>
{
__TEMPLATE_ARG_DictLines
}
</mca:CSharpValue>
</InArgument> </InArgument>
</mwcwa:ControlledActivity.InputSettings> </mwcwa:ControlledActivity.InputSettings>
</mwcwa:ControlledActivity> </mwcwa:ControlledActivity>
)XAMLTL"; )XAMLTL";
constexpr auto ACTIVITY_XAML_TEMPLATE_WITHOUT_INPUTSETTINGS =
R"XAMLTL( <mwcwa:ControlledActivity ClassName="__TEMPLATE_ARG_ClassName" DisplayName="__TEMPLATE_ARG_DisplayName" TaskId="__TEMPLATE_ARG_TaskId" InputSettings="{x:Null}" __TEMPLATE_ARG_EntityDefPlaceholder>
</mwcwa:ControlledActivity>
)XAMLTL";
// This 2 variable below were designed to support custom TypeArguments type, but CIS seems not support it...
constexpr auto ACTIVITY_DICT_TYPENAME = "scg:Dictionary(x:String, x:String)";
constexpr auto ACTIVITY_DICT_TEMPLATE_UNESCAPED =
R"XAMLTL( new Dictionary<string, string>()
{
__TEMPLATE_ARG_DictLines
}
)XAMLTL";
constexpr auto ENTITY_DEF_TEMPLATE = R"(coordination:DependencyBinder.EntityName="__TEMPLATE_ARG_EntityName")"; constexpr auto ENTITY_DEF_TEMPLATE = R"(coordination:DependencyBinder.EntityName="__TEMPLATE_ARG_EntityName")";
......
...@@ -31,10 +31,13 @@ auto complexExample() { ...@@ -31,10 +31,13 @@ auto complexExample() {
DEFINE_ACTIVITY(IntegrationTesting, "") DEFINE_ACTIVITY(IntegrationTesting, "")
DEFINE_ACTIVITY(TSConfigAndInterop, "PreRteg.InitiateBareMetalComplete") DEFINE_ACTIVITY(TSConfigAndInterop, "PreRteg.InitiateBareMetalComplete")
// All Names of activity should not contain quotation mark (")
Activity OneMoreMagicActivity("MyName Contains Symbols: {(&)} <>", "FleetAGC.Workflow.Magic");
auto block1 = SCS >> (SearchAnalytics | (SearchFarms >> (ClassisSearchUX | ModernSearch))); auto block1 = SCS >> (SearchAnalytics | (SearchFarms >> (ClassisSearchUX | ModernSearch)));
auto block3 = Loki >> Yggdrasil >> OfficeGraph; auto block3 = Loki >> Yggdrasil >> OfficeGraph;
auto block4 = IC3Tooling >> (MonitoringSetup | (MicroServices >> DevelopmentValidation >> IntegrationTesting)); auto block4 = IC3Tooling >> (MonitoringSetup | (MicroServices >> DevelopmentValidation >> IntegrationTesting));
auto completeFlow = block1 | TSConfigAndInterop | block3 | block4; auto completeFlow = (block1 | TSConfigAndInterop | block3 | block4) >> OneMoreMagicActivity;
auto myMetadata = Metadata("FleetAGC.Workflows.BuildTeams").setXtraAssemblies({"FleetAGC.Workflows"}); auto myMetadata = Metadata("FleetAGC.Workflows.BuildTeams").setXtraAssemblies({"FleetAGC.Workflows"});
println(to_file("BuildTeams.xaml"), completeFlow.generateXaml(myMetadata)); println(to_file("BuildTeams.xaml"), completeFlow.generateXaml(myMetadata));
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment