How can I show cppcheck output in Xcode? - xcode

I want to display cppcheck output directly in the Xcode Issue Navigator. How can I do that?

Here is a simple script that you can add as a Run Script Phase in your Build Phases in Xcode:
#!/bin/bash
srcDir=src
if which cppcheck >/dev/null; then
cppcheck -j 4 --enable=all --inline-suppr $srcDir 2>cppcheck.txt 1>/dev/null
pwd=$(pwd)
sed "s|\[|${pwd}/|" cppcheck.txt | sed 's|\]: |: warning: |'
rm cppcheck.txt
else
echo "warning: cppcheck not installed, install here: http://brewformulas.org/Cppcheck"
fi

Related

Check format for Continous integration

I am trying to write a Makefile command that will output an error if the Go code is not correctly formatted. This is for a CI step. I am struggling with how to get it working in the make file. This solution works on the bash command line:
! gofmt -l . 2>&1 | read
But copying this into the Makefile:
ci-format:
#echo "$(OK_COLOR)==> Checking formatting$(NO_COLOR)"
#go fmt ./...
#! gofmt -l . 2>&1 | read
I get the following error:
/bin/sh: 1: read: arg count
These days, I use golangci-lint, which includes gofmt checking as an option.
But if for some reason you want to do this yourself, the command I previously used for precisely that purpose is:
diff -u <(echo -n) <(gofmt -d ./)
See, for example, the .travis.yml files on one of my projects.

Pipe to another command bash

I cannot seem to get my bash script to work, i want to pipe the output from the gunzip command to another command but it is not working, can anyone help me?
The gunzip command outputs a tar file that i want to then use the tar command to put back yo the original file.
# let the user choose what they want to Restore
echo -n "Select the file or directory you want to Restore"
read Chosendata
echo -e "Starting Restore"
# unziping files
gunzip ${Chosendata} | tar xvf - #Here
# end the restore.
echo -e "Restore complete"
Use gunzip -c.
-c, --stdout write on standard output, keep original files unchanged
Or tar only: tar -xzf ${Chosendata}.

Is it possible to post coverage for multiple packages to Coveralls?

