Pharo - How do I share static resources in version control? - version-control

Suppose I have an image used by some objects in Pharo Smalltalk, how do I version that in the VCS repository? How those kind of static resources are dealt with in Pharo?
I know I can load an image from the Operational System hierarchy tree and put in a class instance variable, for example, and the image persistence will hold it, but I tried to version the package of this class through Monticello, remove and load it back and the image bitmap was lost.
I found this page http://smallthoughts.tonyfleig.com/Blog/article/id/1144940, but since I didn't find the class described in the current Pharo 5 distribution nor in the Catalog I wasn't sure if that would be a good approach.

You have three primary options
Store the assets in methods as code
This is the most common approach, and is was also used by Pharo 5 and prior for storing icons (and is still used by some parts of the system).
The approach is to store the data in some encoded format (typically base64, or byte array) as a string, and then in second method you have a way to decode that. With this approach the assets are just a regular code so you will version it as such. For example:
MyIcons>>icons
^ icons ifNil: [ icons := Dictionary new ]
MyIcons>>myIconContents
^ 'BASE64STRING'
MyIcons>>myIcon
^ icons
at: #myIcon
ifAbsentPut: [ Form fromBinaryStream: (Base64MimeConverter mimeDecodeToBytes: self myIconContents readStream) ].
Ideally you also make the MyIcons class a singleton, so it can cache it properly.
This can be a bit tedious to do manually, so I've written a tool for this some time ago https://github.com/peteruhnak/IconFactory (it's still very basic, but it mostly does its job).
Add the assets in CI / load it on demand from web
If you a producing a pre-built images for end-users with CI (Jenkins, Travis), you can load the assets there as part of the build script. This is, I believe, what Pharo 6 currently uses for icons. However the downside is that the users would have to always use the built image, or it would automatically (from class' initialize) download the assets somewhere from the web (which can be problem if you don't have internet access, or the site is down).
Use Git
Finally, if you are using git to store the code (GitFileTree or IceBerg), then installing the project will also require a copy of the repository (so either it automatically downloads one, or you point it to your local clone). Then you can reference the cloned repo to retrieve the data. This will most likely be a bit finicky, but it should be in principle possible.
Note also that there were some plans to properly manage Assets with Pharo 6 (the current dev version), but I am not sure the state of it, or whether it was dropped for this release (which would push the development for Pharo 7 most likely).

