Project layout with Subversion and static resources - version-control

I'm working on a project which (as usual) contains source code and many static resources like images and generated files (for UI and l10n).
By now, everything is versioned with Subversion, but I think there must be a better way to store the static and generated files and link them on project deployment.
So, in your opinion which option the best?
Keep everything together.
Set a different and more appropriate storage (and probably versioning system) for every different kind of file.
...

Generated files I would svn:ignore. As long as they are automatically re-generated if they don't exist (or the generation process is easy to trigger) versioning the generated files would be just clutter.
Static files - images, style sheets, etc. - I would keep together, as long as they're not so heavy that they'll slow down the whole process. After all, they are a fixed part of your project.

Related

How to create several flash application sharing common codebase in FlashDevelop/ActionScript 3.0?

Situation:
I need several swf/exe output files compiled in FlashDevelop from several projects. More than 60% of ActionScript 3.0 source is common for all project, rest are project-specific. How can I organize that in FlashDevelop? I want to have "one-click-to-build all" setting without duplicating common codebase (so when I need to fix something I do not need to copy-paste solution into several files).
All sources are under develeopment and will change very often.
A straightforward solution is to make an external classpath, for instance:
c:\dev\shared_src\
c:\dev\project1\
c:\dev\project2\
Then configure each project:
Project Properties > Classpath
Add Classpath > select '../shared_src'
PS: of course you should keep everything under source control.
Using svn:externals you could structure your repository in such a way that the commom parts are stored just once in the source control system, so changes made can be synchronised with just a single commit and update cycle.
For example, imagine that you have ^/ProjectA and ^/ProjectB, each of with require ^/Common as a sub directory.
Using svn:externals, pull ^/Common into both projects.
The exact nature of doing this will depend on the version of svn you use, and any client you use (such as TortoiseSvn). Refer to the relevant edition of the svn book for specifics.
The ease of implementing this will depend quite a lot on how separate the common code currently is in your application; and pulling in directories as directories is much more practical than trying to pull them into an existing directory; and unfortunately wildcards for filepaths are not supported.
However, based on your description of your aim; this is the most straight-forward solution I can imagine.
Hope this helps.

What are the Xcode solution organisation best practices and guidelines?

Are there any best practices for how to organise one's solution in xcode
This is mine at the moment from the root:
A folder for each 3rd party framework e.g. KissXML
A folder for my unit tests
A folder for frameworks, products and resources
A folder for MyApp which has sub folders for model, view, controller, database, supporting files and domain.
Mine is:
Main application
Model
Singletons
Helper+managers
Controllers // I keep nibs with their respective class files
View
Resources
images
plists
// ... groups from other types of resources if needed
Supporting files
Unit tests
Frameworks
For reusable code on iOS I use static libraries and add these as separate projects in the Xcode workspace. Even for third-party code, if there is not a static library target, I create one. That way, I treat third-party code the same way as I treat my own library code. Further, then I don't have to worry about versioning of third-party code.
I've found it important to have Xcode mirror the file system organization of the code, at least up to some level. I adopted this practice after reading this blog post. I don't do this below the levels I've listed above, though. This helps when you share code on github, for example. Rather than have downloaders or contributors have to dig through all of your source dumped into a single directory, it is organized into functional buckets. I've seen some projects where the Xcode organization is OK, but every single source file in the file system is dumped into a single directory.
Although no particular method can be devoid of disadvantages, here is what we use
Folder for Application core or Model. This includes sub-folders for
any third party libraries used and folders for specialized model
classes. For example there would be folder for web service handling.
Folder for one major module which would include sub-folders for each
screen containing class files, nibs and resources (this may include
more sub-folders according to the need).
Folder for second major module and so on..
This model serves us one major purpose. Our application core contains stuff like logging, data encryption/decryption etc. So it is very unlikely to be changed for many applications that we develop. Similarly there would be some applications which would need functionality of major module one and add some other things. Therefore these three folder groups are maintained as separate repositories on the subversion.
Now when we start a new project, we create a new repository for the project and link it with the application core repository and other major module repositories according to the need. So any changes made in application core by one project team, is reflected in other projects as well. Same with other major modules. This also helps us to achieve complete modularity.
Of course there would be disadvantages to this scheme, but this scheme has suited us well for many years now :)

Same code base for iPhone/Desktop app

I have an iPhone/iPad app that I want to port to MacOSX. Most of my objective C classes should work just fine as long as they do not contain UIKit stuff. Obviously the interface will be different.
What is the best way to do this in Xcode? Start a completely new project? Add a new target? How can I keep the different platforms in sync? Should I just use git with multiple branches?
I've had difficulty setting up a unified project with different targets for the two OS types, so I generally split this into two projects that share source files.
For an application that will be targeted Mac and iOS, I tend to create one directory for the application. I place the two projects within this, and set up one directory for shared source files, one for iOS-specific stuff, and a third for Mac-specific stuff. This way, you might have different projects, but shared files will update between them as they are changed. The only time you manually have to sync the two is when a new shared file is added to the application and must be added to both projects independently.
You should be able to restructure your existing project to support this without much trouble.
You can also simply add the files from one project as references to the other one. Simply drag them from the source project (where the actual files reside) into the other project. The dialog will ask you whether you want to copy the files. Choose no. This will make the second project point to the files in the first project. Edits go into both projects.
Be careful with this, though, as there are a few differences between APIs in iOS and MacOS, even if they are called the same.

Should I put my output files in source control?