I want to track test coverage on a go project using Coveralls, the instructions for the integration reference using
https://github.com/mattn/goveralls
cd $GOPATH/src/github.com/yourusername/yourpackage
$ goveralls your_repos_coveralls_token
However, this only posts the results for one package and running for packages in turn does not work as the final run overwrites all other runs. Has anyone figured out how to get coverage for multiple packages?
I ended up using this script:
echo "mode: set" > acc.out
for Dir in $(find ./* -maxdepth 10 -type d );
do
if ls $Dir/*.go &> /dev/null;
then
go test -coverprofile=profile.out $Dir
if [ -f profile.out ]
then
cat profile.out | grep -v "mode: set" >> acc.out
fi
fi
done
goveralls -coverprofile=acc.out $COVERALLS
rm -rf ./profile.out
rm -rf ./acc.out
It basically finds all the directories in the path and prints a coverage profile for them separately. It then concatenates the files into one big profile and ships them off to coveralls.
Taking Usman's answer, and altering it to support skipping Godep and other irrelevant folders:
echo "mode: set" > acc.out
for Dir in $(go list ./...);
do
returnval=`go test -coverprofile=profile.out $Dir`
echo ${returnval}
if [[ ${returnval} != *FAIL* ]]
then
if [ -f profile.out ]
then
cat profile.out | grep -v "mode: set" >> acc.out
fi
else
exit 1
fi
done
if [ -n "$COVERALLS_TOKEN" ]
then
goveralls -coverprofile=acc.out -repotoken=$COVERALLS_TOKEN -service=travis-pro
fi
rm -rf ./profile.out
rm -rf ./acc.out
Notice that instead of looking at every directory, I us the go list ./... command which lists all directories that actually get used to build the go package.
Hope that helps others.
** EDIT **
If you are using the vendor folder for Go v.1.6+ then this script filters out the dependencies:
echo "mode: set" > acc.out
for Dir in $(go list ./...);
do
if [[ ${Dir} != *"/vendor/"* ]]
then
returnval=`go test -coverprofile=profile.out $Dir`
echo ${returnval}
if [[ ${returnval} != *FAIL* ]]
then
if [ -f profile.out ]
then
cat profile.out | grep -v "mode: set" >> acc.out
fi
else
exit 1
fi
else
exit 1
fi
done
if [ -n "$COVERALLS_TOKEN" ]
then
goveralls -coverprofile=acc.out -repotoken=$COVERALLS_TOKEN -service=travis-pro
fi
Has anyone figured out how to get coverage for multiple packages?
Note: with Go 1.10 (Q1 2018), that... will actually be possible.
See CL 76875
cmd/go: allow -coverprofile with multiple packages being tested
You can see the implementation of a multiple package code coverage test in commit 283558e
Jeff Martin has since the release of Go 1.10 (Feb. 2018) confirmed in the comments:
go test -v -cover ./pkgA/... ./pkgB/... -coverprofile=cover.out gets a good profile and
go tool cover -func "cover.out" will get a total: (statements) 52.5%.
So it is working!
I have been using http://github.com/axw/gocov to get my code coverage.
I trigger this in a bash script, in here I call all my packages.
I also use http://github.com/matm/gocov-html to format into html.
coverage)
echo "Testing Code Coverage"
cd "${SERVERPATH}/package1/pack"
GOPATH=${GOPATH} gocov test ./... > coverage.json
GOPATH=${GOPATH} gocov-html coverage.json > coverage_report.html
cd "${SERVERPATH}/package2/pack"
GOPATH=${GOPATH} gocov test ./... > coverage.json
GOPATH=${GOPATH} gocov-html coverage.json > coverage_report.html
;;
Hope that helps a little bit.
Here is a pure GO solution:
I create a library that may help, https://github.com/bluesuncorp/overalls
all it does is recursively go through each directory ( aka each package ), run go test and produce coverprofiles, then merges all profiles into a single one at the root of the project directory called overalls.coverprofile
then you can use a tool like https://github.com/mattn/goveralls to send it to coveralls.io
hope everyone likes
In Go 1.13, following command generates coverage for multiple packages
go test -v -coverpkg=./... -coverprofile=profile.cov ./...
go tool cover -func profile.cov
for html report
go tool cover -html=profile.cov -o cover.html

XCode C/C++ Flags Bash Script

Im trying to run the following command on XCode adding it as a C/C++ Flags to I can get the build number coming from a shell script that is executed at the run script phase of my project.
This work fine with GCC on another Unix like system:
-D__BUILD_VERSION=$(cat build_number)
And ok XCode Im trying to use the following:
-D__BUILD_VERSION=$(cat $PROJECT_DIR/build_number)
But it doesn't work, what Im I doing wrong? In XCode, how can I assign the result of cat build_number to the __BUILD_VERSION defined variable?
if you are trying to set that value in the Xcode compile build-phase, you may run into trouble, as i don't know that any interpretive operation takes place with the settings you are trying to set up the way you are trying to set them up.
for auto-setting the version number, i have a much more complex semi-auto-version and auto-numbering scheme so i don't have to remember to change either, or so i can give a version-number i want but always increment the build number, and in both cases, it will put the build number in the About box in the app-settings that are displayed in the iOS system settings.
you may not need much of any of it, but there are a couple of tricks for getting and writing information that you may find useful and may lead to a solution for your problem.
the following scripts were inspired by a stack-overflow answer for how to do this that i can't find at the moment. i put in a bit more work, because (a) i want the version number to show up in the settings displayed in system settings; and (b) Xcode caches the contents of the Info.plist file, so doing this is not nearly as simple as i would have expected.
in a build phase that comes before compile, i run the following (with Run script only when installing unchecked)
sh xolawareStashProductSettings.sh
the contents of xolawareStashProductSettings.sh check the git status of the info.plist file, and if not clean, stash it aside temporarily for later restoration.
#!/bin/sh
#
# should be run prior to the Copy Bundle Resources step
# and prior to any version information modifier scripts
INFOPLIST_GIT_PATH=${PROJECT}/`basename ${INFOPLIST_FILE}`
echo "-- Temp Hold ${INFOPLIST_GIT_PATH} Script --"
set -e
# a fallback in case the user has made changes to the file
if [ `git status --porcelain ${INFOPLIST_GIT_PATH} ]|wc -l` -gt 0 ]; then
echo cp -p ${INFOPLIST_GIT_PATH} ${TARGET_TEMP_DIR}
cp -p ${INFOPLIST_GIT_PATH} ${TARGET_TEMP_DIR}
fi
script #2 (with Run script only when installing unchecked):
sh xolawareStashSettingsBundleRootPlist.sh
the contents of xolawareStashSettingsBundleRootPlist.sh are similar to the contents of script 1.
#!/bin/sh
#
# should be run prior to the Copy Bundle Resources step
# and prior to any version information modifier scripts
echo '-- Temp Hold Settings.bundle/Root.plist Script --'
ROOT_PLIST=${PROJECT}/Resources/Settings.bundle/Root.plist
set -e
# a fallback in case the user has made changes to the file
if [ `git status --porcelain ${ROOT_PLIST} ]|wc -l` -gt 0 ]; then
echo cp -p ${ROOT_PLIST} ${TARGET_TEMP_DIR}
cp -p ${ROOT_PLIST} ${TARGET_TEMP_DIR}
fi
script #3 (with Run script only when installing checked)
sh xolawareIncrementProductSettingsBuildNumber.sh
the contents of xolawareIncrementProductSettingsBuildNumber use plistbuddy to see what it is and bump it by one:
#!/bin/sh
#
# this should be prior to xolawareAboutInfoVersionInfoInSettings.sh
echo "-- Auto-Increment ${INFOPLIST_FILE} Build Version Install Script --"
PLISTBUDDYCMD="/usr/libexec/PlistBuddy -c"
CONFIGURATION_BUILD_SETTINGS_PATH=${CONFIGURATION_BUILD_DIR}/${INFOPLIST_PATH}
CFBV=$(${PLISTBUDDYCMD} "Print :CFBundleVersion" ${PRODUCT_SETTINGS_PATH})
if [[ "${CFBV}" == "" ]]; then
echo "No build number in ${PRODUCT_SETTINGS_PATH}"
exit 2
fi
CFBV=$(expr $CFBV + 1)
set -e
echo ${PLISTBUDDYCMD} "Set :CFBundleVersion $CFBV" "${PRODUCT_SETTINGS_PATH}"
${PLISTBUDDYCMD} "Set :CFBundleVersion $CFBV" "${PRODUCT_SETTINGS_PATH}"
echo ${PLISTBUDDYCMD} "Set :CFBundleVersion $CFBV" "${CONFIGURATION_BUILD_SETTINGS_PATH}"
${PLISTBUDDYCMD} "Set :CFBundleVersion $CFBV" "${CONFIGURATION_BUILD_SETTINGS_PATH}"
script #4 (with Run script only when installing unchecked)
sh xolawareProductSettingsShortVersion-from-git.sh
sh xolawareAboutInfoVersionInfoInSettings.sh
the contents of xolawareProductSettingsShortVersion-from-git rely a little on me tagging my branch in git appropriately, but if i forget, it will use the number of commits since the last commit to auto-version my build for me.
#!/bin/sh
#
# this should be run after xolawareStashSettingsBundleRootPlist.sh
# and prior to xolawareAboutInfoVersionInfoInSettings.sh
echo '-- Get Product Settings Short Version String from git describe --'
PLISTBUDDYCMD="/usr/libexec/PlistBuddy -c"
CONFIGURATION_BUILD_SETTINGS_PATH=${CONFIGURATION_BUILD_DIR}/${INFOPLIST_PATH}
CFBVS=`git describe|awk '{split($0,a,"-"); print a[1]}'`
CFBVSI=`git describe|awk '{split($0,a,"-"); print a[2]}'`
if [[ "$CFBVSI" != "" ]]; then
CFBVS=${CFBVS}.${CFBVSI}
fi
set -e
echo ${PLISTBUDDYCMD} "Set :CFBundleShortVersionString $CFBVS" "${PRODUCT_SETTINGS_PATH}"
${PLISTBUDDYCMD} "Set :CFBundleShortVersionString $CFBVS" "${PRODUCT_SETTINGS_PATH}"
echo ${PLISTBUDDYCMD} "Set :CFBundleShortVersionString $CFBVS" "${CONFIGURATION_BUILD_SETTINGS_PATH}"
${PLISTBUDDYCMD} "Set :CFBundleShortVersionString $CFBVS" "${CONFIGURATION_BUILD_SETTINGS_PATH}"
the contents of xolawareAboutInfoVersionInfoInSettings.sh place the contents in the About box in my Root.plist like i want. it relies on the About box being the first thing in your Root.plist of your settings.bundle:
#!/bin/sh
#
# this should be invoked after xolawareStashInfoAndRootPlist.sh,
# xolawareIncrementProductSettingsBuildNumber.sh and
# xolawareProductSettingsShortVersion-from-git.sh, and before
# the regular Copy Bundle Resources Build Phase
echo '-- Auto-Insert Version Info In System Settings Script --'
PLISTBUDDYCMD="/usr/libexec/PlistBuddy -c"
ROOT_PLIST=${PROJECT_DIR}/${PROJECT}/Resources/Settings.bundle/Root.plist
CFBSVS=`exec -c ${PLISTBUDDYCMD} "Print :CFBundleShortVersionString" ${PRODUCT_SETTINGS_PATH}`
CFBV=`exec -c ${PLISTBUDDYCMD} "Print :CFBundleVersion" ${PRODUCT_SETTINGS_PATH}`
set -e
echo ${PLISTBUDDYCMD} "Set :PreferenceSpecifiers:1:DefaultValue '${CFBSVS} (b${CFBV})'" ${ROOT_PLIST}
${PLISTBUDDYCMD} "Set :PreferenceSpecifiers:1:DefaultValue '${CFBSVS} (b${CFBV})'" ${ROOT_PLIST}
there are also a couple of cleanup scripts to be run after the Compile, Link & Copy bundle resources phases
sh xolawareStashRestoreSettingsBundleRootPlist.sh
this may not be necessary, but i adjust other items in the Root.plist for release builds, so this restores those settings for debug builds.
#!/bin/sh
#
# should be run as the second to last script in Build Phases, after the Copy Bundle Resources Phase
echo "-- Manual Restore $INFOPLIST_FILE Script --"
ROOT_PLIST=${PROJECT}/Resources/Settings.bundle/Root.plist
set -e
# first, see if it was stashed earlier due to uncommitted changes
if [ -e ${TARGET_TEMP_DIR}/Root.plist ]; then
echo mv ${TARGET_TEMP_DIR}/Root.plist ${ROOT_PLIST}
mv ${TARGET_TEMP_DIR}/Root.plist ${ROOT_PLIST}
# the better option when available: restore to the pristine state
elif [ `git status --porcelain ${ROOT_PLIST}|wc -l` -gt 0 ]; then
echo git checkout -- ${ROOT_PLIST}
git checkout -- ${ROOT_PLIST}
fi
and finally, the step to auto-tag the git repo if i haven't already tagged the item just now myself:
sh xolawareProductSettings-git-commit-and-tag.sh
#!/bin/sh
#
# this should be run after xolawareAboutInfoVersionInfoInSettings.sh
# and xolawareProductSettingsShortVersion-from-git.sh
echo "-- ${INFOPLIST_FILE} git commit & tag Install Script --"
SCRIPT_VERSION=`/usr/libexec/PlistBuddy -c 'Print :CFBundleShortVersionString' ${INFOPLIST_FILE}`
SCRIPT_BUILD_NUMBER=`/usr/libexec/Plistbuddy -c 'Print :CFBundleVersion' ${INFOPLIST_FILE}`
if [ `git status --porcelain ${SCRIPT_INFO_PLIST}|wc -l` -gt 0 ]; then
echo git commit -m '"'version ${SCRIPT_VERSION} build ${SCRIPT_BUILD_NUMBER}'"' ${INFOPLIST_FILE}
git commit -m "version ${SCRIPT_VERSION} build ${SCRIPT_BUILD_NUMBER}" ${INFOPLIST_FILE}
fi
echo git tag -f ${SCRIPT_VERSION}
git tag -f -F /dev/null ${SCRIPT_VERSION}
Try:
-D__BUILD_VERSION=`cat $PROJECT_DIR/build_number`
Note the "backticks" - they're not regular single quote characters.
One possibility might be to have the first script put the build number into an environment variable? Not sure if that would work but it might.

bash completion of makefile target

Suppose I have a simple makefile like:
hello:
echo "hello world"
bye:
echo "bye bye"
Then in bash I want something like:
make h < tab >
so it can complete to
make hello
I found a simple way like creating empty files hello and bye but I'm looking for something more sophisticated.
Add this in your ~/.bash_profile file or ~/.bashrc file
complete -W "\`grep -oE '^[a-zA-Z0-9_.-]+:([^=]|$)' ?akefile | sed 's/[^a-zA-Z0-9_.-]*$//'\`" make
This searches for a target in your Makefile titled 'Makefile' or 'makefile' (note the capital ? wildcard in ?akefile) using grep, and pipes it over to the complete command in bash which is used to specify how arguments are autocompleted. The -W flag denotes that the input to the complete command will be a wordlist which is accomplished by passing the results of grep through sed which arranges it into the desirable wordlist format.
Caveats and gotchas:
Your make file is named 'GNUMakefile' or anything else other than 'Makefile' or 'makefile'. If you frequently encounter such titles consider changing the regular expression ?akefile accordingly.
Forgetting to source your ~/.bash_profile or ~/.bashrc file after making the changes. I add this seemingly trivial detail since, to the uninitiated it is unfamiliar.
For any change to your bash files to take effect, source them using the command
source ~/.bashrc
or
source ~/.bash_profile
PS. You also now have the added ability to display the possible make targets by pressing [Tab] twice just like in bash completion. Just make sure you add a space after the command make before typing [Tab] twice.
This answer from 2010 is outdated - the project mentioned here seems to have been discontinued.
Could this be what you're looking for?
http://freshmeat.net/projects/bashcompletion/
make [Tab] would complete on all
targets in Makefile. This project was
conceived to produce programmable
completion routines for the most
common Linux/UNIX commands, reducing
the amount of typing sysadmins and
programmers need to do on a daily
basis.
There's a useful package called bash-completion available for most every OS. It includes Makefile completion.
(If you're using macOS and Homebrew, you can get this via brew install bash-completion.)
This seems to be default in at least Debian Lenny:
$ grep Makefile /etc/bash_completion
# make reads `GNUmakefile', then `makefile', then `Makefile'
elif [ -f ${makef_dir}/Makefile ]; then
makef=${makef_dir}/Makefile
# before we scan for targets, see if a Makefile name was
# deal with included Makefiles
The header of this file states:
# The latest version of this software can be obtained here:
#
# http://bash-completion.alioth.debian.org/
#
# RELEASE: 20080617.5
Here is a completion script that looks at the .PHONY: declaration.
_make_phony_words() {
local opt_revert
if [ -n "${BASH_VERSION:-}" ]; then
shopt -q nullglob || {
opt_revert=1 ; shopt -s nullglob ;
}
elif [ -n "${ZSH_VERSION:-}" ]; then
[[ -o nullglob ]] || {
opt_revert=1 ; setopt nullglob
}
fi
for f in ./?akefile ./*.make ; do
sed -nEe '/^.PHONY/ { s/^.PHONY:[ ]?// ; p ; } ' "$f" | tr ' ' $'\n' | sort -u
done
if [ -n "$opt_revert" ]; then
[ -n "${ZSH_VERSION:-}" ] && unsetopt nullglob
[ -n "${BASH_VERSION:-}" ] && shopt -u nullglob
fi
unset opt_revert
}
_make_phony_complete() {
local cur="${COMP_WORDS[COMP_CWORD]}"
COMPREPLY+=( $(compgen -W "$( _make_phony_words )" -- ${cur}) )
}
complete -F _make_phony_complete make
Makefile completion on steroids!
I had 2 problems with the normal completions:
Problem #1
Sometimes you have targets you want to call like make greet:hi and make greet:hola sort of like namespacing Makefile target names. So your Makefile ends up looking like:
greet\:hola:
echo "hola world"
# OR a .PHONY target
.PHONY: greet\:hi
greet\:hi:
echo "hi world"
In this case the auto-completions after : don't show up as it uses \: in the Makefile as shown above.
Problem #2
There wasn't a way to navigate through the list of all Makefile targets that match my input using arrow keys (or CTRL-p / CTRL-n) in my bash shell.
Basically, I wanted to use fuzzy search like approach on the targets (i.e. fzf).
FZF Repo: https://github.com/junegunn/fzf
Solution
Install FZF Dependency
Using Homebrew
You can use Homebrew (on macOS or Linux)
to install fzf.
brew install fzf
$(brew --prefix)/opt/fzf/install
Using Linux package managers
Package Manager
Linux Distribution
Command
APK
Alpine Linux
sudo apk add fzf
APT
Debian 9+/Ubuntu 19.10+
sudo apt-get install fzf
Conda
conda install -c conda-forge fzf
DNF
Fedora
sudo dnf install fzf
Nix
NixOS, etc.
nix-env -iA nixpkgs.fzf
Pacman
Arch Linux
sudo pacman -S fzf
pkg
FreeBSD
pkg install fzf
pkgin
NetBSD
pkgin install fzf
pkg_add
OpenBSD
pkg_add fzf
XBPS
Void Linux
sudo xbps-install -S fzf
Zypper
openSUSE
sudo zypper install fzf
FZF and : compatible auto-complete command
Put this in your .bashrc
complete -W "\`grep -oE '^[a-zA-Z0-9_.-]+[\\:]*[a-zA-Z0-9_.-]+:([^=]|$)' ?akefile | sort | uniq | sed 's/[^a-zA-Z0-9_.-]*$//' | sed 's/[\]//g' | fzf\`" make
Now just typing make and then hitting the key will work!
DEMO: in action!
Then you can use as following:
make using fzf
I added so I follow "include" directives in Makefile. So my .bashrc looks like this:
function followMakefile() {
grep -oE '^[a-zA-Z0-9_.-]+:([^=]|$)' ?akefile | sed 's/[^a-zA-Z0-9_.-]*$//'
for x in `grep -E '^include' ?akefile | sed 's/include //'`
do
grep -oE '^[a-zA-Z0-9_.-]+:([^=]|$)' $x | sed 's/[^a-zA-Z0-9_.-]*$//'
done
}
complete -W "\`followMakefile\`" make
In Ubuntu 10.04, source the following file:
. /etc/bash_completion
or uncomment it in
/etc/bash.bashrc

Resources