How to reliably detect os/platform in Go - operating-system

Here's what I'm currently using, which I think gets the job done, but there's got to be a better way:
func isWindows() bool {
return os.PathSeparator == '\\' && os.PathListSeparator == ';'
}
As you can see, in my case all I need to know is how to detect windows but I'd like to know the way to detect any platform/os.
Play:
http://play.golang.org/p/r4lYWDJDxL

Detection at compile time
If you're doing this to have different implementations depending on the OS, it is more useful to
have separate files with the implementation of that feature and add build tags to each
of the files. This is used in many places in the standard library, for example in the os package.
These so-called "Build constraints" or "Build tags" are explained here.
Say you have the constant PATH_SEPARATOR and you want that platform-dependent, you
would make two files, one for Windows and one for the (UNIX) rest:
/project/path_windows.go
/project/path_unix.go
The code of these files would then be:
path_windows.go
// +build windows
package project
const PATH_SEPARATOR = '\\'
path_unix.go
// +build !windows
package project
const PATH_SEPARATOR = '/'
You can now access PATH_SEPARATOR in your code and have it platform dependant.
Detection at runtime
If you want to determine the operating system at runtime, use the runtime.GOOS
variable:
if runtime.GOOS == "windows" {
fmt.Println("Hello from Windows")
}
While this is compiled into the runtime and therefore ignores the environment,
you can nevertheless be relatively certain that the value is correct.
The reason for this is that every platform that is worth distinguishing needs
rebuilding due to different executable formats and thus has a new GOOS value.

Have you looked at the runtime package? It has a GOOS const: http://golang.org/pkg/runtime/#pkg-constants

It's 2022 and the correct answer for go 1.18+ is:
At runtime you want:
if runtime.GOOS == "windows" {
// windows specific code here...
}
If you need to determine the filesystem path separator character
Use: os.PathSeparator
Examples:
c:\program files
/usr/local/bin
If you need the Path List separator as used by the PATH environment variable
Use: os.PathListSeparator
Examples:
/usr/local/bin:/usr/local:
"C:\windows";"c:\windows\system32";

Since this is an older question and answer I have found another solution.
You could simply use the constants defined in the os package. This const returns a rune so you would need to use string conversion also.
string(os.PathSeparator)
string(os.PathListSeparator)
Example: https://play.golang.org/p/g6jnF7W5_pJ

I just stumbled on this looking for something else and noticed the age of this post so I'll add a more updated addition. If you're just trying to handle the correct filepath I would use filepath.Join(). Its takes all of the guesswork out of os issues. If there is more you need, other than just filepath, using the runtime constants (runtime.GOOS & runtime.GOARCH) are the way to go: playground example

I tested in Go 1.17.1 which really worked for me.
package main
import (
"fmt"
"runtime"
)
func main(){
fmt.Println(runtime.GOOS)
}
Output:
darwin

With regards to detecting the platform, you can use Distribution Detector project to detect the Linux distribution being run.

The first answer from #nemo is the most apropiate, i just wanted to point out that if you are currently a user of gopls language server the build tags may not work as intended.
There's no solution or workaround up to now, the most you can do is change your editor's lsp configs (vscode, neovim, emacs, etc) to select a build tag in order to being able to edit the files with that tag without errors.
Editing files with another tag will not work, and trying to select multiple tags fails as well.
This is the current progress of the issue github#go/x/tools/gopls

Related

Where to find "Log Dyld API Usage" and "Log Library Loads" on XCode 11?

