best practice for dart root access - dart

I'm the author of dshell a dart package and tooling for building cli applications/scripts with dart.
https://pub.dev/packages/dshell
I'm looking into how dshell should interact with sudo.
The first problem I've come across is how do deal with paths.
If I do a pub activate global dshell, then dart installs dshell and its executables so that they are on the linux path for the current user.
This works fine until you try to run a dshell script using sudo.
e.g.
sudo dshell main.dart.
The sudo command essentially changes the user to the root user. As such the PATH variable changes and the HOME var changes. The result is that the dart and dshell paths are no longer on the path.
Is there a best practice for putting a dart package on a global path so that it (and its dependencies) are available to root and other users?

Related

How does Nix able to install individual NPM packages as standalone software?

CAVEAT: If you would like to use Serverless Framework with Nix/NixOS, this is not the way to do it: the package you end up with is outdated, and (as stated below) it probably won't work anyway. See thread on NixOS Discourse.
Wanted to try out Serverless via nix-shell so I looked it up, ran the command
nix-shell -v -p nodePackages.serverless
a̶n̶d̶ i̶t̶ w̶o̶r̶k̶s̶ f̶l̶a̶w̶l̶e̶s̶s̶l̶y̶.1
What makes this possible without requiring me to install Node manually to be able to run npm install -g serverless? (E.g., Is the node_modules folder somewhere in the Nix store? What happens if I nix-shell another Node package - will they share that same directory?)
[1]: It does not... See this Reddit thread; probable setuid issue. Still interested in the behind the scene stuff though.
This question is more like a todo because I really would like to figure it out myself but don't have the time for it right now...
This is possible because it was packaged with node2nix. This tool generates expressions that fetch the various packages and put them in a node_modules directory.
Indeed it's not perfect and some package need some extra fixing up to make them work well. The node2nix tooling could 'learn' from the cabal2nix integration in Nixpkgs to improve the quality of packaging and the Nixpkgs developer experience.

Is it possible to create a custom cdk init template to leverage pipenv for my python project?

I would like to utilize pipenv as my virtual environment manager and for my dependency management for my Python cdk projects, upon running 'cdk init'. I read that you can specify a 'custom' application template but could not find documentation on creating one. Is it possible and can the virtual environment/dependency manager be controlled using this feature?
I would like to be able to run 'cdk init hello-world --language python' and have the scaffolding for the project be generated BUT using pipenv.
It's not possible to do that without modifying the source code for the CDK package itself. You likely won't want to manage your own divergent version of the standard package.
I've shoe-horned CDK to work with PipEnv a couple of times, and it's more work than it's worth at this point. The problem is that PipEnv forces the . delimiter in the package name to a -; pipenv install aws-cdk.aws-rds is listed as aws-cdk-aws-rds in the Pipfile, and the package installations don't actually work.
There's an open issue on the repo for this though (https://github.com/aws/aws-cdk/issues/3671), so you could +1 there in hopes that they can address it. It really is an issue with Pipenv though.
Following the link from Scott for the open issue, it looks like this works now, provided the package name is in quotes.

How to install waf?

I have cloned and built the waf script using:
./waf-light configure
Then to build my project (provided by Gomspace) I need to add waf and the eclipse.py to my path. So far I haven't found better than this setenv script:
WAFROOT=~/git/waf/
export PYTHONPATH=$WAFROOT/waflib/extras/:$PYTHONPATH
export PATH=~/git/waf/:$PATH
Called with:
source setenv
This is somehow a pretty ugly solution. Is there a more elegant way to install waf?
You don't install waf. The command you found correctly builds waf: /waf-light configure build Then for each project you create, you put the built waf script into that projects root directory. I can't find a reference, but this is the way in which waf:s primary author Thomas Nagy wants the tool to be used. Projects that repackage waf to make the tool installable aren't "officially sanctioned."
There are advantages and disadvantages with non-installation:
Disadvantages:
You have to add the semi-binary 100kb large waf file to your repository.
Because the file contains binary code, people can have legal objections to distributing it.
Advantages:
It doesn't matter if new versions of waf break the old API.
Users don't need to install waf before compiling the project -- having Python on the system is enough.
Fedora (at least Fedora 22) has a yum package for waf, so you could see that it's possible to do a system install of waf, albeit with a hack.
After you run something like python3 ./waf-light configure build, you'll get a file called waf that's actually a Python script with some binary data at the end. If you put it into /usr/bin and run it as non-root, you'll get an error because it fails to create a directory in /usr/bin. If you run it as root, you'll get the new directory and /usr/bin/waf runs normally.
Here's the trick that I learned from examining the find_lib() function in the waf Python script.
Copy the waf to /usr/bin/waf
As root, run /usr/bin/waf. Notice that it creates a directory. You'll see something like /usr/bin/.waf-2.0.19-b2f63c807a4215294bf6005410c74c18
mv that directory to /usr/lib, dropping the . in the directory name, e.g. mv /usr/bin/.waf-2.0.19-b2f63c807a4215294bf6005410c74c18 /usr/lib/waf-2.0.19-b2f63c807a4215294bf6005410c74c18
If you want to use waf with Python3, repeat Steps 2-3 running the Python script /usr/bin/waf under Python3. Under Python3, the directory names will start with .waf3-/waf3- instead instead of .waf-/waf-.
(Optional) Remove the binary data at the end of /usr/bin/waf.
Now, non-root should be able to just use /usr/bin/waf.
That said, here's something to consider, like what another answer said: I believe waf's author intended waf to be embedded in projects so that each project can use its own version of waf without fear that a project will fail to build when there are newer versions of waf. Thus, the one-global-version use case seems to be not officially supported.

