Dart const variables not bootstrapping correctly - environment-variables

I have the following Dart project structure:
myapp/
pubspec.yaml
pubspec.lock
asset/
packages/
build/
web/
MyAppClient.dart
Lookups.dart
Here is MyAppClient.dart:
library myapp;
part "Lookups.dart";
// Load/set environmental variables.
// At runtime SERVER_NAME should be "example.com"
String SERVER_NAME = const String.fromEnvironment(Lookups.ENV_VAR_SERVER_NAME);
// Construct all the URL globals used throughout the application. Each of these Strings should
// be visible everywhere in the "myapp" library
String SERVER_BASE_URL_PATTERN = "http://%s/" + Lookups.APP_NAME;
String SERVER_BASE_URL = SERVER_BASE_URL_PATTERN.replaceAll("%s", SERVER_NAME);
String DO_SOMETHING_URL = SERVER_BASE_URL + Lookups.DO_SOMETHING_SERVICE_ENDPOINT;
void main() {
// Expecting: http://example.com/myapp/doSomething, where "example.com" is the
// "serverName" env var loaded from String.fromEnvironment.
window.alert("DO_SOMETHING_URL = $DO_SOMETHING_URL");
}
And here is Lookups.dart:
part of myapp;
abstract class Lookups {
// Environmental variables.
static const String ENV_VAR_SERVER_NAME = "serverName";
// HTTP/AJAX/URL lookups.
static final String APP_NAME = "myapp";
static final String DO_SOMETHING_SERVICE_ENDPOINT = "/doSomething";
}
When I run pub build and try to run this in a browser (FF v22.0), the HTML does not display correctly and in Firebug I get an Illegal Arguments error. I have a feeling I am not instantiating my global Strings (DO_SOMETHNG_URL, etc.) correctly. Any ideas?

It looks like pub build does not support the -D command line arguments that are used by dart2js to handle environment variables. (You can file an issue).
$ pub build -DserverName=example.com
Could not find an option with short name "-D"

Related

what is ${modulesPath} is configuration.nix

In /etc/nixos/configuration.nix, I have this code
{ lib, pkgs, config, modulesPath, ... }:
with lib;
let
nixos-wsl = import ./nixos-wsl;
in
{
imports = [
"${modulesPath}/profiles/minimal.nix"
nixos-wsl.nixosModules.wsl
];
I would like to know what "${modulesPath} is.
I have tried in shell.
echo ${modulesPath}
nothing
I have tried to print it in a nix interpreter.
nix repl
${modulesPath}
error: syntax error, unexpected DOLLAR_CURLY
modulePath
error: undefined variable 'modulesPath'
nothing too.
Does somebody what is that and more generally how to get the value of "nix constant"
update
I missed something important:
I have to import it in nix repl like this.
nix repl
{modulesPath}: modulesPath
«lambda # (string):1:1»
It say that it is a lamdba. I thought it would give a string value.
Quoting from the nixpkgs source:
For NixOS, specialArgs includes modulesPath, which allows you to import extra modules from the nixpkgs package tree without having to somehow make the module aware of the location of the nixpkgs or NixOS directories.
{ modulesPath, ... }: {
imports = [
(modulesPath + "/profiles/minimal.nix")
];
}
This is performed in nixos/lib/eval-config-minimal.nix, as follows:
lib.evalModules {
inherit prefix modules;
specialArgs = {
modulesPath = builtins.toString ../modules;
} // specialArgs;
};
Because this is done in <nixpkgs>/nixos/lib, ../modules becomes <nixpkgs>/nixos/modules.
$ nix repl
Welcome to Nix 2.8.1. Type :? for help.
nix-repl> "${toString <nixpkgs>}/nixos/modules/profiles/minimal.nix"
"/nix/store/qdblsqzrzarf9am35r6nqnvlsl7dammk-source/nixos/modules/profiles/minimal.nix"
...run this on your own machine, and you'll get a directory that exists for you.

How do I access files in a Shared Library?

I have a Shared Library with a .groovy script that I call in a jenkinsfile like this:
MySharedLibFunction{ .. some args}
I also have a .ps1 file in my shared library I want to execute. But if I do powershell pwd from in my shared library function when I call that function from my jenkinsfile the current working directory is the jenkins working directory of my pipeline where the jenkinsfile is located (which is usually what you want).
Is there a way to access files in the shared lib? I want to do powershell -File ps1FileInMySharedLibVarsFolder.ps1
You can only get the contents using the built-in step libraryResource. That's why have the following functions in my shared library to copy it to a temporary directory and return the path to the file:
/**
* Generates a path to a temporary file location, ending with {#code path} parameter.
*
* #param path path suffix
* #return path to file inside a temp directory
*/
#NonCPS
String createTempLocation(String path) {
String tmpDir = pwd tmp: true
return tmpDir + File.separator + new File(path).getName()
}
/**
* Returns the path to a temp location of a script from the global library (resources/ subdirectory)
*
* #param srcPath path within the resources/ subdirectory of this repo
* #param destPath destination path (optional)
* #return path to local file
*/
String copyGlobalLibraryScript(String srcPath, String destPath = null) {
destPath = destPath ?: createTempLocation(srcPath)
writeFile file: destPath, text: libraryResource(srcPath)
echo "copyGlobalLibraryScript: copied ${srcPath} to ${destPath}"
return destPath
}
As it returns the path to the temp file, you can pass this to any step expecting a file name:
sh(copyGlobalLibraryScript('test.sh'))
for a file residing in resources/test.sh within your shared library.
stephenking's answer is more complete but for simple cases the following will do:
writeFile file: 'ps1FileInMySharedLibVarsFolder.ps1', text: libraryResource('ps1FileInMySharedLibVarsFolder.ps1')
powershell ".\\ps1FileInMySharedLibVarsFolder.ps1"

get heap dump from command line using jmx

Is it possible to get a server heap dump on a running process on linux (CentOS) using JMX from command line ?
can't open VisualVM,
can't install jmap
It can be done with this simple code:
import com.sun.management.HotSpotDiagnosticMXBean;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.management.JMX;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
#SuppressWarnings("restriction")
public class CreateHeapDump
{
public static void main(String[] args) throws Exception
{
String host = args[0];
String port = args[1];
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + host + ":" + port + "/jmxrmi");
JMXConnector jmxc = JMXConnectorFactory.connect(url, null);
MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();
ObjectName mbeanName = new ObjectName("com.sun.management:type=HotSpotDiagnostic");
HotSpotDiagnosticMXBean bean = JMX.newMBeanProxy(mbsc, mbeanName, HotSpotDiagnosticMXBean.class, true);
String fileName = "heap_dump_" + new SimpleDateFormat("dd.MM.yyyy HH.mm").format(new Date()) + ".hprof";
boolean onlyLiveObjects = true;
bean.dumpHeap(fileName, onlyLiveObjects);
}
}
Compile it:
javac CreateHeapDump.java
Call it from command line:
java CreateHeapDump localhost 9010
This won't be pretty, but it works. Having said that, you might want to consider scripting this in Groovy or Jython, or even JavaScript....
I added a quickie add-on to jmxlocal, a project which implements standard JMX remoting for local JVMs. It now supports a command line invocation of one command against the connected MBeanServer, and the command must be specified in Java code.
Clone the repo and build with mvn clean install.
Copy the jar (jmxlocal-1.0-SNAPSHOT.jar) to your target server.
Execute the dump JMX command using the PID of the target java process as follows:
java -jar target/jmxlocal-1.0-SNAPSHOT.jar -j service:jmx:attach:///<PID> -c "conn.invoke(on(\"com.sun.management:type=HotSpotDiagnostic\"), \"dumpHeap\", new Object[]{\"/tmp/heap.dump\", true}, new String[]{String.class.getName(), boolean.class.getName()})"
The output will be
Command Executed. Result [null]
and you should find your dump file at /tmp/heap.dump.
If you need to, you can supply credentials using the -u [username] and -p [password] arguments.

