fpm_dependency Module

# Dependency management

## Fetching dependencies and creating a dependency tree

Dependencies on the top-level can be specified from:

  • package%dependencies
  • package%dev_dependencies
  • package%executable(:)%dependencies
  • package%test(:)%dependencies

Each dependency is fetched in some way and provides a path to its package manifest. The package%dependencies of the dependencies are resolved recursively.

To initialize the dependency tree all dependencies are recursively fetched and stored in a flat data structure to avoid retrieving a package twice. The data structure used to store this information should describe the current status of the dependency tree. Important information are:

  • name of the package
  • version of the package
  • path to the package root

Additionally, for version controlled dependencies the following should be stored along with the package:

  • the upstream url
  • the current checked out revision

Fetching a remote (version controlled) dependency turns it for our purpose into a local path dependency which is handled by the same means.

## Updating dependencies

For a given dependency tree all top-level dependencies can be updated. We have two cases to consider, a remote dependency and a local dependency, again, remote dependencies turn into local dependencies by fetching. Therefore we will update remote dependencies by simply refetching them.

For remote dependencies we have to refetch if the revision in the manifest changes or the upstream HEAD has changed (for branches and tags).

For the latter case we only know if we actually fetch from the upstream URL.

In case of local (and fetched remote) dependencies we have to read the package manifest and compare its dependencies against our dependency tree, any change requires updating the respective dependencies as well.

## Handling dependency compatibilties

Currenly ignored. First come, first serve.



Contents


Interfaces

public interface resize

Overloaded reallocation interface

  • private pure subroutine resize_dependency_node(var, n)

    Reallocate a list of dependencies

    Arguments

    Type IntentOptional AttributesName
    type(dependency_node_t), intent(inout), allocatable:: var(:)

    Instance of the array to be resized

    integer, intent(in), optional :: n

    Dimension of the final array size


Derived Types

type, public, extends(dependency_config_t) :: dependency_node_t

Dependency node in the projects dependency tree

Components

TypeVisibility AttributesNameInitial
logical, public :: done =.false.

Dependency is handled

type(git_target_t), public, allocatable:: git

Git descriptor

character(len=:), public, allocatable:: name

Name of the dependency

character(len=:), public, allocatable:: path

Local target

character(len=:), public, allocatable:: proj_dir

Installation prefix of this dependencies

character(len=:), public, allocatable:: revision

Checked out revision of the version control system

logical, public :: update =.false.

Dependency should be updated

type(version_t), public, allocatable:: version

Actual version of this dependency

Type-Bound Procedures

procedure, public :: info

Print information on this instance

procedure, public :: register

Update dependency from project manifest

type, public :: dependency_tree_t

Respresentation of a projects dependencies

Read more…

Components

TypeVisibility AttributesNameInitial
character(len=:), public, allocatable:: cache

Cache file

type(dependency_node_t), public, allocatable:: dep(:)

Flattend list of all dependencies

character(len=:), public, allocatable:: dep_dir

Installation prefix for dependencies

integer, public :: ndep =0

Number of currently registered dependencies

integer, public :: unit =output_unit

Unit for IO

integer, public :: verbosity =1

Verbosity of printout

Type-Bound Procedures

generic, public :: add => add_project, add_project_dependencies, add_dependencies, add_dependency

Overload procedure to add new dependencies to the tree

generic, public :: dump => dump_to_file, dump_to_unit, dump_to_toml

Writing of dependency tree

generic, public :: find => find_dependency, find_name

Find a dependency in the tree

procedure, public :: finished

Depedendncy resolution finished

generic, public :: load => load_from_file, load_from_unit, load_from_toml

Reading of dependency tree

generic, public :: resolve => resolve_dependencies, resolve_dependency

Resolve dependencies

generic, public :: update => update_dependency

Update dependency tree


Subroutines

public pure subroutine new_dependency_node(self, dependency, version, proj_dir, update)

Create a new dependency node from a configuration

Arguments

Type IntentOptional AttributesName
type(dependency_node_t), intent(out) :: self

Instance of the dependency node

type(dependency_config_t), intent(in) :: dependency

Dependency configuration data

type(version_t), intent(in), optional :: version

Version of the dependency

character(len=*), intent(in), optional :: proj_dir

Installation prefix of the dependency

logical, intent(in), optional :: update

Dependency should be updated

public subroutine new_dependency_tree(self, verbosity, cache)

Create a new dependency tree

Arguments

Type IntentOptional AttributesName
type(dependency_tree_t), intent(out) :: self

Instance of the dependency tree

integer, intent(in), optional :: verbosity

Verbosity of printout

character(len=*), intent(in), optional :: cache

Name of the cache file