Created
October 13, 2017 17:43
-
-
Save hdonnay/9bb0b598b2461fa518df86c0fe2c2782 to your computer and use it in GitHub Desktop.
work (nix-shell wrapper)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define _XOPEN_SOURCE 700 | |
#include <errno.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#include <string.h> | |
#include <sys/stat.h> | |
extern char **environ; | |
static char *cfgdirs[] = { | |
"/.nix-profile/cfg/work/", | |
"/lib/work/", | |
NULL, | |
}; | |
static char *nixdirs[] = { | |
"/nixpkgs", // First one is tried without the workspace appended. | |
"/nixpkgs-", | |
NULL, | |
}; | |
char *workdir(char *n) { | |
char *d; | |
struct stat s; | |
size_t sz; | |
d = getenv("WORK_DIR"); | |
if(d != NULL) | |
return d; | |
sz = 7 + strlen(getenv("HOME")) + strlen(n); | |
d = malloc(sz); | |
snprintf(d, sz,"%s/work/%s", getenv("HOME"), n); | |
if(stat(d, &s) != 0) | |
mkdir(d, 0755); // Don't care if this fails. | |
return d; | |
} | |
char *workcfgdir() { | |
char *d; | |
int i; | |
size_t sz; | |
struct stat s; | |
d = getenv("WORK_CFG_DIR"); | |
if(d != NULL) | |
return d; | |
sz = 24 + strlen(getenv("HOME")); | |
d = malloc(sz); | |
strncpy(d, getenv("HOME"), sz); | |
for(i = 0; cfgdirs[i] != NULL; i++){ | |
strcat(d, cfgdirs[i]); | |
if(stat(d, &s) == 0){ | |
break; | |
} | |
} | |
if(cfgdirs[i] == NULL){ | |
perror("no config dirs exist"); | |
exit(EXIT_FAILURE); | |
} | |
return d; | |
} | |
char *nixpath(char *wd, char *n) { | |
int i; | |
char *np, d[4096]; | |
struct stat s; | |
np = malloc(4096); | |
strcpy(np, getenv("NIX_PATH")); | |
for(i = 0; nixdirs[i] != NULL; i++, d[0] = '\0'){ | |
strcat(d, wd); | |
strcat(d, nixdirs[i]); | |
if(i != 0) | |
strcat(d, n); | |
if(stat(d, &s) == 0){ | |
strcat(np, ":"); | |
strcat(np, n); | |
strcat(np, "="); | |
strcat(np, d); | |
break; | |
} | |
} | |
strcat(np, ":ssh-config-file=/dev/null:ssh-auth-sock=/dev/null"); | |
return np; | |
} | |
int main(int argc, char *argv[]) { | |
char *wd, *wcd, *np; | |
if(argc != 2){ | |
fprintf(stderr, "specify work directory\n"); | |
exit(EXIT_FAILURE); | |
} | |
wd = workdir(argv[1]); | |
if(setenv("WORK_DIR", wd, 1) != 0){ | |
perror("unable to set environment"); | |
exit(EXIT_FAILURE); | |
} | |
printf("# work dir: %s\n", wd); | |
wcd = workcfgdir(); | |
if(setenv("WORK_CFG_DIR", wcd, 1) != 0){ | |
perror("unable to set environment"); | |
exit(EXIT_FAILURE); | |
} | |
printf("# config dir: %s\n", wcd); | |
np = nixpath(wd, argv[1]); | |
if(setenv("NIX_PATH", np, 1) != 0){ | |
perror("unable to set environment"); | |
exit(EXIT_FAILURE); | |
} | |
printf("# using NIX_PATH: %s\n", np); | |
char *sh; | |
sh = getenv("SHELL"); | |
if(sh == NULL) | |
sh = "bash"; | |
int sz; | |
sz = 5 + strlen(argv[1]) + strlen(wcd); | |
char nf[sz]; | |
snprintf(nf, sz, "%s%s.nix", wcd, argv[1]); | |
execlp("nix-shell", "--show-trace", "--command", sh, nf, NULL); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment