Access to user environment variable - dart

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

Related

Gatsby .env.production variables - undefined

When building a Gatsby project I'm getting all env variables undefined in production environment.
In development everything is fine.
I have 2 similar .env.development and .env.production files.
In my gatsby-config.js I have
require('dotenv').config({
path: `.env.${process.env.NODE_ENV}`,
});
and if I console.log(process.env.NODE_ENV) during gatsby build it gives production and the variables can be accessed and logged out.
But later in code something like
return request.post(`${process.env.GEOCODING_CF_URL}/latlng`, {...});
gives request to http://localhost:9000/ru/undefined/latlng.
What am I doing wrong and how this issue can be fixed?
UPDATE:
When I run gatsby build - process.env.NODE_ENV is production
When I run gatsby serve - process.env.NODE_ENV is undefined
If this can help in any way.
If you use environment variables in node you don't need a prefix (like in your gatsby-config.js). However, if you need to use them in a component or a page you must add GATSBY_ as a prefix, so GEOCODING_CF_URL should be GATSBY_GEOCODING_CF_URL
For me, NODE_ENV=production yarn gatsby serve did the trick.
https://www.gatsbyjs.com/docs/how-to/local-development/environment-variables/
Accessing Environment Variables in the browser.
By default, environment variables are only available in Node.js code and are not available in the browser as some variables should be kept secret and not exposed to anyone visiting the site.
To expose a variable in the browser, you must preface its name with GATSBY_. So GATSBY_API_URL will be available in browser code but API_KEY will not.
Variables are set when JavaScript is compiled so when the development server is started or you build your site.
src/pages/index.js
Copysrc/pages/index.js: copy code to clipboard
import React, { useState, useEffect } from "react"
function App() {
const [data, setData] = useState()
useEffect(async () => {
const result = await fetch(
`${process.env.GATSBY_API_URL}/users`
).then(res => res.json())
setData(result.data)
})
return (
<ul>
{data.map(user => (
<li key={user.id}>
<a href={user.url}>{user.name}</a>
</li>
))}
</ul>
)
}
export default App

Expose Rails Env to Webpacker

I'm running Rails v5 with Webpacker v2. Everything's been smooth so far, but I've hit one hiccup: how to expose Rails helpers to my TypeScript.
I know Webpacker ships with rails-erb-loader, so I was expecting that I'd be able to add .erb to a TypeScript file, and then import that file elsewhere:
// app/javascript/utils/rails.ts.erb
export const env = "<%= Rails.env %>"
export function isEnv(envName: string) {
return env == envName
}
// app/javascript/packs/application.ts
import { env } from "../utils/rails"
But Webpack can't find the "rails" file even if I modify the typescript loader to include ERB files:
module.exports = {
test: /.ts(\.erb)?$/,
loader: 'ts-loader'
}
All I see is:
error TS2307: Cannot find module '../utils/rails'.
What's the best way to go about exposing Rails helpers and variables to my JavaScript?
Rails env comes from your environment variable. This means you configure it by setting (in bash for example) the variable in this way:
export RAILS_ENV=production
As a consequence, you don't need to deal with Rails at all.
// app/javascript/utils/rails.ts.erb
export const env = process.env.RAILS_ENV || "development"
export function isEnv(envName: string) {
return env == envName
}
This comes with a great advantage: you don't have to load the whole rails app just to compile your javascript. Rails can become really slow on first load if your app grows.
Since you won't have access to process.env on the frontend (browser), you also need a way to make it exist. In webpack, this is done through the DefinePlugin:
Update your webpack configuration to use the plugin (in plugins section): new webpack.DefinePlugin({ "process.env": { RAILS_ENV: process.env.RAILS_ENV } }) and you will get a process.env.RAILS_ENV available in the client
Rails Env can be accessed through:
process.env.RAILS_ENV

Invoking shell scripts on Windows under MSYS using Command

