Running `go test` in parent directory of multiple go modules - unit-testing

Take a look at this directory structure:
/root
/one
go.mod
go.sum
main.go
main_test.go
/two
go.mod
go.sum
main.go
main_test.go
Let's say I'm in the parent directory root/ and I want to run all the tests in all subdirectories. What do I do? I've tried go test./... and got the following error:
go: warning: "./..." matched no packages
no packages to test

Yes, this will not work with go test, which expects to work on a single module rooted in the current directory or its parent. It won't work with nested modules either.
You'll need a shell trick like using find or something equivalent to execute in each module (see Cerise Limón's comment for example). Projects will typically use a Makefile or a test.sh script to run that.
One larger project I was working on has a list of all its modules (https://github.com/google/go-cloud/blob/master/allmodules) and then several scripts that operate on this list. For example the test script just loops through this file and runs go test for each directory, along other things.
You don't necessarily need a separate file listing the modules (the go-cloud project uses that for other management tasks) but it just demonstrates one way large projects with multiple modules handle things.

Promoting #Cerise Limón's comment to answer:
find . -name go.mod -execdir go test ./... \;

Building on other answers here:
find . -name go.mod -execdir go test ./... \;
works but always returns a 0 exit code. I need this to fail my CI if any test fails.
find . -name go.mod -execdir go test ./... \; | grep -zqv FAIL
works for me (note by default grep returns status code 0 if there is a match)

Related

How do I exclude files from a jest cli command?

Is there a jest equivalent, or a way of doing it in bash, to the git regex approach for including files that match one regex (all files in the /tests folder), but then exclude any that match a second (any test files that include API in the name)? e.g.
git ls-files -- 'tests' ':!:*API*'
I would like to do it as single line command because I want to be able to run all the tests in the /tests directory, but in two mutually exclusive sets using a single yarn test script from my package.json file.
EDIT: Expanding on Brenda J. Butler's answer:
yarn jest `find tests -type f ! -name \*API\* | grep -v .DS_`
Realising that jest can take either a regex OR a file list,
using backticks to do a bash substitution, and
additionally, as this is on MacOS, using a grep -v to also pull out the .DS_Store from the file list.
bash:
# finding files under tests whose names don't contain API
$ find tests -type f ! -name \*API\*
# finding files under tests whose names contain API
$ find tests -type f -name \*API\*

F# package for Sublime Text Build System absent

I am starting out with F# and trying to get it to work with Sublime Text 3 with a package, https://github.com/fsharp/sublime-fsharp-package. After installing the package using Package Control, I see F# appear as an available language to use in Sublime Text's bottom bar, and syntax highlighting appears to work more or less, from what I can tell, but the build system for F# fails to appear as it should.
So, trying to fix things, I run "build.sh install" and get an error, "Cannot open assembly '.paket/paket.bootstrapper.exe': No such file or directory." I am sort of stuck. Many thanks for any help.
From the comments you've made, you appear to be a little unfamiliar with the Unix underpinnings of OS X. I'll explain those first, then I'll suggest something for you to try that may fix your problem.
Technically, files or directories whose name starts with . are not "reserved for the system" as you put it; they're hidden. Now, it's true that Finder won't allow you to create files or directories whose name starts with ., because Apple didn't want to have to field all the tech-support calls from people who didn't know about the hidden-files feature: "I named my file ... more important stuff for work and now it's gone! Help!!!" But if you're in the Terminal app, then you can easily create files or directories with . as their first letter: mkdir .foo should work. You won't see it when you do ls, but ls -a (a for "all") will show you all files, including hidden files. And you can also do cd .foo and create files inside the hidden .foo directory -- and while the .foo folder won't show up in Finder, it will be perfectly accessible in the Terminal, and to any F# programs you might write.
So when you say that you cloned https://github.com/fsprojects/Paket but it failed to include the .github and .paket directories, I think you just don't know how to see them. You can't see them in the Finder (well, you can if you jump through a couple of hoops but I don't think it's worth the effort), but you can see them with ls -a. Just open your terminal, run cd /Users/Username/Paket, and then run ls -a and I think you'll see that the .paket and .github directories were indeed created by your git clone command.
So what you should probably try is this:
Go to https://github.com/fsprojects/Paket/releases/latest
Download the paket.bootstrapper.exe and paket.exe files. Put them in /Users/Username/Downloads (or wherever the default OS X Downloads directory is if it's different -- just as long as it's somewhere where you can find them easily).
Open the Terminal app.
Go to the directory where you've unpacked the Sublime Text 3 package. I.e., in the Terminal app, run cd /Users/Username/Library/Application\ Support/Sublime\ Text\ 3/Packages/sublime-fsharp-package-master.
Run ls -a and see if there's a .paket directory.
If it does not exist, run mkdir .paket.
Now do cd .paket so you're in the hidden .paket directory under sublime-fsharp-package-master.
Now do ls and see if there's a paket.bootstrapper.exe file.
If it doesn't exist, then copy in the .exe files you downloaded earlier:
cp /Users/Username/Downloads/paket.bootstrapper.exe .
cp /Users/Username/Downloads/paket.exe .
Important: Now do cd .. to go back up to the /Users/Username/Library/Application\ Support/Sublime\ Text\ 3/Packages/sublime-fsharp-package-master/ directory.
Now instead of running /Users/Username/Library/Application\ Support/Sublime\ Text\ 3/Packages/sublime-fsharp-package-master/build.sh install, try running it as ./build.sh install. (And also try ./build.sh Install, since I'm pretty sure the capital I is necessary).
(BTW, If you're not familiar with the syntax that I used in steps 9, 10 and 11, where I used a single . or two dots .. in commands, those are a long-standing Unix idiom: . means "the current directory", and .. means "the parent directory".)
I just looked at the build.sh script that you've been running, and it seems to assume that you've done a cd into the package's base directory (the sublime-fsharp-package-master directory) before running the script. So that could explain why it was failing: you were running it from a different directory, rather than doing a cd first. Hence why I marked step 10 as important: I think that was the root cause of the problem.

Execute gradle build task from any location

I´m trying to build my gradle projects from other locations than the project folder itself, but it always says it couldn´t find build task.
What I´ve tried so far:
sudo ./myprojects/myapp/gradlew build
sudo ./myprojects/myapp/gradlew ./myprojects/myapp/build
How can I execute a gradle build task from any location?
Various people have written (and published) scripts to execute gradlew from any subproject directory (in a multi-project build). To reliably execute Gradle from any subdirectory, it is necessary to set the "current project directory" via -p. It would be nice to have this restriction lifted (this would make a good feature request).
You may try this script, which is 90-lines long: https://github.com/dougborg/gdub
Or use this straightforward one-liner I use myself:
function lookupgradle() {
find . .. ../.. ../../.. ../../../.. ../../../../.. ../../../../../.. -maxdepth 1 -name 'gradlew' -executable -print -quit
}
alias g='$(lookupgradle)'
If you'll find out that it is still required to specify project directory, add -p .:
alias g='$(lookupgradle) -p .'
./usmobile-microservice/gradlew -p ./usmobile-microservice clean buildUI
./project_directory/gradlew -p ./project_directory clean build
worked for me

`go test` file modification monitoring for automated testing

Is there a way to have go test run whenever a project's files are modified?
Perhaps there is a good general solution to run a command when files in a path are modified that could be used for this use?
You can use inotifywait for that. Example watching some dir and executing go test on close while having data written:
inotifywait -e close_write <dir> | while read file; do go test; done
Or you write your own tool in go utilizing the howeyc/fsnotify package: Similar example application.
There's also rerun, written in ruby:
rerun go test
Above command will watch the current directory for changes and run go test when a change occurs.

How to list all subdirectories with a string but not subdirectories of a match

In a bash script I would like to parse the names of all subdirectories and find all subdirectories that have a matching string, but I do not want subdirectories of a match. I am interested in automating construction of my $PATH and $PYTHONPATH variables based on directory structure.
Here's an example:
Let's say I want to go through my ~/dev and ~/bin folders and find all subdirectories with bin/ which holds programs that I will want to run at the shell. I can get a list with
$ ls -lR $HOME/bin $HOME/dev |grep "\/" | grep "bin:"
/Users/dat5h/bin:
/Users/dat5h/bin/project/bin:
...
These can all be appended to $PATH and have all available scripts ready to run.
BUT, let's say I was searching for directories with python modules and packages to add to $PYTHONPATH. I could conceivably look for all directories that start with /py-. So, I try:
$ ls -lR $HOME/bin $HOME/dev |grep "\/" | grep "/py-"
/Users/dat5h/bin/py-test:
/Users/dat5h/bin/py-test/test-package:
/Users/dat5h/bin/py-test/test-package/nested-test:
...
My thinking is that I would not want to put package directories and subdirectories into the path. I'm pretty sure that would be strange, but I am actually new to python so suggestions would be helpful. How would I go about constructing a test case to only get directories with py-* but non of the subsequent subdirectories?
I tried:
$ ls -lR $HOME/bin $HOME/dev |grep "\/" | egrep "/py-.*[^/]:"
But this doesn't get the job done either. Maybe a better regex? Any help would be greatly appreciated!
SOLUTION
The solution I ended up satisfied with was the find suggested below with a cutoms regex:
find $HOME/bin $HOME/dev -type d -regex ".*\/py\(\w\|-\w\)*"
This will find all subdirectories of ~/bin and ~/dev that are some variant of "pySOMETHING", "py-SOMETHING", "pySOME_THING_ELSE", or "py-SOME_THING_ELSE" but does not grab any subdirectories of those unless they also match this string. This ensures that I can have some simple naming convention for all of my directories with python modules/packages and import them this way without accidentally being able to import nested packages without the hierarchy.
Does this:
find -type d -regex ".*py.*bin.*"
give you some start?