Source Configuration Architecture

From OpenPetra Wiki
Revision as of 14:02, 20 July 2016 by Moray (talk | contribs) (Created page with "OpenPetra is a very large and complex project. Several parts of it are automatically generated by other parts. The easiest way to understand how it all fits together is to tak...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

OpenPetra is a very large and complex project. Several parts of it are automatically generated by other parts. The easiest way to understand how it all fits together is to take a bird's-eye view of the build process. In real life, this is handled automatically by clicking "Generate Solution" in the OpenPetra Developers' Assistant, or by typing "nant generateSolution" at the command prompt in a newly checked-out working directory.

OpenPetra uses NAnt as its build tool. NAnt uses buildfiles containing lists of Targets and the instructions to build those Targets. The default buildfile is the first *.build file in the current directory; in our case that would be OpenPetra.build at the top of the working directory tree. We have defined many NAnt Tasks for OpenPetra, some of which are listed on this page.

By opening up what happens during Generate Solution, we can see what all the generated code is, where it comes from, and how to control it.

Detailed reference, with some more "How-To's": Build system with our own NAnt tools and tasks


The Version Number

The first thing to do is pull the Bazaar version info for the current branch into delivery\bin\vcs-revision.txt. Now it can be included in the source code and displayed in the application.

nant pullVCSVersionInfo

The Namespace Map

At various stages in the build processes, the namespace maps delivery\projects\namespace.map must be generated. This is already written into the NAnt build tasks and will happen as needed. Namespace maps are used internally by the development enviromnent and compiler to map the projects in OpenPetra to the C# namespaces.

This is how, for example, the Ict.Petra.Server.lib.MCommon project uses the Ict.Petra.Server.MCommon namespace.

The Project Files

The project files – delivery\projects\*\*.csproj and *.sln – define the different Projects within the overall Solution for the different development environments and the msbuild compiler. Like the namespace map, this is written as a dependency within NAnt to ensure it happens as needed.

If you add new files to a project (or updating your branch pulls in new files) then Visual Studio won't be able to build the project properly until the project file is updated too.

nant generateProjectFiles

The Tools

The next thing to do is build the tools that are used in the remainder of the build process. This includes the following files:

delivery\bin\Ict.Tools.CodeGeneration.dll
delivery\bin\Ict.Tools.GenerateWinForms.exe
delivery\bin\Ict.Tools.GenerateSQL.exe
delivery\bin\Ict.Tools.GenerateORM.exe
delivery\bin\Ict.Tools.GenerateGlue.exe

as well as come Common code needed by the tools.

nant generateTools

The Forms

OpenPetra's forms and user controls are defined in .yaml files. This step parses petra.xml and the form & control .yaml files to build them into the C# *-generated.Designer.cs and *-generated.cs files required by the compiler.

A form's -generated.cs code is supplemented by a .ManualCode.cs file to handle specific processing. If you add a new method to a form's .ManualCode.cs file, it won't be called unless you regenerate the form (see Documentation YAML for OpenPetra Forms#ManualCode)! In certain cases one also needs to add the appropriate section to the form's .yaml file and regenerate the form. For example, to add verification code to a report, you add a ReadControlsVerify() method. But you also need to add the corresponding READCONTROLSLOCALVARS to the TemplateParameters section of the .yaml and regerate the form, or the call won't be included in the main generated code.

nant generateWinforms

The Object-Relational Model

The Object-Relational Model (ORM) is the Data Access Layer for accessing the DB data in a typesafe way by creating typed data tables, typed datasets and typed access classes that provide convenient access to them. There are 4 parts to the process:

generateORMCachedTables
Generates the cached tables.
Parses csharp\ICT\Petra\Shared\lib\data\*.TypedDataSets.xml to produce *Cacheable-generated.cs
Details: Documentation Cacheable Tables
generateORMData
Generates the files for Ict.Petra.Shared.lib.data, ie. the typed tables and typed datasets.
Parses typed table namespaces, validation and datasets to produce *Tables-generated.cs, *Validation-generated.cs, *DataSets-generated.cs
generateORMAccess
Generates the files for Ict.Petra.Server.lib.data, ie. the access files for reading from and writing to the database.
Parses typed table namespaces and datasets to produce *Access-generated.cs and Cascading-generated.cs
generateORMReferenceCounts
Generates the server web connector classes that perform table reference counting.
Parses *.yaml files and produces csharp\ICT\Petra\Server\lib\*\web\ReferenceCount-generated.cs

nant generateORM

The Glue

The "glue" is the set of interfaces and instantiators between the client and server. This parses .cs files for namespaces and produces Shared\lib\Interfaces\*Interfaces-generated.cs, Server\lib\*\connect\Instantiator.AutoHierarchy-generated.cs, and Server\lib\*\connect\Instantiator.Connectors-generated.cs.

nant generateGlue

The 3rd-Party DLLs

OpenPetra uses a number of 3rd-party DLLs. The vast majority of these are freely distributable and automatically included as part of the application; others can only be distributed under licence. This step is used where permitted to copy the licensed FastReport DLLs from the location specified by the FASTREPORT_DLL_PATH environment variable to delivery\bin.

nant copyFrDlls

The SOLUTION!

Now all the generated project files, forms, datasets, tables, access code, interfaces, instantiators etc. are in place, we can use msbuild to compile the entire application from the generated OpenPetra.sln solution file (NAnt drives msbuild for us, no need to know about it in detail!).

If anything changes that the generated code or manually written code depends upon, remember to regenerate the appropriate code before recompiling (with nant quickCompile) with either the single steps lined out above, or by using

nant generateSolution: this will execute all build steps lined up on this page in correct order and hence will ensure that all generated code and manually written code will be tied together. It is also a requirement to run this NAnt Task before a Branch gets committed to 'trunk' to ensure that the whole process runs through without any hiccups!

Developer's Assistant

Your reward for a successful build is the OpenPetra Developers' Assistant, which is built along with everything else. It provides an extremely helpful front-end and guide to NAnt and Bazaar so that you don't have to remember all these commands, and it manages all your database configurations. Find it in delivery\bin\Ict.Tools.DevelopersAssistant.exe and copy it to your desktop or somewhere. It maintains its settings in your AppData\Local folder, and updates itself automatically if it detects a newer copy of itself in your current branch.