Stream Components
A stream component is similar to an import of default paths because both allow the stream client to have access to files outside of the current stream. An advantage of a stream component is that it avoids the maintenance issues associated with keeping default paths up to date.
Stream Components allow stream client views to include other stream views. Any stream can become a component by being referenced in another stream view.
Components can be nested to arbitrary levels. For example, stream A references component stream B, which references component stream C, which references component stream D.
A stream cannot reference itself as a component, either directly or indirectly through other referenced component streams.
Enabling stream components
By default, the stream components feature is not enabled. To enable this feature, set the dm.stream.components
configurable to 1
.
Defining readonly stream components
A readonly stream component is defined with this syntax:
component_type component_folder component_stream[@[change | automatic_label]]
such as
readonly dirB //streams/B
where
component_type | component_folder | component_stream[@[change | automatic_label]] |
---|---|---|
is |
Specifies a directory prefix for each component view file. The specified directory is directly under the workspace root directory. |
Specifies the name and path of the component stream, which can be pinned to a change or automatic label. If
|
If neither @change
nor @automatic_label is specified, the view is not pinned to any change number but instead defaults to the current revision at that time.
StreamAtChange applies to components@change
Do not confuse @change
with @head
because a StreamAtChange applies to all streams, including those contributing view as Components.
For example, when setting StreamAtChange=86
, you are asking for the view at change 86
, which includes the streamviews for //str/comp-devDD
at change 86
(or before).
Although the spec for the stream might have a component at the head revision when setting StreamAtChange=86
, the version limit is at 86
, not at head
. In this scenario, the value of @change
overrides the value of @head
.
Examples of stream components
For example, given three streams, //streams/A, //streams/B, and //streams/C,
and //streams/A has a component definition
readonly dirB //streams/B
and //streams/B has a component definition
readonly dirC //streams/C
a client of //streams/A
therefore has the views
//streams/A/... //clientname/... //streams/B/... //clientname/dirB/... //streams/C/... //clientname/dirB/dirC/...
and a client of //streams/B therefore has the views
//streams/B/... //clientname/... //streams/C/... //clientname/dirC/...
In this example, the client of /streams/A does not need to maintain default paths for //streams/B and //streams/C. Therefore, if //streams/C upgrades its path for a new library version, all the stream views that consume the //streams/C component automatically have access to that new library version.
For security, the p4 protect protections table remains in force. For example, if a user has //clientname/dirB/dirC/...
in the component view, but lacks the read
protection for that directory, that user cannot read those files.
source stream and source path type
Suppose that stream A consumes component B, and B consumes component C, and C has a path
import oRead/... //other/oRead/...
This causes a client of A to get the view
//other/oRead/... //clientOfA/dirB/dirC/oRead/...
where A is the stream, C is the source stream, and import
is the source path type.
In other words, C is the source stream because C is a component that A consumes.
inheritance and noinherit
Component views are inherited by descendants of the defining stream, unless a descendant has a noinherit
ParentView. For example, if a mainline stream consumes two components, the development stream that is a child of that mainline stream also consumes those same two components.
If a descendant stream is converted to have a noinherit
ParentView, the component definition is copied to the descendant. In this way, a noinherit
ParentView child stream can continue to consume the same components directly as it did by inheritance from its parent prior to conversion to noinherit
.
A stream component only affects client views. Branch views are not affected by stream components, so integrations between parent and child are unaffected by component definitions.
additional information
See also the p4 help stream
command-line output.
Writable components
Starting in 2022.2, a stream consumer can set the component_type
to readonly
, writeimport+
, or writeall
. Both writeimport+
, or writeall
allow stream consumer clients to open for edit and submit changes to files in certain paths in the stream component:
writeimport+ | writeall |
---|---|
applies solely to import+ paths in the stream component |
applies to share , isolate , or import+ paths in the stream component |
See the path types for the Paths field of p4 stream in Helix Core Command-Line (P4) Reference. |
defining writeable stream components
A writeable stream component is defined with this syntax:
component_type component_folder component_stream
such as
writeimport+ dirWI //streams/W1
or
writeall dirWA //streams/WA
where
component_type | component_folder | component_stream |
---|---|---|
is |
Specifies a directory prefix for each component view file. The specified directory is directly under the workspace root directory. |
Specifies the name and path of the component stream. Writeable stream components do NOT support |
effective component type and the end component
The effective component type in a chain of components of different types is whichever component_type
is the most restrictive for views originating from the end component in the chain.
The end component is the final component in a chain of components. In the Examples of stream components above where stream A consumes B, and B consumes C, the end component is C.
Consider these two cases:
-
If stream A defines a
writeall
component B, and B defines areadonly
component C, the views that originate from paths in the end component, C, arereadonly
-
Because
readonly
is the most restrictivecomponent_type
, ifreadonly
exists at any location in the chain,readonly
applies throughout the chain when the view originates from the end component
-
-
If stream A defines a
writeimport+
component B, and B defines awriteall
component C, the views in A that originate fromshare
orisolate
paths in the end component, C, arereadonly
, whileimport+
paths in C are writable.-
Because
writeimport+
is more restrictive thanwriteall
, it iswriteimport+
that applies throughout the chain when the view originates from the end component, andwriteimport+
prevents writing toshare
orisolate
paths.
-
Viewing imported files
The --streamviews
option of p4 dirs
, p4 files
, and p4 fstat
reports files and directories from stream Paths and Components. Imported files are represented as symbolic links under the stream depot path.
For example, if stream C has the import, and there is one actual file in each of A, B, and C
then
p4 stream -o //root/C
includes in its output:
Paths: share ... import oRead/... //other/oRead/...
and
p4 sync -f
outputs:
//root/A/a1#1 - refreshing /home/maria/test/components/client/a1 //root/B/b1#1 - refreshing /home/maria/test/components/client/dirB/b1 //root/C/c1#1 - refreshing /home/maria/test/components/client/dirB/dirC/c1 //other/oRead/or1#1 - refreshing /home/maria/test/components/client/dirB/dirC/oRead/or1
and
p4 files --streamviews //root/A/...
outputs:
//root/A/dirB/dirC/oRead/or1#1 (mapped to //other/oRead/or1) - add change 4 (text) //root/A/a1#1 - add change 8 (text) //root/A/dirB/b1#1 (mapped to //root/B/b1) - add change 9 (text) //root/A/dirB/dirC/c1#1 (mapped to //root/C/c1) - add change 10 (text)
The --streamviews
option is convenient because you can view this report without having to create a new workspace.