I am trying to invoke commands in Rust (1.0 beta 3) on Windows 7 in an MSYS2 environment, but I cannot understand how to do it.
Suppose that you have this very simple script called myls in your home folder:
#!/bin/bash
ls
And now create a simple program in Rust that calls the script:
use std::process::Command;
use std::path::Path;
fn main()
{
let path_linux_style = Path::new("~/myls").to_str().unwrap();
let path_win_style = Path::new("C:\\msys64\\home\\yourname\\myls").to_str().unwrap();
let out_linux = Command::new(path_linux_style).output();
let out_win = Command::new(path_win_style).output();
match out_linux
{
Ok(_) => println!("Linux path is working!"),
Err(e) => println!("Linux path is not working: {}", e)
}
match out_win
{
Ok(_) => println!("Win path is working!"),
Err(e) => println!("Win path is not working: {}", e)
}
}
Now, if you try to execute it, you will get the following output:
Linux path is not working: The system cannot find the file specified.
(os error 2)
Win path is not working: %1 is not a valid Win32 application.
(os error 193)
So I am not able to invoke any command in MSYS environment.
How can I solve it?
EDIT:
I noticed that if I invoke an executable, the problem doesn't happen, so it seems to be related to invocation of bash script. Anyway, it's quite annoying since it makes compiling projects depending on external C/C++ code (that need to launch configure script) tricky to get to work.
The Windows example doesn't work because Windows isn't a Unix. On Unix-like systems, the #! at the beginning of a script is recognized, and it invokes the executable at the given path as the interpreter. Windows doesn't have this behavior; and even if it did, it wouldn't recognize the path name to the /bin/bash, as that path name is one that msys2 emulates, it is not a native path name.
Instead, you can explicitly execute the script you want using the msys2 shell, by doing something like the following (alter the path as appropriate, I have msys32 installed since it's a 32 bit VM)
let out_win = Command::new("C:\\msys32\\usr\\bin\\sh.exe")
.arg("-c")
.arg(path_win_style)
.output();

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('...');
}

How to compile a Delphi 7 project group file (.bpg) using the command line?

I've grouped a lot of projects in a project group. All the info is in the project.bpg. Now I'd like to automatically build them all.
How do I build all the projects using the command line?
I'm still using Delphi 7.
I never tried it myself, but here is a German article describing that you can use make -f ProjectGroup.bpg because *.bpgs essentially are makefiles.
You can also run Delphi from the command line or a batch file, passing the .bpg file name as a parameter.
Edit: Example (for D2007, but can be adjusted for D7):
=== rebuild.cmd (excerpt) ===
#echo off
set DelphiPath=C:\Program Files\CodeGear\RAD Studio\5.0\bin
set DelphiExe=bds.exe
set LibPath=V:\Library
set LibBpg=Library.groupproj
set LibErr=Library.err
set RegSubkey=BDSClean
:buildlib
echo Rebuilding %LibBpg%...
if exist "%LibPath%\%LibErr%" del /q "%LibPath%\%LibErr%"
"%DelphiPath%\%DelphiExe%" -pDelphi -r%RegSubkey% -b "%LibPath%\%LibBpg%"
if %errorlevel% == 0 goto buildlibok
As I said as a comment to Ulrich Gerhardt answer, the make project_group.bpg is useless if your projects are in subdirectories. Make won't use relative paths and the projects won't compile correctly.
I've made a python script to compile all the DPRs in every subdirectory. This is what I really wanted to do, but I'll leave the above answer as marked. Although it didn't worked for me, It really answered my question.
Here is my script to compile_all.py . I believe it may help somebody:
# -*- coding: utf-8 -*-
import os.path
import subprocess
import sys
#put this file in your root dir
BASE_PATH = os.path.dirname(os.path.realpath(__file__))
os.chdir(BASE_PATH)
os.environ['PATH'] += "C:\\Program Files\\Borland\\Delphi7\\Bin" #your delphi compiler path
DELPHI = "DCC32.exe"
DELPHI_PARAMS = ['-B', '-Q', '-$D+', '-$L+']
for root, dirs, files in os.walk(BASE_PATH):
projects = [project for project in files if project.lower().endswith('.dpr')]
if ('FastMM' in root ): #put here projects you don't want to compile
continue
os.chdir(os.path.join(BASE_PATH, root))
for project in projects:
print
print '*** Compiling:', os.path.join(root, project)
result = subprocess.call([DELPHI] + DELPHI_PARAMS + [project])
if result != 0:
print 'Failed for', project, result
sys.exit(result)
Another vantage of this approach is that you don't need to add new projects to your bpg file. If it is in a subdir, it will compile.

Resources