Automate AssemblyFileVersion Incrementation using GIT - vb.net

Ok I understand that this is probably not conventional, but that aside: I am using the AssemblyFileVersion as kind of my "Build Name" string. It is formated like this:
' File Version information for an assembly consists of the following four values:
'
' Year
' Month
' Day
' Commit Number for that day
'
' Build Name can either be alpha | beta | hotfix | release
' alpha - is a development buildname with rapid changing API
' beta - is a production build for our beta users
' hotfix - is a production version with a bug fix
' release - is a standard issue production version.
<Assembly: AssemblyVersion("0.8.3")>
<Assembly: AssemblyFileVersion("13.10.24.3")>
<Assembly: AssemblyBuildName("alpha")>
Unfourtunately I am having to adjust the AssemblyInfo.vb EVERY TIME I do a git commit. Now I know GIT actually stores the commits in like a log file several places in the .git directory. My question is: is there anyway to automate this file to read from the git files to see what the year/month/day/commit#ForThatDay and automatically adjust the AssemblyFileVersion (or even a custom Assembly Attribute)?

I would use git describe in order to get an id representing the tag/SHA1 of the current commit, and integrate it in your Assembly file.
v1.0-2-g2414721-DEV
^ ^ ^ ^
| | | \-- if a dirtyMarker was given, it will appear here if the repository is in "dirty" state
| | \---------- the "g" prefixed commit id. The prefix is compatible with what git-describe would return - weird, but true.
| \------------- the number of commits away from the found tag. So "2414721" is 2 commits ahead of "v1.0", in this example.
\----------------- the "nearest" tag, to the mentioned commit.
It is similar to "Automatically versioning Android project from git describe with Android Studio/Gradle", but to be adapted to vb.net.
Or you can have "fake revision number".
For a more complete build Assembly file generation, see that maven plugin "maven-git-commit-id-plugin" (again, to be adapted to a vb.net build).
It can generate a file as complete as:
{
"branch" : "testing-maven-git-plugin",
"describe" : "v2.1.0-2-g2346463",
"commitTime" : "06.01.1970 # 16:16:26 CET",
"commitId" : "787e39f61f99110e74deed68ab9093088d64b969",
"commitIdAbbrev" : "787e39f",
"commitUserName" : "Konrad Malawski",
"commitUserEmail" : "konrad.malawski#java.pl",
"commitMessageFull" : "releasing my fun plugin :-)
+ fixed some typos
+ cleaned up directory structure
+ added license etc",
"commitMessageShort" : "releasing my fun plugin :-)",
"buildTime" : "06.01.1970 # 16:17:53 CET",
"buildUserName" : "Konrad Malawski",
"buildUserEmail" : "konrad.malawski#java.pl"
}
That illustrates how you can ask the git repo for all kind of different information (not just the date, but the branch, committer, commit message, ...).
See the DescribeCommand.java for more details on the implementation.

Related

CMake add_custom_target() to format source code induces clock skew

