I'm writing a Symfony Console PHP application which takes a version number in the constructor.
$app = new Application('myapp', '1.0');
I've already found that it's easy to forget to bump the version number when making a new git tag release. How can I do this dynamically/automatically?
Aside from here on SO, I searched packagist pretty deeply because I thought for sure this was a common thing, but wasn't able to turn up anything.
I thought at first to write a function that would do something like this:
chdir(__DIR__);
shell_exec('git describe --abbrev=0 --tags');
But because I globally require this CLI app with composer, it doesn't have the git repository with the source code.
My next idea is that I know I can at least get it from composer
composer global show myname/mypackage
But this spits out a ton of information and there's no option that I'm aware of to just show the version number. I feel like filtering through all this with something like regex might be overkill. Is there any better way?
Pulling the version number from somewhere could be difficult, because you could run an older version of the application but wrongly pull the newest version number.
You could add a "release.version" file to your repo that only contains the version number and read this to pass it to the constructor.
Then you can use a git hook like pre-commit to update this file before you commit a tag.
This however is not recommended in distributed systems because it could lead to collisons, but for smaller teams or teams with a dedicated release manager it might be ok.
Read here: https://wincent.com/blog/automatic-deployment-numbering-in-git
and How do I enable ident string for Git repos?
It would maybe be enough to have a pre-commit hook that checks for a new tag and just reminds you to increment the version in the code ;).
Related
I ran composer in order to use guzzle. It resulted in these directories:
composer
gabrieldarezzo
guzzlehttp
psr
ralouphie
symfony
I noticed the file car.png in the gabrieldarezzo/colorizzar/. That whole directory seemed useless for guzzle so I deleted it and the code still works. I tried deleting some of the other directories, one at a time, but to code failed. Is there a way to know which files are actually required?
Edited after comments:
The purpose of this question is to ask if all of the files composer adds are necessary. I re-ran composer to a new location and it installed version 6.5.8. The gabrieldarezzo was not included so I must have ran composer for some other package at some point. From all of the replies I can see that the answer to my question is yes, they are required. I appreciate all of the replies to this.
That whole directory seemed useless for guzzle so I deleted it and the code still works.
This statement is meaningless without talking about what code still worked - in other words, which files are required depends on what you're actually doing.
If you ask Composer to install Guzzle and then write a PHP file that just says echo 'Hello world'; then you could delete the whole of the vendor directory, and clearly nothing would break. Or you could write echo \GuzzleHttp\RequestOptions::ALLOW_REDIRECTS; and delete everything except for vendor/guzzle/guzzlehttp/src/RequestOptions.php where that constant is defined.
Is there a way to know which files are actually required?
In theory, you could statically analyze a piece of code, recursively identifying which pieces of code were reachable, and therefore what the minimum set of files used would be. You could also monitor a running application and see which files it opened, at the PHP autoloader level or even at the OS / file system level.
But the question is why do you care?
It's important to understand that no file will actually be read and loaded into memory unless it is referenced in some way. This is the purpose of autoloading. So deleting files will not make any difference to the compilation or execution speed of your application.
Deleting the files will reduce the disk space needed to store the application, but it would be rare for the space involved to be a significant proportion of what you have available. It would also reduce the bandwidth needed to deploy it, but source code generally compresses well, so once bundled into something like a tar.gz, this saving is generally also insignificant.
A final note which might be relevant is that none of these files should be committed in your version history. You should commit composer.json and composer.lock, and mark the entirety of the vendor directory as "ignored" (e.g. in a .gitignore file). You can then get the exact dependencies used by any version by running composer install, which reads the versions from composer.lock.
Whenever you require third-party packages without deeply reviewing and track-listing every single file with cryptographically secure content hashes of the reviews outcome, you can easily run into the situation you describe.
The problem with "randomly" deleting such directories is that it does not replace proper dependency checking, but merely prevents the (now removed) code from being loaded onto production systems to be analysed and executed in memory (or in the case of the car.png for some other reason?).
Now between those two poles there is a lot of room and commonly development projects and the people running them aren't important enough that dependencies actually get reviewed thoroughly albeit most of them come without fitness for a particular purpose and a disclaimer in very bold letters.
However if that is a project you look into and you find that some files look fishy, report the issue to the project if you care and it means something to you.
Sometimes projects do not make (extended) use of the dist distribution of a Composer Package (concept) and there is room for improvement (it should go without saying that this is with no judgement of any of those projects practices). E.g. to exclude development resources in production use. This has the benefit that you don't need to remove files "randomly" but you cooperate with actual developers and software distributors.
I wish to be able to do something like:
php --determine-oldest-supported-php-version test.php
And get this output:
7.2
That is, the php binary checks test.php for all function calls or syntax used, and then spits out the oldest version of PHP which would be able to run the script.
The purpose would be for me to create a script which goes through all the .php files in my library/framework and figures out which version of PHP I should consider to be the "oldest supported version".
Currently, I'm doing this manually. Whenever I knowingly use a new feature, function or syntax, I bump up a variable to "7.4" or whatever, and then compare the currently used PHP version against that on runtime. This is not ideal, as you can imagine, and I could very well forget to bump up this value or bump it up too much, or too little, etc.
It would be much nicer to be able to determine this automatically, with such a feature in PHP itself.
I have of course looked through the list of options and PHP has no such feature as far as I can tell. Since I basically answered my own question right away, are there any plans on such a feature in the future?
The only guarantee given is that PHP will remain compatible within the same major version.
You may be interested in looking at the article
Why You Should Be Using Supported PHP Versions.
The tool you are looking for is the GitHub project
PHP_CodeSniffer,
further described in the article
PHPCompatibility update.
You may run it using a command such as:
phpcs --standard=PHPCompatibility --runtime-set testVersion 5.4 <path-of-your-php-files>
My project is a collection of PHP scripts using MySQL as a database and needs to be installed locally using WAMP/LAMP/MAMP.
Previously I've been sending the users a link to a zipped archive and having them overwrite it, but since I took the plunge to GitHub, I've realized that there are far better ways; namely Service Hooks in GitHub. However, this would work fine as long as I don't alter the database in any way, which is a good possibility.
I've been toying with the idea of how I would implement this, but I can't find a clear solution. So far I've concluded with that I need to have a directory (say update/) which contains .sql files for each update. The PHP script will then check said directory for a file corresponding with the new version number (not sure how I will define a version number; I was thinking of using the commit ID, but that won't be available until after the commit, so...).
I would love some input on this!
Here's how I would tackle this (not the most elegant or performant):
Add a flag in the DB with a version number
Add a min-version number in your DB layer PHP file
Check that the DB version is greater than the min-version
If it is: continue about your business
Else: Run the PHP file in update/ which would have a series of ALTER TABLE commands to be run on the DB server
Update the min-version number in the DB to the latest number
All done
Alternately instead of querying the DB you can have a file which is generated by your DB interface PHP file (and ignored with .gitignore) which you can just as above.
I would really recommend checking out Doctrine and its migration feature.
This does exactly what you are looking for, plus you get a very nice tool for working with all other aspects of your database handling.
I have seen a few that only have the checkout functions and options to view the diff and revisions but none with the option to commit changes, so my question:
Any PHP svn GUI with commit functionally?
Update:
to simplify even more:
i need a browser-based interface to a SVN repo that supports write operations, do you know of any?
I suspect the reason one doesn't exist is because it'd be clumsy to use.
You wouldn't have direct file system access (I don't think even Flash or Silverlight provide that, but I could be wrong), so you'd need to upload the files you want to commit or diff.
If you're not using any browser plugins you'd be further limited to uploading a single file at a time, which isn't the way SVN is meant to work. You commit a whole changeset, not one file at a time.
The only feasible way to do this I guess is to have your working copy also on the server and do your editing in the browser as well. At which point though you're not looking for just a web SVN GUI, you're looking for a web-based IDE that has SVN support.
--Edit--
The closest I've been able to find is this http://kodingen.com/ which is still in beta, and looks like it plans to have SVN support but it's not currently available in the beta version (at the time of this answer)
We have a PHP 5 web application and we're currently evaluating PHP CodeSniffer in order to decide whether forcing code standards improves code quality.
We use subversion for our code repository and deployment base and I have added a SVN pre-commit hook to ensure all files committed are free from coding standard smells. The hook technically works but causes too many headaches to be actually useful:
If we have to fix an emergency bug that is causing a site outage, the last thing we need is the commit to be denied due to some minor whitespace indentation issue.
We have ALOT of legacy code that has sometimes hundreds of phpcs errors - it is not pragmatic to fix all the phpcs errors in these files right now. One example is a file full of functions that don't have doc comments. Another example is if a class name starts with a lowercase letter an error is thrown but fixing this might involve changing 10, 20+ files which would need need committing which would then be sniffed, recurse...
We have some files that are a bit large (e.g. 4000 lines of code?) and phpcs takes several minutes to check them. Delaying the commit by this long is unacceptable.
I haven't tested this yet but I imagine if you do a svn branch and commit it, phpcs will check everything and take a very long time to check all 1000 files?
Given that we can't refactor our whole codebase today - Does anyone know how I can use a svn commit parameter that will tell the svn pre-commit hook to not run phpcs?
Or perhaps there is another way to remove the headaches described?
Why run it on a pre-commit? I've used both PHPUnderControl and Hudson to automate php "builds"... Basically, they run an ant/phing build script which runs the automated tests (PHPUnit) and code quality scanners (including PHPCS) after every commit (automatically detected). So it won't reject the commit, but it will send a nice email to whomever you want that the build failed and list why (the specific lines of offending code)...
We have found the following works well, balancing the need to get code in without fuss, but preventing releases that diverge from our standards.
First, we have an "open arms" policy on commit:
All code, working or not, conforming or not, accepted: so long as its commit log message has a bug tracking ID (pre-commit hook check)
Encourages frequent commits & its benefits: collaboration, undo, backup
Then, we have a "clenched fist" policy on staging/release builds:
Build fails if any, even trivial, deviation from rules, which means:
mandatory syntax correctness, standards compliance, code
documentation, and all tests pass with flying colors
Prevents releasing anything buggy. If something buggy does get
through, it's a problem with the code AND a problem with the build
(process hole, not enough tests, etc.)
All of that is automated through phing using phpcs (and of course phpunit, phpdocumentor, etc).
I think ircmaxell has a excellent point - this kind of standards checking should be somewhere other than a pre-commit hook, e.g. in a continuous integration envioronment or at a pinch, a post-commit hook and should be based around information providing rather than blocking commits!
Bearing this in mind, I decided for the moment, to use an opt-in approach. I configured the svn pre-commit hook to look in the commit message for a keyword and run phpcs if it was found.
In pre-commit hook script, e.g. /var/www/svn/repos/<reponame>/hooks/;
#!/bin/sh
REPOS="$1"
TXN="$2"
SVNLOOK=/usr/bin/svnlook
PHPCS=/usr/bin/scripts/phpcs-svn-pre-commit
if [[ `$SVNLOOK log -t $TXN $REPOS | tr "[:upper:]" "[:lower:]"` =~ "\[?standardcode\]?" ]]; then
# Run the PHP code sniffer
PHPCS_STRICT=`$PHPCS "$REPOS" -t "$TXN"`
if [[ $? -ne 0 ]]; then
echo "$PHPCS_STRICT" >>/dev/stderr
echo "*** Commit blocked - Please fix coding standard errors." >>/dev/stderr
exit 1
fi
fi
exit 0
Notes:
The keyword I chose was [standardcode] and the log message was converted to lowercase to make the keyword match case insensitive.
The phpcs commit hook (/usr/bin/scripts/phpcs-svn-pre-commit) comes packaged with phpcs (at least in CentOS 5.5).
The idea is that a developer can choose to put the keyword in their commit message as a sort of badge of honour but they are not forced to have their code checked if it is not appropriate for their commit.