The version control system currently used by Pharo (called Monticello) cannot deal with those kinds of artefacts. Monticello knows about classes, methods, traits and a couple of other things but it stores neither variable data (e.g. your bitmap in the class variable) nor additional resources.
That being said, you can use a Git repository as the backend (see FileTree for the Monticello repository and you are free to add resources to the Git repository as you want (as long as you don't modify the FileTree structure). You can then simply load those when necessary.

Related

Should libs ands frameworks be subject to a version controlling repository?

Our sw project uses for its build process different libs (popular as well as special ones) and a framework. The libs never change, whereas the framework could be changed from time to time to an updated version.
For extended further developing we want to use a version control system. Which of these solutions is the most elegant one:
The full project with all libs and the framework gets uploaded in the version control system's repository thus everyone has exactly the same files, but the use of space in the repository is enormous.
Only the artifacts of the project which are getting effectively changed over time (the main program) are in the repository. Used libs and the framework are stored on a central NAS. -> Files could be used for other projects, too.
Like 2, but everyone hast a copy of the libs and the framework on his local workspace.
For my taste solution 2 or 3 sound better, because I think that the repository should be as light as possible. What are you recommending?
This is obviously a matter of opinion, but my opinion is that the most important characteristic of version control is the ability to reproduce source at a particular point. That includes libraries. There are downsides (boost is huge, for example), but it guarantees that everyone gets the same code, especially in the case of obsolete or unsupported libraries.
You can have both; structure your source control so that it separates your source and your lib/framework. People can put them in different places locally if they so choose, but everybody will have the same codebases.
Disks are cheap; time wasted trying to figure out why people aren't all seeing the same thing isn't. The most important thing is that everyone stay in synch.

Organizing Different Versions of App in Xcode

I'm developing an iPhone app that can edit images. Ultimately, I want to have a small version that allows the user to simply edit their images, and a large version that allows social networking of the images. Then I'd like to develop a version of each for the iPad.
Being that this is my first foray into commercial mobile development, I'm confused about how to organize all these versions in Xcode. Obviously, there will be file reuse shared between each version. I guess my question is, how do I go about organizing these separate projects in the most efficient way so that they share files and so when I edit a particular file that is shared, the changes are made to each version of the application? Is there some kind of construct to follow in XCode?
Are there any links or literature on how to go about doing this? (was not sure the correct term to search for it).
Remember: If you find yourself repeating/duplicating something, suspect that you're doing it wrong.
Your Xcode project will have 4 targets in this scenario. The basic target layout for this setup looks like this:
A Static Library (for your shared source files)
A Resource Bundle (for your shared resources)
App-Full (Universal)
App-Lite (Universal)
The apps link to the shared static library, and copy the resource bundle.
Naturally, apps will have sources/libraries/dependencies which differ -- those go in the app target (or some other dependency).
Given your background: Plan on it taking a good amount of time (initially and as you go) and patience to figure out how these dependencies should be composed, used, and maintained.
I would suggest keeping the "lite" and "full" projects separate but within the same workspace. That way you can keep the shared files in one project and simply use a shared reference to them in the other. All changes made to the shared files from either project will affect both.
As far as iPhone/iPad versions, I would also suggest that you keep these apps completely separate but within the same workspace (so that they can share code) as well. If you look around about the suggestions for managing both apps in a single project (aka, universal app), the only real benefit is that customers can buy one app and can download it on either device and some may get upset if that isn't available to them. If your app is free, don't worry about it.
Lastly, a caveat about workspaces, you need to uniquely name your files across all projects. For example if you're working with a project that uses a MainViewController.h subclass and another project that uses a MainViewController.h subclass, you could assign or edit the wrong one by accident regardless of what project you're in, so be wary. If using unique file names is a problem, you can bypass using workspaces by simply creating an empty project to dump all of your shared code into and then add references to your standalone apps from there.
If you choose to keep various copies of your project for different functionality, it will be eventually confusing, as there are places when XCode offers you one thing instead of another. One such place is - when you open a project from location X, it will also show you your copy from location Y since you opened it last time. As a result, you are likely to commit more mistakes. Organizer is one more such place where you can make mistakes.
XCode is self-contained enough to maintain both iPhone and iPad versions. You will have two separate storyboards which can be made part of one project if you chose universal as the type of app.
As for various features, you shouldn't be maintaining separate copies of your project. Instead, recommended way is to keep all features within single project, and have app logic provide access to various features.
XCode keeps version of your build under Targets section when you click project. To maintain multiple versions through your dev cycle, use source code repository (git or svn).

With Xcode 4, what is the proper way have a main project + a shared code project?

Currently I have an iPhone app that is just one large project. It has hundreds of code files. I have one folder called "Helper" that includes all of my classes that I have created. I'm going to be making a second app that also needs to use the exact same code that is in the "Helper" folder.
What is the proper way to share that "Helper" code between two projects/apps? Should I put it in its own project file and then add both the main app + "Helper" to a common workspace? I'm not interested in making static libraries or anything... I just want the code segregated somehow.
I've already tried making a second "blank" project file and dragging the code into it, but when I try to build Xcode just thinks I am missing header files now... for some reason it's not seeing the code in the other project.
It would be ideal if there were a clean distinction between the shared code and the code unique to your current app. If there isn't yet, try to make sure everything that will be shared is not dependent on anything from the code unique to the project.
One way you could accomplish this is by using a Git Repo and then making the shared code its own repo project. Then, in the repo for both projects, include the helper code as a submodule.
I've worked with projects that use submodules, though I haven't set up the submodule aspect myself as of yet. The benefit here is that any changes you make to "helper" can be pulled into the both projects, so the changes are synchronized.
If you aren't familiar with Git yet, I recommend getting familiar. Setting up a Git repo on your computer, even if you aren't collaborating with others, is pretty useful. XCode currently offers the option of setting up a repo when you create your project. If you haven't done that, or aren't sure though, you can still create a repo after the fact.
I use source tree to manage my repositories. Creating a repo is pretty straightforward and easy from there SourceTree. However, you can use GitHub's own desktop client, or any other client if you wish - depending on how you set up your project.
Some information about setting up a submodule in git: Setting up a submodule
So, to recap:
Make sure your "helper" code can stand on its own
Put the helper code into its own repo
Include the helper repo as a submodule to any project you want the code in.
Hope that helps!
It sounds to me the situation you have described is exactly what a framework is designed to solve. What you would likely end up doing is creating another project with all of your shared code within it and creating a framework which your applications could link against.
I would suggest reading Apple's Framework Programming Guide. From the introduction to the guide:
Mac OS X makes extensive use of frameworks to distribute shared code and resources, such as the interfaces to the system itself. You can create frameworks of your own to provide shared code and resources to one or more of your company’s applications. You can also create frameworks containing class libraries or add-on modules with the intention of distributing them to other developers.
You can put the shared code in a separate folder and then add it to the both projects.
But don't forget to add the path of the folder to the User Header Search Paths in Build Settings > Search Paths.
I'm not interested in making static libraries or anything...
Yet, for iOS, a static library target is exactly what you'd use.
No workspace required, just a separate Xcode project with that shared static library, which both apps reference.

Project layout with Subversion and static resources

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.

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.