Skip to main content
Jump to: navigation, search

Buckminster Project/docs/drafts/ActionSpec

< Buckminster Project
Revision as of 04:39, 12 December 2005 by Thallgren (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Buckminster Action Specification

You need stuff to do things -> To perform an action you must fulfill its requirements.

Others may regard the things you do as stuff they need -> An action can produce artifacts that fulfill requirements of other actions.

You need stuff for a reason -> There is always a purpose behind a component dependency.

ASpec elements

A aspec defines the four top-level elements artifacts, actions, requirements, and usages.

An artifact is a named collection of files and/or folders.

An action is something that can be executed. It can have zero or many requirements. The execution of an action will often produce a new artifact.

A usage is very similar to an action but it cannot be directly executed. Instead, it defines the components participation in an action defined elsewhere. A usage is triggered by the purpose of a requirement from an external action or usage. A usage or action may imply another usage of the same component.

A requirement can be either local or external. A local requirement states that an artifact must be present in the component. An external requirement names another component together with a purpose. The external component must be listed as a dependency in the <a href="cspec.html">Component Specification</a>.

Purpose qualified dependency

An external requirement qualifies a dependency with a purpose. When an aspec is used, a dependency that has no purpose will be ignored. The purpose says "I need this component in order to <purpose>". Here's an example:

Assume that we have three Java components, A, B, and C. A use classes present in B. B in turn use classes from C but hides this completely from A. When compiling A, a compiled version of B is needed but there's no need for C. When running A, clearly both B and C will be needed.

Object Oriented methodology tells us that it would be bad if A needs to know about the runtime dependency from B to C. It would be much better if A can say "I need B in order to compile" or "I need B in order to run" and B could answer, "You need me in order to run? Then I need to bring C along as well". The purpose qualified dependencies resolves this elegantly.

Artifact and derived components

A component will always contain at least one artifact. A source component from a CVS repository will always contain the artifact "source". This artifact is typically one single folder. Different actions such as "compile" or "archive" can produce new artifacts. It is often beneficial to store such artifacts in repositories and offer them as alternatives to the source when a component needs to resolve its dependencies. An FTP or HTTP based repository that stores pre-compiled binaries is a good example of this. In Buckminster lingo, such a binary is a derived component. It will contain a cspec similar to the one bundled with the original source pruned from the actions that produced the binary. The pruning will limit the component usage as well of course.

Since pruning removes actions and usages, some dependencies might end up purposeless. Such dependencies will be pruned too.


Buckminster allow artifacts to be variable. Variability is achieved through artifact attributes and by actions that can produce artifacts attributed in different ways. A trivial example of this is a compiler that can compile the same source, either stripped and optimized (distribution), or with symbols and not optimized (for debug purpose). Rather than having two artifacts and two actions (and two of every required artifact, etc.) attributes can be set in the outmost action that will be propagated all the way.

A attribute can be set in the artifact declaration or stem from the action that produces the artifact. The initial artifact of a cspec is never variable since it does not stem from an action. The more derived an artifact is, the less variable it becomes. A pre-built binary is typically not variable at all.

If an artifact defines that an attribute stems from the producing action, then that action must somehow provide the attribute. It can do this either by declaring that it is the originator (such as a compiler using attributes to control command line options) or by propagating it to at least one of its required artifacts and/or dependencies. It may also add new attributes to its requirements and/or dependencies.

Names of actions and artifacts

Buckminster does not stipulate the names of artifacts but here are some examples:

  • source
    no associated action, this is often an initial artifact.
  • compiled
    produced by the action compile, requires the artifact source.
  • docs
    produced by the action generate-docs, requires the artifact source.
  • archived-binary
    produced by the action archive, requires the artifact compiled.
  • archived-docs
    produced by the action archive-docs, requires the artifact docs.
  • archived-source
    produced by the action archive-source, requires the artifact source.
  • distribution
    produced by the action distribute, requires the artifacts archived-binary, archived-docs, and sometimes archived-source.

Some sample purpose names:

  • compiling
    The original action is compile.
  • linking
    The original action is link.
  • running
    The original action is run.
  • testing
    The original action is test. This purpose would imply running and add artifacts specific for testing.


Back to the top