-
Notifications
You must be signed in to change notification settings - Fork 1.7k
[Do not review] CLI: Initialize template support #40195
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
base: feature/wsl-for-apps
Are you sure you want to change the base?
Changes from all commits
1d2b390
6189485
90f800f
1b06ed8
e3fdd17
f331dbb
99fb198
3304aaa
b254595
5dc677e
000d50d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,15 +6,52 @@ list(TRANSFORM WSLC_SUBDIR_PATHS APPEND /*.cpp OUTPUT_VARIABLE SOURCE_PATTERNS) | |
| file(GLOB_RECURSE HEADERS CONFIGURE_DEPENDS ${HEADER_PATTERNS}) | ||
| file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS ${SOURCE_PATTERNS}) | ||
|
|
||
| # Build Go template renderer library | ||
| set(GO_TEMPLATE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/tools/gotemplate) | ||
| set(GO_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated/gotemplate") | ||
|
|
||
| # Reuse TARGET_PLATFORM already normalized by the root CMakeLists.txt | ||
| if("${TARGET_PLATFORM}" STREQUAL "arm64") | ||
| set(GO_ARCH arm64) | ||
| set(GO_LIB_MACHINE ARM64) | ||
| else() | ||
| set(GO_ARCH amd64) | ||
| set(GO_LIB_MACHINE X64) | ||
| endif() | ||
|
|
||
| set(GO_OUTPUT_DLL ${GO_OUTPUT_DIR}/render.dll) | ||
| set(GO_OUTPUT_LIB ${GO_OUTPUT_DIR}/render.lib) | ||
| add_custom_command( | ||
| OUTPUT ${GO_OUTPUT_DLL} ${GO_OUTPUT_LIB} | ||
| COMMAND ${CMAKE_COMMAND} -E make_directory ${GO_OUTPUT_DIR} | ||
| COMMAND ${CMAKE_COMMAND} -E env GOOS=windows GOARCH=${GO_ARCH} CGO_ENABLED=1 | ||
| go build -o ${GO_OUTPUT_DLL} -buildmode=c-shared -trimpath -ldflags=-s\ -w render.go | ||
| COMMAND lib /def:${GO_TEMPLATE_DIR}/render.def /out:${GO_OUTPUT_LIB} /machine:${GO_LIB_MACHINE} | ||
| WORKING_DIRECTORY ${GO_TEMPLATE_DIR} | ||
| DEPENDS ${GO_TEMPLATE_DIR}/render.go ${GO_TEMPLATE_DIR}/render.def | ||
| COMMENT "Building Go template renderer library" | ||
| VERBATIM | ||
| ) | ||
|
|
||
| add_custom_target(gotemplate_lib ALL DEPENDS ${GO_OUTPUT_DLL} ${GO_OUTPUT_LIB}) | ||
|
Comment on lines
+9
to
+36
|
||
|
|
||
|
Comment on lines
+24
to
+37
|
||
| # Include Go source files for browsing in Solution Explorer | ||
| set(GO_SOURCES ${GO_TEMPLATE_DIR}/render.go) | ||
| set_source_files_properties(${GO_SOURCES} PROPERTIES HEADER_FILE_ONLY TRUE) | ||
|
|
||
| # Object library for WSLC components. | ||
| # Used to build the executable and also unit testing components. | ||
| add_library(wslclib OBJECT ${SOURCES} ${HEADERS}) | ||
| add_library(wslclib OBJECT ${SOURCES} ${HEADERS} ${GO_SOURCES}) | ||
| target_include_directories(wslclib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${WSLC_SUBDIR_PATHS}) | ||
|
|
||
| target_link_libraries(wslclib | ||
| ${COMMON_LINK_LIBRARIES} | ||
| yaml-cpp | ||
| common) | ||
| common | ||
| ${GO_OUTPUT_LIB}) | ||
|
|
||
| # Add dependency on Go library | ||
| add_dependencies(wslclib gotemplate_lib) | ||
|
|
||
| target_precompile_headers(wslclib REUSE_FROM common) | ||
| set_target_properties(wslclib PROPERTIES FOLDER windows) | ||
|
|
@@ -24,7 +61,11 @@ add_executable(wslc $<TARGET_OBJECTS:wslclib>) | |
|
|
||
| target_link_libraries(wslc wslclib) | ||
|
|
||
| add_custom_command(TARGET wslc POST_BUILD | ||
| COMMAND ${CMAKE_COMMAND} -E copy_if_different ${GO_OUTPUT_DLL} $<TARGET_FILE_DIR:wslc>/render.dll | ||
| ) | ||
|
Comment on lines
+64
to
+66
|
||
|
|
||
| set_target_properties(wslc PROPERTIES FOLDER windows) | ||
|
|
||
| # For prettier source tree browsing | ||
| source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SOURCES} ${HEADERS}) | ||
| source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SOURCES} ${HEADERS} ${GO_SOURCES}) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -31,10 +31,6 @@ void Argument::Validate(const ArgMap& execArgs) const | |
| { | ||
| switch (m_argType) | ||
| { | ||
| case ArgType::Format: | ||
| validation::ValidateFormatTypeFromString(execArgs.GetAll<ArgType::Format>(), m_name); | ||
| break; | ||
|
|
||
| case ArgType::Signal: | ||
| validation::ValidateWSLCSignalFromString(execArgs.GetAll<ArgType::Signal>(), m_name); | ||
| break; | ||
|
|
@@ -144,29 +140,19 @@ WSLCSignal GetWSLCSignalFromString(const std::wstring& input, const std::wstring | |
| return static_cast<WSLCSignal>(signalValue); | ||
| } | ||
|
|
||
| void ValidateFormatTypeFromString(const std::vector<std::wstring>& values, const std::wstring& argName) | ||
| { | ||
| for (const auto& value : values) | ||
| { | ||
| std::ignore = GetFormatTypeFromString(value, argName); | ||
| } | ||
| } | ||
|
|
||
| FormatType GetFormatTypeFromString(const std::wstring& input, const std::wstring& argName) | ||
| FormatType GetFormatTypeFromString(const std::wstring& input) | ||
| { | ||
| if (IsEqual(input, L"json")) | ||
| { | ||
| return FormatType::Json; | ||
| } | ||
| else if (IsEqual(input, L"table")) | ||
|
|
||
| if (IsEqual(input, L"table")) | ||
| { | ||
| return FormatType::Table; | ||
| } | ||
| else | ||
| { | ||
| throw ArgumentException(std::format( | ||
| L"Invalid {} value: {} is not a recognized format type. Supported format types are: json, table.", argName, input)); | ||
| } | ||
|
|
||
| return FormatType::Template; | ||
|
AmelBawa-msft marked this conversation as resolved.
Comment on lines
151
to
+155
|
||
| } | ||
|
|
||
| } // namespace wsl::windows::wslc::validation | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,67 @@ | ||||||
| /*++ | ||||||
|
|
||||||
| Copyright (c) Microsoft. All rights reserved. | ||||||
|
|
||||||
| Module Name: | ||||||
|
|
||||||
| GoTemplateRenderer.cpp | ||||||
|
||||||
| GoTemplateRenderer.cpp | |
| TemplateRenderer.cpp |
Copilot
AI
Apr 16, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The header comment’s Module Name says "GoTemplateRenderer.cpp" but the file is TemplateRenderer.cpp. Please update the comment to match the actual filename to avoid confusion when grepping or auditing.
Copilot
AI
Apr 16, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The extern declarations use mutable char* and require const_cast when calling from std::string. Since the Go function does not mutate the inputs, declare the parameters as const char* in the C++ extern (and adjust the Go signature/usage if needed) to avoid casting away const.
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,42 @@ | ||||||||
| /*++ | ||||||||
|
|
||||||||
| Copyright (c) Microsoft. All rights reserved. | ||||||||
|
|
||||||||
| Module Name: | ||||||||
|
|
||||||||
| TemplateRenderer.h | ||||||||
|
|
||||||||
| Abstract: | ||||||||
|
|
||||||||
| This file contains the interface for rendering Go templates with JSON data. | ||||||||
|
|
||||||||
| --*/ | ||||||||
|
|
||||||||
| #pragma once | ||||||||
|
|
||||||||
| #include <string> | ||||||||
|
|
||||||||
| namespace wsl::windows::wslc::core { | ||||||||
|
|
||||||||
| struct TemplateRenderer | ||||||||
| { | ||||||||
| enum class RenderResult | ||||||||
| { | ||||||||
| Success = 0, | ||||||||
| Fail_NullPointer = 1, | ||||||||
| Fail_ParseJSON = 2, | ||||||||
| Fail_ParseTemplate = 3, | ||||||||
| Fail_ExecuteTemplate = 4, | ||||||||
|
|
||||||||
| // Catch-all for any unknown errors | ||||||||
| Fail_Unknown = -1, | ||||||||
| }; | ||||||||
|
|
||||||||
| // Renders a Go template with the provided JSON data. | ||||||||
| // Returns true on success with the rendered output, false on failure with an error message. | ||||||||
|
||||||||
| // Returns true on success with the rendered output, false on failure with an error message. | |
| // Returns RenderResult::Success on success, in which case output contains the rendered output. | |
| // Returns a failure RenderResult on failure, in which case output contains an error message describing the failure. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -25,6 +25,7 @@ enum class FormatType | |
| { | ||
| Table, | ||
| Json, | ||
| Template, | ||
| }; | ||
|
Comment on lines
25
to
29
|
||
|
|
||
| struct ContainerOptions | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -11,6 +11,7 @@ Module Name: | |||||
| Implementation of container command related execution logic. | ||||||
|
|
||||||
| --*/ | ||||||
|
|
||||||
| #include "Argument.h" | ||||||
| #include "ArgumentValidation.h" | ||||||
| #include "CLIExecutionContext.h" | ||||||
|
|
@@ -20,6 +21,7 @@ Module Name: | |||||
| #include "SessionModel.h" | ||||||
| #include "SessionService.h" | ||||||
| #include "TableOutput.h" | ||||||
| #include "TemplateRenderer.h" | ||||||
| #include <wil/result_macros.h> | ||||||
| #include <wslc_schema.h> | ||||||
|
|
||||||
|
|
@@ -29,6 +31,7 @@ using namespace wsl::windows::common::wslutil; | |||||
| using namespace wsl::windows::wslc::execution; | ||||||
| using namespace wsl::windows::wslc::models; | ||||||
| using namespace wsl::windows::wslc::services; | ||||||
| using namespace wsl::windows::wslc::core; | ||||||
|
|
||||||
| namespace wsl::windows::wslc::task { | ||||||
| void AttachContainer::operator()(CLIExecutionContext& context) const | ||||||
|
|
@@ -167,6 +170,18 @@ void ListContainers(CLIExecutionContext& context) | |||||
| table.Complete(); | ||||||
| break; | ||||||
| } | ||||||
| case FormatType::Template: | ||||||
| { | ||||||
| auto templateStr = WideToMultiByte(context.Args.Get<ArgType::Format>()); | ||||||
| for (const auto& container : containers) | ||||||
| { | ||||||
| auto json = ToJson(container, c_jsonPrettyPrintIndent); | ||||||
|
||||||
| auto json = ToJson(container, c_jsonPrettyPrintIndent); | |
| auto json = ToJson(container); |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -22,13 +22,15 @@ Module Name: | |||||
| #include "PullImageCallback.h" | ||||||
| #include "TableOutput.h" | ||||||
| #include "Task.h" | ||||||
| #include "TemplateRenderer.h" | ||||||
| #include <format> | ||||||
|
|
||||||
| using namespace wsl::shared; | ||||||
| using namespace wsl::windows::common::string; | ||||||
| using namespace wsl::windows::common::wslutil; | ||||||
| using namespace wsl::windows::wslc::execution; | ||||||
| using namespace wsl::windows::wslc::services; | ||||||
| using namespace wsl::windows::wslc::core; | ||||||
|
|
||||||
| namespace wsl::windows::wslc::task { | ||||||
| void BuildImage(CLIExecutionContext& context) | ||||||
|
|
@@ -124,6 +126,18 @@ void ListImages(CLIExecutionContext& context) | |||||
| table.Complete(); | ||||||
| break; | ||||||
| } | ||||||
| case FormatType::Template: | ||||||
| { | ||||||
| auto templateStr = WideToMultiByte(context.Args.Get<ArgType::Format>()); | ||||||
| for (const auto& image : images) | ||||||
| { | ||||||
| auto json = ToJson(image, c_jsonPrettyPrintIndent); | ||||||
|
||||||
| auto json = ToJson(image, c_jsonPrettyPrintIndent); | |
| auto json = ToJson(image); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| EXPORTS | ||
| TryRenderGoTemplate | ||
| FreeGoString | ||
|
Comment on lines
+1
to
+3
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CGO cross-compilation is often not supported without an appropriate cross C compiler. This command sets GOARCH based on TARGET_PLATFORM (including arm64) while forcing CGO_ENABLED=1; building an ARM64 WSLC binary on an x64 host is likely to fail. Consider either building this DLL only for native builds, or wiring up CC/CXX for the required cross compiler, or disabling templates on cross-arch builds.