The Cirrus CI config included the codecov token in cleartext as I was under the
impression that this was necessary for coverage reports on pull requests to work
correctly. But this seems to be also causing pushes in other people's
Elvish repositories to appear in the master branch's commit history
(https://app.codecov.io/gh/elves/elvish/commits). Changing the token to be
encrypted might fix the problem; if this breaks coverage reports on pull
requests the token can be switched back to cleartext.
Test helpers will necessarily contain some lines that are only executed on test
failure, so exluding them from test coverage is still a good idea.
Also exclude pkg/web.
There is more work to be done but this should address 99.9999% of the
expected uses of a `printf` builtin. Some corner cases which don't have
a POSIX analog, such as support for Elvish bool types will be implemented
in future changes.
Resolves#1132
The implementation of useOp has not been updated correctly to accomodate the
fact that the namespaces are no longer modified in place.
This fixes#1212.
This commit replaces scopeOp, the only remaining place that mutates *Ns in
place, with nsOp, which performs copy-on-write for *Ns.
As a result, the "eval" command no longer mutates the passed namespace. The
default namespace it uses is also changed to match the default of "-source" (an
amalgamated namespace from the local and upvalue scopes), making "-source $file"
equivalent to "eval (slurp <$file)", and formally deprecated.
Another result is that (*Evaler).Eval can now guard the mutation of the global
namespace with the mutex, making it concurrency-safe to execute multiple sources
that touch the global namespace.
This fixes#1137.
Also change the variable name used to keep the Exception returned from "err" to
"exc".
This uncovers several error scenarios that were not returning Exception, and
would result in the absense of stack traces when such errors occur.
This change is a preparation step for refining all *Op types to return Exception
as the error.
Keeping Exception as a struct type will make such a change error-prone, since
a (*Exception)(nil) != error(nil), so if an *Op returns a nil *Exception, it
is not nil if the return value is stored in an error-typed variable.
Doing something like the following is likely to result in too many open
files (assuming `ulimit -n` == 256) resulting in a panic:
> fn fact [n]{ if (== $n 0) { put 1 } else { put (* $n (fact (- $n 1))) } }
> fact 60
panic: interface conversion: error is *os.SyscallError, not
*eval.Exception
goroutine 24161 [running]:
github.com/elves/elvish/pkg/eval.(*pipelineOp).exec.func1(0x152a5a0,
0xc000dca210, 0xc000a44e70, 0xc00057b540, 0xc001030590, 0x203000)
github.com/elves/elvish/pkg/eval/compile_effect.go:153 +0x152
created by github.com/elves/elvish/pkg/eval.(*pipelineOp).exec
github.com/elves/elvish/pkg/eval/compile_effect.go:149 +0x225
Exception: elvish exited with 2
Fixes#1208
- Move NewEnvListVar to pkg/eval/vars.
- De-export GlobPattern, GlobFlag and ExternalCmd.
- Merge editor.go and chdir.go into eval.go, value_helper.go into compile_value.go.
- Remove eval_internal_test.go and replace it with a new test for $pid.
This change makes Ns immutable from the exposed API. Internally there is exactly
one place that still mutates Ns, in scopeOp; this will be addressed later.
- Make Evaler mostly thread-safe. The only remaining thread-unsafe part is the
modules field, which is more tricky than other fields.
- Remove the state and evalerScopes type, and move their fields into Evaler.
- Expose valuePrefix via a get method, and change PortsFromFiles to take the
prefix instead of a *Evaler. Also expose a PortsFromStdFiles.
- Make Evaler a normal field of Frame, instead of an embedded field. This makes
access to global states more explicit.
The Evaler keeps global states and needs to be accessed concurrently. Mutations
to global states have fairly low throughput, so it makes sense to use a single
mutex.
On the other hand, the compiler is always used on a single thread, so it does
not need any mutex protection, so there is no need to put the mutex inside
deprecationRegistry.
- Remove the Op type; it is no longer used by any code outside the eval package
and its use within the package is limited.
- Replace (*Evaler).execOp with (*Evaler).prepareFrame.
- Remove reliance on scopeOp, concentrating all the scope for creating the local
scope in (*closure).call.
- Check options at the very beginning, and include all unsupported options in the
error.
The -source command now runs with a temporary namespace that is amalgamated
from the local and up namespace of the caller -source; this means that it can
no longer mutate its caller's local scope, which is the only possible sensible
behavior anyway.
This fixes#1202.