I want to disable the printing of Logging Dynamic loader events (dyld) in the XCode console. I found a solution here.
But I couldn't find Log Dyld API Usage and Log Library Loads options in product scheme diagnostics of XCode 11. Please help me find them.
PS: If there is a new process in Xcode11 for disabling logs, please let me know.
Answer: This step by step solution is suggested below in the answers. I am just attaching this picture for a better understanding.
Dynamic loader
Events environment variables
One would say that you can set environment variables like DYLD_PRINT_APIS=0, DYLD_PRINT_APIS=false, DYLD_PRINT_APIS=no, ... but it doesn't work in this way. Check the source code:
else if ( strcmp(key, "DYLD_PRINT_APIS") == 0 ) {
gLogAPIs = true;
}
In other words gLogAPIs is true when the variable exists. You can set it to whatever value, keep it empty, it will be always enabled if the variable exists.
Xcode scheme
UI for this setting is gone in the Xcode 11, but it can still be in the scheme file. Let's say that you have a simple project Foo. The scheme is located at Foo/Foo.xcodeproj/xcshareddata/xcschemes/Foo.xcscheme1). It's a XML file. Quit Xcode and open this file in any editor and search for the LaunchAction element.
There will be:
LaunchAction element attribute like enableAddressSanitizer = "YES"2) or
DYLD_... environment variable set.
Just remove this attribute/environment variable and you should be fine.
1) The exact path can vary, because it the scheme can be included in the workspace, project, ...
2) I don't have a previous version (10) of Xcode installed, can't check for the exact name, but it should be there and it will be obvious which one it is. This one, I used, is for the Address Sanitizer checkbox. If you find the exact name, let me know and I will update this answer or answer it yourself and I'll delete this one.
Update
Instructions above helped OP to find exact XML element names. One has to remove:
LaunchAction/AdditionalOptions/AdditionalOption elements
where the key is either DYLD_PRINT_LIBRARIES and/or DYLD_PRINT_APIS

Is there auto-import functionality for typescript in Visual Studio Code?

