Question

I use Perforce to manage several web applications. All apps share common front end files (css, JS, and java velocity code). I would like to create a vanilla application and have files shared with the other apps. Developers will not be able to edit these files in the child apps (something like p4 streams import), but when they sync to the app, it will pull down app files and (a copy of) shared files. Editing these files will only happen in the vanilla app.

I have been trying to get a solution via streams to work. The problem (as with standard workspace mapping) is that I cannot map a file to many places.

I have built my vanilla app as a Main stream (itself a conglomerate of tools from various locations in perforce). Then I created Development branches for each app, using a combination of Share and Import. A workspace must be created to match each streams.

Complicating this is that each app has four environments (dev, qa, stage, live). I'm not seeing a clear path on that problem.

What won't work for us:

  • HTTP distribution. We initially shared our js resources via web calls, but this posed problematic when a site was down. We want the JS files distributed (via p4) as LOCAL files.
  • Compiled JARs. These shared files will change too often, and there is no compiled code. It is a solution, but not one was want.

We are new to streams, and are accustomed to one workspace for the entire depot. Maybe I just need to give that up?

Was it helpful?

Solution

You should be able to do this with streams without too much difficulty. Assuming that I understand what you're doing, we solved a similar problem using streams.

We have a series of libraries that are maintained by an internal group, which are expected to be used in a variety of apps. These are kept in their own streams:

//LibraryA/main/...
//LibraryB/main/...

For major versions, they are locked down to distributions:

//LibraryA/r1_0/...
//LibraryB/r2_0/...
//LibraryB/r2_0/...

so that we can maintain API consistency without having to use @ specifications in the other streams. This may be an unnecessary step for you, but it helps us.

Then we have our projects, also in streams:

//Project1/main/...
//Project1/r1_0/...
//Project2/main/...
//Project2/r1_0/...

For each project stream, the libraries are included using the import directive, so the stream specification for //Project1/main/... would be:

share ...
import LibraryA/...  //LibraryA/main/...
import LibraryB/...  //LibraryB/r1_0/...

In this case, the share line states that child streams of main will share all files that belong directly to the stream and the import lines indicate read-only importation of the specific libraries into the directories in the stream. In this case, stream //LibraryA/main/... is imported as LibraryA/... in the tree, etc.

The result in a checked out version of /Project1/main/:

project1.html
images/p1i1.jpg
images/p1i2.jpg
LibraryA/l1c1.c
LibraryA/l1c2.c
LibraryB/l2c1.c
LibraryB/l2c2.c

When changes are made to either the /LibraryA/main/... stream or the /LibraryB/r1_0 stream and /Project1/main/... is p4 sync ..., then you will get the latest code for each library.

As for the qa/dev/stage/prod environments, it's not quite clear from your problem definition here how those differ, but here are two options:

If they are just environments, you can set them up as stream workspaces, and they can individually be used to check out and possibly modify versions of the data.

If they instead are supposed to imply a process movement from dev->qa->stage->prod or similar, you can implement them as streams and explicitly promote code to move from one to the next. For example:

//Project1/dev
//Project1/qa
//Project1/stage
//Project1/prod

In this case, dev would be a mainline stream, qa might be a read-only stream using the virtual stream type if they have no editing capabilities at all. stage would likely be a release stream which comes from the dev stream.

Much of this structure depends on how you are defining your development process. In a more agile process, the mainline branch should be kept very close to your dev branches and you might use continuous delivery off of a stable mainline. In more of a waterfall process, you will likely have release branches which receive code from the mainline branch for testing and movement to production.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top