Yeoman. The filename, directory name, or volume label syntax is incorrect

Reinstalled Windows 10 (Version 10.0.14393). Reinstalled the following:
Java
java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)
nodejs (v6.9.5)
NPM (3.10.10)
Yarn (v0.19.1)
Yeoman (installed with yarn global add yo)
When I write yo -v in cmd in any folder, runned with administrator or not, I take:
The filename, directory name, or volume label syntax is incorrect.
UPDATE:
The only workaround I found is to use the full path of yo:
C:\Users\<username>\AppData\Local\Yarn\config\global\node_modules\.bin\yo.cmd
It may be that your PATH does not point to global NPM modules yet. The FAQ and links are more helpful for gnu/linux or mac users. The PATH is a list of the places that your operating system checks whenever you type a command.
Since you are using Windows, to add the modules path temporarily (just for one session) at the prompt, just type (obviously use the correct path with your correct username and please take note of the ; separator character):
path = %path%;C:\Users\<username>\AppData\Local\Yarn\config\global\node_modules\.bin\
You should then be able to run 'yo -v' without pointing to the full path name, since the console now knows to check that folder also. If that works for you, you can add that path permanently using the instructions described on another SO post here.
Finally (and this is only slightly related to your question), since i notice you've got the Windows 10 anniversary update, if you have Linux experience, you may prefer to use "Windows subsystem for Linux", which is a bash shell (Ubuntu 14) on Windows, that you can use instead of the default command prompt. You can find it under "Add / Remove programs --> Turn Windows features on or off --> (scroll right down) --> Windows subsystem for Linux (beta)". Your local file system will be at "/mnt/c" so you can get to it from within the shell or from windows explorer. I've had fewer problems using this and since so many tutorials are written with bash (not command prompt) in mind, it's useful to use it instead of cmd.
You'll need to install dependencies in the usual way using apt-get (as it won't use the ones you've installed on the windows side) and you'll need to prefix commands that make system changes with 'sudo'. e.g.
sudo npm -g modulename

Does luarocks management have "./node_modules" equivalent for projects?

In NodeJS/NPM, you can create a package.json and run npm install to install all your dependencies in a folder within your project: ./node_modules. (A project can be an app or another module/package.)
Ruby also has a "bundler" system (using a .bundle file) that keeps track of gems specific to a dir (ie project).
Does LuaRocks have similar conventions? Or is it recommeneded to install everything to /usr or $HOME?
So far I've been able to get similiar functionality, but I have to create a custom LuaRocks config file and specify --tree=my_local_lua_rocks_dir every time I want to install a rock. Granted, I can always create a bash script. The point is that it seems I'm going against a convention.
It is possible to install rocks into a directory under the current directory, using the --tree flag:
luarocks install --tree ./lua_modules lpeg
And then you have to configure your package.path and package.cpath variables in Lua (settable via LUA_PATH and LUA_CPATH environment variables) so it finds the modules installed inside it. There are several ways to do this conveniently: this tutorial explains how to do it, with more examples.
Instead of using Vert, I've decided to just edit the LuaRocks config file:
In /etc/luarocks/config.lua :
rocks_servers = {
[[http://rocks.moonscript.org/]],
[[http://luarocks.org/repositories/rocks]]
}
rocks_trees = {
[[/usr/local]],
[[./my_dir]]
}
./my_dir is relative to the pwd you're in, not to the location of the config file. Of course, change my_dir to whatever you want.
"The order of the rock_trees matters: When installing rocks, LuaRocks tries to pick a location to store the rock starting from the bottom of the list; when loading rocks in runtime, LuaRocks scans from the top of the list." From: http://luarocks.org/en/Config_file_format
Then in your .bashrc:
eval `luarocks path`
export PATH=$PATH:my_dir/bin
However, for certain commands you now have to specify the tree or it will give you a confusing error:
luarocks make --tree=my_dir

Resources