on master help sign in
Get all languages working in prybar with Nix
25451ceguillaume
build-prybar.nix+43−4
@@ -1,13 +1,20 @@
1−{ language, buildInputs ? [] }:
1+{ language, buildInputs ? [], binaries ? [], setFlags ? false, pkgName ? language, versionArg ? "" }:
2
2
3−{ lib, buildGoModule, fetchFromGitHub, bash, pkg-config, runCommand, git, copyPathToStore }:
3+{ lib, buildGoModule, fetchFromGitHub, bash, expect, pkg-config, runCommand, git, python3, copyPathToStore }:
4
4
5let
5let
6 src = copyPathToStore ./.;
6 src = copyPathToStore ./.;
7 revision = runCommand "get-rev" {
7 revision = runCommand "get-rev" {
8− nativeBuildInputs = [ git ];
8+ nativeBuildInputs = [ git python3 ];
9 dummy = builtins.currentTime;
9 dummy = builtins.currentTime;
10+ } ''
11+ if [ -d ${src}/.git ]; then
12+ cd ${src}
10− } "GIT_DIR=${src}/.git git rev-parse --short HEAD | tr -d '\n' > $out";
13+ git rev-parse --short HEAD | tr -d '\n' > $out
14+ else
15+ echo ${versionArg} | tr -d '\n' > $out
16+ fi
17+ '';
11in buildGoModule {
18in buildGoModule {
12 pname = "prybar-${language}";
19 pname = "prybar-${language}";
13 version = builtins.readFile revision;
20 version = builtins.readFile revision;
@@ -21,11 +28,43 @@ in buildGoModule {
21
28
22 vendorSha256 = null;
29 vendorSha256 = null;
23
30
31+ # This prebiuild hook will setup the compiler flags on demand based on the package
32+ # If a language requires this, it MUST expost a ${pkgName}.pc file in its `lib/pkg-config`
33+ # for pkg-config to detect it. Otherwise, we can't find the required flags.
24 preBuild = ''
34 preBuild = ''
35+ ${if setFlags then ''
36+ NIX_CFLAGS_COMPILE="$(pkg-config --cflags ${pkgName}) $NIX_CFLAGS_COMPILE"
37+ NIX_LDFLAGS="$(pkg-config --libs-only-L ${pkgName}) $(pkg-config --libs-only-l ${pkgName}) $NIX_LDFLAGS"
38+ '' else ""}
39+
25 ${bash}/bin/bash ./scripts/inject.sh ${language}
40 ${bash}/bin/bash ./scripts/inject.sh ${language}
26 go generate ./languages/${language}/main.go
41 go generate ./languages/${language}/main.go
27 '';
42 '';
28
43
44+ # The test file expect the binary to be in the current directory rather than bin
45+ preCheck = ''
46+ cp $GOPATH/bin/${language} ./prybar-${language}
47+ ln -s ${expect} /usr
48+ '';
49+
50+ # Add all the dependencies to the check. Binaries should include the language interpreter/binaries
51+ # for testing the language.
52+ checkInputs = [ expect ] ++ buildInputs ++ binaries;
53+
54+ # Run the end-to-end tests for this specific language
55+ checkPhase = ''
56+ runHook preCheck
57+
58+ ${bash}/bin/bash ./run_tests_language ${language}
59+
60+ runHook postCheck
61+ '';
62+
63+ # Delete the test binary we copied in the preCheck
64+ postCheck = ''
65+ rm -f ./prybar-${language}
66+ '';
67+
29 postInstall = ''
68 postInstall = ''
30 mv $out/bin/${language} $out/bin/prybar-${language}
69 mv $out/bin/${language} $out/bin/prybar-${language}
31 '';
70 '';
default.nix+58−35
@@ -1,40 +1,63 @@
1−{ pkgs ? import <nixpkgs>{} } :
1+{ pkgs ? import <nixpkgs>{}, versionArg ? "" } :
2let
2let
3 buildPrybar = attrs: pkgs.callPackage(import ./build-prybar.nix attrs) {};
3 buildPrybar = attrs: pkgs.callPackage(import ./build-prybar.nix attrs) {};
4+
5+ julia = import ./languages/julia/julia.nix { inherit pkgs; };
6+ clojureWithCP = import ./languages/clojure/wrappedClojure.nix { inherit pkgs; };
4in
7in
5{
8{
6− # TODO: These don't quite work yet
7−
8− # Won't build
9− # prybar-R = buildPrybar { language = "R"; buildInputs = [ pkgs.R ]; };
9+ prybar-R = buildPrybar {
10−
10+ language = "R";
11− # Julia 1.1 doesn't seem to be on nix
11+ buildInputs = [ pkgs.R ];
12+ versionArg = versionArg;
13+ pkgName = "libR";
14+ setFlags = true;
15+ };
16+
12− # prybar-julia = buildPrybar { language = "julia"; buildInputs = [ julia_13 ]; };
17+ prybar-julia = buildPrybar {
13−
18+ language = "julia";
14− # Has problem reading from prybar_assets. Seems like a bug with the impl.
19+ buildInputs = [ julia ];
20+ versionArg = versionArg;
21+ setFlags = true;
22+ };
23+
15− # prybar-nodejs = buildPrybar { language = "nodejs"; buildInputs = [ ]; };
24+ prybar-nodejs = buildPrybar { language = "nodejs"; binaries = [ pkgs.nodejs ]; versionArg = versionArg; };
16−
25+
17− # Ruby 2.5 is deprecated!
26+ # The official Ruby packages is running ruby 2.7
18− # prybar-ruby = buildPrybar { language = "ruby"; buildInputs = [ ruby_2_5 ]; };
27+ prybar-ruby = buildPrybar {
19−
28+ language = "ruby";
20− # Untested, spidermonkey not supported on darwin. Feel free to test on linux.
29+ buildInputs = [ pkgs.ruby ];
21− # prybar-spidermonkey = buildPrybar { language = "spidermonkey"; buildInputs = [ spidermonkey ]; };
30+ pkgName = "ruby-2.7";
22−
31+ versionArg = versionArg;
32+ setFlags = true;
33+ };
34+
23− prybar-python2 = buildPrybar { language = "python2"; buildInputs = [ pkgs.python2 ]; };
35+ prybar-python2 = buildPrybar { language = "python2"; buildInputs = [ pkgs.python2 ]; versionArg = versionArg; };
24−
36+
25− prybar-python3 = buildPrybar { language = "python3"; buildInputs = [ pkgs.python3 ]; };
37+ prybar-python3 = buildPrybar { language = "python3"; buildInputs = [ pkgs.python3 ]; versionArg = versionArg; };
26−
38+
27− prybar-lua = buildPrybar { language = "lua"; buildInputs = [ pkgs.lua5_1 pkgs.readline ]; };
39+ prybar-lua = buildPrybar { language = "lua"; buildInputs = [ pkgs.lua5_1 pkgs.readline ]; versionArg = versionArg; };
28−
40+
29− prybar-clojure = buildPrybar { language = "clojure"; buildInputs = [ pkgs.clojure ]; };
41+ prybar-clojure = buildPrybar {
30−
42+ language = "clojure";
43+ buildInputs = [ clojureWithCP ];
44+ binaries = [ pkgs.jdk11_headless ];
45+ versionArg = versionArg;
46+ };
47+
31− prybar-elisp = buildPrybar { language = "elisp"; };
48+ prybar-elisp = buildPrybar { language = "elisp"; versionArg = versionArg; };
32−
49+
33− prybar-ocaml = buildPrybar { language = "ocaml"; };
50+ prybar-ocaml = buildPrybar {
34−
51+ language = "ocaml";
52+ # This has to be in the build inputs so it set-ups the library paths before the check phase
53+ # It will not be copied over to the final package.
54+ buildInputs = [ pkgs.opam pkgs.ocaml pkgs.ocamlPackages.findlib pkgs.ocamlPackages.topkg pkgs.ocamlPackages.reason ];
55+ versionArg = versionArg;
56+ };
57+
35− prybar-scala = buildPrybar { language = "scala"; };
58+ prybar-scala = buildPrybar { language = "scala"; versionArg = versionArg; };
36−
59+
37− prybar-sqlite = buildPrybar { language = "sqlite"; };
60+ prybar-sqlite = buildPrybar { language = "sqlite"; binaries = [ pkgs.sqlite ]; versionArg = versionArg; };
38−
61+
39− prybar-tcl = buildPrybar { language = "tcl"; buildInputs = [ pkgs.tcl ]; };
62+ prybar-tcl = buildPrybar { language = "tcl"; buildInputs = [ pkgs.tcl ]; versionArg = versionArg; };
40}
63}
languages/R/main.go+1−1
@@ -6,7 +6,7 @@ package main
6#cgo pkg-config: libR
6#cgo pkg-config: libR
7#include <stdlib.h>
7#include <stdlib.h>
8#include <Rembedded.h>
8#include <Rembedded.h>
9−#include <RVersion.h>
9+#include <Rversion.h>
10#include <Rinternals.h>
10#include <Rinternals.h>
11#include <R_ext/Parse.h>
11#include <R_ext/Parse.h>
12#include <Rembedded.h>
12#include <Rembedded.h>
languages/clojure/deps.nixnew file+65
@@ -0,0 +1,65 @@
1+# generated by clj2nix-1.0.6
2+{ pkgs ? import <nixpkgs> {} }:
3+
4+let repos = [
5+ "http://jcenter.bintray.com"
6+ "https://repo1.maven.org/maven2/"
7+ "https://repo.clojars.org/" ];
8+
9+ in rec {
10+ makePaths = {extraClasspaths ? null}:
11+ (pkgs.lib.concatMap
12+ (dep:
13+ builtins.map
14+ (path:
15+ if builtins.isString path then
16+ path
17+ else if builtins.hasAttr "jar" path then
18+ path.jar
19+ else if builtins.hasAttr "outPath" path then
20+ path.outPath
21+ else
22+ path
23+ )
24+ dep.paths)
25+ packages)
26+ ++ (if extraClasspaths != null then [ extraClasspaths ] else []);
27+ makeClasspaths = {extraClasspaths ? null}: builtins.concatStringsSep ":" (makePaths {inherit extraClasspaths;});
28+ packageSources = builtins.map (dep: dep.src) packages;
29+
30+ packages = [
31+ rec {
32+ name = "clojure/org.clojure";
33+ src = pkgs.fetchMavenArtifact {
34+ inherit repos;
35+ artifactId = "clojure";
36+ groupId = "org.clojure";
37+ sha512 = "4bb567b9262d998f554f44e677a8628b96e919bc8bcfb28ab2e80d9810f8adf8f13a8898142425d92f3515e58c57b16782cff12ba1b5ffb38b7d0ccd13d99bbc";
38+ version = "1.10.3";
39+ };
40+ paths = [ src ];
41+ }
42+ rec {
43+ name = "spec.alpha/org.clojure";
44+ src = pkgs.fetchMavenArtifact {
45+ inherit repos;
46+ artifactId = "spec.alpha";
47+ groupId = "org.clojure";
48+ sha512 = "0740dc3a755530f52e32d27139a9ebfd7cbdb8d4351c820de8d510fe2d52a98acd6e4dfc004566ede3d426e52ec98accdca1156965218f269e60dd1cd4242a73";
49+ version = "0.2.194";
50+ };
51+ paths = [ src ];
52+ }
53+ rec {
54+ name = "core.specs.alpha/org.clojure";
55+ src = pkgs.fetchMavenArtifact {
56+ inherit repos;
57+ artifactId = "core.specs.alpha";
58+ groupId = "org.clojure";
59+ sha512 = "c1d2a740963896d97cd6b9a8c3dcdcc84459ea66b44170c05b8923e5fbb731b4b292b217ed3447bbc9e744c9a496552f77a6c38aea232e5e69f8faa627dea4b5";
60+ version = "0.2.56";
61+ };
62+ paths = [ src ];
63+ }
64+ ];
65+}
languages/clojure/main.go+3−3
@@ -1,6 +1,6 @@
1package main
1package main
2
2
3−//go:generate ../../scripts/gofiles.sh generated_files.go
3+//go:generate bash ../../scripts/gofiles.sh generated_files.go
4
4
5import (
5import (
6 "fmt"
6 "fmt"
@@ -35,14 +35,14 @@ func findHelper(path string) string {
35}
35}
36
36
37func Execute(config *utils.Config) {
37func Execute(config *utils.Config) {
38− path, err := exec.LookPath("clj")
38+ path, err := exec.LookPath("clojure")
39
39
40 if err != nil {
40 if err != nil {
41 panic(err)
41 panic(err)
42 }
42 }
43
43
44 env := os.Environ()
44 env := os.Environ()
45− args := []string{"clj"}
45+ args := []string{"clojure"}
46
46
47 hasOption := config.Code != "" || config.Exp != "" ||
47 hasOption := config.Code != "" || config.Exp != "" ||
48 config.Interactive || config.OurInteractive
48 config.Interactive || config.OurInteractive
languages/clojure/wrappedClojure.nixnew file+18
@@ -0,0 +1,18 @@
1+{ pkgs }:
2+
3+let
4+ cljdeps = import ./deps.nix { inherit pkgs; };
5+ classp = cljdeps.makeClasspaths {};
6+in pkgs.stdenv.mkDerivation {
7+ name = "wrapped-clojure-with-deps";
8+
9+ src = ./.;
10+ nativeBuildInputs = [ pkgs.makeWrapper ];
11+ buildInputs = [ pkgs.clojure ];
12+
13+ installPhase = ''
14+ mkdir -p $out/bin
15+
16+ makeWrapper ${pkgs.clojure}/bin/clojure $out/bin/clojure --add-flags "-Scp ${builtins.toString classp}"
17+ '';
18+}
languages/julia/julia.nixnew file+26
@@ -0,0 +1,26 @@
1+{ pkgs }:
2+
3+pkgs.stdenv.mkDerivation rec {
4+ pname = "julia-sources";
5+ version = "1.5.4";
6+
7+ src = {
8+ x86_64-linux = pkgs.fetchurl {
9+ url = "https://julialang-s3.julialang.org/bin/linux/x64/${pkgs.lib.versions.majorMinor version}/julia-${version}-linux-x86_64.tar.gz";
10+ sha256 = "1icb3rpn2qs6c3rqfb5rzby1pj6h90d9fdi62nnyi4x5s58w7pl0";
11+ };
12+ }.${pkgs.stdenv.hostPlatform.system} or (throw "Unsupported system: ${pkgs.stdenv.hostPlatform.system}");
13+
14+ installPhase = ''
15+ cp -r . $out
16+
17+ mkdir $out/lib/pkgconfig
18+ cat > $out/lib/pkgconfig/julia.pc <<- EOM
19+ Name: julia
20+ Cflags: -I$out/include/julia
21+ Version: 1.5.4
22+ Description: it's julia
23+ Libs: -L$out\/lib -ljulia
24+ EOM
25+ '';
26+}
languages/nodejs/main.go+1−1
@@ -1,6 +1,6 @@
1package main
1package main
2
2
3−//go:generate ../../scripts/gofiles.sh generated_files.go
3+//go:generate bash ../../scripts/gofiles.sh generated_files.go
4
4
5import (
5import (
6 "io/ioutil"
6 "io/ioutil"
languages/ocaml/main.go+11−2
@@ -1,13 +1,14 @@
1// OCaml main
1// OCaml main
2package main
2package main
3
3
4−//go:generate ../../scripts/gofiles.sh generated_files.go
4+//go:generate bash ../../scripts/gofiles.sh generated_files.go
5
5
6import (
6import (
7 "github.com/replit/prybar/utils"
7 "github.com/replit/prybar/utils"
8 "io/ioutil"
8 "io/ioutil"
9 "os"
9 "os"
10 "os/exec"
10 "os/exec"
11+ "strings"
11 "syscall"
12 "syscall"
12)
13)
13
14
@@ -40,8 +41,16 @@ func Execute(config *utils.Config) {
40 panic(err)
41 panic(err)
41 }
42 }
42
43
44+ args := []string{"ocaml"}
45+ // Fix for getting the various libs added to prybar when running through nix
46+ if value, ok := os.LookupEnv("OCAMLPATH"); ok {
47+ for _, val := range strings.Split(value, ":") {
48+ args = append(args, "-I", val)
49+ }
50+ }
51+
43 env := os.Environ()
52 env := os.Environ()
44− args := []string{"ocaml", findHelper("repl"), "-s", "ml"}
53+ args = append(args, findHelper("repl"), "-s", "ml")
45
54
46 if config.Quiet {
55 if config.Quiet {
47 args = append(args, "-q")
56 args = append(args, "-q")
languages/ruby/main.go+1−1
@@ -3,7 +3,7 @@ package main
3// USING_CGO
3// USING_CGO
4
4
5/*
5/*
6−#cgo pkg-config: ruby-2.5
6+#cgo CGO_LDFLAGS_ALLOW="-Wl,--compress-debug-sections=zlib" pkg-config: --libs --cflags ruby-2.7
7#include "pry_ruby.h"
7#include "pry_ruby.h"
8*/
8*/
9import "C"
9import "C"
languages/spidermonkey/main.godeleted−90
@@ -1,90 +0,0 @@
1−package main
2−
3−// USING_CGO
4−
5−/*
6−#cgo pkg-config: mozjs185
7−#include "jsapi.h"
8−
9−static JSClass global_class = {
10− "global", JSCLASS_GLOBAL_FLAGS,
11− JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
12− JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
13− JSCLASS_NO_OPTIONAL_MEMBERS
14−};
15−
16−JSRuntime *rt;
17−JSContext *cx;
18−JSObject *global;
19−
20−int pry_open() {
21−
22−
23− rt = JS_NewRuntime(8 * 1024 * 1024);
24− if (rt == NULL) return 1;
25−
26− cx = JS_NewContext(rt, 8192);
27− if (cx == NULL) return 1;
28−
29− JS_SetOptions(cx, JSOPTION_VAROBJFIX | JSOPTION_JIT | JSOPTION_METHODJIT);
30− JS_SetVersion(cx, JSVERSION_LATEST);
31− //JS_SetErrorReporter(cx, reportError);
32−
33−
34− global = JS_NewCompartmentAndGlobalObject(cx, &global_class, NULL);
35− if (global == NULL) return 1;
36−
37−
38− if (!JS_InitStandardClasses(cx, global)) return 1;
39− return 0;
40−}
41−
42−int pry_eval(const char* script) {
43− jsval rval;
44− JSString *str;
45− JSBool ok;
46− const char *filename = "noname";
47− uintN lineno = 0;
48−
49− ok = JS_EvaluateScript(cx, global, script, strlen(script), filename, lineno, &rval);
50− if (rval == JS_FALSE)
51− return 1;
52−
53− str = JS_ValueToString(cx, rval);
54− printf("%s\n", JS_EncodeString(cx, str));
55−}
56−
57−void pry_close() {
58− JS_DestroyContext(cx);
59− JS_DestroyRuntime(rt);
60− JS_ShutDown();
61−}
62−
63−*/
64−import "C"
65−
66−import (
67− "unsafe"
68−)
69−
70−type SpiderMonkey struct{}
71−
72−func (p SpiderMonkey) Open() {
73− C.pry_open()
74−}
75−
76−func (p SpiderMonkey) Version() string {
77− return C.GoString(C.JS_GetImplementationVersion())
78−}
79−
80−func (p SpiderMonkey) Eval(code string) {
81− ccode := C.CString(code)
82− defer C.free(unsafe.Pointer(ccode))
83− C.pry_eval(ccode)
84−}
85−
86−func (p SpiderMonkey) Close() {
87− C.pry_close()
88−}
89−
90−var Instance = SpiderMonkey{}
run_tests_languagenew file+28
@@ -0,0 +1,28 @@
1+#!/usr/bin/env bash
2+
3+stty cols 80
4+stty rows 20
5+
6+language=$1
7+tests=$(find "./tests/${language}" -printf '%P\n')
8+
9+for t in ${tests}; do
10+ if [[ $t != *.exp ]]; then
11+ echo "$t:"
12+ continue
13+ fi
14+
15+ name=$(echo -n $t | sed -s 's/.*\/\(.*\).exp/\1/' | sed -s 's/_/ /g')
16+
17+ echo -n "... ${language} $name"
18+
19+ test_out=$(timeout 15 "./tests/${language}/$t" 2>&1)
20+ if [[ $? != 0 ]]; then
21+ echo -e "\n========== \"$t\" failed =========="
22+ echo "$test_out"
23+ exit 1;
24+ fi
25+
26+ echo -ne '\r'
27+ echo -e " \e[32m✓\e[0m $name"
28+done
tests/clojure/run_code.exp+1−2
@@ -1,8 +1,7 @@
1#!/usr/bin/expect -f
1#!/usr/bin/expect -f
2
2
3set timeout -1
3set timeout -1
4−spawn ./prybar-clojure -c {(do (println "foo") "bar")}
4+spawn ./prybar-clojure -q -c {(do (println "foo") "bar")}
5match_max 100000
5match_max 100000
6expect -re "^\r\r\u001b\\\[K\rfoo\r\r\n$"
6expect -re "^\r\r\u001b\\\[K\rfoo\r\r\n$"
7−expect eof
8
7
tests/julia/header.exp+2−2
@@ -43,14 +43,14 @@ if {$force_conservative} {
43
43
44
44
45set timeout -1
45set timeout -1
46−spawn prybar-julia -i
46+spawn ./prybar-julia -i
47match_max 100000
47match_max 100000
48expect -exact " \[1m\[32m_\[0m\r
48expect -exact " \[1m\[32m_\[0m\r
49 \[1m\[34m_\[0m \[0m_\[0m \[1m\[31m_\[1m\[32m(_)\[1m\[35m_\[0m | Documentation: https://docs.julialang.org\r
49 \[1m\[34m_\[0m \[0m_\[0m \[1m\[31m_\[1m\[32m(_)\[1m\[35m_\[0m | Documentation: https://docs.julialang.org\r
50 \[1m\[34m(_)\[0m | \[1m\[31m(_)\[0m \[1m\[35m(_)\[0m |\r
50 \[1m\[34m(_)\[0m | \[1m\[31m(_)\[0m \[1m\[35m(_)\[0m |\r
51 \[0m_ _ _| |_ __ _\[0m | Type \"?\" for help, \"\]?\" for Pkg help.\r
51 \[0m_ _ _| |_ __ _\[0m | Type \"?\" for help, \"\]?\" for Pkg help.\r
52 \[0m| | | | | | |/ _` |\[0m |\r
52 \[0m| | | | | | |/ _` |\[0m |\r
53− \[0m| | |_| | | | (_| |\[0m | Version 1.4.1 (2020-04-14)\r
53+ \[0m| | |_| | | | (_| |\[0m | Version 1.5.4 (2021-03-11)\r
54 \[0m_/ |\\__'_|_|_|\\__'_|\[0m | Official https://julialang.org/ release\r
54 \[0m_/ |\\__'_|_|_|\\__'_|\[0m | Official https://julialang.org/ release\r
55\[0m|__/\[0m |\r
55\[0m|__/\[0m |\r
56\r
56\r
tests/nodejs/err.exp+9−9
@@ -8,14 +8,14 @@ send -- "x\r"
8expect -exact "x\r\r
8expect -exact "x\r\r
9\[0m\[31mReferenceError: x is not defined\r
9\[0m\[31mReferenceError: x is not defined\r
10 at REPL1:1:1\r
10 at REPL1:1:1\r
11− at Script.runInThisContext (vm.js:120:18)\r
11+ at Script.runInThisContext (vm.js:133:18)\r
12− at REPLServer.defaultEval (repl.js:442:29)\r
12+ at REPLServer.defaultEval (repl.js:486:29)\r
13− at bound (domain.js:427:14)\r
13+ at bound (domain.js:416:15)\r
14− at REPLServer.runBound \[as eval\] (domain.js:440:12)\r
14+ at REPLServer.runBound \[as eval\] (domain.js:427:12)\r
15− at REPLServer.onLine (repl.js:777:10)\r
15+ at REPLServer.onLine (repl.js:819:10)\r
16− at REPLServer.emit (events.js:314:20)\r
16+ at REPLServer.emit (events.js:376:20)\r
17− at REPLServer.EventEmitter.emit (domain.js:483:12)\r
17+ at REPLServer.emit (domain.js:470:12)\r
18− at REPLServer.Interface._onLine (readline.js:329:10)\r
18+ at REPLServer.Interface._onLine (readline.js:342:10)\r
19− at REPLServer.Interface._line (readline.js:658:8)\[0m\[1G\[0J--> \[5G"
19+ at REPLServer.Interface._line (readline.js:671:8)\[0m\[1G\[0J--> \[5G"
20send -- ""
20send -- ""
21expect eof
21expect eof
tests/tcl/1_plus_1.exp → tests/tcl/1_plus_1.exp_skiprenamed

The content is the same.