(For usage refer to USAGE.md)
Gradle supports including other projects as dependencies. A good example for this can be found here as explained in the blog post.
The author summarises the three msot important things as:
- A multi-project build must have the settings.gradle file in the root directory of the root project because it specifies the projects that are included in the multi-project build.
- If we have to add common configuration or behavior to all projects of our multi-project build, we should add this configuration (use allprojects) to the build.gradle file of our root project.
- If we have to add common configuration or behavior to the subprojects of our root project, we should add this configuration (use subprojects) to the build.gradle file of our root project.
I ended up using this approach for a game I'm developing. The core module is one project and all the frontends are other projects.
Using git add -p
you can interactively choose which parts of your work you want to add/stage. This even allows you to add different parts of a file, while leaving out others.
Source: https://www.youtube.com/watch?v=duqBHik7nRo
xclip
is an awesome tool which can be used to pipe output to the clipboard. Use -selection c
so that you can paste using Ctrl
+ V
.
# example
xclip -selection c ~/somefile.txt
Up until now I've always been using the beStrictAboutCovers
in the phpunit.xml
configuration file. Today I learned about the forceCoversAnnotation
annotation.
The effect is similar: only the code specified by @covers
will count towards the total code coverage. With forceCoversAnnotation
however the @uses
annotation is not required. I like @uses
but if often clogs up a test class when using lots of small value objects.
screenkey is a python app which shows key presses in an overlay on the screen. Nice for live coding to show off key combinations and shortcuts.
--mods-only
shows only modifiers, because normal letters are probably not interesting and --vis-shift
shows shift every time it is pressed.
No installation required, just start the app after cloning the repo ./screenkey --mods-only --vis-shift
Let's Encrypt provides free certificates for everyone. 90 day renewal can be automated through cronjobs.
Explained by a developer: https://www.youtube.com/watch?v=zJ0JMl1B7yY
git-imerge solves the problem of resolving many merge conflicts in large merge operations.
Video by the developer: http://www.youtube.com/watch?v=FMZ2_-Ny_zc
I finally decided to find out how to pipe HTML straight to a browser without having to write it to a file and then open that file in the browser and then deleting the file etc.
The solution is a small ruby gem called bcat and it's usage is just as you'd imagine (taken from the project's website):
# With build tools:
make test |bcat
rake test |bcat
# As a clipboard viewer:
pbpaste |bcat # macos
xclip -o |bcat # X11
# For previewing HTML:
markdown README.md |bcat
redcloth README.textile |bcat
erb -T - template.erb |bcat
mustache < template.mustache |bcat
pygmentize -Ofull,style=colorful -f html main.c |bcat
B. Meyer makes an interesting point (among many from his book Agile! - The Good, the Hype, and the Ugly) about the different types of complexities in software projects. He compares the two types to pasta:
- Additive complexity is like lasagne. You just keep piling new parts on top of the existing parts and it works (this is, of course, an ideal for agile projects).
- Multiplicative complexity, however, is more like linguine (or spaghetti), meaning the parts are entangled and hard to separate. Projects which have lots of this types of complexities (which is more than one might think) require some upfront planning to reduce waste (which would be the result of treating these tasks in pure agile manner).## Native Watch Using
inotify-tools
Don't bother installing node or ruby gems when you can simply run the following inline command on any UNIX system with inotify-tools installed:
# watch a single file for any type of changes and display on change
while inotifywait someText.txt; do cat someText.txt; done
# watch a folder for any type of change and run make if there is
while inotifywait -r src; do make; done
-
$0
-$99
x-th argument provided to the script/function.$0
is always the script name even when accessed from within a function.$1+
will work in functions. -
$?
Exit code of the last process. -
$_
Last argument. -
$!
PID of last process. -
$@
All arguments.
Note: Always quote variables to avoid word-splitting (except when using [[
for tests). Run shellcheck
to make sure.
Use -L
instead of -h
for compatibility.
if [[ -L /path/to/suspected_symlink ]]; then
echo "is symlink"
else
echo "no symlink"
fi
Declare a variable with ARRAY=(one two three)
and reference it using echo ${ARRAY[*]}
or echo ${ARRAY[2]}
for a single element.
Note that brackets are not required in for statements: for i in 1 2 3; do echo $i; done
Postman provides dynamic variables which can be used to generate content for requests e.g.
{
"name": "Test Variant {{$randomInt}}",
"id": "{{$guid}}"
}
See: https://learning.postman.com/docs/postman/variables-and-environments/variables-list/
By using kwalletcli
you can poll for entries using e.g.
kwallet-query -l kdewallet -f Toolbox -r 'JetBrains Account OAuth'
git for-each-ref
is better suited for automated branch parsing than git branch
.
Example usage which deletes branches which aren't on upstream:
git for-each-ref --shell --format='ref=%(refname:short); gone=%(if:equals=[gone])%(upstream:track)%(then)gone%(end); if [ "gone" = "$gone" ]; then echo "upstream for $ref is gone, will delete."; git branch -D "$ref"; else echo "will not delete $ref."; fi' 'refs/heads/**' | while read cmd; do eval "$cmd"; done
issueFunction in commented("by currentUser()")
gpg --list-keys 2>/dev/null | grep <your_email> -C2
gpg --edit-key <the_key_id_you_want>
# interactive prompt starts
key 0
# note you will not see a * next to the key, but unless there
# is an error the key is selected
expire
1y
key 1
expire
1y
# ... for all keys and subkeys
save
# publish the change
gpg --keyserver pgp.mit.edu --send-keys <the_key_id_you_want>
KDE special window settings can be accessed even without a titlebar by using the shortcut Alt + F3. From there you can set opacity, window size, borders etc.
inxi
is a convenient tool to display system information in a readable well formatted way. Use the -F
flag to display all information and optionally -c 0
in order to turn off colors (because it looked weird on my terminal).
Example:
inxi -F -c 0
System: Host: lin-haeuslmannm Kernel: 4.15.0-159-generic x86_64 bits: 64 Desktop: KDE Plasma 5.12.9
Distro: Ubuntu 18.04.6 LTS
Machine: Device: laptop System: Dell product: XPS 15 9560 serial: N/A
Mobo: Dell model: 05FFDN v: A00 serial: N/A UEFI: Dell v: 1.23.1 date: 05/25/2021
Battery BAT0: charge: 61.4 Wh 100.0% condition: 61.4/97.0 Wh (63%)
hidpp__0: charge: N/A condition: NA/NA Wh
CPU: Quad core Intel Core i7-7700HQ (-MT-MCP-) cache: 6144 KB
clock speeds: max: 3800 MHz 1: 800 MHz 2: 800 MHz 3: 800 MHz 4: 800 MHz 5: 800 MHz 6: 800 MHz
7: 800 MHz 8: 800 MHz
Graphics: Card-1: Intel Device 591b
Card-2: NVIDIA GP107M [GeForce GTX 1050 Mobile]
Display Server: x11 (X.Org 1.19.6 ) driver: i915
Resolution: 1920x1080@60.01hz, 1920x1080@60.00hz, 1920x1080@60.00hz
OpenGL: renderer: Mesa DRI Intel HD Graphics 630 (KBL GT2) version: 4.6 Mesa 20.0.8
Audio: Card-1 Intel CM238 HD Audio Controller driver: snd_hda_intel Sound: ALSA v: k4.15.0-159-generic
Card-2 Asahi Kasei Microsystems AK5370 I/F A/D Converter driver: USB Audio
Card-3 Logitech OrbiCam driver: USB Audio
Card-4 Realtek driver: USB Audio
Network: Card-1: Qualcomm Atheros QCA6174 802.11ac Wireless Network Adapter driver: ath10k_pci
IF: wlp2s0 state: up mac: 9c:b6:d0:e9:ca:77
Card-2: Atheros
IF: null-if-id state: N/A speed: N/A duplex: N/A mac: N/A
Drives: HDD Total Size: 1024.2GB (45.5% used)
ID-1: /dev/nvme0n1 model: PC300_NVMe_SK_hynix_1TB size: 1024.2GB
Partition: ID-1: / size: 407G used: 378G (98%) fs: ext4 dev: /dev/nvme0n1p8
ID-2: swap-1 size: 64.00GB used: 0.00GB (0%) fs: swap dev: /dev/nvme0n1p7
RAID: No RAID devices: /proc/mdstat, md_mod kernel module present
Sensors: System Temperatures: cpu: 65.5C mobo: N/A
Fan Speeds (in rpm): cpu: 3678 fan-2: 3713
Info: Processes: 484 Uptime: 1:53 Memory: 13523.0/32017.9MB Client: Shell (zsh) inxi: 2.3.56
If you are trying to find a specific element within a JSON array you can use jq's select()
filter.
Example:
jq '.services[] | select(.name == "awesome-service") | .version' services.json
Given an object like:
{
"key1": {
"key": "value1"
},
"key2": {
"key": "value2"
}
}
you can use a combination of map_values
, select
and contains
to find the right object and then keys
to get the matching keys:
map_values(select(contains({"key": "value2"}))) | keys[]
contains(element)
: returnstrue
if whatever is passed into it matchesselect(boolean_expression)
: returns the input or nothing if the expression doesn't matchmap_values(x)
: runs the filter function x on all inputs
the same function can also be written using the update-assignment operator |=
:
.[] |= select(contains({"key": "value2"})) | keys[]
.[]
creates an iterator and |=
assigns a new value to each element. Similarly to the previous function empty values are filtered out using the combination of select
and contains
.
You can use the GitHub API in order to download a list of all public and private gists from a logged in account (i.e. Bearer token):
curl -L \ ─╯
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer $(secret-tool lookup keyId GitHubPersonalAccessToken)" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/gists
Generated on mar 19 dic 2023 13:50:10 CET