Given: http://developer.android.com/resources/faq/commontasks.html#filelist
What are the best practices for getting your projects into source control? I ask because if you simply right click on your project, choose team, etc. you end up with the /bin & /gen folders, .classpath as well as all the Eclipse related items.
If I'm inheriting a project with .../workspace/projectName et al. included how can I clean that up to include only the items relevant to the aforementioned URL?
I summarized all my findings in a blog post that can be found here: http://www.aydabtudev.com/2011/05/what-goes-into-source-control-android.html
I executed the following commands from within my project folder to get them out of source control:
svn rm --keep-local .classpath
svn rm --keep-local .project
svn rm --keep-local default.properties
svn rm --keep-local proguard.cfg
svn rm --keep-local bin/
svn rm --keep-local gen/
Then I executed the following command to add them to an ignore list:
svn pe svn:ignore .
Add each item above without the associated command like so:
.classpath
.project
bin/
...
I followed that up with a commit and an update to solidify my changes.
svn commit -q -m "Removing files" .
svn update
It would seem the smarter way to do this would be to configure the Ignored Resources under the Eclipse Team preferences.
If you're using SVN, you should selectively add files/directories to your repository.
For example with the following directory structure (quick example from my disk):
res/
src/
build/
.idea/
You do not want the build directory, nor the personal preferences for your IDE (.idea folder) adding, so you would only issue the command: svn add res src
To (I think) answer your second point, I'd manage everything to do with version control from command line initially, and then let your IDE do it.
My apologies if I'm missing the point of the question.
Here are some basic points:
Don't store stuff in version control that your source code produces. For example, if you build a jarfile, don't store that jarfile under source control.
Source control is for source. If you have releases, use a release repository like Artifactory. Don't let the Maven stuff scare you away. Maybe you don't use Maven (now), but a Maven repository tool is in standard format, and makes it easy to find your releases. Artifactory can work with Ant/Ivy, and with a little elbow grease, you can get it to work with C and C++ projects too.
Which brings me to the next statement: Don't store your jarfiles (if you're a Java project) in your source repository. It's convenient, but you'll end up hating yourself for it in the long run. Binary files take a long time to process in many source control systems and they can take up lots of room. What's even worse is that you lose information about them. For example what version of common-utils.jar is checked into Subversion that my project now depends upon. Again, use Artifactory and Ant/Ivy or Maven. If you're non-Java, you can use wget or curl to fetch your dependent libraries out of Artifactory. Again, don't let the whole Maven thing scare you.
If you have a Java project, and you don't use Maven, insist that code is stored in the repository using Maven's standard layout. That is, Java code is stored under src/main/java and non Java files are under src/main/resources. The advantage is that it makes it easy to move from project to project, and new developers can quickly find where things are. Plus, it makes your build.xml files much cleaner. You can use any standard repository layout you want, but by insisting on Maven's standard, you can squelch all complaints. "Hey, I agree with you, but Maven says you put your code under this directory. Sorry, I wish I could help, but my hands are tied"
If you're using Subversion, stick with the standard, trunk, branches, tags style and don't be too fancy. I'm not 100% crazy about the layout myself. (I'd rather have a main under the branches directory and no trunk), but you'll simply confuse developers and make support more difficult, and all for very little gain.
Make sure all projects (if you're using Ant) have standard target names. Again, I borrow Maven's naming convention. Make sure all build.xml use the description parameter in target names, and that internal only targets don't use description. That way, ant -p works. Also make sure that all built artifacts are under the target directory (again, Maven's way). It makes it easy to do a clean if you only have to delete the target directory. The idea of clean is to restore your layout to pristine checkout condition. Makes it much easier to use a tool like Jenkins. Which reminds me...
Use a continuous build tool like Jenkins. It helps you enforce your policy and standards. Unlike many tools, developers actually like Jenkins. And, you can add stuff like automatic testing, checkstyle, etc.
1.
It depends on your workflow. If you expect everybody who will ever work on your project to use eclipse having the .classpath folder in there is good because it keeps all your settings(library paths, external dependencies..)
To the best of my knowledge subclipse doesn't put the /bin folder under version control(it probably happened because of the weird way the repository shaped as you describe in 2.) because eclipse can generate that one on the fly as soon as it has the /src folder.
usually moving everything under /workspace/projectName to / and deleting /workspace is sufficient.
Related
I saw a lot of examples for .gitignore files for AndroidStudio, some have .idea in them, and some don't.
Is there a good reason not to add the entire .idea dir to .gitignore?
If it should not be completely ignored, are there specific files inside .idea (such as .iml) that should be in .gitignore?
You can take a look at this page :
IntelliJ doc about project configuration files
In the "Directory-based format", a particular line is interesting :
The .idea directory contains a set of configuration files (.xml). Each file contains only a portion of configuration data pertaining to a certain functional area which is reflected in the name of a file, for example, compiler.xml, encodings.xml, modules.xml.
Almost all of the files contain information core to the project itself, such as names and locations of its component modules, compiler settings, etc. Thus, these files may (and should) be kept under version control.
However, I properly HATE to make project IDE-dependent (I am currently working on a project made with NetBeans and it hurts to use it with Eclipse which becomes the standard of my company).
So, to answer your question :
If you do not use something like Maven or Gradle to manage dependencies and build : keep the directory under version control. This way, the correct configuration of the project and dependencies will be available for everyone. In the counterpart, all developers will have to set their environment exactly the same way that you define it in the config files.
If you do use something like Maven or Gradle : correctly configure these tools and do not keep the directory under version control. Actually, all the information contained inside config files should be stored in Maven/Gradle files. Then let your developers configure their IDE depending of their environment. This way, using Eclipse, IntelliJ, Linux, Windows ... will not be a problem anymore.
OK, so after some "Yes" and "No" answers, I am adding a "Yes and no" answer :)
The problem is that .idea is used for both project build configuration (dependencies declaration) and project settings (inspections, etc.).
You definitely don't want to use your IDE for your build configuration, but you might want to share the settings among the team. That's why you need to ignore only a part of the .idea content (like the libraries folder and the modules.xml file), but keep others in the version control (e.g. the copyright, dictionaries and inspectionProfiles folders and files under .idea like dynamic.xml, codeStyleSettings.xml, etc.).
The concept of keeping the project configuration in VC is valid. I did this with my team because all of our developers happened to use PHPStorm for our projects and so it made sense to keep a common configuration ... in concept. We wanted to use the same dictionary files, the same coding standard rules, and the same plugin configurations.
The reason why I qualify this with "in concept" is because there were issues with JetBrains' .idea folder that led to us not being able to use it. These were probably issues that could have been avoided or fixed, but it was unclear to us how to do it right, and we think that's a fault of JetBrains because as developers we do not have time nor desire to search for solutions on how to make our IDE work correctly.
That being said, the issues were had are the following:
Symlinking project folders doesn't work right.
When I set up my projects, I symlink them into my home directory. What we discovered was that the project was set-up to use the exact symlink rather than just treating it like a concrete directory. This means that if another developer keeps his project in a different place, or simply does not use symlinks, the entire directory will be missing from the project navigator because it is quite literally looking for the symlink. What's worse is that I could never find this path value in the configuration. We were unable to find the exact config in the files constituting our .idea folder.
Definition files are partitioned to users by default. This means if I want to add a word to my dictionary, it will be listed as a definition for me, jgreathouse, but other users will have their own definition section. The flagged words will still show up as a spelling mistake for other users. This is not desireable. The reason I add it to my definition file is because the IDE is wrong. I want these definitions to be intuitively shared with other users.
Colleagues kept overwriting the configurations because their IDE would overwrite the configurations with their config currently in Memory. What I mean is that, a developer would be working, and merge their repository from origin, which would contain a project configuration change, instead of their IDE changing configurations, or even giving them a choice, it would automatically overwrite the .idea configuration with the current in-memory configuration of their IDE. In my opinion this makes the .idea configuration unusable as a shared configuration. In order to work around this, the developer would literally have to shut down that instance of their IDE, pull the repo, and re-open their IDE. It makes no sense to keep a shared configuration if the IDE instantly overwrites it with the configuration currently in memory. It's like not having a shared configuration at all.
I've done these types of shared IDE configurations in VC before with Visual Studio and Netbeans and it was always fine; but with .idea it feels simply unusable which is disappointing. I wish JetBrains would get on top of it and make it a better user experience.
As a complement to the explanations in this question GitHub's .gitignore template for Android includes the following files:
# IntelliJ
*.iml
.idea/workspace.xml
.idea/tasks.xml
.idea/gradle.xml
.idea/assetWizardSettings.xml
.idea/dictionaries
.idea/libraries
# Android Studio 3 in .gitignore file.
.idea/caches
.idea/modules.xml
# Comment next line if keeping position of elements in Navigation Editor is relevant for you
.idea/navEditor.xml
Notice also this entry from JetBrains guidelines on How to manage projects under Version Control Systems about sharing IDE project files with other developers:
What needs to be shared:
All files under the .idea directory in the project root except the
items that store user-specific settings: workspace.xml
usage.statistics.xml shelf directory
How should external libraries be included into Android projects?
I see this documentation from Google:
http://developer.android.com/tools/support-library/setup.html#libs-with-res
...which says they should be kept outside the source tree for the project, and referenced as dependencies.
The guide for Facebook libraries says the same thing:
https://developers.facebook.com/docs/android/getting-started/facebook-sdk-for-android/
What about when the project is going into source control, and will be worked on by multiple developers? Is it possible to be sure other developers will have the correct versions of libraries if they're not included in source control?
It seems as though it might be better to check in the whole tree of these external libraries under say an "external" folder in the project and then reference them as libraries from there? The above links don't say this is wrong, but is there any reason not to do that?
I could not find anything against this approach, but maybe my search skills are off.
Thanks!
You have basically tree options (referring to git):
Putting the source or binaries into your git repository.
You can create/clone extra repositories and link these as submodule into your main repository.
Use gradle/android-studio to maintain remote binary dependencies.
In my opinion, option 3. is the best. It speeds up build time and reduces the date saved in your internal repository. Referencing most open source projects, googles libraries and even the Facebook API is just a one liner in your build.gradle file.
For internal libraries or anything not uploaded to some maven repository, you can create a local maven repository and link that.
And in the end, you have the option 2. to create a library submodule within git and gradle to handle it efficiently.
If you want to stick to eclipse + ant, try 2. first.
At least ant will work out of the box for building all things.
Setting up eclipse is a bit more difficult but can be done.
Option 1. is easy to implement, but It might get messy at some point.
Copy jar file in android project libs forlder and right click on jar file and click on bulid path-> add to build path.
If you want to add jar file then copy your jar file and put in to libs folder, and if you want to add external library then import your library project go to project properties and select android tab and add external library with add button.
I'm using ActionBarSherlock as a library. We haven't included ABS into our repository so everyone participating our project must download and install it separately. ActioBarSherlock is an Android library project and I have got it running by opening it and my project in the same Eclipse's workspace (neither of those are copied into workspace, they both exists in another folder) and adding it into my project.properties by following this:
Referencing a library project.
That reference path is relative and since everyone might have ABS in different folder, we also have different paths in Eclipse's project.properties file as android.library.reference.1. Is there any way locally override that library path so that we can have project.properties in our repo but Eclipse will use locally some other path? Currently I have to manually fix that path after every time I pull from our repo because of different paths.
There exists other *.properties files but Eclipse ignores them:
local.properties
Customizable computer-specific properties for the build system. If you use Ant to build the project, this contains the path to the SDK installation. Because the content of the file is specific to the local installation of the SDK, the local.properties should not be maintained in a source revision control system. If you use Eclipse, this file is not used.
ant.properties
Customizable properties for the build system. You can edit this file to override default build settings used by Ant and also provide the location of your keystore and key alias so that the build tools can sign your application when building in release mode. This file is integral to the project, so maintain it in a source revision control system. If you use Eclipse, this file is not used.
Just have each person put it in projectroot/libs. The newer (ADT 17 and above, IIRC) versions of the ADT will automatically pick it up and compile it into your app. Note that the folder is libs, with an s, and not lib. Using /lib won't work.
Options:
project.properties: You could create a link in every users home folder, libs and have the path in the project.properties refer to ~/libs
Using a common library:
Create a library project called "common". In settings, have it export the jar. In your Android application, import the jar.
Personally I think configuring with maven would be best but the 2nd option was quickest.
What about if you ignore the project.properties in your repo? That way each user can keep their own and you won't need to override it all the time. I don't think you can override that locally.
Another option to simplify things is you can export the project as a JAR file instead of referencing it as a library project. If you don't need to modify ABS code you can right click the project -> java -> jar file and all the developers can keep that in the same place for the sake of simplicity.
Edit: This question is no longer needed for our project since we moved from Eclipse to Android Studio and Gradle build system. Eclipse with Maven should have worked too, as #bgs suggested.
Our previous approach:
Still looking for better alternative but so far we ended up keeping project.properties in our repo. project.properties does not get overridden if there is no changes to it when pulling. We also suggest in our README that users add this
[alias]
commit = commit -X project.properties
to their .hg/hgrc configuration file to prevent accidentally commiting changes of that file.
This method has at least one drawback: When merging, you might get error like this abort: cannot partially commit a merge (do not specify files or patterns) even when you commit your merge with hg commit -m 'merge'. If this happens, disable that alias temporarily.
I am currently using Git on the command line to help me incrementally add features without breaking existing code. The part that worries me is this line of output from Git after committing:
[optimized_managed_event 6c9a98c] Added managed event insert into my ContentProvider
12 files changed, 202 insertions(+), 16 deletions(-)
rewrite bin/classes.dex (87%)
rewrite bin/classes/com/zeroe/SmartCalProvider.class (85%)
Should I worry about the rewrites if they are .class files and other types that aren't text? I am fairly new to Git, but am pretty comfortable with the command line and I understand the basic workflow for most Git projects:
> git add .
> git commit -m 'comment on commit'
> git checkout [master]
> git merge [branch]
What I am slightly worried about is issues that can occur when committing, then merging since Android projects have a lot of files that it creates itself in different formats.
My question is essentially in anything I need to worry about when doing this in Android development?
Create .gitignore in the root of your project and add at least the following:
*~
*.apk
bin
gen
local.properties
.apt_generated
This way you avoid putting in repository automatically generated files, which usually blows the repository size up without any reason. The only automatically generated files you might want to save are proguard/ files, which might be necessary to unroll the call-stack after the user-generated crash reports.
Also, I found it's very helpful to have giggle utility installed to see what changes you have in your files.
I asked this question on the android-developers group but didn't get any response, so I thought I'd try here.
The ADT eclipse plugin seems to have a pretty rigid idea of how an Android project should be structured - per http://developer.android.com/guide/developing/eclipse-adt.html, it needs to have the AndroidManifest.xml file at the root level of the project, plus res, assets, gen and src folders at the top level, and so on.
I'm wondering if it's possible to get the plugin to be a little more flexible with the layout it recognizes. In particular, I've been using a build plugin for the (scala-based) simple-build-tool, which expects projects to be laid out in a more Maven-like fashion, like so:
src/
main/
AndroidManifest.xml
assets/
res/
scala/
java/
test/
resources
<files to include in test jar here>
scala/
<test Scala sources>
java/
<test Java sources>
(see the simple-build-tool docs).
This is a layout I'm used to from maven-based java development. When I load a project like it up in ADT, though, I get a lot of complaints about a missing AndroidManifest.xml, a missing res directory, and so on. These things are all present, they just aren't where ADT expects them to be.
I don't necessarily need to use ADT to build my project, but I'd like to use it (and Eclipse) for editing. Can anybody tell me whether it's possible to make it more flexible in the directories it uses to find various Android-related resources?
Also, can anyone tell me whether the ADT plugin is open-source? I can't seem to find a link to its source code anywhere.
(As a note, I've also been trying to wrangle sbt to just do things in a way that ADT likes, and it's probably possible to do but it seems very tedious.)
Here's is where you can find the ADT source for r3 0.94, couldn't find the latest though
I do not believe you can change the Android project structure and have ADT understand it. It would be "very tedious" to do that even with the Ant-based command-line builds -- you'd have to make your own copy of the various Android Ant tasks, modify them to suit (and hope the underlying build tools allow what you want), then maintain them forever in the face of Android SDK updates.
Your structure is actually fairly close to the Android expectation, if you consider main/ to be the Android project. If you can convince sbt to allow src/ instead of java/ there, and if sbt won't complain about the resulting bin/ and gen/ you will wind up with in main/ after a compile, you might get it to work.
As far as I can tell, ADT requires those folder names, but there is a workaround: you can create "linked folders" in Eclipse. These are similar to symbolic links in Unix, but are stored in the Eclipse .project file instead of the filesystem, so they are only visible to Eclipse.
You can create one by right clicking in Eclipse the root of the project, and then selecting "Create New Folder". Click on "Advanced" and select the option to create a linked folder. Then type in where you want it to link to. You can use PROJECT_LOC at the begining to specify the project directory, so for your example you would type PROJECT_LOC/src/main/res as the folder to link to, and use the automatically generated name of "res" for the created folder.