----------------------------------------------------------------------- -- are-installer -- Resource selector, preparer and installer -- Copyright (C) 2012, 2017, 2021 Stephane Carrez -- Written by Stephane Carrez (Stephane.Carrez@gmail.com) -- -- Licensed under the Apache License, Version 2.0 (the "License"); -- you may not use this file except in compliance with the License. -- You may obtain a copy of the License at -- -- http://www.apache.org/licenses/LICENSE-2.0 -- -- Unless required by applicable law or agreed to in writing, software -- distributed under the License is distributed on an "AS IS" BASIS, -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- See the License for the specific language governing permissions and -- limitations under the License. ----------------------------------------------------------------------- with Ada.Finalization; private with Ada.Strings.Unbounded; private with Ada.Containers.Vectors; private with Ada.Containers.Indefinite_Vectors; private with Ada.Containers.Indefinite_Ordered_Maps; private with GNAT.Regpat; private with DOM.Core; private with Util.Log; -- = Rules = -- The `Advanced Resource Embedder` provides several mechanisms to integrate -- files in the generated code. -- -- An XML file file contains a set of rules which describe how to select the -- files to include in the generator. The XML file is read and resource rules -- introduced by the `resource` XML element are collected. -- -- The source paths are then scanned and a complete tree of source files is created. -- Because several source paths are given, we have several source trees with possibly -- duplicate files and names in them. -- -- The source paths are matched against the resource rules and each installation rule -- is filled with the source files that they match. -- -- The resource installation rules are executed in the order defined -- in the `package.xml` file. Each resource rule can have its own way to make -- the installation for the set of files that matched the rule definition. -- A resource rule can copy the file, another can concatenate the source files, -- another can do some transformation on the source files and prepare it before being -- embedded and used by the generator. -- -- @include are-installer-copies.ads -- @include are-installer-concat.ads -- @include are-installer-exec.ads -- @include are-installer-bundles.ads -- @include are-installer-merges.ads package Are.Installer is type Installer_Type is limited new Ada.Finalization.Limited_Controlled with private; -- Read the XML package file that describes the resources and build the list -- of rules to collect and build those resources. procedure Read_Package (Installer : in out Installer_Type; File : in String; Context : in out Context_Type'Class); -- Scan the directory collecting the files that must be taken into account and -- processed by the distribution rules. procedure Scan_Directory (Installer : in out Installer_Type; Path : in String; Context : in out Context_Type'Class); -- Add a simple rule to copy the files matching the pattern on the resource. procedure Add_Rule (Installer : in out Installer_Type; Resource : in Are.Resource_Access; Pattern : in String); -- Execute the installation rules and collect the resources to be written -- in the context. procedure Execute (Installer : in out Installer_Type; Context : in out Context_Type'Class); -- Clear the rules and files that have been loaded. procedure Clear (Installer : in out Installer_Type); private type Directory_List; type Directory_List_Access is access all Directory_List; -- A `File_Record` refers to a source file that must be processed by a resource -- rule. It is linked to the directory which contains it through the `Dir` member. -- The `Name` refers to the file name part. type File_Record (Length : Natural) is record Dir : Directory_List_Access; Name : String (1 .. Length); end record; package File_Record_Vectors is new Ada.Containers.Indefinite_Vectors (Index_Type => Positive, Element_Type => File_Record); subtype File_Vector is File_Record_Vectors.Vector; subtype File_Cursor is File_Record_Vectors.Cursor; -- Get the first source path from the list. function Get_Source_Path (From : in File_Vector; Use_First_File : in Boolean := False) return String; -- The file tree represents the target distribution tree that must be built. -- Each key represent a target file and it is associated with a `File_Vector` which -- represents the list of source files that must be used to build the target. package File_Tree is new Ada.Containers.Indefinite_Ordered_Maps (Key_Type => String, Element_Type => File_Vector, "<" => "<", "=" => File_Record_Vectors."="); package Directory_List_Vector is new Ada.Containers.Vectors (Index_Type => Positive, Element_Type => Directory_List_Access); -- The `Directory_List` describes the content of a source directory. type Directory_List (Length : Positive; Path_Length : Natural) is record Files : File_Record_Vectors.Vector; Directories : Directory_List_Vector.Vector; Rel_Pos : Positive := 1; Name : String (1 .. Length); Path : String (1 .. Path_Length); end record; -- Get the relative path of the directory. function Get_Relative_Path (Dir : in Directory_List) return String; -- Strip the base part of the path function Get_Strip_Path (Base : in String; Path : in String) return String; -- Build a regular expression pattern from a pattern string. function Make_Regexp (Pattern : in String) return String; -- Build a regular expression pattern from a pattern string. function Make_Regexp (Pattern : in String) return GNAT.Regpat.Pattern_Matcher; -- Scan the directory whose root path is `Path` and with the relative path -- `Rel_Path` and build in `Dir` the list of files and directories. procedure Scan (Path : in String; Rel_Path : in String; Dir : in Directory_List_Access); type Match_Rule is record Base_Dir : Ada.Strings.Unbounded.Unbounded_String; Match : Ada.Strings.Unbounded.Unbounded_String; end record; package Match_Rule_Vector is new Ada.Containers.Vectors (Index_Type => Positive, Element_Type => Match_Rule); -- ------------------------------ -- Distribution rule -- ------------------------------ -- The Distrib_Rule represents a distribution rule that must be executed on -- a given file or set of files. type Distrib_Rule is abstract tagged record Dir : Ada.Strings.Unbounded.Unbounded_String; Resource : Are.Resource_Access; Matches : Match_Rule_Vector.Vector; Excludes : Match_Rule_Vector.Vector; Files : File_Tree.Map; Level : Util.Log.Level_Type := Util.Log.DEBUG_LEVEL; Strip_Extension : Boolean := False; Source_Timestamp : Boolean := False; end record; type Distrib_Rule_Access is access all Distrib_Rule'Class; -- Get a name to qualify the installation rule (used for logs). function Get_Install_Name (Rule : in Distrib_Rule) return String is abstract; -- Install the file File according to the distribution rule. procedure Install (Rule : in Distrib_Rule; Target : in String; File : in File_Vector; Context : in out Context_Type'Class) is abstract; -- Scan the directory tree whose root is defined by Dir and find the files -- that match the current rule. procedure Scan (Rule : in out Distrib_Rule; Dir : in Directory_List); procedure Scan (Rule : in out Distrib_Rule; Dir : in Directory_List; Base_Dir : in String; Pattern : in String; Exclude : in Boolean); procedure Execute (Rule : in out Distrib_Rule; Context : in out Context_Type'Class); -- Get the target path associate with the given source file for the distribution rule. function Get_Target_Path (Rule : in Distrib_Rule; Base : in String; File : in File_Record) return String; -- Get the source path of the file. function Get_Source_Path (Rule : in Distrib_Rule; File : in File_Record) return String; -- Get the path that must be exported by the rule. function Get_Export_Path (Rule : in Distrib_Rule; Path : in String) return String; -- Add the file to be processed by the distribution rule. The file has a relative -- path represented by Path. The path is relative from the base directory -- specified in Base_Dir. procedure Add_Source_File (Rule : in out Distrib_Rule; Path : in String; File : in File_Record); -- Remove the file to be processed by the distribution rule. This is the opposite of -- Add_Source_File and used for the rules. procedure Remove_Source_File (Rule : in out Distrib_Rule; Path : in String; File : in File_Record); -- Load and add the file in the resource library. procedure Add_File (Rule : in Distrib_Rule; Name : in String; Path : in String; Modtime : in Ada.Calendar.Time; Override : in Boolean := False); -- Create a resource rule identified by `Kind`. -- The resource rule is configured according to the DOM tree whose node is `Node`. function Create_Rule (Kind : in String; Node : in DOM.Core.Node) return Distrib_Rule_Access; -- A list of rules that define how to build the distribution. package Distrib_Rule_Vectors is new Ada.Containers.Vectors (Index_Type => Positive, Element_Type => Distrib_Rule_Access); type Installer_Type is limited new Ada.Finalization.Limited_Controlled with record Rules : Distrib_Rule_Vectors.Vector; Trees : Directory_List_Vector.Vector; end record; procedure Delete (Directory : in out Directory_List_Access); overriding procedure Finalize (Installer : in out Installer_Type); end Are.Installer;