How to find path to the package directory when the script is running with `pub run` command

I am writing a package that loads additional data from the lib directory and would like to provide an easy way to load this data with something like this:
const dataPath = 'mypackage/data/data.json';
initializeMyLibrary(dataPath).then((_) {
// library is ready
});
I've made two separate libraries browser.dart and standalone.dart, similar to how it is done in the Intl package.
It is quite easy to load this data from the "browser" environment, but when it comes to the "standalone" environment, it is not so easy, because of the pub run command.
When the script is running with simple $ dart myscript.dart, I can find a package path using dart:io.Platform Platform.script and Platform.packageRoot properties.
But when the script is running with $ pub run tool/mytool, the correct way to load data should be:
detect that the script is running from the pub run command
find the pub server host
load data from this server, because there could be pub transformers and we can't load data directly from the file system.
And even if I want to load data directly from the file system, when the script is running with pub run, Platform.script returns /mytool path.
So, the question is there any way to find that the script is running from pub run and how to find server host for the pub server?
I am not sure that this is the right way, but when I am running script with pub run, Package.script actually returns http://localhost:<port>/myscript.dart. So, when the scheme is http, I can download using http client, and when it is a file, load from the file system.
Something like this:
import 'dart:async';
import 'dart:io';
import 'package:path/path.dart' as ospath;
Future<List<int>> loadAsBytes(String path) {
final script = Platform.script;
final scheme = Platform.script.scheme;
if (scheme.startsWith('http')) {
return new HttpClient().getUrl(
new Uri(
scheme: script.scheme,
host: script.host,
port: script.port,
path: 'packages/' + path)).then((req) {
return req.close();
}).then((response) {
return response.fold(
new BytesBuilder(),
(b, d) => b..add(d)).then((builder) {
return builder.takeBytes();
});
});
} else if (scheme == 'file') {
return new File(
ospath.join(ospath.dirname(script.path), 'packages', path)).readAsBytes();
}
throw new Exception('...');
}

Access to user environment variable

In my .bashrc file:
export DART_SDK=/home/nicolas/dart/dart-sdk
In command line, it works when I "echo" it. But I cannot see this user variable from dart with, I just see system variable but not mine:
var env = Platform.environment;
env.forEach((k,v) => print("Key=$k Value=$v"));
I tried:
on windows and it works
on mac but doesn't work
Is my user variable is not well defined? Is my code is bad? It's a bug?
Using the following code:
import 'dart:io'; // Server side / command line only package.
main() {
Map<String, String> env = Platform.environment;
env.forEach((k, v) => print("Key=$k Value=$v"));
}
I was able to override environment variables on both Windows and Mac. On Mac I had to add the line to .bash_profile (.bashrc is not loaded on my Mac).
John
Here is the link to dart docs: https://api.dartlang.org/1.13.0/dart-io/Platform-class.html

Resources