I tried to change the directory using a normal cd command, but it says execvp(): No such file or directory.
These are the lines:
fs = require 'fs'
util = require 'util'
{spawn} = require 'child_process'
clientTest = (callback) ->
d = spawn 'cd', ['client']
d.stderr.on 'data', (data) ->
process.stderr.write data.toString()
d.stdout.on 'data', (data) ->
util.log data.toString()
d.on 'exit', (code) ->
callback?() if code is 0
I'm guessing I have to do something withe the filesystem?
cd is a built-in shell command. Try running
/usr/bin/cd /dir
from your shell; you'll find that it doesn't do anything. Likewise, running cd from Node has no effect.
Instead of spawning cd, you should change the working directory with process.chdir.
Related
I have two Nix Flakes: One contains an application, and the other contains a plugin for that application. When I build the application with the plugin, I get the error
error: path '/nix/store/3b7djb5pr87zbscggsr7vnkriw3yp21x-mainapp-go-modules' is not valid
I have no idea what this error means and how to fix it, but I can reproduce it on both macOS and Linux. The path in question is the vendor directory generated by the first step of buildGoModule.
The minimal setup to reproduce the error requires a bunch of files, so I provide a commented bash script that you can execute in an empty folder to recreate my setup:
#!/bin/bash
# I have two flakes: the main application and a plugin.
# the mainapp needs to be inside the plugin directory
# so that nix doesn't complain about the path:mainapp
# reference being outside the parent's root.
mkdir -p plugin/mainapp
# each is a go module with minimal setup
tee plugin/mainapp/go.mod <<EOF >/dev/null
module example.com/mainapp
go 1.16
EOF
tee plugin/go.mod <<EOF >/dev/null
module example.com/plugin
go 1.16
EOF
# each contain minimal Go code
tee plugin/mainapp/main.go <<EOF >/dev/null
package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}
EOF
tee plugin/main.go <<EOF >/dev/null
package plugin
import log
func init() {
fmt.Println("initializing plugin")
}
EOF
# the mainapp is a flake that provides a function for building
# the app, as well as a default package that is the app
# without any plugins.
tee plugin/mainapp/flake.nix <<'EOF' >/dev/null
{
description = "main application";
inputs = {
nixpkgs.url = github:NixOS/nixpkgs/nixos-21.11;
flake-utils.url = github:numtide/flake-utils;
};
outputs = {self, nixpkgs, flake-utils}:
let
# buildApp builds the application from a list of plugins.
# plugins cause the vendorSha256 to change, hence it is
# given as additional parameter.
buildApp = { pkgs, vendorSha256, plugins ? [] }:
let
# this is appended to the mainapp's go.mod so that it
# knows about the plugin and where to find it.
requirePlugin = plugin: ''
require ${plugin.goPlugin.goModName} v0.0.0
replace ${plugin.goPlugin.goModName} => ${plugin.outPath}/src
'';
# since buildGoModule consumes the source two times –
# first for vendoring, and then for building –
# we do the necessary modifications to the sources in an
# own derivation and then hand that to buildGoModule.
sources = pkgs.stdenvNoCC.mkDerivation {
name = "mainapp-with-plugins-source";
src = self;
phases = [ "unpackPhase" "buildPhase" "installPhase" ];
# write a plugins.go file that references the plugin's package via
# _ = "<module path>"
PLUGINS_GO = ''
package main
// Code generated by Nix. DO NOT EDIT.
import (
${builtins.foldl' (a: b: a + "\n\t_ = \"${b.goPlugin.goModName}\"") "" plugins}
)
'';
GO_MOD_APPEND = builtins.foldl' (a: b: a + "${requirePlugin b}\n") "" plugins;
buildPhase = ''
printenv PLUGINS_GO >plugins.go
printenv GO_MOD_APPEND >>go.mod
'';
installPhase = ''
mkdir -p $out
cp -r -t $out *
'';
};
in pkgs.buildGoModule {
name = "mainapp";
src = builtins.trace "sources at ${sources}" sources;
inherit vendorSha256;
nativeBuildInputs = plugins;
};
in (flake-utils.lib.eachDefaultSystem (system:
let
pkgs = nixpkgs.legacyPackages.${system};
in rec {
defaultPackage = buildApp {
inherit pkgs;
# this may be different depending on your nixpkgs; if it is, just change it.
vendorSha256 = "sha256-pQpattmS9VmO3ZIQUFn66az8GSmB4IvYhTTCFn6SUmo=";
};
}
)) // {
lib = {
inherit buildApp;
# helper that parses a go.mod file for the module's name
pluginMetadata = goModFile: {
goModName = with builtins; head
(match "module ([^[:space:]]+).*" (readFile goModFile));
};
};
};
}
EOF
# the plugin is a flake depending on the mainapp that outputs a plugin package,
# and also a package that is the mainapp compiled with this plugin.
tee plugin/flake.nix <<'EOF' >/dev/null
{
description = "mainapp plugin";
inputs = {
nixpkgs.url = github:NixOS/nixpkgs/nixos-21.11;
flake-utils.url = github:numtide/flake-utils;
nix-filter.url = github:numtide/nix-filter;
mainapp.url = path:mainapp;
mainapp.inputs = {
nixpkgs.follows = "nixpkgs";
flake-utils.follows = "flake-utils";
};
};
outputs = {self, nixpkgs, flake-utils, nix-filter, mainapp}:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = nixpkgs.legacyPackages.${system};
in rec {
packages = rec {
plugin = pkgs.stdenvNoCC.mkDerivation {
pname = "mainapp-plugin";
version = "0.1.0";
src = nix-filter.lib.filter {
root = ./.;
exclude = [ ./mainapp ./flake.nix ./flake.lock ];
};
# needed for mainapp to recognize this as plugin
passthru.goPlugin = mainapp.lib.pluginMetadata ./go.mod;
phases = [ "unpackPhase" "installPhase" ];
installPhase = ''
mkdir -p $out/src
cp -r -t $out/src *
'';
};
app = mainapp.lib.buildApp {
inherit pkgs;
# this may be different depending on your nixpkgs; if it is, just change it.
vendorSha256 = "sha256-a6HFGFs1Bu9EkXwI+DxH5QY2KBcdPzgP7WX6byai4hw=";
plugins = [ plugin ];
};
};
defaultPackage = packages.app;
}
);
}
EOF
You need Nix with Flake support installed to reproduce the error.
In the plugin folder created by this script, execute
$ nix build
trace: sources at /nix/store/d5arinbiaspyjjc4ypk4h5dsjx22pcsf-mainapp-with-plugins-source
error: path '/nix/store/3b7djb5pr87zbscggsr7vnkriw3yp21x-mainapp-go-modules' is not valid
(If you get hash mismatches, just update the flakes with the correct hash; I am not quite sure whether hashing when spreading flakes outside of a repository is reproducible.)
The sources directory (shown by trace) does exist and looks okay. The path given in the error message also exists and contains modules.txt with expected content.
In the folder mainapp, nix build does run successfully, which builds the app without plugins. So what is it that I do with the plugin that makes the path invalid?
The reason is that the file modules.txt generated as part of vendoring will contain the nix store path in the replace directive in this scenario. The vendor directory is a fixed output derivation and thus must not depend on any other derivations. This is violated by the reference in modules.txt.
This can only be fixed by copying the plugin's sources into the sources derivation – that way, the replace path can be relative and thus references no other nix store path.
I'm trying to build the hasura cli: https://github.com/hasura/graphql-engine/tree/master/cli with the following code (deps derived from dep2nix):
{ buildGoPackage, fetchFromGitHub }:
buildGoPackage rec {
version = "1.0.0-beta.2";
name = "hasura-${version}";
goPackagePath = "github.com/hasura/graphql-engine";
subPackages = [ "cli" ];
src = fetchFromGitHub {
owner = "hasura";
repo = "graphql-engine";
rev = "v${version}";
sha256 = "1b40s41idkp1nyb9ygxgsvrwv8rsll6dnwrifpn25bvnfk8idafr";
};
goDeps = ./deps.nix;
}
but I get the following errors after the post-installation fixup step:
find: '/nix/store/gkck68cm2z9k1qxgmh350pq3kwsbyn8q-hasura-cli-1.0.0-beta.2': No such file or directory.
What am I doing wrong here? For reference, I'm on macOS and using home-manager.
For anyone still wondering:
There are a couple of things to consider:
dep has been deprecated in favor of go modules
This is also reflected in Nix, as buildGoPackage is now legacy and moved to buildGoModule
There is already a hasura-cli package in nixpkgs. You can just use it with nix-shell -p hasura-cli
i am using below Rscript as a mapper on hadoop streaming. i want to see log info\warn etc on console of tasktracker or any other place of log that oozie does however its not coming any reason . My oozie job is successfully completed
Script
#! /usr/bin/env Rscript
library(methods)
library(utils)
library(devtools)
library(corpcor)
library(getopt)
library(logging)
library(HadoopStreaming)
main <- function() {
paste("A", 1:50, sep = "")
input <- file("stdin", open = "r")
loginfo("CUSTOM ERROR")
targets <- read.table(file="meta_reference1.csv", sep=";")
print("############################################")
print(target)
close(input)
}
Updated Rscript for testing purpose
#! /usr/bin/env Rscript
library(methods)
library(utils)
library(devtools)
library(corpcor)
library(getopt)
library(logging)
library(HadoopStreaming)
main <- function() {
write("prints to stderr", stderr())
write("prints to stdout", stdout())
}
No log appeared .. please suggest
Try using write instead of print, worked for me.
write("prints to stderr", stderr())
write("prints to stdout", stdout())
I have read around stackoverflow and the gradle forms, but I am still stumped. The ultimate goal here is that after I copy some files, I want to set the writable flag -- because 'copy' doesn't like overwriting read-only files on 'nix (huh...), nor can it be forced to do so (harumph!).
Here is the outline of what I have:
task setPermissions (type : Exec) {
executable = 'chmod -R +w'
}
// ... a little while later ...
task('somethingElse') << {
// ... unrelated stuff ...
def String targetDir = "$aVar/theTarget"
// >> TASK CALL <<
setPermissions {
commandLine = [executable + " $targetDir"]
}
// but that doesn't work... this does...
proc = Runtime.getRuntime().exec("chmod -R +w $deployDir")
proc.waitFor()
}
I have tried variations in "setPermissions".
Trial 1:
commandLine = 'chmod'
args = '-R', '+w'
In which case I appended the target directory to "args" when I called setPermissions.
Trial 2:
commandLine = 'chmod -R +w'
In which case I appended the target directory to "commandLine" when I called setPermissions. I also tried making it the only "args" value.
Trial 3:
commandLine = 'chmod', '-R', '+w'
In which case I appended the target directory to "commandLine" when I called setPermissions. I also tried making it the only "args" value.
So what am I doing wrong here that an Exec task won't run this properly, but the Rt.gR.exec() will?
You can't call a task from another task. You'll have to make one depend on the other, or call the Project.exec method from a task action. The syntax for configuring the exec method is exactly the same as for the Exec task.
PS: Have you tried to use Copy.fileMode instead of chmod?
I'm writing my first Rakefile. The first things that I see in the doc is "there is no special format for a Rakefile" and "there is no special syntax in a Rakefile".
Ok, so I had to come up with something on my own, but I can see at least two problems with my creature:
1) I need to create a number of folders, five of them. The sequence of 6 directory tasks looks a bit weird. The list of 5 dependencies in deploy task looks even more weird. Can I shrink it down to one line somehow?
2) I need to repeat my directory name literals two times - when I define their deployment paths and when I copy the contents. Can I avoid that without introducing 5 more variables?
In Java Ant I would create a properties file with all name literals - can I do that with Rake?
This is what I've got:
WEBAPPSDIR = '/var/webapps/'
WEBAPPNAME = 'foo.local'
WEBAPPDIR = File.join(WEBAPPSDIR, WEBAPPNAME)
VIEWSDIR = File.join(WEBAPPDIR, 'views')
PUBLICDIR = File.join(WEBAPPDIR, 'public')
CSSDIR = File.join(PUBLICDIR, 'css')
IMAGESDIR = File.join(PUBLICDIR, 'images')
TMPDIR = File.join(WEBAPPDIR, 'tmp')
HTMLDIR = File.join(PUBLICDIR, 'html')
directory VIEWSDIR
directory CSSDIR
directory HTMLDIR
directory IMAGESDIR
directory TMPDIR
desc 'Deploy to webapps dir'
task :deploy => [VIEWSDIR, CSSDIR, IMAGESDIR, TMPDIR, HTMLDIR] do
cp 'config.ru', WEBAPPDIR
Dir.glob('*.rb') {|f| cp f, WEBAPPDIR}
Dir.glob('views/*.{mab,str}') {|f| cp f, VIEWSDIR}
Dir.glob('css/*.css') {|f| cp f, CSSDIR}
Dir.glob('images/*.{png,jpg,gif}') {|f| cp f, IMAGESDIR}
Dir.glob('html/*.html') {|f| cp f, VIEWSDIR}
end
desc 'Cleans webapp dir'
task :clean do
rm_r WEBAPPDIR, {force: true}
end
Other thoughts/links/examples are welcome too.
This does not really answer your question - but why don't you use capistrano ? If you don't know it already, it's a ruby tool frequently used to handle deployments smoothly