Is there any shortcut that will allow me to auto generate my typescript imports? Like hitting ctrl+space next to the type name and having the import declaration placed at the top of the file. If not, what about intellisense for filling out the module reference path so that I wont have to do it manually? I would really love to use vscode but having to do manual imports for typescript is killing me.
There are rumors of making it support tsconfig.json (well, better than rumors). This will allow us to be able to use all files for our references.
Your feature would be to create an auto import of all commonly used 3rd party libs into the typings. Perhaps auto scan the files and create a list of ones to go gather. Wouldn't it be fine to just have a quick way to add several of these using tsd directly from Code (interactively)?
I believe the plugin called "TypeScript Importer" does exactly what You mean: https://marketplace.visualstudio.com/items?itemName=pmneo.tsimporter .
Automatically searches for TypeScript definitions in workspace files and provides all known symbols as completion item to allow code completion.
With it You can truly use Ctrl+Space to choose what exactly You would like to be imported.
You can find and install it from Ctrl+Shift+X menu or just by pasting ext install tsimporter in Quick Open menu opened with Ctrl+P.
I know a solution for Visual Studio (not Visual Studio Code, I'm using the 2015 Community edition, which is free), but it needs some setup and coding -- however, I find the results to be adequate.
Basically, in Visual Studio, when using the Web-Essentials extension, .ts files can be dragged into the active document to automatically generate a relative reference path comment:
/// <reference path="lib/foo.ts" />
With which of course we might as well wipe it, because it's an import statement we need, not a reference comment.
For this reason, I recently wrote the following command snippet for Visual Commander, but it should be easily adaptable to other use casese as well. With Visual Commander, your drag the needed imports into the open document, then run the following macro:
using EnvDTE;
using EnvDTE80;
using System.Text.RegularExpressions;
public class C : VisualCommanderExt.ICommand
{
// Called by Visual Commander extension.
public void Run(EnvDTE80.DTE2 DTE, Microsoft.VisualStudio.Shell.Package package)
{
TextDocument doc = (TextDocument)(DTE.ActiveDocument.Object("TextDocument"));
var p = doc.StartPoint.CreateEditPoint();
string s = p.GetText(doc.EndPoint);
p.ReplaceText(doc.EndPoint, this.ReplaceReferences(s), (int)vsEPReplaceTextOptions.vsEPReplaceTextKeepMarkers);
}
// Converts "reference" syntax to "ES6 import" syntax.
private string ReplaceReferences(string text)
{
string pattern = "\\/\\/\\/ *<reference *path *= *\"([^\"]*)(?:\\.ts)\" *\\/>";
var regex = new Regex(pattern);
var matches = Regex.Matches(text, pattern);
return Regex.Replace(text, pattern, "import {} from \"./$1\";");
}
}
When running this snippet, all reference comments in the active document will be replaced with import statements. The above example is converted to:
import {} from "./lib/foo";
This has just been released in version 1.18.
From the release notes:
Auto Import for JavaScript and TypeScript
Speed up your coding with auto imports for JavaScript and TypeScript. The suggestion list now includes all exported symbols in the current project. Just start typing:
If you choose one of the suggestion from another file or module, VS Code will automatically add an import for it. In this example, VS Code adds an import for Hercules to the top of the file:
Auto imports requires TypeScript 2.6+. You can disable auto imports by setting "typescript.autoImportSuggestions.enabled": false.
The files attributes in the tsconfig.json file allows you to set your reference imports in your whole project. It is supported with Visual Studio Code, but please note that if you're using a specific build chain (such as tsify/browserify) it might not work when compiling your project.

Obtaining Solaris Device path

I am working on Solaris 12 and I am trying to get device path like this:
/pci#0,0/pci108e,4856#1f,2:devctl
I could obtain the this path through CLI using prtconf -v. How could I obtain the path through api using C function? I tried serveral functions in libdevinfo, such as di_devfs_path, but it didn't give the same path as the prtconf gives me. Should I use functions like di_node_name, di_instance, di_binding_name to get pieces of information and construct the path by my own. Or there is a function to get the whole device path?
Thanks.
Firstly, unless you're working for Oracle in the Systems division, you're not working on Solaris 12. (If you are working for Oracle, why haven't you asked
Oracle internal mailing lists for help?)
Secondly, the :devctl node is a minor for the device, so you'll need to walk the minor nodes using di_walk_minor() and check di_minor_name() to see if it matches your criteria.
Finally, yes, this should work on Solaris 10 and later.

is there a way to list words in the current Red console

Is there an object like rebol/words available in the REPL build with console.red ?
I am using the red-master currently on github ( it says alpha and Latin-1 only but no other version id and I didn't see anything at top of console.red)
I was trying some functions but didn't have a listing of those available ( it may be right under my nose ... )
thanks
Use words-of system/words to get a list of all words defined in global context.
Use system/version to get the version and system/build/date for the build date.

How could I embedded socket in Lua internally, just like oslib, debuglib?

I want to implement the function like embedding the socket function in my Lua build.
So I don't need to copy socket.core.dll any more (just for fun).
I search the maillist, and see some guys discuss the topic,
http://lua-users.org/lists/lua-l/2005-10/msg00269.html
But I have question for the details steps, who could give me a detailed steps for changing the lua and luasocket code to make them work together (not with dll method).
I tried these steps in windows xp with VC2008:
1) copy luasocket code to Lua project.
2) add some code
static const luaL_Reg lualibs[] = {
{"", luaopen_base},
{LUA_LOADLIBNAME, luaopen_package},
{LUA_TABLIBNAME, luaopen_table},
{LUA_IOLIBNAME, luaopen_io},
{LUA_OSLIBNAME, luaopen_os},
{LUA_STRLIBNAME, luaopen_string},
{LUA_MATHLIBNAME, luaopen_math},
{LUA_DBLIBNAME, luaopen_debug},
{LUA_SOCKETLIBNAME, luaopen_socket_core}, // add this line
{LUA_MIMELIBNAME, luaopen_socket_core}, // add this line
{NULL, NULL}
};
3) build the project, and run it.
When I type print(socket._VERSION), it shows luasocket 2.0.2, it is correct.
When I type print(socket.dns.toip("localhost")), it shows 127.0.0.1 table: 00480AD0, it is correct too.
But when I try to use other features, for example bind, it can't work.
Who could tell me the reason?
you need put luasocket stuff into the package.preload table, in this way:
lua_getfield(L, LUA_GLOBALSINDEX, "package");
lua_getfield(L, -1, "preload");
lua_pushcfunction(L, luaopen_socket_core);
lua_setfield(L, -2, "socket.core");
// add mime.core yourself...
luasocket is a mixed C/lua module, you need to bundle both versions into your application if you want it to work without any extra files.
socket.lua loads socket.core (from socket/core.dll)
mime.lua loads mime.core (from mime/core.dll)
So in order for your application to work you will need to build all the .dll files and the .lua files into your application and manually load them (or set them up to be loaded correctly via custom package loaders).
The email you quoted is tweaking the package.preload table (in a way that appears a tad odd now but might work anyway) to get the built-in C code to be loaded correctly when require is called.
Try running
for k, v in pairs(socket) do print(k, v) end
and maybe we'll be able to help.