Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ This project follows [pub-flavored semantic versioning][pub-semver]. ([more][pub
[pub-semver]: https://www.dartlang.org/tools/pub/versioning.html#semantic-versions
[pub-semver-readme]: https://pub.dartlang.org/packages/pub_semver

## 4.3.0

- [feat] Moved `lib/src/dotenv.dart` and `lib/src/parser.dart` into `lib/` and deleted the empty `lib/src` directory. With this change, the user can now import the `Parser` class without importing files from the `lib/src` directory, because that is considered a bad practice. [See lint implementation_imports](https://dart.dev/tools/linter-rules/implementation_imports)
- [deps] added package `universal_io`
- [fix] typo, renamed `Parser._singleQuot` to `Parser._singleQuote`
- [fix] replaced dependencies of `dart:io` in `lib/dotenv.dart` and `lib/parser.dart` with `package:universal_io/io.dart`, this should make the package compatible with flutter web and fix [#33][]

## 4.2.0

- [feat] add optional parameter `quiet` to `DotEnv` constructor
Expand Down Expand Up @@ -102,3 +109,4 @@ Initial release.
[#16]: https://github.com/mockturtl/dotenv/issues/16
[#21]: https://github.com/mockturtl/dotenv/pull/21
[#27]: https://github.com/mockturtl/dotenv/pull/27
[#33]: https://github.com/mockturtl/dotenv/issues/33
4 changes: 1 addition & 3 deletions example/example.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import 'dart:io';

import 'package:dotenv/dotenv.dart';

void main() {
Expand All @@ -19,4 +17,4 @@ void main() {
p('your home directory is still: ${env['HOME']}');
}

p(String msg) => stdout.writeln(msg);
p(String msg) => print(msg);
89 changes: 88 additions & 1 deletion lib/dotenv.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
import 'package:meta/meta.dart';
import 'package:universal_io/io.dart';

import 'parser.dart';

/// Loads key-value pairs from a file into a [Map<String, String>].
///
/// The parser will attempt to handle simple variable substitution,
/// respect single- vs. double-quotes, and ignore `#comments` or the `export` keyword.
/// Loads environment variables from a `.env` file.
///
/// ## usage
Expand All @@ -19,4 +28,82 @@
///
/// const _requiredEnvVars = ['host', 'port'];
/// bool get hasEnv => env.isEveryDefined(_requiredEnvVars);
export 'package:dotenv/src/dotenv.dart';
class DotEnv {
/// If true, the underlying map will contain the entries of [Platform.environment],
/// even after calling [clear].
/// Otherwise, it will be empty until populated by [load].
final bool includePlatformEnvironment;

/// If true, suppress "file not found" messages on [stderr] during [load].
final bool quiet;

final _map = <String, String>{};

DotEnv({this.includePlatformEnvironment = false, this.quiet = false}) {
if (includePlatformEnvironment) _addPlatformEnvironment();
}

/// Provides access to the underlying [Map].
///
/// Prefer using [operator[]] to read values.
@visibleForTesting
Map<String, String> get map => _map;

/// Reads the value for [key] from the underlying map.
///
/// Returns `null` if [key] is absent. See [isDefined].
String? operator [](String key) => _map[key];

/// Calls [Map.addAll] on the underlying map.
void addAll(Map<String, String> other) => _map.addAll(other);

/// Calls [Map.clear] on the underlying map.
///
/// If [includePlatformEnvironment] is true, the entries of [Platform.environment] will be reinserted.
void clear() {
_map.clear();
if (includePlatformEnvironment) _addPlatformEnvironment();
}

/// Equivalent to [operator []] when the underlying map contains [key],
/// and the value is non-empty. See [isDefined].
///
/// Otherwise, calls [orElse] and returns the value.
String getOrElse(String key, String Function() orElse) =>
isDefined(key) ? _map[key]! : orElse();

/// True if [key] has a nonempty value in the underlying map.
///
/// Differs from [Map.containsKey] by excluding empty values.
bool isDefined(String key) => _map[key]?.isNotEmpty ?? false;

/// True if all supplied [vars] have nonempty value; false otherwise.
///
/// See [isDefined].
bool isEveryDefined(Iterable<String> vars) => vars.every(isDefined);

/// Parses environment variables from each path in [filenames], and adds them
/// to the underlying [Map].
///
/// Logs to [stderr] if any file does not exist; see [quiet].
void load([
Iterable<String> filenames = const ['.env'],
Parser psr = const Parser(),
]) {
for (var filename in filenames) {
var f = File.fromUri(Uri.file(filename));
var lines = _verify(f);
_map.addAll(psr.parse(lines));
}
}

void _addPlatformEnvironment() => _map.addAll(Platform.environment);

List<String> _verify(File f) {
if (!f.existsSync()) {
if (!quiet) stderr.writeln('[dotenv] Load failed: file not found: $f');
return [];
}
return f.readAsLinesSync();
}
}
9 changes: 4 additions & 5 deletions lib/src/parser.dart → lib/parser.dart
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import 'dart:io';

import 'package:meta/meta.dart';
import 'package:universal_io/io.dart';

/// Creates key-value pairs from strings formatted as environment
/// variable definitions.
class Parser {
static const _singleQuot = "'";
static const _singleQuote = "'";
static const _keyword = 'export';

static final _comment = new RegExp(r'''#.*(?:[^'"])$''');
Expand Down Expand Up @@ -49,10 +48,10 @@ class Parser {
if (k.isEmpty) return {};

var rhs = stripped.substring(idx + 1, stripped.length).trim();
var quotChar = surroundingQuote(rhs);
var quoteChar = surroundingQuote(rhs);
var v = unquote(rhs);

if (quotChar == _singleQuot) // skip substitution in single-quoted values
if (quoteChar == _singleQuote) // skip substitution in single-quoted values
return {k: v};

return {k: interpolate(v, env)};
Expand Down
90 changes: 0 additions & 90 deletions lib/src/dotenv.dart

This file was deleted.

3 changes: 2 additions & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: dotenv
version: 4.2.0
version: 4.3.0

description: Load environment variables from a `.env` file.
homepage: https://github.com/mockturtl/dotenv
Expand All @@ -9,6 +9,7 @@ environment:
dependencies:
args: ^2.3.0
meta: ^1.7.0
universal_io: ^2.2.2

dev_dependencies:
tidy: ^3.1.0
Expand Down
2 changes: 1 addition & 1 deletion test/dotenv_test.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import 'package:collection/collection.dart' show MapEquality;
import 'package:dotenv/src/dotenv.dart';
import 'package:dotenv/dotenv.dart';
import 'package:test/test.dart';

void main() {
Expand Down
2 changes: 1 addition & 1 deletion test/parser_test.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'dart:io';
import 'dart:math';

import 'package:dotenv/src/parser.dart';
import 'package:dotenv/parser.dart';
import 'package:test/test.dart';

void main() {
Expand Down