Since 4D v19, you can start the compilation of a project with a simple command. You might be wondering what you can use this for!
Your team may consist of several developers, so why not automate the compilation at each code push on your source control server? It is always easier to identify an error when it is quickly detected.
Another case is when your project consists of several components. You can write a method that compiles, builds, and then copies the component to the host database.
This blog will discuss the different technical points that are very useful to create your own automation tools, along with an example application.
Launch a 4D application with a command line
You can launch 4D via the command line by specifying the project to open and choosing which options to activate. Here is a reminder of some options that can be very useful to automate an action.
Headless
For the execution of repetitive and automatically triggered tasks, the presence of an interface is unnecessary. If you pass the “–headless” option in the command line, your 4D, 4D Server, or merged application will run without an interface.
For more details, you can read this blog post: Headless 4D applications.
Dataless
The “–dataless” option allows you to ask 4D not to open a data file. For example, loading a data file is unnecessary if you create a script to launch a compilation.
Just to be clear, dataless mode is rarely used. If you open 4D in dataless mode, you can’t open a data file using 4D commands after launching 4D. You’ll find all the details in the documentation.
User param
Automating repetitive tasks does not mean doing exactly the same thing each time. For example, you can trigger a task every hour with options for a quick and easy check, and every night, run another task that takes more time and resources.
The option “–user-param” allows you to pass a string in the command line. Then with the Get database parameter command and the user param value constant, you can get the string passed in the command line.
$result:=Get database parameter(User param value;$userParam)
For more details, you can read this blog post.
Compile a project USING A command
Thanks to the Compile project command, you can launch the compilation of a project by passing its path. The command also accepts an options object that allows you to set up your compilation. For example, you can specify the dependencies of your project, the Intel and Silicon target, etc.
$status:=Compile project($file; $options)
If there is an error, the command returns an object with the list of errors composed of the error message, the name of the method, and the line number. As a reminder, you can use the METHOD OPEN PATH command to open the code editor directly on the line concerned. To discover all the options of this command, We recommend reading this blog post or the documentation.
It’s important to know the possibilities this command offers, and how to use it properly. But the other great news is that you can run it in a project in interpreted mode, with the “–dataless” and “–headless” options, without a development license! So if you use an external server solution to compile your application, for example, using the git action on GitHub, you don’t need to inject your license on the third-party server.
Generate Log file
With automatic tasks, it is essential to have logs to know that the task has been executed, and to recover the errors in case of a problem. But in reality, it is not so simple. The management is different between macOS and Windows. The file architecture on the servers can be different. And the script can be executed on one of your servers or an external server.
The solution that we propose is to use the LOG EVENT command with the Into system standard outputs constant. Then, you can redirect the standard stream and the error stream to one or several files in the command line. So it is straightforward to adapt to your environment without changing the script.
Last but not least, knowing when the script was executed, when the error occurred, can be useful. The Timestamp command is perfect for this; it returns a string of characters that can easily be added to a log file with millisecond precision.
LOG EVENT(Into system standard outputs; Timestamp+" - I am an information"; Error information)
LOG EVENT(Into system standard outputs; Timestamp+" - I am an error"; Error message)
Concrete examples
Voilà! Following all the previous tips, we have created a project available on GitHub to compile a project. We pass a stringified object to “–user-param,” which contains three attributes:
- path: the path of the project to compile (mandatory attribute)
- options: options object passed to the Compile Project command (optional attribute)
- quit: pass false to not close 4D after compilation, useful for tests; by default, 4D closes after execution (optional attribute)
Here are some examples of command lines, don’t forget to adapt the paths.
Launch a syntax check:
- macOS
/.../Contents/MacOS/4D --structure /.../Tool_Compilation.4DProject --user-param "{\"path\":\"/.../myProject.4DProject\",\"options\":{\"targets\":[]}}" --headless --dataless 2>.../errlog.txt 1>.../infolog.txt
- Windows
C:\...DD.exe --structure C:\...\Tool_Compilation.4DProject --user-param "{\"path\":\"/.../myProject.4DProject\",\"options\":{\"targets\":[]}}" --headless --dataless 2>C:\...\errlog.txt 1>C:\...\infolog.txt
Here is the content of our infolog.txt file; the errlog.txt is empty:
2021-08-25T17:38:52.197Z - Start script 2021-08-25T17:38:54.961Z - user-param: {"path":"/.../myProject.4DProject","options":{"targets":[]}} 2021-08-25T17:38:54.964Z - {"success":true,"errors":[]} 2021-08-25T17:38:54.999Z - End script
Compiling with the default settings:
- macOS
/.../Contents/MacOS/4D --structure /.../Tool_Compilation.4DProject --user-param "{\"path\":\"/.../myProject.4DProject\"}" --headless --dataless 2>.../errlog.txt 1>.../infolog.txt
- Windows
C:\...DD.exe --structure C:\...\Tool_Compilation.4DProject --user-param "{\"path\":\"/.../myProject.4DProject\"}" --headless --dataless 2>C:\...\errlog.txt 1>C:\...\infolog.txt
Compiling with options passed to the Compile project command:
- macOS
/.../Contents/MacOS/4D --structure /.../Tool_Compilation.4DProject --user-param "{\"path\":\"/.../myProject.4DProject\",\"options\":{\"targets\":[\"x86_64_generic\"]}}" --headless --dataless 2>.../errlog.txt 1>.../infolog.txt
- Windows
C:\...DD.exe --structure C:\...\Tool_Compilation.4DProject --user-param "{\"path\":\"/.../myProject.4DProject\",\"options\":{\"targets\":[\"x86_64_generic\"]}}" --headless --dataless 2>C:\...\errlog.txt 1>C:\...\infolog.txt
What’s Next?
Now it’s up to you. Don’t hesitate to share on GitHub or on the forum your ideas or solutions to automate tasks.