-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathdotenv.m
90 lines (75 loc) · 3.31 KB
/
dotenv.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
classdef dotenv
% Dotenv Implementation of dotenv pattern
% dotenv allows you to load environment variables at runtime without
% committing your .env file to source control. A common reason for
% doing this is that you need a password or API key but don't want to
% embed that in your code or in source control.
% See https://github.com/motdotla/dotenv for inspiration
% Copyright 2019-2021 The MathWorks, Inc.
properties (SetAccess = immutable)
env % Structure to hold key/value pairs. Access via d.env.key.
end
properties (Access = private)
fname
end
methods
function obj = dotenv(location)
% d = dotenv([path/to/file.env]) -- load .env file from current working directory or specified via path.
obj.env = struct;
switch nargin
case 1 % if there is an argument load that file
obj.fname = location;
case 0 % otherwise load the file from the current directory
obj.fname = '.env';
end
% ensure we can open the file
try
fid = fopen(obj.fname, 'r');
assert(fid ~= -1);
catch
throw( MException('DOTENV:CannotOpenFile', "Cannot open file: " + obj.fname + ". Code: " + fid) );
end
fclose(fid);
% load the .env file with name=value pairs into the 'env' struct
% 20b (v9.10) introduced readlines()
if verLessThan('matlab', '9.10')
lines = string(splitlines(fileread(obj.fname)));
else
% I put in the feature request for readlines() so I better
% use it :)
lines = readlines(obj.fname);
end
notOK = startsWith(lines, '#');
lines(notOK) = [];
% expr splits the line into a key / value pairs with regex
% capture. It captures one or more characters up to the first
% instance of an '=' in 'key' and then zero or more characters
% into 'value'.
expr = "(?<key>.+?)=(?<value>.*)";
kvpair = regexp(lines, expr, 'names');
% Deal with single entry case where regexp does not return a
% cell array
if iscell(kvpair)
kvpair(cellfun(@isempty, kvpair)) = [];
kvpair = cellfun(@(x) struct('key', x.key, 'value', x.value), kvpair);
end
% to be able to use dot reference we need to convert it to a
% structure
obj.env = cell2struct(strtrim({kvpair.value}), [kvpair.key], 2);
end
function val = subsref(obj, s)
% Overload subsref to handle d.env (all key/value pairs) vs. d.env.key (the value specified by the supplied key)
if size(s, 2) == 1
% this handles the case of d.env
val=obj.env;
else
% this handles the case of d.env.KEY_NAME
if isfield(obj.env, s(2).subs)
val = obj.env.(s(2).subs);
else
val = "";
end
end
end
end
end