I've been asked to put every single file in my project under source control, including the database file (not the schema, the complete file).
This seems wrong to me, but I can't explain it. Every resource I find about source control tells me not to put generated output files in a source control system. And I understand, it's not "source" files.
However, I've been presented with the following reasoning:
Who cares? We have plenty of bandwidth.
I don't mind having to resolve a conflict each time I get the latest revision, it's just one click
It's so much more convenient than having to think about good ignore files
Also, if I have to add an external DLL file in the bin folder now, I can't forget to put it in source control, as the bin folder is not being ignored now.
The simple solution for the last bullet-point is to add the file in a libraries folder and reference it from the project.
Please explain if and why putting generated output files under source control is wrong.
You haven't explained what "the database file" is.
I would certainly include 3rd party libraries in source control, as they're necessarily for the build and it's good to have a way of reproducing a build at a later time with the library versions you used at that particular moment. But yes, those libraries should be included from a "libraries" folder rather than the output directory.
I wouldn't generally include my own libraries built from the sources elsewhere in the same repository - although I have been in situations where that's been worth doing, where some projects didn't use the "latest and greatest" version of a common library, but just occasionally updated.
The most important practical argument I'd give against including everything, in a world where disk, processor and network are considered free and instantaneous, is that it makes it harder to tell what really changed for any given commit. It's easier to look down a list of 3 source files than 3 source files and 150 binaries from the obj/bin directories.
Generated output files (in general) are "dangerous" in a VCS because:
what you need to version is how to regenerate them: the day you will need to actually update them, chances are you won't remember how to do it
they can contain some private generated file which make them work on the committer desktop, but not on a client one ("works on my machine" TM syndrome)
some generated file are not easily stored in delta (binary especially), making them consuming lots of space (and the topic of cleaning that space will come-up someday...)
External libraries are not generated directly by your project, and can be put in a VCS, although external repositories like a public Maven repo are better at this kind of management.
Do we also put compiled object files such as class files, executables, DLLs build from our source? What about when we're doing serious volume testing and that database becomes many gigabytes or terabytes in size?
The clue is in the name: it's Source Code Management System.
I can understand the simplicity of put eveything in, it's more likely that developer doesn't forget some important file. But if you're doing regular automated builds then surely that gets picked up anyway?
I think the key phrase is here:
It's so much more convenient than
having to think about good ignore
files
Are you explicitly forbiden from having good ignore files? My guess is that already you are excluding .exe and .class (or whatever) files. Suppose you did take the trouble to exclude your database would that be a problem? Why? It's a concious action that you are chosing to take for the commone good. In Eclipse it's a couple of seconds work to add a new file type to the workspace's CVS ignore rules for all projects.
A rule of "No Ignore Files" is almost self-evidently absurd. Once you have the freedom the have some ignore files then why not just use them intelligently to exclude the DB? Who is inconveninced? Only yourself, if anyone, and you're prepared to do the extra work.

Do you version "derived" files?

Using online interfaces to a version control system is a nice way to have a published location for the most recent versions of code. For example, I have a LaTeX package here (which is released to CTAN whenever changes are verified to actually work):
http://github.com/wspr/pstool/tree/master
The package itself is derived from a single file (in this case, pstool.tex) which, when processed, produces the documentation, the readme, the installer file, and the actual files that make up the package as it is used by LaTeX.
In order to make it easy for users who want to download this stuff, I include all of the derived files mentioned above in the repository itself as well as the master file pstool.tex. This means that I'll have double the number of changes every time I commit because the package file pstool.sty is a generated subset of the master file.
Is this a perversion of version control?
#Jon Limjap raised a good point:
Is there another way for you to publish your generated files elsewhere for download, instead of relying on your version control to be your download server?
That's really the crux of the matter in this case. Yes, released versions of the package can be obtained from elsewhere. So it does really make more sense to only version the non-generated files.
On the other hand, #Madir's comment that:
the convenience, which is real and repeated, outweighs cost, which is borne behind the scenes
is also rather pertinent in that if a user finds a bug and I fix it immediately, they can then head over to the repository and grab the file that's necessary for them to continue working without having to run any "installation" steps.
And this, I think, is the more important use case for my particular set of projects.
We don't version files that can be automatically generated using scripts included in the repository itself. The reason for this is that after a checkout, these files can be rebuild with a single click or command. In our projects we always try to make this as easy as possible, and thus preventing the need for versioning these files.
One scenario I can imagine where this could be useful if 'tagging' specific releases of a product, for use in a production environment (or any non-development environment) where tools required for generating the output might not be available.
We also use targets in our build scripts that can create and upload archives with a released version of our products. This can be uploaded to a production server, or a HTTP server for downloading by users of your products.
I am using Tortoise SVN for small system ASP.NET development. Most code is interpreted ASPX, but there are around a dozen binary DLLs generated by a manual compile step. Whilst it doesn't make a lot of sense to have these source-code versioned in theory, it certainly makes it convenient to ensure they are correctly mirrored from the development environment onto the production system (one click). Also - in case of disaster - the rollback to the previous step is again one click in SVN.
So I bit the bullet and included them in the SVN archive - the convenience, which is real and repeated, outweighs cost, which is borne behind the scenes.
Not necessarily, although best practices for source control advise that you do not include generated files, for obvious reasons.
Is there another way for you to publish your generated files elsewhere for download, instead of relying on your version control to be your download server?
Normally, derived files should not be stored in version control. In your case, you could build a release procedure that created a tarball that includes the derived files.
As you say, keeping the derived files in version control only increases the amount of noise you have to deal with.
In some cases we do, but it's more of a sysadmin type of use case, where the generated files (say, DNS zone files built from a script) have intrinsic interest in their own right, and the revision control is more linear audit trail than branching-and-tagging source control.