Re: Project templates
Re: Project templates
- Subject: Re: Project templates
- From: "Karan, Cem (Civ, ARL/CISD)" <email@hidden>
- Date: Mon, 30 Jun 2008 08:54:43 -0400
- Thread-topic: Project templates
On Sunday, June 29, 2008 8:42 AM Philip Aker wrote:
> I found your post very thought provoking. Especially the TEMPLATE part
> where we supply definitions, delimiters, and encoding. I've tried to
> merge your "This is what I need" outline above with a "This is one way
> to do it" notion and present a sketch of what an Xcode Project
> Template instance might look like below. The DATE and USER definitions
> have been blended into the TEMPLATE idea using the macros" element to
> contain named sets of them. These are referenced from the
> macro-expansion-files and rename-files elements which indicate what is
> to be expanded.
I just want to make sure we're thinking exactly the same thing here; is
the XML template being supplied by Xcode to a script, for the script to
modify, or is the script supplying Xcode an XML file, from which Xcode
builds a new project?
> Discussion:
>
> One problem that's bound to come up: given a new template mechanism --
> what to do with the old? In order to create the least amount of
> disruption, new style templates could be housed in a bundle with a
> specific extension (let's call it .xptd (Xcode Project Template
> Directory)). The template importer will recognize the new format and
> delete the bundle extension in when presenting its name in the
> template list. A bundle format, whether like an actual bundle
> (.component, .plugin, etc.), a framework, or shallow bundle (.rtfd)
> would provide lots of familiar and convenient organizational
> possibilities. Not the least of which would be to use custom keys in
> the Info.plist for setting up the environment.
I REALLY LIKE this idea! It goes WAY beyond what I was originally
thinking; I was just thinking about a single script generating
everything. With bundles, we can have resources, etc. bound up with the
script.
> Practical Goals:
>
> 1. Do away with the current practice of housing an .xcodeproj and then
> have to munge it. Instead, proceed with the idea that the new XML
> format will be processed by various means to insert entries in what is
> essentially an empty project (always supplied by the processor).
Agreed.
> 2. Assume that all input files are UTF-8 unless they have have a
> Unicode BOM. Otherwise the encoding must be specified as an attribute
> in its file element.
Agreed.
> 3. There won't be much need for us to deal with UUID-type
> cross-referencing in our specification. That's the kind of stuff best
> dealt with in transformational code by the processor so we'll opt for
> the human-readable form when it's necessary.
Agreed.
> 4. Make use of .xcconfig files for our project/target settings and set
> up our Info.plist to make use of those setting definitions (like
> $ARCHES, $CURRENT_PROJECT_VERSION, INSTALL_PATH, etc.). This would
> seem to obviate the PRODUCT category above because all the details can
> be covered in an xcconfig.
I'm not sure if I agree with this; my thought is that the script should
accept information about what the user wants set up (the dictionaries
from my earlier message), and then generate whatever is necessary and
return that to Xcode. I think the difference in our philosophies is
that I see this template as an active object, like a delegate in the
Cocoa framework. When the user wants to generate a new project, Xcode
asks the template to generate the project for it. Xcode then accepts
the output of the script, and puts it where the user wants. Here is an
outline of what I'm talking about:
The template bundle has all the necessary resources to generate a
project. These resources can be anything needed by the template,
pictures, sounds, whatever. The template bundle also has a UUID to
distinguish itself from all other templates. The template is missing
the crucial information that must be supplied by Xcode, such as the name
of the user, date, etc. So, the following happens:
1) The user selects a project template from within Xcode, and supplies
things like the project name, etc.
2) Xcode accepts this information, and builds a dictionary of this, and
other relevant information.
3) Xcode creates a new directory within /tmp, and copies the template
bundle there. It also writes out a new plist within the bundle that
contains the complete dictionary generated in step 2 (writing the
dictionary as a plist ensures that any language that is able to read a
text file can also read the dictionary)
4) Xcode then changes directories to the new directory in /tmp. It then
chroot jails itself, and sets its effective ID to nobody.
5) Xcode then forks off a child that will run the script. (IIRC, the
child's real user ID is now nobody; that means that a malicious script
can't simply revert to Xcode's user ID and then run itself). Xcode can
revert itself to the its real user ID, get of out jail, etc. The child
can talk to Xcode via pipes, but it can't go anywhere, or do anything
dangerous. Thus, it is stuck with the bundle only.
6) Child runs the script, which is then able to do anything it wants to.
This is the real reason for all the protections above; it means that
Xcode doesn't have to figure out if a template script is evil, or
malformed, or anything else; it just needs to run it, and wait for the
output.
7) Script generates output in the chroot() jail mentioned above, and
exits. The simplest way to do this is to modify the bundle in place;
after all, the template that is in the jail is just a copy anyways, so
it doesn't matter what happens to it.
8) Child informs parent process (Xcode proper) that the project has been
created. Or, if the child went haywire, it can be killed off, and /tmp
can be examined at leisure, or eliminated.
9) Child exits
10) Xcode notes the UUID that was associated with the original project
template, and loads that into the newly minted project bundle,
overwriting anything that the script tried to put in there (prevents one
script from pretending that a different script generated the project
bundle)
11) Xcode copies the project wherever it belongs.
12) At some later time, the user wants to generate more files for their
project. Xcode can then find the original generating template from the
UUID embedded in the project bundle. Using the original template, it
can ask for more files. This lets us have different templates for
different companies; e.g., as an independent contractor, you may have 5
different templates whose main difference is the boilerplate legal code
they require. By having different template bundles, each with their own
UUID, Xcode can choose to use the original template each and every time
you want to generate more files. That means all files belonging to a
particular project will share the same boilerplate code.
The idea I have is that the only information the script has is that
supplied by Xcode; this encourages encapsulation, and allows the Xcode
team to move things around as necessary. It also forces all of us
template designers to keep our templates clean; we don't have access to
the user's data, so we can't hard code in anything. This helps ensure
that when we pass templates around to our friends, post them on the
internet, etc., they work on other people's systems. Finally, it gives
us a little bit of protection against badly behaving scripts; that means
that Xcode won't introduce any new security holes (well, except for the
fact that the generated project may itself be a virus, but there are
limits to what I can think of before my second cup of coffee! ;)).
Thanks,
Cem Karan
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Xcode-users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden