Trying to import some modules but get "..which can not be read" - d

I am new to D and am trying to create a simple starter project with sub modules. I have been following the d2d source structure, as an example, but I can't get my project to compile using DUB.
My folder structure is:
Ranger
examples
template0 <== compiling in this directory
source
app.d
dub.json
source
ranger
geometry
package.d
point.d
package.d
app.d contains:
import std.stdio;
import ranger;
void main()
{
writeln("Edit source/app.d to start your project.");
}
ranger/package.d:
module ranger;
public import ranger.geometry;
ranger/geometry/package.d:
module ranger.geometry;
public import ranger.geometry.point;
When I compile from the template0 directory it keeps failing:
dub build --force
Invalid source/import path: /home/iposthuman/Documents/Development/D/Ranger/examples/template0/~/Documents/Development/D/Ranger/source
Performing "debug" build using /home/iposthuman/dlang/dmd-2.084.0/linux/bin64/dmd for x86_64.
template0 ~master: building configuration "application"...
/home/iposthuman/Documents/Development/D/Ranger/source/ranger/package.d(5,15): Error: module geometry is in file 'ranger/geometry.d' which cannot be read
import path[0] = source import path1 = /home/iposthuman/Documents/Development/D/Ranger/source
import path[2] = /home/iposthuman/dlang/dmd-2.084.0/linux/bin64/../../src/phobos
import path[3] = /home/iposthuman/dlang/dmd-2.084.0/linux/bin64/../../src/druntime/import
/home/iposthuman/dlang/dmd-2.084.0/linux/bin64/dmd failed with exit code 1.
I don't understand why the import path has two paths smashed together not do I know how to fix it.
I don't understand the involving geometry.d because there isn't a file called geometry.d--but there is a folder with a package. ...I am confused.
My dub.json contains what I believe is the correct path to my ranger source code:
{
"authors": [
"William Cleveland"
],
"copyright": "Copyright © 2019, William Cleveland",
"description": "A minimal D application.",
"license": "MIT",
"name": "template0",
"importPaths": [
"source",
"~/Documents/Development/D/Ranger/source"
]
}
Am I using DUB wrong or configuring the json wrong???
I didn't think using D was going to be this difficult just to get something basic working. I have searched everywhere on Modules and find only trivial examples.
Thanks.

Dub doesn't translate ~ to your home directory. ~ is POSIX-speak, but dub is a cross-platform application.
Either use /home/iposthuman/Documents/Development/D/Ranger/source or ../../source.
Preferrably the latter, because it won't break when your username changes or you share your project with someone else.

I think weltensturm's answer is the right idea but slightly off. I would change
"importPaths": [
"source",
"~/Documents/Development/D/Ranger/source"
]
to
"importPaths": [
"source",
"../../../source"
]
Basically you just need to go back one more directory to access source.
I don't understand the involving geometry.d because there isn't a file called geometry.d--but there is a folder with a package. ...I am confused.
This is because when you import a module, dub expects there to be a file with that name or a package.d file like you have inside of a folder with the name of the module. So if you do import foo; there should be a file called foo.d or package.d inside a folder called foo which has module foo; at the beginning of it. I think what you have is right, but since your import path is wrong, dub is looking in the wrong place for geometry.d or the folder geometry.
Side note, you could always turn the folder that you are importing into a package using dub. And run dub add-local ./. Then you can add it as a dependency to the other project by doing "my-project": "~master"

Related

Adding a JSON data file to GCP Dataflow package and using it inside the code

I want to add a JSON file to my Dataflow (Apache Beam) package and use it inside the code.
I've seen several questions on Stack Overflow with different answers, and I tried the recommended approach with a MANIFEST.in and adding data_files to the setup.py file. But nothing I tried works for me.
Here is my current setup.
(I have mapping.json in both the common folder and the root folder for testing purposes.)
MANIFEST.in
recursive-include common *.json
setup.py
import setuptools
setuptools.setup(
packages=setuptools.find_packages(),
data_files=[
("common", ["mapping.json"])
],
include_package_data=True,
install_requires=[
'apache-beam[gcp]==2.31.0',
'python-dateutil==2.8.1'
],
)
Using the file inside common/config.py
import json
from pathlib import Path
def _load_category_theme_mapping(file_name):
path = Path(__file__).parent / file_name
with path.open('r', encoding='utf-8') as file:
return json.load(file)
mapping = _load_category_theme_mapping("mapping.json")
I'm using Flex Templates to run my Dataflow job and I copy the common folder to the target common folder.
When I run the Dataflow job with this setup, it just throws an error.
FileNotFoundError: [Errno 2] No such file or directory: '/usr/local/lib/python3.7/site-packages/common/category_theme_mapping.json'
I tried moving the .json file outside of the common folder (into the root folder) and changed the code (and the Dockerfile) accordingly to read from the base folder.
Then I changed the setup.py file to have the data_files to (".", ["mapping.json"] and MANIFEST.in to have include *.json, but it still fails.
I also tried without having a MANIFEST.in, but then the launcher fails without any informative log.
Any idea what I'm doing wrong?

How does poky/meta/lib/oe/image.py get included when building core-image-minimal.bb?

I am using the Yocto Project, Jethro release. However, I think this question applies to other releases as well.
I need to modify the image creation process. I have read the BitBake manual, but I still don't know how a full python script or several scripts are included.
Here is what I have found so far:
bitbake core-image-mininmal
After bitbake reads all the config files and parses bblayers.conf, it searches all the layer directories for the recipe core-image-minimal.bb
In core-image-minimal.bb, we have:
inherit core-image
This inherits the class core-image.bbclass which in turn inherits image.bbclass which contains the bitbake code:
fakeroot python do_rootfs () {
from oe.rootfs import create_rootfs
from oe.image import create_image
from oe.manifest import create_manifest
# generate the initial manifest
create_manifest(d)
# generate rootfs
create_rootfs(d)
# generate final images
create_image(d)
}
Searching the source tree for the text create_image, I found the following in image.py:
def create_image(d):
Image(d).create()
and also:
def create(self):
bb.note("###### Generate images #######")
pre_process_cmds = self.d.getVar("IMAGE_PREPROCESS_COMMAND", True)
post_process_cmds = self.d.getVar("IMAGE_POSTPROCESS_COMMAND", True)
I've also created my own class my-class.bbclass and put the following in it:
fakeroot python do_rootfs_prepend () {
print("==> do_rootfs_prepend")
}
fakeroot python do_rootfs_append () {
print("==> do_rootfs_append")
}
and I see the messages in the log file, so I know this is working to add my python code to the do_rootfs function in image.bbclass.
However, I would still like to know how image.py and a whole bunch of other *.py files are included (e.g. rootfs.py) from the poky/meta/lib/oe directory.
First, note that rootfs/image code has been refactored quite a bit after the Jethro release: the last releases do not have some of the functions referred to in your example.
There's no Yocto-specific magic in the library function usage: they are used via standard python module import, just with meta/lib/ in the module search path, e.g.
from oe.image import create_image
will make the create_image() function from meta/lib/oe/image.py available in the current scope.

Write unittest and save in the separate folder

I am trying to write a unittest for my class. First of all, i install the package unittest and create a spec folder to save all my unittest files. Then i create a test dart file with following contents:
library i18n_test;
import 'package:unittest/unittest.dart';
void main() {
}
When i run the file, i got the following error
Unable to open file: D:\Dart\i18n\bin\spec\packages\unittest\unittest.dart'file:///D:/Dart/i18n/bin/spec/i18n_test.dart': error: line 3 pos 1: library handler failed
import 'package:unittest/unittest.dart';
As i mentioned, i saved my unittest file in the spec folder, i think that because the compiler could not find the package unittest.
My Folder structure looks like:
What do i wrong?
The error is caused by a missing packages symlink in your spec folder.
see https://code.google.com/p/dart/issues/detail?id=16947
Anyway
unit tests should be put into the test folder (i18n/test).
This way your test code won't be included in the build output.
It's best to have most of your code in the lib folder to make it easy to import into your tests using package imports like:
import 'package:i18n/my_dart_file.dart';
you should still be able to import from bin or web using relative imports like
import '../bin/my_dart_file.dart';
but that form is not very refactoring-friendly.

ImportError: No module named for my code on Readthedocs

I am trying to link my Sphinx documentation with ReadtheDocs. I can build the documentation locally but when I try to have ReadtheDocs automatically generate the documentation I get the following error:
Sphinx Standard Error
Making output directory...
Exception occurred:
File "/var/build/user_builds/mousedb/checkouts/latest/Docs/source/conf.py", line 25, in <module>
from mousedb import settings
ImportError: No module named mousedb
The full traceback has been saved in /tmp/sphinx-err-n_8fkR.log, if you want to report the issue to the developers.
Please also report this if it was a user error, so that a better error message can be provided next time.
Either send bugs to the mailing list at <http://groups.google.com/group/sphinx-dev/>,
or report them in the tracker at <http://bitbucket.org/birkenfeld/sphinx/issues/>. Thanks!
My project name is mousedb. I don't understand why I get this import error in the auto-build but not locally.
Update
Based on the comments I think that this is an issue for importing my settings file into a sibling Docs directory. Rather than doing an absolute import (as I had been doing) I should be doing a relative import based on the location of settings.py and conf.py.
I want to import my settings file into my conf.py with the following directory structure:
-mousedb
--settings.py
-Docs
--source
---conf.py
--build
You originally talked about a "local absolute path to my code" and now about setting up relative paths to your code. This probably means you're not using a setup.py file and also not a virtualenv.
In the same directory as Docs/ and mousedb/, add a setup.py:
from setuptools import setup
setup(name='mousedb',
version='0.1',
description="My sample package",
long_description="",
author='TODO',
author_email='todo#example.org',
license='TODO',
packages=['mousedb'],
zip_safe=False,
install_requires=[
'Django',
# 'Sphinx',
# ^^^ Not sure if this is needed on readthedocs.org
# 'something else?',
],
)
After committing/pushing/whatever this file, you can go to your readthedocs settings for your project. Enable the "use virtualenv" setting. This will "nstall your project inside a virtualenv using setup.py install".
The end result is that everything python-related that readthedocs does will have your project in it's sys.path.
The probable cause of your problems is that you run sphinx from within your "root" directory on your local system, where python magically finds the mousedb/ package in your current directory. But readthedocs apparently runs it from within the Docs/ directory and thus cannot find mousedb.

Go build: "Cannot find package" (even though GOPATH is set)

Even though I have GOPATH properly set, I still can't get "go build" or "go run" to find my own packages. What am I doing wrong?
$ echo $GOROOT
/usr/local/go
$ echo $GOPATH
/home/mitchell/go
$ cat ~/main.go
package main
import "foobar"
func main() { }
$ cat /home/mitchell/go/src/foobar.go
package foobar
$ go build main.go
main.go:3:8: import "foobar": cannot find package
It does not work because your foobar.go source file is not in a directory called foobar. go build and go install try to match directories, not source files.
Set $GOPATH to a valid directory, e.g. export GOPATH="$HOME/go"
Move foobar.go to $GOPATH/src/foobar/foobar.go and building should work just fine.
Additional recommended steps:
Add $GOPATH/bin to your $PATH by: PATH="$GOPATH/bin:$PATH"
Move main.go to a subfolder of $GOPATH/src, e.g. $GOPATH/src/test
go install test should now create an executable in $GOPATH/bin that can be called by typing test into your terminal.
Although the accepted answer is still correct about needing to match directories with package names, you really need to migrate to using Go modules instead of using GOPATH. New users who encounter this problem may be confused about the mentions of using GOPATH (as was I), which are now outdated. So, I will try to clear up this issue and provide guidance associated with preventing this issue when using Go modules.
If you're already familiar with Go modules and are experiencing this issue, skip down to my more specific sections below that cover some of the Go conventions that are easy to overlook or forget.
This guide teaches about Go modules: https://golang.org/doc/code.html
Project organization with Go modules
Once you migrate to Go modules, as mentioned in that article, organize the project code as described:
A repository contains one or more modules. A module is a collection of
related Go packages that are released together. A Go repository
typically contains only one module, located at the root of the
repository. A file named go.mod there declares the module path: the
import path prefix for all packages within the module. The module
contains the packages in the directory containing its go.mod file as
well as subdirectories of that directory, up to the next subdirectory
containing another go.mod file (if any).
Each module's path not only serves as an import path prefix for its
packages, but also indicates where the go command should look to
download it. For example, in order to download the module
golang.org/x/tools, the go command would consult the repository
indicated by https://golang.org/x/tools (described more here).
An import path is a string used to import a package. A package's
import path is its module path joined with its subdirectory within the
module. For example, the module github.com/google/go-cmp contains a
package in the directory cmp/. That package's import path is
github.com/google/go-cmp/cmp. Packages in the standard library do not
have a module path prefix.
You can initialize your module like this:
$ go mod init github.com/mitchell/foo-app
Your code doesn't need to be located on github.com for it to build. However, it's a best practice to structure your modules as if they will eventually be published.
Understanding what happens when trying to get a package
There's a great article here that talks about what happens when you try to get a package or module: https://medium.com/rungo/anatomy-of-modules-in-go-c8274d215c16
It discusses where the package is stored and will help you understand why you might be getting this error if you're already using Go modules.
Ensure the imported function has been exported
Note that if you're having trouble accessing a function from another file, you need to ensure that you've exported your function. As described in the first link I provided, a function must begin with an upper-case letter to be exported and made available for importing into other packages.
Names of directories
Another critical detail (as was mentioned in the accepted answer) is that names of directories are what define the names of your packages. (Your package names need to match their directory names.) You can see examples of this here: https://medium.com/rungo/everything-you-need-to-know-about-packages-in-go-b8bac62b74cc
With that said, the file containing your main method (i.e., the entry point of your application) is sort of exempt from this requirement.
As an example, I had problems with my imports when using a structure like this:
/my-app
├── go.mod
├── /src
├── main.go
└── /utils
└── utils.go
I was unable to import the code in utils into my main package.
However, once I put main.go into its own subdirectory, as shown below, my imports worked just fine:
/my-app
├── go.mod
├── /src
├── /app
| └── main.go
└── /utils
└── utils.go
In that example, my go.mod file looks like this:
module git.mydomain.com/path/to/repo/my-app
go 1.14
When I saved main.go after adding a reference to utils.MyFunction(), my IDE automatically pulled in the reference to my package like this:
import "git.mydomain.com/path/to/repo/my-app/src/my-app"
(I'm using VS Code with the Golang extension.)
Notice that the import path included the subdirectory to the package.
Dealing with a private repo
If the code is part of a private repo, you need to run a git command to enable access. Otherwise, you can encounter other errors This article mentions how to do that for private Github, BitBucket, and GitLab repos: https://medium.com/cloud-native-the-gathering/go-modules-with-private-git-repositories-dfe795068db4
This issue is also discussed here: What's the proper way to "go get" a private repository?
I solved this problem by set my go env GO111MODULE to off
go env -w GO111MODULE=off
Note: setting GO111MODULE=off will turn off the latest GO Modules feature.
Reference: Why is GO111MODULE everywhere, and everything about Go Modules (updated with Go 1.17)
GO111MODULE with Go 1.16
As of Go 1.16, the default behavior is GO111MODULE=on, meaning that if
you want to keep using the old GOPATH way, you will have to force Go
not to use the Go Modules feature:
export GO111MODULE=off
In the recent go versions from 1.14 onwards, we have to do go mod vendor before building or running, since by default go appends -mod=vendor to the go commands.
So after doing go mod vendor, if we try to build, we won't face this issue.
Edit: since you meant GOPATH, see fasmat's answer (upvoted)
As mentioned in "How do I make go find my package?", you need to put a package xxx in a directory xxx.
See the Go language spec:
package math
A set of files sharing the same PackageName form the implementation of a package.
An implementation may require that all source files for a package inhabit the same directory.
The Code organization mentions:
When building a program that imports the package "widget" the go command looks for src/pkg/widget inside the Go root, and then—if the package source isn't found there—it searches for src/widget inside each workspace in order.
(a "workspace" is a path entry in your GOPATH: that variable can reference multiple paths for your 'src, bin, pkg' to be)
(Original answer)
You also should set GOPATH to ~/go, not GOROOT, as illustrated in "How to Write Go Code".
The Go path is used to resolve import statements. It is implemented by and documented in the go/build package.
The GOPATH environment variable lists places to look for Go code.
On Unix, the value is a colon-separated string.
On Windows, the value is a semicolon-separated string.
On Plan 9, the value is a list.
That is different from GOROOT:
The Go binary distributions assume they will be installed in /usr/local/go (or c:\Go under Windows), but it is possible to install them in a different location.
If you do this, you will need to set the GOROOT environment variable to that directory when using the Go tools.
TL;DR: Follow Go conventions! (lesson learned the hard way), check for old go versions and remove them. Install latest.
For me the solution was different. I worked on a shared Linux server and after verifying my GOPATH and other environment variables several times it still didn't work. I encountered several errors including 'Cannot find package' and 'unrecognized import path'. After trying to reinstall with this solution by the instructions on golang.org (including the uninstall part) still encountered problems.
Took me some time to realize that there's still an old version that hasn't been uninstalled (running go version then which go again... DAHH) which got me to this question and finally solved.
Running go env -w GO111MODULE=auto worked for me
Without editing GOPATH or anything, in my case just worked the following:
/app
├── main.go
├── /utils
└── utils.go
Import packages where needed. This can be unintuitive, because it isn't relative to the app path. You need to add the app in the package path too:
main.go:
package main
import(
"app/util"
)
Being in app directory, run:
go mod init app
go get <package/xxx>
go build main.go / go run main.go
You should be good to go.
GOPATH = /home/go
appPath = /home/projects/app
Create a proper go.mod and go.sum with go mod init app (delete old before)
After that resolve all dependencies like missing packages with go get github.com/example/package.
In simple words you can solve the import problem even with GO111MODULE=on with the following syntax for import:
import <your_module_name>/<package_name>
your_module_name -> module name which can be found in the go.mod file of the module as the first line.
example: github.com/nikhilg-hub/todo/ToDoBackend
package_name -> Path to your package within module.
example: orm
So the import statement would look like:
import "github.com/nikhilg-hub/todo/ToDoBackend/orm"
According to me we need to specify the module name + package name because we may need a same package name in two or more different modules.
Note: If you are importing a package from same module still you need to specify the full import path like above.
If you have a valid $GOROOT and $GOPATH but are developing outside of them, you might get this error if the package (yours or someone else's) hasn't been downloaded.
If that's the case, try go get -d (-d flag prevents installation) to ensure the package is downloaded before you run, build or install.
GOROOT should be set to your installation directory (/usr/local/go).
GOPATH should be set to your working directory (something like /home/username/project_folder).
GOPATH should not be set to GOROOT as your own project may need to install packages, and it's not recommended to have those packages in the Go installation folder. Check out this link for more.
For me none of the above solutions worked. But my go version was not the latest one. I have downloaded the latest version and replaced the older version in my mac os after that it worked perfectly.
I had a similar problem when building a docker file:
[1/3] STEP 9/9: RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o manager main.go
api/v1alpha1/XXX.go:5:2: cannot find package "." in:
/workspace/client/YYY/YYY.go
This only appeared when building the Dockerfile, building locally worked fine.
The problem turned out to be a missing statement in my Dockerfile:
COPY client/ client/
I do not understand why this happens, we must be able to import from wherever our file is in its nest, since I have discovered that if we have more than one nest this will throw an error.
package main
import (
"fmt"
"indexer/source/testPackage3" // this will be show a GOROOT error.
"indexer/testPackage"
"indexer/testPackage2"
)
func main() {
fmt.Println("Agile content indexer -")
fmt.Println(testPackage.Greeting())
fmt.Println(testPackage2.Greeting())
fmt.Println(testPackage3.Greeting())
}
├── testPackage2
│ ├── entry2.go
│ └── source
│ └── entry3.go
To conclude, I just want to tell you, the entry3.go file will not work when imported into my main file, which in this case is (main.go), I do not understand why, therefore, I have simply chosen to use a depth folder in the packages I need to export.
entry.go, entry2.go will work perfectly when imported, but entry3.go will not work..
In addition, both the directory and the name of the package must be the same so that they work properly when importing them.
Have you tried adding the absolute directory of go to your 'path'?
export PATH=$PATH:/directory/to/go/