numtide / devshell Goto Github PK
View Code? Open in Web Editor NEWPer project developer environments
Home Page: https://numtide.github.io/devshell/
License: MIT License
Per project developer environments
Home Page: https://numtide.github.io/devshell/
License: MIT License
Hi @zimbatm , I encountered this error when using indirect package definitions via [[commands]]
. In turn using plain package
, the problem is not observable.
Do you have any clou?
devshell git:(err-shell-level) โ stack
/nix/store/r3j288vpmczbl500w6zz89gyfa4nr0b1-bash-4.4-p23/bin/bash: warning: shell level (1000) too high, resetting to 1
/nix/store/r3j288vpmczbl500w6zz89gyfa4nr0b1-bash-4.4-p23/bin/bash: warning: shell level (1000) too high, resetting to 1
^C
Reproducible on my machine on this minimal branch: https://github.com/blaggacao/devshell/tree/err-shell-level
Instead of copying the descriptions into markdown files, it would be nice if the mkDevShell/options.nix file could be used to automatically generate the doc.
Take a look at https://github.com/nix-community/home-manager/tree/master/doc to see how they are doing it.
See for example this claim. Firejail? Is this motion at all on-scope?
I decided to close #22 as a special case of the need for user shell transparency.
What I mean by that is that devshell scripts should/might gain a notion of the underlying user shell.
The current use case I can think of is prompt modifications, such as with jlesquembre/kubeprompt#13 that need to have awareness of the target shell to choose correct escape codes.
But also the possibility to declare shell functions that are brought over to the target shell might have it's use case, if I'm not mistaken and that's already the case.
This is a relatively barren issue since I have not a lot of context on the underlying issues, but I wanted to log this question for further development.
/cc @jlesquembre
Let's keep an eye on how fast this is compared to pkgs.mkShell
. The nix module system is relatively complicated and might take more time to evaluate.
First of all, thank you again in the open for this strategic piece of work!
I want to report a use case we hit:
just
) would not be able to export this environment out of his process scopeIs it legit to thing of a way to export environment variables structurally, not within a '' literal string part ''
?
Maybe it's not legit, though, and we should use overlays to modify the invoking commands to behave differently in the context of the nix shell.
Users might want to extend or override some of the project devshell.toml settings with their own.
If a devshell.local.toml
exists, also load that.
sometimes I want to put rustPlatform.rustcSRC
into RUST_SRC_PATH
, so it will return the evaluated path.
maybe the implementation is like:
[env]
RUST_SRC_PATH="(rustPlatform.rustcSrc)"
I'm not sure it is possible in toml
.
For some reason, nix develop
stopped working:
$ nix develop
error: --- Error --------------------------------------------------------------------------------------------------------------------------------------------------- nix
error: --- Error --- nix-daemon
builder for '/nix/store/vfc8ydhi6sacga3j677ww6djzi6cfqfh-mkDevShell-env.drv' failed to produce output path '/nix/store/28vlpzyvc8i5c22v9hws8nfwds4537sh-mkDevShell-env'
The mkDevShell-env.drv
has different builder args than what is defined in the nix code:
"builder": "/nix/store/sdvgyx4635dwbmiqwmc8zhsj92zd7456-bash-interactive-4.4-p23/bin/bash",
"args": [
"/nix/store/0c88xw36hn0wzmnlyai9s3sibbnq3pnd-get-env.sh"
],
Normally, when I use mkShell, nix-direnv will symlink the resulting derivation into gcroots
, preventing it from being garbage collected, but this functionality seems to be absent when using devshell.
I had a use case where I needed packages from two nixpkgs version:
My solution so far, no idea if it's optimal, but wanted to share:
# flake.nix
{
inputs.nixpkgsUnstable.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
outputs = { self, nixpkgs, flake-utils, devshell, nixpkgsUnstable }:
let
name = "CashBoxy";
config = {};
in flake-utils.lib.simpleFlake {
inherit self name nixpkgs config;
overlay = import ./overlay.nix {inherit nixpkgsUnstable config;};
shell = ./devshell.nix;
};
}
# overlay.nix
{ nixpkgsUnstable, config }: final: prev:
{
CashBoxy =
let
pkgsUnstable = import nixpkgsUnstable {
inherit config;
localSystem = prev.stdenv.buildPlatform;
crossSystem = prev.stdenv.hostPlatform;
};
in
{
kicad = pkgsUnstable.kicad;
freecad = pkgsUnstable.freecad;
};
}
# devshell.nix
{ pkgs }:
with pkgs; mkDevShell {
name = "CashBoxy";
packages = [
CashBoxy.kicad
CashBoxy.freecad
];
}
I found it tricky, so I wanted to share one option, if somebody is looking for how to do it.
Please don't regard this at any rate authoritative. It's just me playing around... (!)
Line 119 in 8850638
Trying to put together a gitops (mono-)repo cli-driver from composable pieces, including devshell, I'd like to apply project specific customization to the command prompt.
For some dev envronments, there is a use case to install udev rules for non-root device access (MODE="0666"
) to specific devices such as a particular arduino board.
The current nixos-specific workarround is to use services.udev.package = [ pkgs.platformio ];
.
However, this does not properly encapsulate the desired state of the development shell.
Maybe this ultimately falls into the same problem category as managing PKI or DNS for development environments on the host system.
Further links:
The udev rules are read from the files located in the system rules directories /usr/lib/udev/rules.d and /usr/local/lib/udev/rules.d, the volatile runtime directory /run/udev/rules.d and the local administration directory /etc/udev/rules.d. All rules files are collectively sorted and processed in lexical order, regardless of the directories in which they live. However, files with identical filenames replace each other. Files in /etc/ have the highest priority, files in /run/ take precedence over files with the same name under /usr/. This can be used to override a system-supplied rules file with a local file if needed; a symlink in /etc/ with the same name as a rules file in /usr/lib/, pointing to /dev/null, disables the rules file entirely. Rule files must have the extension .rules; other extensions are ignored.
To manipulate potential candidate destination at /run/udev/rules.d
, root access seems required (who would have thought ๐):
โ ~ ls -la /run/udev/
drwxr-xr-x root root 160 B Mon Dec 21 11:15:39 2020 ๏ .
/cc @carlosluquec
NIX_PATH=
/home/blaggacao/.nix-defexpr/channels
PATH=
/home/blaggacao/.nix-profile/bin:
/home/blaggacao/.cargo/bin:
/home/blaggacao/.npm-global/bin:
/home/blaggacao/.poetry/bin:
/home/blaggacao/go/bin:
/home/blaggacao/bin:
/home/blaggacao/.local/bin:
/usr/local/bin:
/usr/bin:
/bin:
/usr/games:
/usr/local/go/bin:
/snap/bin:
/home/blaggacao/.fzf/bin
$ nix-shell
NIX_PATH=
# I don't have those...
nixpkgs=/nix/var/nix/profiles/per-user/root/channels/nixpkgs:
/nix/var/nix/profiles/per-user/root/channels:
# Only this is valid
/home/blaggacao/.nix-defexpr/channels
PATH=
# Those would shadow devshell packages
/home/blaggacao/.nix-profile/bin:
/home/blaggacao/.nix-profile/bin:
/nix/var/nix/profiles/default/bin:
/nix/store/979a6pz5pcvlqv41k0wq91gbbqaz0ws4-neptun.nix-env/bin:
/nix/store/xadrr3l5jvkkm3g3lb2g81j5wz51zqdv-bash-interactive-4.4-p23/bin:
/nix/store/sdvgyx4635dwbmiqwmc8zhsj92zd7456-bash-interactive-4.4-p23/bin:
# Refrain
/home/blaggacao/.nix-profile/bin:
/home/blaggacao/.cargo/bin:
/home/blaggacao/.npm-global/bin:
/home/blaggacao/.poetry/bin:
/home/blaggacao/go/bin:
/home/blaggacao/bin:
/home/blaggacao/.local/bin:
/usr/local/bin:
/usr/bin:
/bin:
/usr/games:
/usr/local/go/bin:
/snap/bin:
/home/blaggacao/.fzf/bin:
# Repeat everybody!
/home/blaggacao/.nix-profile/bin:
/home/blaggacao/.cargo/bin:
/home/blaggacao/.npm-global/bin:
/home/blaggacao/.poetry/bin:
/home/blaggacao/go/bin:
/home/blaggacao/bin:
/home/blaggacao/.local/bin:
/usr/local/bin:
/usr/bin:
/bin:
/usr/games:
/usr/local/go/bin:
/snap/bin:
/home/blaggacao/.fzf/bin
Furthermore would not have any effect:
{
env = {
NIX_PATH = "nixpkgs=${pkgs.path}";
};
}
For example on Linux, cabal needs the binutils
package, but not on macOS. Some packages are also not supported on all platforms.
It would be good if there was a mechanism to restrict the addition of certain packages on a per-platform basis.
It would be good to be able to generate the Go struct from the Nix module to guarantee that they stay in sync.
The schema defined in mkDevShell/options.nix is the canonical version and devshell/config.go needs to be kept in sync with it. To avoid unnecessary discrepancy, it would be great if the latter could be derived from the former.
Line 66 in 8850638
I might miss a deeper reason, but as a naive user, I would have expected:
{
env = {
KUBECONFIG="$HOME/.kube/config";
};
}
to work. Instead it evaluates to $HOME/.kube/config
literally. Although the workaround is straight forward, I want to ensure with this issue it is intentional.
work around
{
bash = {
extra = ''
export KUBECONFIG="$HOME/.kube/config"
'';
};
}
This is not directly a responsibility of devshell but is related to making a comfortable development environment.
Oftentimes, developers want to be able to test one or more services locally, with HTTPS enabled, in order to replicate the production environment as much as possible. This ticket contains some notes on what I think is the ideal setup.
We need the cooperation of the host on two fronts:
*.test
TLD for localhostThe .test TLD is reserved and is therefore guaranteed to never be clashing with external domains. https://en.wikipedia.org/wiki/.test
The developer can either edit their /etc/hosts, or have a local DNS resolver that maps all the *.test domains to localhost.
Open question: how to handle port-mapping so that multiple services can bind? On Linux, 127.X.X.X is all reserved for localhost so each service could technically get their own IPs. Maybe we can use a dictionary to IP mapping or something like that.
Ideally, a localhost service is running that talks ACME protocol.
The CA public certificate would be installed in the computer's trust cert.
The CA private certificate is installed in the ACME service and used to issue new certificates.
The services themselves would query the ACME protocol to acquire new certs and use http01 for validation.
Ideally, the CA can be pinned to it can only issue certs for the .test top-level. That way if the private certificate gets leaked, the impact would still be limited.
This issue aims to replace #16 with a more concise and well defined generic use case instead of calling for particular tooling, see #16 (comment).
Shift left is a strategy to move CI and CD components into the โ figuratively โ "airplane mode".
This typically involves a range of things like:
In my interpretation, this approach mainly avoids the ownership mismatch of central tooling.
Typical tools involed in the solution are:
.editorconfig
make
or just
)NixOS allows the user to override nixpkgs from within the module system. What happens under the hood is quite magic really.
In order to minimize the amount of nix plumbing needed, we could introduce something like that that allows a poor-man's nixpkgs pinning and configuration:
[nixpkgs.src]
url = "git+https://github.com/NixOS/nixpkgs"
rev = "<commit-id>"
[nixpkgs.config]
allowBroken = true
allowUnfree = true
I hope devshell will grow into an universal tool, if wsl2 is properly supported for nix.
It would be interesting to hear, if somebody has already experience to share, so that I can provide instructions to windows users for a repository I maintain.
While refactoring and playing on #28 according to the new module structure, I was feeling a slight need for tearing down the custom certificate upon leaving the devshell (so in order to safely "clean up after myself").
Hence I thought, maybe a goodbye
sequence similar to #62 could be helpful.
On the other hand, this might be a dangerous feature (in the sense of a powerful door that can never be shut again).
In shellHook
, we can unset some environment variables, like unset GOPATH GOROOT
.
When there are a lot of dependencies, printing all the binaries takes more than one shell page, which is not super helpful. Would it be better if the menu was constructed manually?
Since 22da01b was merged, the shell now has a dependency on tput
from the "curses" package.
I do have some custom packages for dev shells. For example kustomize is a central devshell component to us, but it's been under ongoing heavy development and release activity for the past year or so. Sometimes the last monday's version does not include the latest required bux fixes.
The pace at which nixpkgs catches up โ even though extraordinarily up to date โ is still sometimes too slow for our use case.
It would be interesting to think of ways how plain nix packages could be plugged into a toml config-based approach and work together with this cli tool seamlessly.
I think devops-responsible persons do have sometimes similar problems: how to ship latest critical bugfixes in devop tools to all developers quickly
Originally posted by @blaggacao in #13 (comment)
Because of how the module system works, the values in the top module are set before anybody else.
This causes an issue because a user might want to set the NIX_PATH
to nixpkgs:$NIXPKGS_PATH
, which is set after.
I get the following error with the default motd: error: \u characters in JSON strings are currently not supported
Probably the hammer
Line 107 in 827e007
Setting a custom motd fixed the issue.
Is this fix sufficient for now? Remove emoji until nix v3?
[[commands]]
package = "git"
could internally fall back to
{
name = git.pname;
help = git.meta.description;
}
Sometimes, some packages only make sense on one architecture. For example binutils
is needed for GHC on Linux but breaks builds on macOS.
The current workaround is to add a shell.nix and inject the dependency there.
let
pkgs = import <nixpkgs> { overlays = [
# replace this with your own method of loading the devshell dependency
./devshell/overlay.nix
]; };
importTOML = file: {
_file = file;
config = builtins.fromTOML (builtins.readFile file);
};
in
pkgs.mkDevShell {
imports = [
# First load the TOML
(importTOML ../devshell.toml)
];
config = {
packages = pkgs.lib.optionals pkgs.stdenv.isLinux [
# `ar` is needed on Linux for `cabal build`
pkgs.binutils
];
};
}
My first intuition was to claim a tight integration with pre-commit would be the way to go. Sleeping over it I think differently, hence this very issue comes to be. It proposes to consider the possibility of a shortcut and aspire a clear cut, simple and clean re-implementation.
Alarm! Doesn't nix package tools? โ And is arguably better at doing so?!? Since, we are left with git hooks and workdir management. A typical pre-commit pre-push
hook is relatively straight forward:
pre-push
#!/nix/store/n8nviwmllwqv0fjsar8v8k8gjap1vhcw-python3-3.7.6/bin/python3
"""File generated by pre-commit: https://pre-commit.com"""
from __future__ import print_function
import distutils.spawn
import os
import subprocess
import sys
# work around https://github.com/Homebrew/homebrew-core/issues/30445
os.environ.pop('__PYVENV_LAUNCHER__', None)
HERE = os.path.dirname(os.path.abspath(__file__))
Z40 = '0' * 40
ID_HASH = '138fd403232d2ddd5efb44317e38bf03'
# start templated
CONFIG = '.pre-commit-config.yaml'
HOOK_TYPE = 'pre-push'
INSTALL_PYTHON = '/nix/store/n8nviwmllwqv0fjsar8v8k8gjap1vhcw-python3-3.7.6/bin/python3.7'
SKIP_ON_MISSING_CONFIG = False
# end templated
class EarlyExit(RuntimeError):
pass
class FatalError(RuntimeError):
pass
def _norm_exe(exe):
"""Necessary for shebang support on windows.
roughly lifted from `identify.identify.parse_shebang`
"""
with open(exe, 'rb') as f:
if f.read(2) != b'#!':
return ()
try:
first_line = f.readline().decode('UTF-8')
except UnicodeDecodeError:
return ()
cmd = first_line.split()
if cmd[0] == '/usr/bin/env':
del cmd[0]
return tuple(cmd)
def _run_legacy():
if __file__.endswith('.legacy'):
raise SystemExit(
"bug: pre-commit's script is installed in migration mode\n"
'run `pre-commit install -f --hook-type {}` to fix this\n\n'
'Please report this bug at '
'https://github.com/pre-commit/pre-commit/issues'.format(
HOOK_TYPE,
),
)
if HOOK_TYPE == 'pre-push':
stdin = getattr(sys.stdin, 'buffer', sys.stdin).read()
else:
stdin = None
legacy_hook = os.path.join(HERE, '{}.legacy'.format(HOOK_TYPE))
if os.access(legacy_hook, os.X_OK):
cmd = _norm_exe(legacy_hook) + (legacy_hook,) + tuple(sys.argv[1:])
proc = subprocess.Popen(cmd, stdin=subprocess.PIPE if stdin else None)
proc.communicate(stdin)
return proc.returncode, stdin
else:
return 0, stdin
def _validate_config():
cmd = ('git', 'rev-parse', '--show-toplevel')
top_level = subprocess.check_output(cmd).decode('UTF-8').strip()
cfg = os.path.join(top_level, CONFIG)
if os.path.isfile(cfg):
pass
elif SKIP_ON_MISSING_CONFIG or os.getenv('PRE_COMMIT_ALLOW_NO_CONFIG'):
print(
'`{}` config file not found. '
'Skipping `pre-commit`.'.format(CONFIG),
)
raise EarlyExit()
else:
raise FatalError(
'No {} file was found\n'
'- To temporarily silence this, run '
'`PRE_COMMIT_ALLOW_NO_CONFIG=1 git ...`\n'
'- To permanently silence this, install pre-commit with the '
'--allow-missing-config option\n'
'- To uninstall pre-commit run '
'`pre-commit uninstall`'.format(CONFIG),
)
def _exe():
with open(os.devnull, 'wb') as devnull:
for exe in (INSTALL_PYTHON, sys.executable):
try:
if not subprocess.call(
(exe, '-c', 'import pre_commit.main'),
stdout=devnull, stderr=devnull,
):
return (exe, '-m', 'pre_commit.main', 'run')
except OSError:
pass
if os.path.isfile('/nix/store/1kfw43by83rd2ri483vqbd32srm4v45d-pre-commit-1.21.0/bin/pre-commit') and os.access('/nix/store/1kfw43by83rd2ri483vqbd32srm4v45d-pre-commit-1.21.0/bin/pre-commit', os.X_OK):
return ('/nix/store/1kfw43by83rd2ri483vqbd32srm4v45d-pre-commit-1.21.0/bin/pre-commit', 'run')
if distutils.spawn.find_executable('pre-commit'):
return ('pre-commit', 'run')
raise FatalError(
'`pre-commit` not found. Did you forget to activate your virtualenv?',
)
def _rev_exists(rev):
return not subprocess.call(('git', 'rev-list', '--quiet', rev))
def _pre_push(stdin):
remote = sys.argv[1]
opts = ()
for line in stdin.decode('UTF-8').splitlines():
_, local_sha, _, remote_sha = line.split()
if local_sha == Z40:
continue
elif remote_sha != Z40 and _rev_exists(remote_sha):
opts = ('--origin', local_sha, '--source', remote_sha)
else:
# ancestors not found in remote
ancestors = subprocess.check_output((
'git', 'rev-list', local_sha, '--topo-order', '--reverse',
'--not', '--remotes={}'.format(remote),
)).decode().strip()
if not ancestors:
continue
else:
first_ancestor = ancestors.splitlines()[0]
cmd = ('git', 'rev-list', '--max-parents=0', local_sha)
roots = set(subprocess.check_output(cmd).decode().splitlines())
if first_ancestor in roots:
# pushing the whole tree including root commit
opts = ('--all-files',)
else:
cmd = ('git', 'rev-parse', '{}^'.format(first_ancestor))
source = subprocess.check_output(cmd).decode().strip()
opts = ('--origin', local_sha, '--source', source)
if opts:
return opts
else:
# An attempt to push an empty changeset
raise EarlyExit()
def _opts(stdin):
fns = {
'prepare-commit-msg': lambda _: ('--commit-msg-filename', sys.argv[1]),
'commit-msg': lambda _: ('--commit-msg-filename', sys.argv[1]),
'pre-merge-commit': lambda _: (),
'pre-commit': lambda _: (),
'pre-push': _pre_push,
}
stage = HOOK_TYPE.replace('pre-', '')
return ('--config', CONFIG, '--hook-stage', stage) + fns[HOOK_TYPE](stdin)
if sys.version_info < (3, 7): # https://bugs.python.org/issue25942
def _subprocess_call(cmd): # this is the python 2.7 implementation
return subprocess.Popen(cmd).wait()
else:
_subprocess_call = subprocess.call
def main():
retv, stdin = _run_legacy()
try:
_validate_config()
return retv | _subprocess_call(_exe() + _opts(stdin))
except EarlyExit:
return retv
except FatalError as e:
print(e.args[0])
return 1
except KeyboardInterrupt:
return 1
if __name__ == '__main__':
exit(main())
It corresponds to a per-hook-configuration-interface roughly in the lines of:
entry: /nix/store/s4vwm64km5xc6glq69fa2dn6s0fl57dv-nixpkgs-fmt-0.6.1/bin/nixpkgs-fmt
exclude: ^$
files: \\.nix$ # include filter regex - include when a certain git diff touches one of those files
id: nixpkgs-fmt
name: nixpkgs-fmt
pass_filenames: true # whether to pass touched filenames as argument to the tool
types: # include filter using identity lib - this is interesting and convenient
- file
In addition to this, one can selectively skip hooks by passing SKIP="nixpkgs-fmt,..."
.
It is also a handy feature to manually execute those configurations against all files (irrespective of them being touched by a certain commit range, but respecting the include / exclude filters) in order to do ad-hoc or general cleanups. The CLI interface for this task is bad, though: devshell cold attempt to do better.
[pre-commit]
[[nixpkgs-fmt]]
entrypoint = "$DEVSHELL_DIR/bin/nixpkgs-fmt ..."
exclude = ["^.ignore.me.nix$"]
include = ["(\\w|\\/)+?\\.nix$"]
types = [ "files", "nix" ]
pass_filenames = true
[pre-push]
[[go-lint]] # name
entrypoint = "$DEVSHELL_DIR/bin/go-lint? ..."
types = [ "go" ]
### ๐จ Welcome to mkDevShell ####
# Commands
devshell-menu - print this menu
devshell-root - change directory to root
pre-commit.nixpkgs-fmt - used to format Nix code
pre-push.go-lint - used to format Go code
Coming from devshell and integrating it with nix flakes, I can perceive how it would be useful if devshell could expose a flakify
helper function, so that:
nix check
nix build
This would make flakes integration more elegant. CI and people not familiar with devshell could do nix check
/ nix build .#...
, but developers could still do menu
and then let's say test-all
within a nix shell.
Surely, this use case is easily handled coming from nix flakes transition into devshell. (command = "${pkgs.myproject.my_local_script}/bin/my-local-scipt ...";
)
So I'm not sure if it is concern of devshell to shovel people into nix flakes via the proposed transition facilities...
As mkDevShell
gains more attributes, it becomes more and more useful to build types and documentation into the function.
The [devshell].packages
section doesn't tell users how to find packages to add to the list.
Most current users are familiar with Nix, but that might not always be the case.
https://search.nixos.org/packages is a good place to take a look.
The current documentation is not quite correct. The CLI is not ready and will not be for a while. Instead, document how to integrate using the nix-shell
.
Based on real experienced frustration, it would be extremely powerful to have a wrapper to go get
, so that when you go get
something within a devshell environment, it automatically generates a valid nix package descriptor.
Similar for other languages.
Alternative (less intrusive) UX:
devshell go get ...
devhsell pip install ...
(with mach-nix)Bonus:
-devshell upstream
-> generates a PR to nixpkgs with custom packages ๐ โ problem nixpkgs folder "chaos" maybe does not provide sufficiently clear metadata
My experience is that it took a very long time to get all tooling set up (one time effort, but who knows if I decide to change tooling tomorrow, on the go).
{
bash = {
extra = ''
# kube-ps1 context & namespace prompt
source $(which kube-ps1) # doesn't run in the final shell
echo Run: $(tput bold; tput setaf 3)source '$(which kube-ps1)'$(tput sgr0)
export RPROMPT='$(kube_ps1)'
'';
};
}
I want to elide to ask the user to manually run:
$ source $(which kube-ps1)
The shell function kube_ps1
is not loaded into the final shell using either direnv
or plain nix-shell
.
Is this only supposed to work with nix develop
?
It looks as if the following trampoline was arranged for this use case, though:
Lines 213 to 227 in 8850638
โ kube-ps1
It looks like this variable is not being injected in older versions of Nix.
TODO: find out at which version of Nix this started working.
sometimes one wants to get all the build dependencies of a package into the environment
#18 provides for use cases of pre-push hooks specifically. #16 (comment) provides analysis for why a lightweight implementation is superior beyond the mere benefit of being leightweight.
That means, the consolidated intended use case does not require git workdir management. What's worse, providing such would induce misinterpretations about the consolidated intended use case.
Therefore, it is proposed for devshell to arrange for:
A simple command sequence
.git/hooks/pre-push
.The facility is capable of detecting modified files against the reference git ref,
The facility passes the modified files list
The command itself needs to arrange for
identify
Right now there is no guidance on how to best get started with the project
I think flakes are an excellent code / knowledge sharing platform infrastructure.
I would like to seek structural guidance (later on: eg. examples / templates) on how to combine those ideas in a proper way.
I'm also wondering, how user provided devshells would / could / should interact with project provided devshells.
https://github.com/guumaster/hostctl is a great tool for manipulating local /etc/hosts
for development.
But it also defies the very principles of isolated devshell environments.
The way it usually works is:
.etchosts
file checked into version controlsudo $(which hostctl) add $profilename --from .etchosts
sudo $(which hostctl) remove $profilename
It also can be activated and deactivated, once loaded, with:
... enable
... disable
But those latter commands seem more useful for interactive usage for special requirements or temporary profile switches, and are not relevant to the genuine setup of a devshell.
Though in order to accommodate for this local /etc/hosts management through devshell, I think two things would have to be achieved.
Or take a completely other approach, like: https://github.com/bAndie91/libnss_homehosts (at least for nixos users that might be a hidden goodie, if packaged there)
Or just acknowledge it would be cool, but no thanks! Too complicated. ๐
I'm testing this on a Mac (nix flakes enabled), and I'm getting this output:
% nix develop
mktemp: illegal option -- -
usage: mktemp [-d] [-q] [-t prefix] [-u] template ...
mktemp [-d] [-q] [-u] -t prefix
### ๐จ Welcome to devshell ####
[commands]
devshell-menu - print this menu
devshell-root - change directory to root
[devshell]$
I've been unable to find any mention of mktemp
in this repo, however it seems to be related to mkDevShell since I can use mkShell from nixpkgs without ever seeing the above output. On NixOS everything is fine.
My use case is being able to run bundle install
in the shell for projects using Ruby gems with native dependencies that need to be compiled with gcc (say, libxml or Postgres client). This works when I specify those pacakges as buildInputs
in pkgs.mkShell
, but there's no option to do so with devshell and even when I hacked the source a bit to pass it down to buildEnv
it doesn't help either โ the culprit seems to be the list of environment variables passed down to the env (it's lacking the compiler-related envvars).
I'm not sure what's the best direction to take here (I'm a bit of a newb when it's coming to using nix as something other than a glorified ansible for my home infrastructure) but I think it's an useful use-case to cover.
There are various places where we convert strings to shell scripts. And those assume that the script will be using bash.
Add a bit of logic in nix that checks if the string starts with a shebang. If there is a shebang, write the script as-is. Otherwise, add the bash shebang.
Not all users are familiar with nix and nixpkgs and know how to search for packages.
It should be possible to put an approximate package name and have devshell throw an error and recommend something based on the Levenshtein distance of the name.
There is already an implementation out there from @infinisil: https://github.com/NixOS/nixpkgs/pull/79877/files
[env]
BAR = "123"
FOO = "$BAR"
This construct has the advantage of being straight-forward and easy to understand. But it has one issue: values are always escaped and the user has to use the [bash.extra]
section in order to do more advanced stuff. Which in turn is problematic because bash.extra is not easily extensible by other modules.
If we want to support dynamic values, we will have to introduce an array like this:
[[envs]]
name = "BAR"
value = "123"
[[envs]]
name = "FOO"
dyn_value = "$BAR"
We can draw inspiration on Kubernetes to see how they are doing this on pods.
Another useful option would be a depends = [ "BAR" ]
key that would allow to re-shuffle the list. Essentially making this a DAG.
As you can see, this makes the whole setup more verbose.
Should we keep both constructs or is one enough?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.