Helix Core Server User Guide (2019.2)

Stream paths and inheritance between parents and children

Child streams inherit folder paths and behavioral rules from their parents. When we talk about inheritance between parents and children, it helps to think in the following terms:

  • Permissiveness: what actions (submit, sync, etcetera) are permitted on a path?

    Path types are inherited from parent streams, and you cannot override the effects of the path types assigned by parent streams. In other words, child streams are always as permissive or less permissive than their parents, but never more permissive. For example, if a parent stream defines a path as isolate, its child streams cannot redefine the path as share to enable integrations.

  • Inclusiveness: what paths are included in the stream?

    Since children cannot, by definition, be more inclusive than their parents, you cannot include a folder path in a child that is not also included in its parent. This means, for example, that you cannot add an isolate path to a child if the folders in that path are not also included in the parent.

    In the example in the table below, the incorrectly defined Dev stream, which is a child of Main, contains an isolate path that does not work, because it includes folders that are not included in the parent. In order to isolate the config/ folder in the Dev stream, that folder has to be included as a share or isolate path in Main:

    Incorrect Correct
    Stream: //Acme/Main
    Parent: none
    Paths: share apps/...
    Paths: share tests/...
    
    
    Stream: //Acme/Dev
    Parent: //Acme/Main
    Paths: share apps/...
           share tests/...
           isolate config/...
    Stream: //Acme/Main
    Parent: none
    Paths: share apps/...
           share tests/...
           share config/...
    
    Stream: //Acme/Dev
    Parent: //Acme/Main
    Paths: share apps/...
           share tests/...
           isolate config/...

Example   Simple share

Let’s start with a simple case: two streams, //Ace/main and its child //Ace/dev.

Stream: //Ace/main
Parent: none
Paths:  share ...

Stream: //Ace/dev
Parent: //Ace/main
Paths:  share ...

In this case, the entire stream path is shared. When you switch your workspace to the //Ace/main stream, the workspace view looks like this:

//Ace/main/... //bruno_ws/...

The workspace view maps the root of the //Ace/main stream to your workspace. When you you switch your workspace to the //Ace/dev stream, the workspace view is this:

//Ace/dev/... //bruno_ws/...

And the branch view for //Ace/dev/ looks like this:

//Ace/dev/... //Ace/main/...

In other words, the entire dev stream can be synced to workspaces, and the entire stream can be branched, merged, and copied.

Example   Share and import

Let’s look at an example where software components are housed in three separate depots: //Acme, //Red, and //Tango.

The Acme mainline is configured like this:

Stream: //Acme/Main
Parent: none
Paths:  share apps/...
        share tests/...
        import stuff/... //Red/R6.1/stuff/...
        import tools/... //Tango/tools/...

If you switch your workspace to the //Acme/Main stream, this would be your workspace view:

//Acme/Main/apps/...  //bruno_ws/apps/...
//Acme/Main/tests/... //bruno_ws/tests/...
//Red/R6.1/stuff/...  //bruno_ws/stuff/...
//Tango/tools/...     //bruno_ws/tools/...

The stream’s Paths field lists folders relative to the root of the stream. Those are the folders you get in your workspace, beneath your workspace root. The shared folders are mapped to the //Acme/Main path, and the imported paths are mapped to their locations in the //Red and //Tango depots.

Example   Share, isolate, exclude, and import

Let’s say that your team doesn’t want to do actual development in the mainline. In this example, XProd feature team has a development stream of their own, defined like this:

Stream: //Acme/XProd
Parent: //Acme/Main
Paths:  import ...
        isolate apps/bin/...
        share apps/xp/...
        exclude tests/...

Switching your workspace to the //Acme/XProd stream gives you this view:

//Acme/Main/apps/...      //bruno_ws/apps/...
//Acme/XProd/apps/bin/... //bruno_ws/apps/bin/...
//Acme/XProd/apps/xp/...  //bruno_ws/apps/xp/...
//Red/R6.1/stuff/...      //bruno_ws/stuff/...
//Tango/tools/...         //bruno_ws/tools/...
-//Acme/XProd/tests/...   //bruno_ws/tests/...

Here we see workspace view inheritance at work. The contents of imported paths are mapped into your workspace. The shared and isolated paths are mapped to the child stream; these contain the files the XProd team is working on and will be submitting changes to. And the excluded path (marked with a minus sign in the view) doesn’t appear in the workspace at all.

Because the //Acme/XProd stream has a parent, it has a branch mapping that can be used by the copy and merge commands. That branch view consists of the following, with just one path shared by the child and parent.

-//Acme/XProd/apps/...     //Acme/Main/apps/...
-//Acme/XProd/apps/bin/... //Acme/Main/apps/bin/...
//Acme/XProd/apps/xp/...   //Acme/Main/apps/xp/...
-//Acme/XProd/stuff/...    //Acme/Main/stuff/...
-//Acme/XProd/tests/...    //Acme/Main/tests/...
-//Acme/XProd/tools/...    //Acme/Main/tools/...

When you work in an //Acme/XProd workspace, it feels as if you’re working in a full branch of //Acme/Main, but the actual branch is quite small.

Example   Child that shares all of the above parent

Let’s suppose that Lisa, for example, creates a child stream from //Acme/XProd. Her stream spec looks like this:

Stream: //Acme/LisaDev
Parent: //Acme/XProd
Paths:  share ...

Lisa’s stream has the default view template. Given that Lisa’s entire stream path is set to share, you might expect that her entire workspace will be mapped to her stream. But it is not, because inherited behaviors always take precedence; sharing applies only to paths that are shared in the parent as well. A workspace for Lisa’s stream, with its default view template, has this client view:

//Acme/Main/apps/...        //bruno_ws/apps/...
-//Acme/LisaDev/tests/...   //bruno_ws/tests/...
//Acme/LisaDev/apps/bin/... //bruno_ws/apps/bin/...
//Acme/LisaDev/apps/xp/...  //bruno_ws/apps/xp/...
//Red/R6.1/stuff/...        //bruno_ws/stuff/...
//Tango/tools/...           //bruno_ws/tools/...

A workspace in Lisa’s stream is the same as a workspace in the XProd stream, with one exception: the paths available for submit are rooted in //Acme/LisaDev. This makes sense; if you work in Lisa’s stream, you expect to submit changes to her stream. By contrast, the branch view that maps the //Acme/Dev stream to its parent maps only the path that is designated as shared in both streams:

-//Acme/Main/apps/...        //XProd/apps/...
-//Acme/LisaDev/tests/...    //XProd/tests/...
-//Acme/LisaDev/apps/bin/... //XProd/apps/bin/...
//Acme/LisaDev/apps/xp/...   //bruno_ws/apps/xp/...
-//Red/R6.1/stuff/...        //XProd/stuff/...
-//Tango/tools/...           //XProd/tools/...

The default template allows Lisa to branch her own versions of the paths her team is working on, and have a workspace with the identical view of non-branched files that she would have in the parent stream.