ADUC_Result ScriptHandlerImpl::PrepareScriptArguments()

in src/extensions/step_handlers/script_handler/src/script_handler.cpp [266:502]


ADUC_Result ScriptHandlerImpl::PrepareScriptArguments(
    ADUC_WorkflowHandle workflowHandle,
    std::string resultFilePath,
    std::string workFolder,
    std::string& scriptFilePath,
    std::vector<std::string>& args)
{
    ADUC_Result result = { ADUC_GeneralResult_Failure };

    const char* selectedComponentsJson = nullptr;
    JSON_Value* selectedComponentsValue = nullptr;
    JSON_Object* selectedComponentsObject = nullptr;
    JSON_Array* componentsArray = nullptr;
    size_t componentCount = 0;
    JSON_Object* component = nullptr;

    std::string fileArgs;
    std::vector<std::string> argumentList;
    std::stringstream filePath;
    const char* scriptFileName = nullptr;

    char* installedCriteria = nullptr;
    const char* arguments = nullptr;
    const char* propNA = "n/a";

    if (workflowHandle == nullptr)
    {
        result.ExtendedResultCode = ADUC_ERC_UPDATE_CONTENT_HANDLER_INSTALL_FAILURE_NULL_WORKFLOW;
        goto done;
    }

    installedCriteria = workflow_get_installed_criteria(workflowHandle);

    // Parse components list. If the list is empty, nothing to download.
    selectedComponentsJson = workflow_peek_selected_components(workflowHandle);

    if (!IsNullOrEmpty(selectedComponentsJson))
    {
        selectedComponentsValue = json_parse_string(selectedComponentsJson);
        if (selectedComponentsValue == nullptr)
        {
            result.ExtendedResultCode = ADUC_ERC_UPDATE_CONTENT_HANDLER_INSTALL_FAILURE_MISSING_PRIMARY_COMPONENT;
            goto done;
        }

        selectedComponentsObject = json_value_get_object(selectedComponentsValue);
        componentsArray = json_object_get_array(selectedComponentsObject, "components");
        if (componentsArray == nullptr)
        {
            result.ExtendedResultCode = ADUC_ERC_UPDATE_CONTENT_HANDLER_INSTALL_FAILURE_MISSING_PRIMARY_COMPONENT;
            goto done;
        }

        // Prepare target component info.
        componentCount = json_array_get_count(componentsArray);

        if (componentCount == 0)
        {
            result.ResultCode = ADUC_Result_Download_Skipped_NoMatchingComponents;
            goto done;
        }

        if (componentCount > 1)
        {
            Log_Error("Expecting only 1 component, but got %d.", componentCount);
            result.ExtendedResultCode = ADUC_ERC_SCRIPT_HANDLER_TOO_MANY_COMPONENTS;
        }

        component = json_array_get_object(componentsArray, 0);
        if (component == nullptr)
        {
            result.ExtendedResultCode = ADUC_ERC_SCRIPT_HANDLER_INVALID_COMPONENTS_DATA;
            goto done;
        }
    }

    // Prepare script file info.
    scriptFileName = workflow_peek_update_manifest_handler_properties_string(workflowHandle, "scriptFileName");
    if (IsNullOrEmpty(scriptFileName))
    {
        result.ExtendedResultCode = ADUC_ERC_SCRIPT_HANDLER_MISSING_SCRIPTFILENAME_PROPERTY;
        workflow_set_result_details(workflowHandle, "Missing 'handlerProperties.scriptFileName' property");
        goto done;
    }

    filePath << workFolder.c_str() << "/" << scriptFileName;
    scriptFilePath = filePath.str();

    //
    // Prepare script arguments.
    //

    // Add customer specified arguments first.
    arguments = workflow_peek_update_manifest_handler_properties_string(workflowHandle, "arguments");
    if (arguments == nullptr)
    {
        Log_Info("Script workflow doesn't contain 'arguments' property. This is unusual, but not an error... ");
        arguments = "";
    }
    fileArgs = arguments;

    Log_Info("Parsing script arguments: %s", arguments);
    argumentList = ADUC::StringUtils::Split(fileArgs, ' ');
    for (size_t i = 0; i < argumentList.size(); i++)
    {
        const std::string argument = argumentList[i];
        if (!argument.empty())
        {
            if (argument == "--component-id-val")
            {
                const char* val = json_object_get_string(component, "id");
                if (val != nullptr)
                {
                    args.emplace_back(val);
                }
                else
                {
                    args.emplace_back(propNA);
                }
            }
            else if (argument == "--component-name-val")
            {
                const char* val = json_object_get_string(component, "name");
                if (val != nullptr)
                {
                    args.emplace_back(val);
                }
                else
                {
                    args.emplace_back(propNA);
                }
            }
            else if (argument == "--component-manufacturer-val")
            {
                const char* val = json_object_get_string(component, "manufacturer");
                if (val != nullptr)
                {
                    args.emplace_back(val);
                }
                else
                {
                    args.emplace_back(propNA);
                }
            }
            else if (argument == "--component-model-val")
            {
                const char* val = json_object_get_string(component, "model");
                if (val != nullptr)
                {
                    args.emplace_back(val);
                }
                else
                {
                    args.emplace_back(propNA);
                }
            }
            else if (argument == "--component-version-val")
            {
                const char* val = json_object_get_string(component, "version");
                if (val != nullptr)
                {
                    args.emplace_back(val);
                }
                else
                {
                    args.emplace_back(propNA);
                }
            }
            else if (argument == "--component-group-val")
            {
                const char* val = json_object_get_string(component, "group");
                if (val != nullptr)
                {
                    args.emplace_back(val);
                }
                else
                {
                    args.emplace_back(propNA);
                }
            }
            else if (argument == "--component-prop-val")
            {
                if (i < argumentList.size() - 1)
                {
                    std::string propertyPath = "properties.";
                    propertyPath += argumentList[i + 1];
                    const char* val = json_object_dotget_string(component, propertyPath.c_str());
                    if (val != nullptr)
                    {
                        args.emplace_back(val);
                    }
                    else
                    {
                        args.emplace_back(propNA);
                    }
                    i++;
                }
                else
                {
                    args.emplace_back(propNA);
                }
            }
            else
            {
                args.emplace_back(argument);
            }
        }
    }

    // Default options.
    args.emplace_back("--work-folder");
    args.emplace_back(workFolder);

    args.emplace_back("--result-file");
    args.emplace_back(resultFilePath);

    if (IsNullOrEmpty(installedCriteria))
    {
        Log_Info("Installed criteria is null.");
    }
    else
    {
        args.emplace_back("--installed-criteria");
        args.emplace_back(installedCriteria);
    }

    result = { ADUC_Result_Success };

done:
    if (selectedComponentsValue != nullptr)
    {
        json_value_free(selectedComponentsValue);
    }

    workflow_free_string(installedCriteria);
    return result;
}