how to nest a git project in a git project? - php

Issue: Nest a git repo in a git repo WITHOUT storing the second repo in the hosts master repo. The repos need to be two separate entity's. This way I can easily update a client sites base code (used on multiple sites).
Reason for two repos: I have a base php framework that my projects use. Each client gets their own repo that has the files required for that site. Due to the way git/submodules work I have to keep the "framework" as the master repo with the "clients code" as the submodule. The reason is I MUST have the index.php & .htaccess (part of the framework) in the root. That's fine since my framework is designed to extend as needed. I can just put any client files I need in the "site" folder and store that as a separate repo. The obvious downside is in order to setup the site you have to first install the "framework repo" then install the "client repo". Since these are private this setup is fine. I also liked the benefit of being able to update my framework from another project. Trouble is now any push's I do from that clone include the "client code". Also since I need the same setup for my local test of the framework that submodule gets added back to the main framework repo. I thought well why not just clone the "site" folder that holds the "client code" and add that folder to the ignore list. I have to update each by hand but again thats fine. However torisegit seems to think that its now a subproject (limited support) and I cant even add that folder to the ignore list. So i'm assuming nesting git clones is bad but I could be doing it wrong.
Goal: I need to be able to deploy two repos. My "framework" im sure has to be the base/root repo. Then I need to embed somehow a second "client" repo in a folder inside the base repo. The "client" repo never stores the framework code, just its own code. I want to be able to update and push changes to the "framework code" (its alpha so lots of bug fixes) without it storing anything about the "client code" so I can easly just clone it into a new folder for a new site. Again client code is stored in a single folder one level up from the frameworks root. (See example below). Doing this as a git clone breaks TortoiseGit and possibly git when I try to copy paste a folder and even add it by hand to the ignore file. Adding it as a submodules adds it to the master repo so when I clone it trys to add it.
Final Thoughts: Perhaps subprojects would work but there does not seem to be much support for it and I dont understand how to use it. Im trying to keep it to major tools so that my two main tools TortoiseGit and NetBeans support everything. Perhaps there is a way to not store a submodule in the master repo but I cant find it. Maybe subfolders would work but again there does not seem to be much support for it. Seems like the simplest would be it just ignore the folder but at least TortoiseGit seems to break when I try this but I could be doing it wrong.
Example Folder Layout:
-.git (framework repo)
- system *framework folder
-- foo *framework folder
-- bar *framework folder
- site (root for second repo aka client)
-- .git (client repo)
-- config.php *client file
- index.php *framework file
- .htaccess *framework file
The "system" folder, index.php and .htaccess are part of the PHP framework and are generic to all my sites. The "site" folder holds the second repo that contains the files for that site. The second option is to rewrite my framework so that its stored in its own folder and gets called by a new index.php. However this is a major rewrite with a pathing nightmare do to the way its written. Plus the issue of dealing with the .htaccess file since that has to be in the root. Sure I could copy it but then any changes to that file would not get updated in a pull. But at this point i think its the only way.
Hope this makes sense. I'm out of ideas but really want to get this to work.

You can always just clone the second repository where ever inside the first you like, then add the second's folder to your .gitignore file.
In your example above, you'd just add:
site/
to your .gitignore.

Git Submodules is the best thing I can think of. Check it out here. It's very handy for splitting up code into reusable repos too.

Related

Managing Multiple Websites with a Single Laravel Codebase