The real problem
I want to apply project level source code formatting to all modified files
Current approach
Use add_custom_target in my top-level CMakeLists.txt file to call a script that applies formatting rules to all files the SCM tool reports as modified:
add_custom_target(Name ALL ${PROJECT_SOURCE_DIR}/../cmake/format_files.bash
)
This rule is before any add_subdirectory calls, because reformatting should take place before all compilation.
Per the documentation:
ALL
Indicate that this target should be added to the default build target so that it will be run every time (the command cannot be called ALL).
When CMake itself runs (like any modification to the CMakeLists.txt files), all is good.
The Symptom
Suppose I perform some spacing-related modification to file Foo.hh (my rules replace tabs with spaces, for example). My build is likely to include something like this:
Scanning dependencies of target Foo
make[2]: Warning: File `projects/foo/src/Foo.hh' has modification time 8.7 s in the future
...
make[2]: warning: Clock skew detected. Your build may be incomplete.
I'm pretty sure it's the source formatting script that somehow runs after dependency scanning (or something like that), modifies Foo.hh, and creates the illusion of clock skew.
What I think the question is
What is the right way to force my build process to assert project standards for source code style prior to building, without potentially creating dependency problems?
Is there a better way to introduce formatting to the build process?
Red Herrings
At first, I thought I was dealing with a true clock skew problem; my development environment is on a VMware VM, and we have had some issues with time in the past, but now I'm 99% sure that all the VMs are using host time. Furthermore, a simple test like this (in the same filesystem as my builds) proves there is no intrinsic clock skew:
$ date ; touch foo ; ls --time-style=+%H:%M:%S -l foo ; date
Thu Jan 17 12:48:59 MST 2019
-rw-rw-r--. 1 1001 1001 0 12:48:59 foo
Thu Jan 17 12:48:59 MST 2019
A key facet of the source code formatting process is that there is no deterministic way to know which files might be modified in the script and which will not. Files that comply with project standards are not touched.
For completeness, here is the script:
#!/bin/bash
# This script is intended to format any modified files to project standards
# Change to the project root
cd $(dirname $0)/..
outfile=format.log
file_list=$( git status --short --untracked-files=all src \
| awk '/^( M|\?\?) .*\.(cpp|hh)/ {print $2}' )
# If we haven't changed any files, exit gracefully
[[ -z $file_list ]] && exit 0
# Format the current working set
echo >> ${outfile}
date '+%Y-%m-%dT%H:%M:%S.%N: ' >> ${outfile}
astyle --project $file_list >>${outfile} 2>&1
This script appends to an output file (I'll probably remove that at some point) that looks like this:
2019-01-17T18:54:20.641765133:
Unchanged src/Foo.cpp
Formatted src/Foo.hh
Unchanged src/Bar.cpp
Based on the discussion at https://discourse.cmake.org/t/cmake-pre-build-command/1083, the answer is "don't do that". Formatting can be a target and building can be a target, but having a build step that modifies the dependencies of another build step (after the dependency tree has been evaluated) is bad.
Instead of formatting my code as part of the build, I added it as a CI check on the build server: if formatting would change the code, the build fails. I also created a pre-commit hook to tell me if my code needs formatting. I don't like hooks that change the code checked in; changed code should always be compiled before commit.

Auto-increment version revision number with wildcard

I'm trying to raise the revision number with each build.
I've therefore tried to the project assembly information -> Assembly Version and File Version to
1 0 0 *
1 0 0 *
However, VS2017 tells me
"Assembly file version: In this field, wildcards ("*") aren't allowed.
How can I do this?
You should remove the AssemblyFileVersion attribute and just keep the AssemblyVersion. If AssemblyFileVersion is not present in the Assembly Information, the file version will automatically be set to the same as the AssemblyVersion at compile time.
Quoting the documentation:
If the AssemblyFileVersionAttribute is not supplied, the AssemblyVersionAttribute is used for the Win32 file versionthat is displayed on the Version tab of the Windows file properties dialog.
I found this:
https://marketplace.visualstudio.com/items?itemName=PrecisionInfinity.AutomaticVersions
It's hilarious that VS doesn't have this built-in.
I know this is a very old question, however it appears when googling "auto increment version visual studio".
Since the current answer doesn't really answer the question, this is what I did:
Assembly Version looks like 1 1 1 *
File Version like 1 1 1 0.
You cannot use wildcards (*) on the file version. If you use them on Assembly leave empty spaces after the wildcard (1 1 * EMPTY).
That works and the error
"Assembly file version: In this field, wildcards ("*") aren't
allowed."
does not appear.
If that still gives you trouble, you could remove the "deterministic" flag editing the .csproj
Yet another option is: https://neele.name/item/versioning-controlled-build
This one works with Visual Studio 2017.
I found it to be easy to use and has the advantage that you can choose to invoke it or not depending on if you are creating a test build or a release build.
Ensure the Projects "Deterministic" property is set to false by editing the .vbproj file:
<PropertyGroup>
<Deterministic>false</Deterministic>
</PropertyGroup>
Then open the AssemblyInfo.vb file and set the assembly version property like this: <Assembly: AssemblyVersion("1.0.*")>
Remove or comment-out the <Assembly: AssemblyFileVersion(...)> attribute since that cannot use wildcards, and if it isn't present, the file will inherit the version assembly number.
Setting the version number to 1.0.*, as in the above example, results in a version number similar to 1.0.8888.99999 where the build is equal to the number of days since January 1, 2000 local time, and the revision is equal to the number of seconds since midnight local time (without taking into account time zone adjustments for daylight saving time), divided by 2.
See the Docs site for details.

change cpack generated name for component RPMs

I am trying to create an RPM installer using cpack (via cmake) that creates multiple RPM files. I've almost got it working but the last remaining stumbling block is controlling the package names.
Specifically I want to control where the component name appears in the RPM file name.
Here is my experimental CMakeLists.txt file which installs foo.txt and bar.txt to two different packages "myproject-foo" & "myproject-bar".
I want the RPMs to follow my own naming conventions (actually I want conventions that are more FSH friendly) but for some reason cmake insists on adding the component name at the end. So I get:
myproject-comp-1.0.i686-foo.rpm
myproject-comp-1.0.i686-bar.rpm
rather than:
myproject-compfoo-1.0.i686.rpm
myproject-compbar-1.0.i686.rpm
I notice it names the source RPMs "more correctly":
E.g.
>rpm -qip <package> | grep source
Source RPM : myproject-foo-1.0-1.src.rpm
Though I do not actually want a source RPM at all (is there a way to blank this field?)
cmake_minimum_required(VERSION 2.8)
message("CMAKE_VERSION=${CMAKE_VERSION}")
SET(DOCDIR "doc")
set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME "core")
install(FILES foo.txt COMPONENT foo DESTINATION "${RPMBUILDROOT}${DOCDIR}")
install(FILES bar.txt COMPONENT bar DESTINATION "${RPMBUILDROOT}${DOCDIR}")
project(myproject CXX)
set(CPACK_PACKAGE_NAME "myproject")
set(CPACK_RPM_COMPONENT_INSTALL ON)
set(CPACK_PACKAGE_VERSION 1.0)
set(CPACK_PACKAGE_VENDOR "some org")
set(CPACK_COMPONENT_foo_DESCRIPTION "the foo component")
set(CPACK_COMPONENT_bar_DESCRIPTION "the bar component")
# mentioned in cpack docs but doesn't seem to do anything here
set(CPACK_COMPONENT_foo_DISPLAY_NAME "foo display name?")
set(CPACK_COMPONENT_bar_DISPLAY_NAME "foo display name?")
set(CPACK_COMPONENT_bar_DEPENDS foo)
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "describe the complete suite of stuff")
set(CPACK_PACKAGE_DESCRIPTION_FILE ${CMAKE_SOURCE_DIR}/README.txt)
# added in cmake 3.6?
set(CPACK_RPM_foo_PACKAGE_SUMMARY "describe the foo package")
set(CPACK_RPM_bar_PACKAGE_SUMMARY "describe the bar package")
set(CPACK_RPM_foo_PACKAGE_NAME "${CPACK_PACKAGE_NAME}-foo")
set(CPACK_RPM_bar_PACKAGE_NAME "${CPACK_PACKAGE_NAME}-bar")
set(CPACK_PACKAGE_DESCRIPTION_FILE ${CMAKE_SOURCE_DIR}/README.txt)
#set(CPACK_RPM_foo_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-foo-${CPACK_PACKAGE_VERSION}.i686")
#set(CPACK_RPM_bar_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-bar-${CPACK_PACKAGE_VERSION}.i686")
set(CPACK_PACKAGING_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX})
set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-comp${CPACK_COMPONENT_DISPLAY_NAME}-${CPACK_PACKAGE_VERSION}.i686")
set(CPACK_RPM_PACKAGE_ARCHITECTURE "i686")
set(CPACK_RPM_PACKAGE_RELOCATABLE TRUE)
include(CPack)
cpack_add_component(foo
DISPLAY_NAME foo comp
DESCRIPTION this is the foocomp)
cpack_add_component(bar
DISPLAY_NAME bar comp
DESCRIPTION this is the bar comp
DEPENDS foo)
It seems like CPACK_PACKAGE_<component>_FILE_NAME or CPACK_PACKAGE_FILE_NAME is not quite working.
I've tried with both cmake 3.4.3 and the latest (3.9.0 at the time of writing) as there is some suggestion of fixes to component based installs in 3.6.0
There is no such variable as the CPACK_COMPONENT_DISPLAY_NAME I've used in CPACK_PACKAGE_FILE_NAME. Also something in cmake adds the component name to the end automatically.
There is a similar question for .deb packages from long ago here but I would rather avoid such a complex solution if possible.
It would be easier to rename the packages after generation (but still feel hacky).
I also note that the package dependency set(CPACK_COMPONENT_bar_DEPENDS foo) is not recorded in the bar package.
Update: 01-Aug-2017
I've added a bug report for cmake here as to my mind there is a bug in the implementation of CPACK_RPM_<component>_PACKAGE_FILE_NAME. At the very least the documentation is insufficiently helpful.
First of there is a large note at the top of the documentation:
Note
part of variables is preferred to be in upper case (for e.g. if component is named foo then use CPACK_RPM_FOO_XXXX variable name format) as is with other CPACK__XXXX variables. For the purposes of back compatibility (CMake/CPack version 3.5 and lower) support for same cased component (e.g. fOo would be used as CPACK_RPM_fOo_XXXX) is still supported for variables defined in older versions of CMake/CPack but is not guaranteed for variables that will be added in the future. For the sake of back compatibility same cased component variables also override upper cased versions where both are present.
So if you have a component named foo, FOO, fOo... the variables are CPACK_RPM_FOO_... otherwise the variables will be ignored - Note that this is the case since the beginning of CPack's existance for the common component variables e.g. CPACK_COMPONENT_foo_DESCRIPTION <- foo part must be in upper case.
Next to the file names - before CPack 3.6 it was not possible to change file names without getting an error and having to copy the generated package manually. Since that version you can set the file name as you like or request the platform specific package name (defined by rpm installation) by setting CPACK_RPM_FILE_NAME or CPACK_RPM_<component>_FILE_NAME to RPM-DEFAULT. See https://cmake.org/cmake/help/v3.6/module/CPackRPM.html?highlight=cpack_rpm_file_name#variable:CPACK_RPM_FILE_NAME
Also set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-comp${CPACK_COMPONENT_DISPLAY_NAME}-${CPACK_PACKAGE_VERSION}.i686") won't work as ${CPACK_COMPONENT_DISPLAY_NAME} is not an anchor and is automatically replaced on that location - not set by you so replacement text is an empty string... So if you really want to set the name manually you should set the RPM packager equivalent of that variable CPACK_RPM_<component>_FILE_NAME for each and every component (so you'll need a for loop or some more copy pasting...) - note that as described in the documentation the file name must end with .rpm and the default is (copied from the documentation) <CPACK_PACKAGE_FILE_NAME>[-<component>].rpm so this is the explanation why component part is always placed at the end.
There are quite a few tests for different CPack packagers here: https://github.com/Kitware/CMake/tree/master/Tests/RunCMake/CPack/tests
So you can explore those snippets as well.
P.S. contributions to the documentation are always welcome :)

IntelliJ: Dynamically updated file header

By default, IntelliJ Idea will insert (something like) the following as the header of a new source file:
/**
* Created by JohnDoe on 2016-04-27.
*/
The corresponding template is:
/**
* Created by ${USER} on ${DATE}.
*/
Is it possible to update this template so that it inserts the last date of modification when the file is changed? For example:
/**
* Created by JohnDoe on 2016-03-27.
* Last modified by JaneDoe on 2016-04-27
*/
It is not supported out of the box. I suggest you do not include information about author and last edit/create time in file at all.
The reason is that your version control system (Git, SVN) contains the same information automatically. So the manual labelling is just duplicate of already existing info, but is only more error prone and needs to be manually updated.
Here's a working solution similar to what I'm using. Tested on mac os.
Create a bash script which will replace first occurrence of Last modified by JaneDoe on $DATE only if the exact value is not contained in the file:
#!/bin/bash
FILE=src/java/test/Test.java
DATE=`date '+%Y-%m-%d'`
PREFIX="Last modified by JaneDoe on "
STRING="$PREFIX.*$"
SUBSTITUTE="$PREFIX$DATE"
if ! grep -q "$SUBSTITUTE" "$FILE"; then
sed -i '' "1,/$(echo "$STRING")/ s/$(echo "$STRING")/$(echo "$SUBSTITUTE")/" $FILE
fi
Install File Watchers plugin.
Create a file watcher with appropriate scope (it may be this single file or any other scope, so that any change in project's source code will update modified date or version etc.) and put a path to your bash script into Program field.
Now every time the file changes the date will update. If you want to update date for each file separately, an argument $FilePath$ should be passed to the script.
This might have been just a comment to #oleg-mikhailov excellent idea, but the code snippet won't fit. Basically, I just tweaked his solution.
I needed a slightly different syntax but that's not the issue. The issue was that when the script ran automatically upon file save using the File Watchers plugin, if ran on a file which doesn't include PREFIX it would run over and over for ever.
I presume the that the issue is with the plugin itself, as it didn't happen when run from the shell, but I'm not sure why it happened.
Anyway, I ended up running the following script (as I said only a slight change with respect to the original). The new script also raises an error if the the prefix doesn't exist. For me this is a feature as Pycharm prompts me with the error, and I can fix the file.
Tested with PyCharm 2021.2.3 on macOS 11.6.
#!/bin/bash
FILE=$1
DATE=`date '+%Y-%m-%d'`
PREFIX="last_modified_date: "
STRING="$PREFIX.*$"
SUBSTITUTE="$PREFIX$DATE"
if ! grep -q "$SUBSTITUTE" "$FILE"; then
if grep -q "$PREFIX" "$FILE"; then
sed -i '' "s/$(echo "$STRING")/$(echo "$SUBSTITUTE")/" $FILE
else
echo "Error!"
echo "'$PREFIX' doesn't appear in $FILE"
exit 1
fi
fi
PHPStorm has not a "hook" for launching task after detect a change in file (just for uploading in server yes). Code templating is based on the creation of file not change.
The behaviour you want (automatic change file after manual change file) can be useful for lot of things but it's circular headhache for editor. Because if you change a file it must change file (and if a file is change ? it change file ?).
However, You can, perhaps, "enable Live Templates" when you launch a "reformat code" which able to rewrite your begin template code that way rewrite date modification.
Other solution is that use a tools with as grunt but I don't know if manage php file.

How to get local bzr commits to server?

lanchpad.net states that for project Emle - Electronic Mathematics Laboratory Equipment, the current focus of development is the 2.0 series
This is what I have done so far:
Set the launchpad.net project to import from the sourceforge.net project Emle (this actually set the launchpad.net project to mirror the sourceforge.net project rather than just inport the content once)
Examined the launchpad.net project to see that the three commits (#1 - #3) which were done in the sourceorge.net project previousley made it into launchpad.net.
Used bzr to get the launchpad.net project which I did while it was still set for mirroring.
Made three changes and commits using bzr (#4 - #6).
Was unable to see the changes on the launchpad.net site.
Requested the mirroring to be stopped (it did).
Here is an extract from lanchpad.net for project Emle 2.0 series showing that launchpad.net has #1 - #3:
Code for this series
The following branch has been registered as the mainline branch for this release series:
lp:emle - C.W.Holeman II
3 revisions, 3 in the past month.
This shows that #4 - #6 have some kind of problem:
$ bzr missing
Using saved parent location: bzr+ssh://bazaar.launchpad.net/~cwhii/emle/2.0/
You have 3 extra revision(s):
------------------------------------------------------------
revno: 6
committer: C.W.Holeman II <cwhii_hcnual#julianlocals.com>
branch nick: lp.emle
timestamp: Sat 2010-02-27 09:13:29 -0800
message:
#528096 Corrected setting of paramter value for emleDir to the dir
attribute value of the message element in the lanuage message file,
lang/emle_lang_XX.xml. Minor refactor - Consistently setting the dir and lang
attributes of html, head and body elements.
------------------------------------------------------------
revno: 5
committer: C.W.Holeman II <cwhii_hcnual#julianlocals.com>
branch nick: lp.emle
timestamp: Sat 2010-02-27 09:08:09 -0800
message:
Minor refactor - improved comment regarding workaround for replacing
html vs head and body elements from index html with lab transformed
XML (to html) document tree.
------------------------------------------------------------
revno: 4
committer: C.W.Holeman II <cwhii_hcnual#julianlocals.com>
branch nick: lp.emle
timestamp: Sat 2010-02-27 09:04:29 -0800
message:
#529089 #529087 Index file html tag lang attribute corrected and empty link tag changed
How do I get the changes that are in bzr on my system to apply to launchpad.net?
More info:
$ bzr check
Checking working tree at '/home/cwhii/work/lp.emle'.
Checking branch at 'file:///home/cwhii/work/lp.emle/'.
Checking repository at 'file:///home/cwhii/work/lp.emle/'.
checked repository <bzrlib.transport.local.LocalTransport url=file:///home/cwhii/work/lp.emle/> format <RepositoryFormat2a>
6 revisions
83 file-ids
checked branch file:///home/cwhii/work/lp.emle/ format Branch format 7
$ bzr merge
Merging from remembered parent location bzr+ssh://bazaar.launchpad.net/~cwhii/emle/2.0/
Nothing to do.
It turnes out that lp:~cwhii/emle/2.0 is an auto-import branch from svn. You're not allowed to write to import branches, even if you own them, because that would cause confusion when the auto-import robot tries to keep writing to them.
So what I suggest you do here is
1- go to http://launchpad.net/people/+newteam and make an emle-dev team, so that you can later let other people write to this project if you want
2- go to http://code.launchpad.net/~cwhii/emle/2.0/+edit and change the name field to "2.0-import" to "get it out of the way"
3- on your pc, in the branch directory, type "bzr push --remember lp:~emle-dev/emle/2.0"
4- on http://launchpad.net/emle/2.0/+linkbranch enter ~emle-dev/emle/2.0 to indicate this is now the focus of development
hope that helps.
(sorry they're not real links, I don't have enough karma here.)
The poor message here is https://launchpad.net/bugs/543797/