diff --git a/lua/pl/app.lua b/lua/pl/app.lua index 736e166e..bfe69793 100644 --- a/lua/pl/app.lua +++ b/lua/pl/app.lua @@ -10,6 +10,18 @@ local path = require 'pl.path' local app = {} + +--- Sets/clears an environment variable default, to use with `utils.getenv`. +-- This links to `utils.setenv_default`. +-- @function setenv_default +-- @usage -- override the global with this implementation to control +-- -- environment variables with defaults on application level. +-- os.getenv = require("pl.utils").getenv +-- +-- utils.setenv_default("MY_APP_CONFIG", "~/.my_app") +app.setenv_default = utils.setenv_default + + --- return the name of the current script running. -- The name will be the name as passed on the command line -- @return string filename @@ -69,8 +81,8 @@ function app.require_here (base, nofollow) end --- return a suitable path for files private to this application. --- These will look like '~/.SNAME/file', with '~' as with expanduser and --- SNAME is the name of the script without .lua extension. +-- These will look like `'~/.SNAME/file'`, with '~' expanded through `path.expanduser` and +-- `SNAME` is the filename of the script without `'.lua'` extension (see `script_name`). -- If the directory does not exist, it will be created. -- @string file a filename (w/out path) -- @return a full pathname, or nil @@ -78,8 +90,8 @@ end -- @usage -- -- when run from a script called 'testapp' (on Windows): -- local app = require 'pl.app' --- print(app.appfile 'test.txt') --- -- C:\Documents and Settings\steve\.testapp\test.txt +-- print(app.appfile 'some\test.txt') +-- -- C:\Documents and Settings\steve\.testapp\some\test.txt function app.appfile(file) local sfullname, err = app.script_name() if not sfullname then return utils.raise(err) end @@ -94,7 +106,9 @@ function app.appfile(file) end --- return string indicating operating system. --- @return 'Windows','OSX' or whatever uname returns (e.g. 'Linux') +-- @treturn[1] string 'Windows' on Windows platforms +-- @treturn[2] string 'OSX' on Apple platforms +-- @treturn[3] string whatever `uname` returns on other platforms (e.g. 'Linux') function app.platform() if path.is_windows then return 'Windows' diff --git a/lua/pl/path.lua b/lua/pl/path.lua index 600bf057..a890f9b6 100644 --- a/lua/pl/path.lua +++ b/lua/pl/path.lua @@ -14,11 +14,11 @@ -- imports and locals local _G = _G local sub = string.sub -local getenv = os.getenv local tmpnam = os.tmpname local package = package local append, concat, remove = table.insert, table.concat, table.remove local utils = require 'pl.utils' +local getenv = utils.getenv local assert_string,raise = utils.assert_string,utils.raise local res,lfs = _G.pcall(_G.require,'lfs') diff --git a/lua/pl/utils.lua b/lua/pl/utils.lua index 7c641035..8636cfba 100644 --- a/lua/pl/utils.lua +++ b/lua/pl/utils.lua @@ -585,6 +585,49 @@ end --- OS functions -- @section OS-functions +do + local env_defaults = {} -- table to track defaults for env variables + local original_getenv = os.getenv -- in case the global function gets patched with this implementation + + + --- Gets an environment variable, whilst falling back to defaults. The defaults can + -- be set using `utils.setenv`. All Penlight modules will use this method to retrieve + -- environment variables. + -- The name is case-sensitive, except on Windows. + -- @tparam string name the environment variable to lookup. + -- @treturn[1] string the value retrieved + -- @treturn[2] nil if the variables wasn't found, and didn't have a default set + -- @see utils.setenv_default + -- @see app.setenv_default + function utils.getenv(name) + utils.assert_string(1, name) + name = is_windows and name:lower() or name + return original_getenv(name) or env_defaults[name] + end + + + + --- Sets/clears an environment variable default, to use with `utils.getenv`. + -- The name is case-sensitive, except on Windows. + -- @tparam string name the environment variable name to set a default for. + -- @tparam[opt] string value the value to assign as a default, if `nil` the default will be cleared. + -- @return nothing + -- @see utils.getenv + -- @see app.setenv_default + function utils.setenv_default(name, value) + utils.assert_string(1, name) + name = is_windows and name:lower() or name + if value == nil then + env_defaults[name] = nil + else + utils.assert_string(1, value) + env_defaults[name] = value + end + end +end + + + --- execute a shell command and return the output. -- This function redirects the output to tempfiles and returns the content of those files. -- @param cmd a shell command @@ -598,8 +641,8 @@ function utils.executeex(cmd, bin) local errfile = os.tmpname() if is_windows and not outfile:find(':') then - outfile = os.getenv('TEMP')..outfile - errfile = os.getenv('TEMP')..errfile + outfile = utils.getenv('TEMP')..outfile + errfile = utils.getenv('TEMP')..errfile end cmd = cmd .. " > " .. utils.quote_arg(outfile) .. " 2> " .. utils.quote_arg(errfile)