My team has recently put together a Laravel codebase that works great for multiple websites. Currently we are running them as an app that installs on a centOS7 profile.
Whenever a new site is required, we fire up a profile, and the code gets cloned in. The codebase depends heavily on packages (custom laravel packages). Currently every site pulls in all of the packages that we have developed. Currently the differences are 1) The .env file. and 2) The theme config files (which come from a package and I'll touch on later).
I want to be able to pull packages based on need, I don't want to pull in every package we've developed. My question is, is there a way around pulling in every package? I was thinking of removing the composer.json file from git and treating it like a config file? I also thought about generating the composer.json file.
Eventually we want to add CI/CD to the process and really automate this thing. I am really fighting to keep the codebase in one repository. Am I wrong? Should we split the codebase up, one repository per project that comes in? But then you have to consider that updates become a nightmare.
Currently, themes are pulled in as packages. Every site has all of the themes in the composer file. The app has admin users that can login and set a theme to active. Still, I'd like if it only pulled in the necessary themes resources.
Sorry if I rambled a bit, but I am wondering how to scale the application properly.
Thanks a bunch!
tldr; How can I run multiple websites using one codebase, while being able to specify different required custom packages?
I haven't actually tested this but you might be able to accomplish what you want by defining multiple composer.json files. Read more on defining other composer.json files
Then, in each composer.json file define a different vendor directory. Example:
{
"config": {
"vendor-dir": "plugins"
}
}
Next, on each install specify which composer.json file to install, From the docs:
By setting the COMPOSER env variable it is possible to set the filename of composer.json to something else.
Example from docs:
COMPOSER=composer-other.json php composer.phar install
Read more on specifying the environment.
Last but not least, you will have to bootstrap your website or application for the specific vendor directory:
require __DIR__.'/../custom-vendor-directory/autoload.php';
This can be customized in your application's index.php file. The original source.

Can we use Composer with sparse SVN checkout to share dependencies?

Our current development setup uses a single Subversion repository containing multiple projects, each with branches, tags, and trunk. We then use a "sparse checkout" to select the projects, and branches of those projects, to work with.
The result is that the directory structure of a working copy matches that of the repository, including branch information, and we never use svn switch. (This style of working will probably be familiar to anyone who uses SVN, but may be surprising to those who don't.)
We are thinking of using Composer to manage both external and internal dependencies, but I'm not sure how this can work with the sparse checkout style of working.
I would like some way of using a directory within the existing checkout to satisfy a dependency, rather than each "root project" needing a separate copy.
For example:
sites/Foo/trunk
depends on lib Aaa, so references lib/Aaa/trunk
depends on lib Bbb 1.5.*, so references lib/Bbb/branches/release-1.5
sites/Bar/trunk
depends on lib Aaa 1.0.*, so references lib/Aaa/branches/release-1.0
depends on lib Bbb 1.5.*, so references lib/Bbb/branches/release-1.5
At present, if I edit the code in lib/Bbb/branches/release-1.5, I can test those changes on both sites, without needing to commit one and update the other.
Is there any way of using Composer to manage these dependencies?
(PS: Please don't answer with "give up on SVN, use Git, it is teh awesomez"; that is an answer to a different question.)
No - I do not believe that you can do this with Composer as standard: it expects to copy the files from whichever source (Packagist/VCS/Zips) to the local vendor folder, which is not what you want.
That said, I believe there are two potential ways you could get this working (at least in part):
Autoloader
You could try using the autoload field in the composer.json file to include the correct files into the project. You would still need to manage the checkouts of the relevant branches/versions manually (like I assume you do now), but you would be able to manage the inclusion of the internal libraries through Composer. This will probably require that your libraries are properly namespaced. The paths to the files for each namespace are relative to the root of the project, but can go below the root (via the /../ path) if required.
To be honest though, if you already have an autoloader for these files, there may not be much advantage to this solution. Relevant Docs
Composer Plugin
You could also write a composer plugin/"custom installer" that could probably manage this. This would have the advantage that you could have it manage checking out the correct parts of the sparse repository to have the correct version available, as well as doing correct wildstar version checking, but would be a much more difficult and riskier venture.
The basic process would be that you would define a new package type (e.g. 'internal-svn-package'). You would create the plugin as an external library that gets installed normally via Composer, which declares (via it's composer.json) that it handles this new type of package. Your custom logic would then be used for any packages that are listed with this custom type. I'm not sure how much of the internal composer logic for SVN checkouts you would be able to reuse however. Relevant Docs

Gitignore files from an existing project

I want to start a new repo on a current project I'm working on, the idea is to have a repo with, say 60% of the files in my project as a template so I can quickly clone it if I need to (I guess I could use gitignore to achieve that but maybe there is a better way of doing it).
For example:
- Website 1 contains these files/folders:
index.php
app/
config/
css/
I want index.php and app/ to be in the repo as the code will be exactly the same for all future websites I clone. But I need config/ and css/ to be unique to each website.
So now if I go to Website 2 and clone the repo from website 1 I would get index.php and app/ but nothing else, which means I would have to copy all other files manually, Is the a better way to do this?
The reason being that when I upgrade files in the repo I can quickly pull/fetch them on the other clones without affecting the unique files, if that makes sense.
Maybe there's a simple way of doing this.
Yea,
Copy what you want your new template repo to contain into a new folder structure and then create the new repo from that.
If the files are ignored, then you cannot get git to pull them.
If you are really desperate, you could make a new branch, where you remove the gitignore file (or the corresponding rows), then commit all files and pull them from the other server.
After that, you reverse your commit on webserver 1, or you unfollow css, config files.
On webserver 2 you would need to manually unfollow the css, config files too after the pull.
I would rather copy the files manually.

Git - Few git repos clones and what not (PHP - framework Lithium, ORM Doctrine 2)

I'm fairly new to git (vcs in general) so I need help with this next case.
I want to start working on a new project, which will be built using php lithium framework, and doctrine 2.
Case:
I have a main project git repository, and now I want to add (clone) lithium framework inside, from github.
Next, I need to clone li3 extension for doctrine 2 (it automatically clones itself and doctrine 2).
Questions:
Is this the right way (I suppose not).
How do you manage cloning inside existing repository (especially that second part, with li3 extension and doctrine 2).
Thanks in advance.
In git there is no such "cloning inside existing repository" (well technically there is but let's don't make this more complicated than needed). What you describe looks like that you want to use the lithium framework and doctrine as a library.
Normally you don not need to put external libraries into your repository. You only need to do this if you plan to modify the library code and put it under version control.
But you should think first about what you would like to do: integrate it into the repository or not. I think the later is the easier one.
You just create your own git repository first. Then you exclude that part of the library folder that you don't want to have under version control. So you can keep things apart quite easily in the beginning.
To set this up, first create your project on disk w/o git. Create the file system and directory layout. Then initialize the git repository within the project's main directory. That's just calling git init inside that directory.
Git will now show the status of all files you have in there when you type git status. Before you do the first commit you can use the methods described in gitignore(5) Manual Page to exclude the libraries and (perhaps configuration files of your IDE) that you do not want to have inside the git repository.
You can always check if the configuration you're editing matches your need by checking the output of git status.
Keep in mind that git ignores empty directories, so if there is a folder you don't want to be added, it will start to show in the status only if it contains at least a file.
When all the files you don't want to have under version control have disappeared from the status listing, you can do your first commit: git commit -m "Initial Commit.".
Depending if you have configured git or not, it will give you an error about your name and email. The error messages point you to what you need to know. It's just that you have an author and email for each commit, which is useful.
And that's it already. Check the web for the commands:
git init
git status
git commit
it's quite easily with git help *command*, like git help init. It takes some time to learn git, so probably create some test-repository to play around. Once you've learned the commands and get used to it (in case of doubt, google your problem), it's supercool to use.

Why to have "build/" folder with PHP project and phing

What is a benefit of having "build/" folder where all the sources will be placed and "built"?
Maybe it's a silly question, but I'm trying to understand Continuous Integration with PHP. Any example of build.xml for phing uses such build/ folder, but what's a sense in that for PHP where a checked out project doesn't require a compilation, only a basic configuration. Copying it all into build/ will just complicate the things, because you'll have doubled files and +1 folder to the web root path (if you'd like to have web UI to run selenium tests on)
Particularly I need phing for two cases:
1) let new user setup his first installation (or update old), right on a working copy
2) run unit/func-tests, phpcc, phpcs, phpdoc etc (all that usually on CI server)
Should I have "build/" for the second task? What is the best practice for PHP?
There are several good reasons to have a build directory (i.e., deployment to multiple environments, performing some text replacement, minimizing and combining CSS and JS, optimizing images, handling of config files etc.)
However, these may not apply in your use cases. There is no rule saying you need this directory. Depending on your thinking on testing in production, a build directory may be a good reason to keep this directory.

Categories