I would like to have shell aliases that effectively are folder-aware, so that when running a command in a folder containing a .php file, the contents of which are just 8.1 for example, the corresponding binary is run.
alias php8.0='/opt/homebrew/Cellar/php#8.0/8.0.26/bin/php'
alias php8.1='/opt/homebrew/Cellar/php/8.1.13/bin/php'
alias phpv='php"$(cat .php)" -v'
The above however, when running phpv returns an error of command not found php8.1. Whereas running php8.1 -v on its own works correctly.
Generally, alias is for simple text that shortens something you type often.
alias ll=`ls -l`
If you're doing anything more complicated that that, use a function, not an alias.
As an exercise, to keep it close to your otiginal idea - set whichever you prefer as the default in your PATH, but when you want a structure to override it, then instead of a local hidden file with a number that gets hack/parsed on the fly, create a local symlink to the one needed in that folder. While it's a security concern, you could just set the local directory in your path and be done. A function can lessen that security concern by localizing that change to the scope of the specific function call.
php() { [[ -L ./php ]] && local PATH=".:$PATH"; # only localize if local symlink exists
local php=$(which php --skip-alias --skip-functions); # variable gets PATH-relevant version
if [[ -x "$php" ]] # checks for relevant success
then "$php" "$#" # runs appropriate version
else "No PHP available." # reports if none
fi
}
This falls down when you start needing entire subdirectory structures that need one version or the other, because now you have to put that symlink (or .php file, or whatever) in every folder in that structure, and it's a mess and a maintenance nightmare.
A better solution would be to set up as clean a structure as possible, and try to put (only) the highest/shortest directory paths at the top of all projects and miscellaneous errata that need alternate versions into a lookup.
phpv() {
local php='php'
local -A altv=(
[/first/dir/to/edit]="/opt/homebrew/Cellar/php#8.0/8.0.26/bin/php"
[/next/dir]="/some/other/version/bin/php"
[/next/dir/for/edits]="/opt/homebrew/Cellar/php#8.0/8.0.26/bin/php"
)
d="$PWD" # set longest path to check
while [[ -n "$d" ]]
do if [[ -n "${altv[$PWD]}" ]] # if there's an override
then php="${altv[$PWD]}" # override the varible
break # get out, using the longest match
fi
d=${d%/*} # check one directory higher for an override
done
$php" "$#" # runs appropriate version
}
This way, if you run phpv -v (or with any other set of arguments) it should check where you are the list of places that get overrides, using the longest match, which allows different overrides in subdirectories, but only requires an override to list the highest, shortest paths that need to use an alternate version. If no overrides are found for your current directory or any parent, then you default to whatever is set in your PATH.
Using the example paths I included, if you are in /usr/bin or /etc/ or /first/dir/to/delete or anywhere else that exactly doesn't SOMEWHERE along its parentage, it will default to your PATH. If you are in /first/dir/to/edit/today it will match /first/dir/to/edit as a parent (any subdir of that path will) and use /opt/homebrew/Cellar/php#8.0/8.0.26/bin/php. If you are in /next/dir/for/lunch it will match /next/dir as a parent and use /some/other/version/bin/php, but in
/next/dir/for/edits it matches the longer path first and uses /opt/homebrew/Cellar/php#8.0/8.0.26/bin/php instead.
Hope all that helps inspire a useful solution.
Related
To add the php apache2 module in Yocto I created a file recipes-devtools/php/php_%.bbappend with the following content:
PACKAGECONFIG = " mysql sqlite3 imap opcache openssl ${#bb.utils.filter('DISTRO_FEATURES', 'ipv6 pam', d)} apache2"
LIBS_pn-php =" -lpthread "
export LIBS
THREADS_pn-php = "pthread"
export THREADS
The module is built, but the file tmp-glibc/sysroots-components/cortexa7hf-neon-vfpv4/php/usr/lib/apache2/modules/libphp7.so is not copied to the rootfs (/usr/lib/apache2/modules/).
Why it does not deploy the file?
As temporary workaround (and to learn how to handle Yocto's path) I'm trying to manually deploy it with a ROOTFS_POSTPROCESS_COMMAND. To avoid absolute paths, what variable should I use to find out the file above under the tmp-glibc output dir? Something like:
${TMPDIR}/sysroots-components/cortexa7hf-neon-vfpv4/php/usr/lib/apache2/modules/libphp7.so
or there's something better?
In Yocto, files (which are installed in ${D} either manually in do_install or by the make, cmake, autotools, etc... in e.g. do_compile) are put in a package when they match one of the regular expression (or glob, not entirely sure about that) contained in FILES_foo.
One recipe can (and usually does) provide multiple packages. So you'd have multiple FILES_foo1 with their own paths to match.
In Yocto, the file is put in the first package where one of the paths in its FILE_foo matches the file. Even if the file matches the paths of other packages, it'll ever be in only one package, the first one.
FWIW, packages are created from leftmost to rightmost in PACKAGES variable in the recipe. By default, the PACKAGES variable is ${PN}-src ${PN}-dbg ${PN}-staticdev ${PN}-dev ${PN}-doc ${PN}-locale ${PACKAGE_BEFORE_PN} ${PN} (c.f. http://git.yoctoproject.org/cgit.cgi/poky/tree/meta/conf/bitbake.conf#n292).
The default FILES_* variables are defined in bitbake.conf as well, c.f. http://git.yoctoproject.org/cgit.cgi/poky/tree/meta/conf/bitbake.conf. Look for everything starting with FILES_.
In there, you can see that by default, FILES_${PN} has ${libdir}/lib*${SOLIBS} (c.f. http://git.yoctoproject.org/cgit.cgi/poky/tree/meta/conf/bitbake.conf#n296) packaged. SOLIBS is, by default, .so.* (c.f. http://git.yoctoproject.org/cgit.cgi/poky/tree/meta/conf/bitbake.conf#n280), which means only dot versions of libraries are packaged in the ${PN} package (if they are not matched by another package before).
FILES_${PN}-dev on the other hand packages ${FILES_SOLIBSDEV} which defaults to ${base_libdir}/lib*${SOLIBSDEV} ${libdir}/lib*${SOLIBSDEV}, with SOLIBSDEV in turns defaults to .so (c.f. http://git.yoctoproject.org/cgit.cgi/poky/tree/meta/conf/bitbake.conf#n313, http://git.yoctoproject.org/cgit.cgi/poky/tree/meta/conf/bitbake.conf#n314 and http://git.yoctoproject.org/cgit.cgi/poky/tree/meta/conf/bitbake.conf#n283).
Please note that library filenames should all start with lib to be able to be matched by the default FILES_*.
TL;DR: By default, lib*.so.* in FILES_${PN} and lib*.so in FILES_${PN}-dev.
For your specific issue, you can see that ${libdir}/apache2 directory is packaged in php-modphp thanks to FILES_${PN}-modphp (c.f. http://git.openembedded.org/meta-openembedded/tree/meta-oe/recipes-devtools/php/php.inc#n243).
So you need to add php-modphp (assuming ${PN} resolves to php) to your image to be able for the lib to be installed in your rootfs.
the code is stored in /var/www/abc -- "CodePath"
when running gitlab-ci (runner), the code is called via /home/gitlab-runner/builds/4v8bC1n9/0/_gitlabgroup_/_gitprojectname_/abc -- "RealPath"
I'm using a local runner and a shell execution.
when I use the realpath() function in my php code, it still shows the "CodePath" when using gitlab ci runner, instead of "RealPath".
How can I get the "RealPath" integrated in my code, or reconfig GitLab to use the "CodePath" instead?
The runner cli options are documented here: https://docs.gitlab.com/runner/executors/shell.html#overview
The path where the job is run and your sources are cloned into is available in the environment variable:
CI_PROJECT_DIR
The full path where the repository is cloned and where the job is run. If the GitLab Runner builds_dir parameter is set, this variable is set relative to the value of builds_dir. For more information, see Advanced configuration for GitLab Runner.
You did no state how you use realpath(path)...
Whilst a path must be supplied, the value can be an empty string. In this case, the value is interpreted as the current directory.
So maybe you hardcode chdir('/var/www/abc'); somewhere?
When you do chdir(getenv('CI_PROJECT_DIR')); before you call realpath() - it should use the CI directory. Assuming you use realpath without a parameter.
Also: maybe you can make some changes and use one of the the built in constants for the current directory: https://www.php.net/manual/en/language.constants.predefined.php
Thanks to madflow's mentioning of the variable I managed to figure out the following:
runners specific configuration files exist and can be configured as described here
I needed to do these things:
specify enable the [runners.custom_build_dir] section in the config.toml
[[runners]]
builds_dir = "/var/www/abc"
[runners.custom_build_dir]
enabled = true
(boolean not in quotes)
specify a variable in my yml
variables:
GIT_CLONE_PATH: $CI_BUILDS_DIR/
on os level there was some privilege setting for the dir required, where I went for quick and dirty 777 on my local machine
composer is usually very slow, and it provide no usual element to represent its progress. I always have to use -vvv option. Is there any way to make it always in verbose mode?
This can be done easily on Linux with an alias.
alias composer="composer -vvv"
You can make this permanent by appending this line to your .bash_profile or equivalent in your home directory.
If you are running on Windows, you can create a batch file wrapper in your PATH, something like:
#echo off
composer -vvv %*
Both of these assume that Composer is in your PATH already - if this is not the case, you'll need to prefix it with the full path.
Here is the situation.. I have some classes that are in one project... My main code is in another project... and i split this up because i am using GIT as my SCM... So when i debug my main code... i would like to step into the classes and debug them, but xdebug won't let me step into them... and i assume its because the classes are in another project... any ideas?
Thanks in advance...
I've run into this as well. I am going to assume that the way your projects look when they are deployed is that the classes in the separate project are copied into some directory somewhere in the main code.
Let's assume the separate project contains only one class, Foo, for simplicity's sake. Let's assume, too, that Foo is present in the deployed "main code" in the directory and file /maincode/external/lib/Foo.php. Finally, let's assume that /maincode/external/lib exists as a directory in your version-controlled "main code" project, and that it contains only a place-holder file and is otherwise empty.
First, use one of the many methods git provides to ignore the contents of the /maincode/external/lib directory in your NetBeans project directory for that project. We're going to make it look like it contains some stuff, and we don't want this directory, that is otherwise supposed to be empty, to get changes committed to it by mistake.
Now that it is ignored, make a symbolic link in that directory to Foo.php over in the other project. In Unix, you want the ln command, e.g.
ln -s /path/to/project/files/MyFooProject/Foo.php Foo.php
In Windows, you are looking for the mklink command, e.g.
mklink Foo.php C:\path\to\project\files\MyFooProject\Foo.php
Give NetBeans a moment or two to think about it (or force the issue by invoking the "Scan for external changes" command in the "Source" menu), and you should see Foo.php show up in the "maincode" project where you made the symbolic link.
Now, when you are tracing through execution and need to step into Foo.php to see what the Foo class is doing, you will step into the one that is in the "maincode" project. Since it is a symbolic link over to the file in the "MyFooProject" project, however, any chanes you make will be reflected over there.
Just be sure to unlink everything (the normal rm commmand in Unix, and the usual del command in Windows, but in the directory where the symbolic link is!) when you are through. Also, if there were things in the directory that you ignored that you want to be able to commit, then un-ignore that directory.
If you need to do this for more than just one file, then you can link whole directories. If, instead of the above, you normally copy the contents of "MyFooProject" into the directory /maincode/external/lib/myfoo/ in the deployed version, then just link the appropriate directory like you did the file above. In Windows, for example,
cd \path\to\project\files\maincode\external\lib
mklink /D myfoo C:\path\to\project\files\MyFooProject
That will make a symbolic directory link. It has been a while since I did anything like that on Unix, so I don't remember the exact command for the same thing on that OS (or if symbolic directory links are even possible on Unix). Once the directory is linked, you should see the new directory plus all of the files and subdirectories show up in your NetBeans "maincode" project, ready for your execution-tracing pleasure.
Again, remember to unlink and un-ignore everything once you are done, lest you wake up the next morning to find yourself confused. :) To unlink the directory in windows...
cd \path\to\project\files\maincode\external\lib
rmdir myfoo
and it should unlink. (Just be careful when you are deleteing and rmdir'ing that you are doing it to the symbolic link!)
I am trying to get into PHP app deployment with Capistrano. I have two config files that I need to be "edited" depending on where I deploy it. It's basic stuff like database name and root url (Codeigniter). Can I make Capistrano edit specified automatically? Let's say I want to edit the following in the file /system/config/edit.php:
$test = '';
// edit to
$test = 'Hello World';
Thanks,
Max
What I generally do in this kind of situation (even though I don't use Capistrano) is to have several config files commited to source control.
For instance :
config.php for development machines
this file is the one that's always used by the application
config.testing.php
config.staging.php
config.production.php
And when deploying the application to the server, I just have to copy the file corresponding to the current environment to "config.php" -- as this one is the one that's always used by the application.
It means that I have to do a file copy during the build process, yes, but :
it means there is no need for any search and replace, that can break
it also means every config files are commited to SVN (or whatever source control software you are using)
If your configuration files become too complex, and duplicate lots of stuff, you can think about having one "default" config file, that's always included, and sub-config files that only define what depends on the environment.
What that, what I said before still stands : just include the "default" file at the begining of each other.
My Unix is knowledge isn't quite up to scratch so I can't quite get the syntax perfect for what you want. However, Capistrano allows you to directly use the Unix command-line by invoking :run_method within your configs.
The Capistrano code might look something like the following:
run "grep -R --files-with-matches '$test = "";' /system/config/ | xargs perl -pi~ -e 's/\$test = "";/$test = "Hello World";/'"
I would check up on that find and replace function working as expected before implementing it live though.
If you need any more help, I'd recommend checking out the Capistrano Handbook, it should answer most of your questions.