Go Down

Topic: Arduino IDE compilation with auto-incremental versioning (Read 372 times) previous topic - next topic

BRIOT_Patrick

May 15, 2019, 11:41 pm Last Edit: May 22, 2019, 10:56 am by BRIOT_Patrick
Hello,

This topic explain how i've add automatic incremental versioning directly inside a sketch.
I'm using Arduino IDE 1.8.9 in Windows 10 OS environment, so i use Microsoft VBscript to add this feature.

First, thanks to Vurdalakov for the first step to this idea (https://codeblog.vurdalakov.net/2017/04/autoincrement-build-number-in-arduino-ide.html).


Next, below the explanations how add this feature to Arduino IDE:

1. Locate platform.txt file and add it this line :

recipe.hooks.prebuild.0.pattern=cscript.exe "{runtime.ide.path}/incrementalversion.vbs" "{build.source.path}" "{build.project_name}" "SKETCH_VERSION"

Code: [Select]

# ESP8266 platform
# ------------------------------

# For more info:
# https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5-3rd-party-Hardware-specification

name=ESP8266 Boards (2.5.1)
version=2.5.1

# These will be removed by the packager script when doing a JSON release

recipe.hooks.prebuild.0.pattern=cscript.exe "{runtime.ide.path}/incrementalversion.vbs" "{build.source.path}" "{build.project_name}" "SKETCH_VERSION"

runtime.tools.signing={runtime.platform.path}/tools/signing.py
runtime.tools.elf2bin={runtime.platform.path}/tools/elf2bin.py
...


2. Create the incrementalversion.vbs file in the Arduino IDE folder installation (C:\Program Files (x86)\Arduino):

Code: [Select]
Const ForReading = 1, ForWriting = 2
Dim FSO, FileINO, strText, strs, build, i

Set FSO=CreateObject("Scripting.FileSystemObject")

Set FileINO=FSO.OpenTextFile(WScript.Arguments.Item(0) & "\" & WScript.Arguments.Item(1), ForReading)
strText=FileINO.ReadAll
FileINO.Close

If  InStr(1, strText, "#define ", vbTextCompare) > 0 _
and InStr(1, strText, WScript.Arguments.Item(2), vbTextCompare) > 0 Then
Set FileINO=FSO.OpenTextFile(WScript.Arguments.Item(0) & "\" & WScript.Arguments.Item(1), ForWriting, True)'
strs=Split(replace(strText,vbcrlf,vbcr),vbcr)
For i=Lbound(strs) to Ubound(strs)
If  InStr(1, strs(i), "#define ", vbTextCompare) > 0 _
and InStr(1, strs(i), WScript.Arguments.Item(2), vbTextCompare) > 0 Then
Wscript.Echo "Current: " & strs(i)
build=Split(Split(strs(i),"""")(1),".")(2)
strs(i)=replace(strs(i),"." & build & chr(34), "." & build+1 & chr(34))
Wscript.Echo "Next   : " & strs(i)
End If
FileINO.write strs(i) & vbcrlf
Next
FileINO.Close
End If


3. Now the automatic incremental versioning new feature is ready to be used !

4. To use it you need to add this define in your sketch :
#define SKETCH_VERSION "1.0.0"

Version string must consist of 3 numbers separated by dots, e.g. 1.0.2. You could modify the two first numbers manually as you want. The last number is a build number that is automatically incremented by the VBS script.

Sketch Example :
Code: [Select]

#include <Arduino.h>

#define SKETCH_VERSION "1.0.2"
//                      | | |_______ Build version : Automatic control
//                      | |_________ Minor Version : Human control
//                      |___________ Major Version : Human control

void setup() {
  Serial.print ("Version: " SKETCH_VERSION);
}

void loop() {}



5. Now, each time you will compile your sketch, the current SKETCH_VERSION will appear in your application.
The compilation will increment the build number in your INO file for the next modification.

IMPORTANT : After the compilation, Arduino IDE couldn't automatically reload the sketch modified in background by this script, so you must first click in menu Tools the command Fix Encoding & Reload and now you could see the next SKETCH_VERSION updated for the next modification of your sketch.



That's all ! I hope this feature could help others.
Patrick

pert

Thanks so much for sharing this information! This sort of thing has been discussed several times here on the Forum over the years, but this is the first time I can remember seeing a fully documented solution presented.

I have a couple of suggestions:

Code: [Select]
#define SKETCH_VERSION "1.0.2"
//                      | | |_______ Build version : Automatic control
//                      | |_________ Minor Version : Human control
//                      |___________ Major Version : Human control

I recommend following the semver specification in your versioning:
https://semver.org/
Quote
Build metadata MAY be denoted by appending a plus sign and a series of dot separated identifiers immediately following the patch or pre-release version. Identifiers MUST comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-]. Identifiers MUST NOT be empty. Build metadata SHOULD be ignored when determining version precedence. Thus two versions that differ only in the build metadata, have the same precedence. Examples: 1.0.0-alpha+001, 1.0.0+20130313144700, 1.0.0-beta+exp.sha.5114f85.
So it would look like this:
Code: [Select]

#define SKETCH_VERSION "1.0.2+1"
//                      | | | |______Build version : Automatic control
//                      | | |_______ Patch version : Human control
//                      | |_________ Minor Version : Human control
//                      |___________ Major Version : Human control




5. Now, each time you will compile your sketch, the current SKETCH_VERSION will appear in your application.
The compilation will increment the build number in your INO file for the next modification.
In order for this to work, the sketch must be saved before each compilation. There is a preference option (File > Preferences > Save when verifying or uploading), that is on by default, but I normally find that behavior annoying and so always have it off. For this reason, it would be a good idea to mention that the sketch must be saved (either automatically or manually) before compiling/uploading.



After the compilation, Arduino IDE couldn't automatically reload the sketch modified in background by this script, so you must first click in menu Tools the command Fix Encoding & Reload and now you could see the next SKETCH_VERSION updated for the next modification of your sketch.
There is a feature that will make this step no longer necessary in the works:
https://github.com/arduino/Arduino/pull/6074
That feature is already available in the Arduino IDE Beta Build:
https://www.arduino.cc/en/Main/Software#beta

BRIOT_Patrick

#2
Jun 22, 2019, 09:43 am Last Edit: Jun 23, 2019, 06:26 am by BRIOT_Patrick
Hello all,

A new version solving unwanted new blank line at the end of INO file and write file only if revision discovered in existing INO file.

WARNING : You can use this code only after removing the space on "c hr(34)" word (2 times). If i want to publish my code as is, it is considered as a virus and blocked by arduino forum, i don't know why. That's why i've done this workaround to publish it.

Code: [Select]
Const ForReading = 1, ForWriting = 2
Dim FSO, FileINO, strText, strs, build, rev, i

Set FSO=CreateObject("Scripting.FileSystemObject")

Set FileINO=FSO.OpenTextFile(WScript.Arguments.Item(0) & "\" & WScript.Arguments.Item(1), ForReading)
strText=FileINO.ReadAll
FileINO.Close

rev=False
strs=Split(replace(strText,vbcrlf,vbcr),vbcr)
For i=Lbound(strs) to Ubound(strs)-2
If  InStr(1, strs(i), "#define ", vbTextCompare) > 0 _
and InStr(1, strs(i), WScript.Arguments.Item(2), vbTextCompare) > 0 Then
Wscript.Echo "Current: " & strs(i)
build=Split(Split(strs(i),"""")(1),".")(2)
strs(i)=replace(strs(i),"." & build & c hr(34), "." & build+1 & c hr(34))
Wscript.Echo "Next   : " & strs(i)
rev = True
End If
Next

If (rev) Then
Set FileINO=FSO.OpenTextFile(WScript.Arguments.Item(0) & "\" & WScript.Arguments.Item(1), ForWriting, True)
FileINO.write Join(strs,vbcr)
FileINO.Close
End If


Best regards.
Patrick

Go Up