Monday, August 20, 2018

Running unix command in Makefile for parsing text and passing it to link line as define -D

$ cat $HOME/version.txt

version=1.2.3.4


$ cat hello.c

#include 

int main()
{
   printf("Software Version = [%s]\n",VERSION);
   return 0;
}

$ cat hello.mk

FILE=$(HOME)/version.txt

VERSION:=`cat $(FILE) | cut -d = -f2 | sed -e 's-^-\\\"-g' -e 's-$-\\\"-g'`

compile :
        gcc -o hello hello.c -DVERSION=$(VERSION)

$ cat test.sh
FILE=$HOME/version.txt
# Append with \" at the beginning and end of the string for the compiler
cat $FILE | cut -d = -f2 | sed -e 's-^-\\\"-g' -e 's-$-\\\"-g'

OUTPUT of test.sh :
\"1.2.3.4\"

Problem :

I am trying to write a makefile (hello.mk) which reads a static file ($HOME/version.txt) which stores version of the software being developed in the form version=x.x.x.x. Makefile reads the file and extracts the version value and passes to the compile line through -D flag. In the 'C' code (hello.c), printing the VERSION detail. The idea is to just maintain the version file for various builds and the build will have the appropriate version number in various logs etc.,

I wrote a simple script test.sh to test the cut | sed option and it works fine from the command line. When I have them in the makefile as a MACRO, I get syntax error for the last $ sed option. Also, when I use some other hacks to get the values from the file, the compile line -DVERSION=$(VERSION) seem to expand to the macro VERSION commands rather than the actual VERSION value.

To test, in the makefile, if I replace VERSION to hardcode value like \"1.2.3.4\, then the compile goes through with desired effect.

The current format of the version file cannot be changed (legacy code and is used by many other tools).

Appreciate if you could help me to resolve this issue or any better way to parse the file.

Solved

You need to quote $ as $$ in make shell scripts. I've also trimmed down your pipeline to just use awk.

hello.mk

...
VERSION := $(shell awk '/^version=/ { split($$0, a, /=/); print a[2];}' $(FILE))
compile :
        gcc -o hello hello.c -DVERSION='"$(VERSION)"'

You need to escape the $ in sed via $$; Additionally, i've used $(shell ...)

mnunberg@csure:/tmp$ make -f hello.mk 
cc -o hello hello.c -DVERSION=\"1.2.3.4\"
mnunberg@csure:/tmp$ ./hello 
Hello. Version is 1.2.3.4
mnunberg@csure:/tmp$ cat hello.mk 
FILE=version.txt

VERSION:=$(shell cat $(FILE) | cut -d = -f2 | sed -e 's-^-\\\"-g' -e 's-$$-\\\"-g')

compile :
    cc -o hello hello.c -DVERSION=$(VERSION)

Learnt a lot from both your replies. Was not aware of the '"$(VERSION)"' in the compile line. That eliminated the need to append " while parsing. Also, the shell command was cool. Not sure why it is different from when I did a backquotes (‘`’).

Thanks much again.

Did the following for now.

hello.mk ::

VERSION:=$(shell sed -e 's-^version=--g' $(FILE))
....
compile :
        gcc -o hello hello.c -DVERSION='"$(VERSION)"'
.....

Sunday, August 19, 2018

Generating UML diagram from C# code

Is there a tool or something that generates UML diagrams from C# code? I'm using Visual Studio 2015(Community) and I know that there is a 'View Class Diagram' option but it doesn't show the relationship between classes.

Solved

You could with previous version of Visual Studio. In Visual Studio 2015 this features has been removed and no more available even in the Enterprise Edition. You still can generate code from diagram but not the opposite. You will not find much for free (you can try NCLASS) if you want to invest money and you have the budget to do there are many good reverse engineering tools: Visual Paradigm Altova...but probably if your only looking for a tool for generating a class diagram from code they offer you much more than you really need.


Saturday, August 18, 2018

Is there a way to coax Entity Framework into finding a foreign key during an insert?

I often have a situation where I have an aggregate with a reference to some other entity using a domain specific ID. When I then save the aggregate via the repository using Entity Framework, I need to get the database id of the referenced entity instead of the domain id.

For example, say I have these classes in my domain (notice the lack of any database ID):

MyDomainEntity

  • MyDomainEntityID
  • SomeProperty
  • IsoLanguageCode (Foreign Domain Identifier)

Language

  • IsoLanguageCode (Domain Identifier)
  • Name

In Entity Framework Code First, my entity classes to persist my domain would look something like this:

MyDomainEntity

  • DbId (Primary Key)
  • MyDomainID
  • SomeProperty
  • LanguageId (Database Foreign Key)

LanguageEntity

  • DbId
  • IsoLanguageCode
  • Name

In order to save an instance of MyDomainEntity, I need to make an extra call to the database to retrieve the database id of the language. This results in two calls to the database. If I was working with pure SQL, I could construct an insert statement to set the LanguageId based on a IsoLanguageCode value, completing the insert in one statement.

My question is, is it possible to coax Entity Framework to discover and assign the foreign key database id in one call? Or do I always have to retrieve the LanguageEntity first, in order to construct MyDomainEntity.

Solved

Entity framework can only do this if you also expose the foreign keys, your database generated values.