How do I run ansible-test on the root of my collection? - ansible

I'm currently developing my own Ansible collection and following the documentation. The directory structure looks like this:
~/.ansible/collections/gertvdijk/mycollection
├── galaxy.yml
├── plugins
│   └── lookup
│   └── mylookup.py
├── README.md
└── tests
└── unit
└── plugins
└── lookup
└── test_mylookup.py
The location ~/.ansible/collections/gertvdijk/mycollection is chosen for convenience so that it's found on the default search paths for collections (COLLECTIONS_PATHS).
The Ansible developer document section Testing collections mentions that I should use ansible-test command from the root of my collection with the given structure.
You must always execute ansible-test from the root directory of a collection.
However, that fails to me, with an error as if I should use this in a project already.
Even running --help fails with the current working directory error:
$ ansible-test --help
ERROR: The current working directory must be at or below:
- an Ansible collection: {...}/ansible_collections/{namespace}/{collection}/
Current working directory: /home/gert/.ansible/collections/gertvdijk/mycollection
Same thing happens by cloning an existing community collection (e.g. community.grafana). The GitHub CI steps include an installation in a ansible_collections/{namespace}/{collection} path (seen here).
Taking that as a work-around for now (I'd like to avoid that); move the repository of the collection to some path that includes /ansible_collections/gertvdijk/mycollection and then run it from there.
This can't be true, right, that the directory name two levels up make or break the ansible-test tool? What am I missing here?

TL;DR: The path for your home collection should be /home/gert/.ansible/collections/ansible_collections/gertvdijk/mycollection
The directories listed in COLLECTION_PATH are actually expected to contain a top level ansible_collections folder. This is linked to the ansible_collections convention used by e.g. module_utils as explained in the documentation
You can also observe how a blank folder gets structured by running e.g.
ansible-galaxy collection install -p /whatever community.grafana
In this case, you will end up with the folder /whatever/ansible_collections/community/grafana.
So your actual home folder collection path should be /home/gert/.ansible/collections/ansible_collections/gertvdijk/mycollection

Related

Swagger-codegen command project structure

I am using swagger to develop a new api written in Go. This is my first swagger project. I installed and used this command to create my project from a swagger.yaml. I aim to make reconfigurations I put into the swagger.yaml file part of my pipeline tasks - putting a task in to execute something like swagger-codegen generate -i ./api/swagger.yaml -l go-server by strategically setting up ignores in my .swagger-codegen-ignore file. There is one thing I don't necessarily like but i can't figure out how to change. Any advice? Do i need to live with it?
the generated directory structure looks like this for go-server
.
├── api
│ └──swagger.yaml
├── go #everyting in this directory is part of the "swagger" package
│ ├── a_handler_function_file.go
│ ├── logger.go
│ ├── model_struct_file.go
│ ├── routers.go
│ └── ...
├── Dockerfile
└── main.go
I am not keen on the directory called go or the package it produces called swagger. I want something more meaningful to the project.
Does it go against conventions to rename the directory?
Is there a way to configure the swagger-codegen to rename these what I want? - I am doing research to see if there is a way but I can't find one.
It seems that SEO magic has not really crawled in a way to effectively land on this page in the swagger-codegen git repo https://github.com/swagger-api/swagger-codegen#customizing-the-generator . maybe this Q and A will help.
One can either use add a -D<configParameterName> to the generate command or one can create a config.json file and add it to the generate command using -c config.yaml.
for go-server there are only two parameters available, packageName and hideGenerationTimestamp.
So I tried swagger-codegen generate -i ./swagger.yaml -l go-server -DpackageName="myPackageName" and it worked!!!
I also tried creating a config.json file that looks like this
{
"packageName": "myPackageName"
}
and then generate command that looks like this swagger-codegen generate -i ./swagger.yaml -l go-server -c config.json
and that works too.
As far as changing the go directory - it looks like I will have to live with it

Where to place go.mod file

I have a repository structure as follows :-
xyz/src
1. abc
- p
- q
- r
2. def
- t
- u
- v
3. etc
- o
- m
- n
I have created a .mod file in src and run go build ./...
Except for local packages everything is fine. So if abc/p is being used in def then it throws the following exception :- cannot find module providing package abc/p. The idea behind keeping the .mod file in src package was to make sure the path is being found from where the mod file is located. Can anyone suggest where should the mod file ideally should be? also i tried placing it one directory above in xyz but still same issue as well as i created one for each sub directory. I am bit confused on this. Will I have to create separate repository for abc and etc. But considering gopath which earlier used to work for the same I think module should also be able to do the same. Any suggestions?
The most common and easiest approach is a single go.mod file in your repository, where that single go.mod file is placed in the root of your repository.
Russ Cox commented in #26664:
For all but power users, you probably want to adopt the usual convention that one repo = one module. It's important for long-term evolution of code storage options that a repo can contain multiple modules, but it's almost certainly not something you want to do by default.
The Modules wiki says:
For example, if you are creating a module for a repository
github.com/my/repo that will contain two packages with import paths
github.com/my/repo/foo and github.com/my/repo/bar, then the first
line in your go.mod file typically would declare your module path as
module github.com/my/repo, and the corresponding on-disk structure
could be:
repo/
├── go.mod <<<<< Note go.mod is located in repo root
├── bar
│   └── bar.go
└── foo
└── foo.go
In Go source code, packages are imported using the full path including
the module path. For example, if a module declared its identity in its
go.mod as module github.com/my/repo, a consumer could do:
import "example.com/my/repo/bar"
That imports package bar from the module github.com/my/repo.
I have a single go.mod in the root of my go application. I am using the following structure inspired by Kat Zien - How Do You Structure Your Go Apps
At the minute one of my applications looks like this
.
├── bin
├── cmd
│   ├── cli
│   └── server
│ └── main.go
├── pkg
│   ├── http
│   │   └── rest
| │ # app-specific directories excluded
│   └── storage
│   └── sqlite
All packages are imported via their full path, i.e. import "github.com/myusername/myapp/pkg/http/rest" otherwise it causes problems all over the place and this was the one change I had to make going from $GOPATH to go mod.
go mod then handles all the dependencies it discovers properly as far as I've discovered so far.

Error with Go modules build using /cmd structure

I'm new to go modules, and am taking them for a spin in a new project which I'm trying to model after the structure described here
Here is an example of my directory structure:
.
├── cmd
│   └── app_name
│   └── main.go
├── go.mod
├── go.sum
├── internal
│   └── bot
│   └── bot.go
└── pkg
├── website_name
│   ├── client.go
│   ├── client.options.go
│   ├── server.go
│   └── server.options.go
└── lib
└── lib.go
Is this idiomatically correct? I know there's not a whole lot of consensus out there, but I'd like to follow best practices.
When I run go build I get 'unexpected module path "github.com/ragurney/app_name/cmd/app_name"', but when I run go build ./... it works. Why?
When I move main.go to the top level everything works as expected. Should I just not use the /cmd pattern with modules?
To answer your first question, its completely opinionated and whatever you like best that is also easy to understand for others you should go with (I think it's fine).
To answer your second question the reason go build ./... works as opposed to go build from the root directory is because ./... starts in the current directory (the root) and searches for all program entry-points and builds them. When you move main.go to the root directory, with this new information, go build working then makes sense, as its only looking in the current directory.
You can explicitly say go build ./cmd/app_name which would also work.
Your application structure works perfectly fine with modules, as I use something very similar to it (https://www.ardanlabs.com/blog/2017/02/package-oriented-design.html) and modules work very well for me.
from what i can tell there is nothing wrong with your project structure. What has worked for me is to run the go build/run command from the project root
eg.
go run github.com/username/project/cmd/somecommand
go build -o somebinary github.com/username/project/cmd/somecommand
I prefer to add the specific file to build, there are some projects with more than one executable
go build -o app ./cmd/server/main.go

Hyperledger Fabric unit test cross-chaincode invocation without collapsing vendor folder

I have been running into compilation issues when I tried to perform unit testing in golang locally, when trying to instantiate and invoke another chaincode through the MockStub object. Below is my file hierarchy:
├── transaction-chaincode
│   ├── transaction.go
│   ├── transaction_test.go
│   └── vendor
└── user-chaincode
├── user.go
├── user_test.go
└── vendor
The scenario here basically involves one of the chaincode, for example user.go, calling the other chaincode transaction.go. The vendor folders in both directories contain the exact same content.
The problem occurs when I try to instantiate a new instance of the transaction chaincode thru shim.NewMockStub in user_test.go, as the transaction mock object looks for the init method from within transaction-chaincode/vendor/ instead of user-chaincode/vendor/, despite the vendor folders having the same packages (and thus the same method).
I was able to get rid of this error by having a single vendor folder at the parent directory of transaction-chaincode & user-chaincode, but I cannot do so for developmental purposes. How would you suggest I solve this unit testing problem while keeping the vendor folders in their respective locations?
If I understood correctly, you are putting shim and other dependencies in each vendor folder. user_test.go then does something like NewMockStub(..., &transaction_chaincode.transaction{}). You want transaction_chaincode.transaction to bind to user/vendor ?
I don't think that'll happen. The shim import in transaction_chaincode.transaction will bind to its transaction_chaincode/vendor.
If the above understanding is correct, why do you think its a "problem" ?

Require paths for rspec tests in a Ruby Gem

I am creating a simple Ruby Gem which is currently laid out as per the example in the Making your own gem documentation.
My directory structure:
.
├── Gemfile
├── Gemfile.lock
├── lib
│   ├── go_run
│   │   ├── parser.rb
│   │   └── runner.rb
│   └── go_run.rb
└── spec
├── go_run_spec.rb
├── parser_spec.rb
└── runner_spec.rb
I originally called the Runner class in lib/go_run/runner.rb just Runner, but now, as per the documented example I have namespaced it under GoRun::Runner. The code works. The problem is that now running bundle exec rspec spec/parser_spec.rb does not. It fails with:
/home/smurf/dev/ruby/go_run/lib/go_run/parser.rb:3:in `<top (required)>': uninitialized constant GoRun (NameError)
The 3rd line of that file is:
class GoRun::Parser
I am requireing the library code in spec/parser_spec.rb using require 'go_run/parser'.
I tried including it with require_relative '../lib/go_run/parser', but that produced the same error.
Does anybody know what I am doing wrong?
Update: I have uploaded the complete code on this branch: https://github.com/henrytk/go_run/tree/stackoverflow-43155117
The problem is originating in lib/go_run/parser.rb rather than from the test itself. Whenever Ruby finds the GoRun::Parser definition, it goes looking for GoRun in the constant lookup table, but it won't be there, and so the program exits with an error.
Note that using lib/go_run.rb as an entry point also will not work, because go_run/parser.rb is required before GoRun is defined.
Part of the problem is using GoRun as both the project level namespace, and an entry point class.
There are a couple of idioms you should consider to fix this situation:
Make GoRun a top level module, used purely for namespacing. Move the logic that lives in the current logic into its own class, for example go_run/cli.rb. The go_run.rb file is then kept as a sort of manifest file, that requires the classes of your project.
Use the nested module- and class syntax. This will define the outer module if it isn't already.
Use a spec_helper.rb file that bootstraps your project using require 'go_run', to make sure everything is properly loaded before running your tests.

Resources