Create Custom Queries
With the CI/CD Automation for Simulink Check support package, you can define a development and verification process for your team by using a process model. You can use queries to find artifacts relevant to your tasks and processes. The support package contains several built-in queries that you can reconfigure and use to find artifacts in your project, but if you need to perform other actions or always want to use a reconfigured version of a built-in query, you can create and add custom queries to your process model.
To find artifacts in your project, you can use the built-in queries that ship with the support package or you can create your own custom queries. Use the built-in queries where possible. If your use case requires custom queries, use the following steps to create a custom query. Note that to reconfigure the functionality of a built-in task, your custom queries can inherit from a built-in query.
After you create a custom query, you can use that query as an input query for a task to modify or filter the task inputs.
Choose Superclass for Custom Query
There are two ways to define custom queries:
Inherit from a built-in query — Use this approach when there is a built-in query that is similar to the custom query that you want to create. When you inherit from a built-in query, like
padv.builtin.query.FindArtifacts
, your custom query inherits the functionality of that query, but then you can override the properties and methods of the class to fit your needs.Inherit from
padv.Query
— Use this approach if your custom query needs to find artifacts in a way that is not similar to a built-in query.padv.Query
is the base class of the built-in queries, so you must completely define the functionality of the query.
Define and Use Custom Query in Process
Create a new MATLAB® class in your project.
Tip
Namespaces can help you organize the class definition files for your custom queries. In the root of your project, create a folder
+processLibrary
with a subfolder+query
and save your class in that folder.To share your custom queries across multiple process models in different projects, consider creating a referenced project that contains your folders and class definition files. Your main projects can then use the referenced project as a shared process library.
Use one of these approaches to define your custom query:
If you are inheriting from a built-in query, you can replace the contents of your class file with this example code:
This example query inherits from the built-in queryclassdef MyCustomQuery<padv.builtin.query.FindArtifacts % query definition goes in this class % by default, this query finds all artifacts in the project methods function obj = MyCustomQuery(NameValueArgs) arguments NameValueArgs.Name = "MyCustomQuery"; end end end end
padv.builtin.query.FindArtifacts
, but you can change that line of code to inherit from another built-in query. Use the properties of the query to specify which sets of artifacts you want the query to return. If you want to override therun
method for a built-in query, check which input arguments therun
method for the built-in query accepts and use the same method signature inside your custom query. For more information, see Built-In Queries.If you are inheriting from
padv.Query
, you can replace the contents of your class file with this example code:A query must have:classdef MyCustomQuery < padv.Query methods function obj = MyCustomQuery(NameValueArgs) obj@padv.Query("MyCustomQuery"); end function artifacts = run(obj,~) artifacts = padv.Artifact.empty; % Core functionality of the query goes here % artifacts = padv.Artifact(artifactType,... % padv.util.ArtifactAddress(fullfile(fileparts)); end end end
a unique name, specified using the
Name
propertya
run
function that returns either apadv.Artifact
object or an array ofpadv.Artifact
objects. For more information, seepadv.Artifact
and Example Custom Queries.
Note
The digital thread only tracks changes to specific types of artifacts. For information on supported artifact types, see Valid Artifact Types. If there is an artifact in your project that the
padv.builtin.query.FindArtifacts
query does not find, the digital thread cannot detect changes to that artifact. If you create custom queries that returnpadv.Artifact
objects with unsupported artifact types, the digital thread will not detect changes to those artifacts. This behavior can impact whether changes to these artifacts cause a task to be marked as outdated. To see a list of the files the digital thread is tracking in your project, see Find Artifacts that Digital Thread Tracks.
You can test your custom query in the MATLAB Command Window executing the
run
function. Note that your project needs to be open for the query to find artifacts. For example, for a queryMyCustomQuery
saved in the namespaceprocessLibrary.query
:run(processLibrary.query.MyCustomQuery)
You can use your custom query in your process model. For example, you can control which artifacts a task iterates over by using your custom query as the iteration query for a task:
This example assumes that you saved your class file in thefunction processmodel(pm) % Defines the project's processmodel arguments pm padv.ProcessModel end t = addTask(pm,"MyCustomTask",... IterationQuery = processLibrary.query.MyCustomQuery); end
+query
folder inside the+processLibrary
folder.You can confirm which artifacts your task iterates over by opening Process Advisor. In the MATLAB Command Window, enter:
The artifacts that the task iterates over appear under the task name in the Tasks column.processAdvisorWindow
Example Custom Queries
Run Task on Data Dictionaries in Project
Suppose you want to find each of the data dictionaries in your project.
There are no built-in queries that perform
this functionality by default, but there is a built-in query
padv.builtin.query.FindArtifacts
that can find
artifacts that meet certain search criteria. Effectively you can create your
own version of the built-in query, but specialized to only find data
dictionaries. You can create a class-based, custom query that inherits from
padv.builtin.query.FindArtifacts
and specifies the
ArtifactType
argument as a Simulink® data dictionary.
classdef FindSLDDs<padv.builtin.query.FindArtifacts %FindSLDDs This query is like FindArtifacts, % but only returns data dictionaries. methods function obj = FindSLDDs(NameValueArgs) arguments NameValueArgs.ArtifactType string = "sl_data_dictionary_file"; NameValueArgs.Name = "FindSLDDs"; end obj.ArtifactType = NameValueArgs.ArtifactType; end end end
The example class FindSLDDs
inherits its properties and
run function from the built-in query
padv.builtin.query.FindArtifacts
, but specifies a
unique Name
and ArtifactType
. The
ArtifactType
is specified as
sl_data_dictionary_file
because that is the artifact
type associated with Simulink data dictionary files. For a list of valid artifact types, see
padv.builtin.query.FindArtifacts
.
You can have a task run once for each data dictionary in your project by using the custom query as the iteration query for the task.
function processmodel(pm) % Defines the project's processmodel arguments pm padv.ProcessModel end t = addTask(pm,"MyCustomTask",... IterationQuery = processLibrary.query.FindSLDDs); end
Sort Artifacts in Specific Order
By default, queries sort artifacts alphabetically by the artifact address.
If you want your query to sort artifacts in a different order, you can
override the internal sortArtifacts
method in a subclass
that defines a custom sort behavior. For example:
classdef FindFileSorted < padv.builtin.query.FindArtifacts methods function obj = FindFileSorted(options) arguments options.ArtifactType string options.IncludeLabel string options.ExcludeLabel string options.IncludePath string options.ExcludePath string options.InProject boolean options.FilterSubFileArtifacts boolean end fwdoptions = namedargs2cell(options); obj@padv.builtin.query.FindArtifacts(fwdoptions{:}); end end methods(Access = protected) % Overload the default sort artifacts logic, in this case % Sorting artifacts based upon their string length rather than % Alphabetically function sortedArtifacts = sortArtifacts(~, artifacts) if isempty(artifacts) sortedArtifacts = artifacts; return; end namesToSort = arrayfun(@(art) art.ArtifactAddress.getFileAddress,artifacts); [~,idx] = sort(strlength(namesToSort)); sortedArtifacts = artifacts(idx); end end end
Note
If you override sortArtifacts
, make sure that
your implementation only changes the order of the artifacts, not the
data type or structure. Do not use
sortArtifacts
to add or remove artifacts
from the query results.
Run Validation Scripts on Spreadsheets
Suppose that your project contains several Excel® spreadsheets and that for each spreadsheet, you have a validation script with the same name as the spreadsheet. You can find the validation scripts by using a custom query and then you can run the validation script on each spreadsheet by using a custom task. For example, the following example custom query searches through the artifacts in the project to find if there are any scripts that have the same name as the iteration artifact.
classdef FindValidationFiles < padv.Query methods function obj = FindValidationFiles(NameValueArgs) arguments NameValueArgs.Name string = string.empty; NameValueArgs.Title string = "Find validation files"; end obj@padv.Query(NameValueArgs.Name, Title=NameValueArgs.Title); % Named Query obj.CanBeUsedAsInputQuery = true; obj.CanBeUsedAsIterationQuery = true; end function paArtifact = run(~,iterationArtifact) paArtifact = padv.Artifact.empty; % Get Name of iteration artifact [~,name] = fileparts(iterationArtifact.ArtifactAddress.getFileAddress()); % Find validation script with same name as iteration artifact validationFileName = strcat(name, ".m"); filePath = which(validationFileName); if ~isempty(filePath) paArtifact = padv.Artifact("xls_validation_file",filePath); end end end end
In the process model, you can add the custom query as an input query for
your custom task so that if you make a change to the validation script, the
task iteration for that spreadsheet automatically becomes outdated. For
example, this example process model uses the built-in query
FindArtifacts
to find the spreadsheets, specifies that a
custom task named RunValidationScript
must iterate over
each spreadsheet returned by the FindArtifacts
query, and
then adds the custom query as an input query for the task.
function processmodel(pm) % Defines the project's processmodel arguments pm padv.ProcessModel end findSpreadsheets = padv.builtin.query.FindArtifacts(IncludePathRegex = "Spreadsheet.*\.xlsx"); validationTask = pm.addTask(RunValidationScript(IterationQuery=findSpreadsheets)); validationTask.addInputQueries(FindValidationFiles); end
The validation task automatically becomes outdated if you make changes to
the validation scripts because you specified the custom query
FindValidationFiles
as an input query for the
task.
See Also
padv.Artifact
| padv.ProcessModel
| padv.Query
| Process
Advisor | runprocess