stevedonovan / Lake

A Lua-based Build Tool
MIT License
134 stars 17 forks source link

List constructor proposals #8

Closed moteus closed 11 years ago

moteus commented 12 years ago

1 List constuctor with remove holes, split strings, expand nested lists and targets. This is part of lakefile for luasql ( IF=choose, L - simple table constuctor );

EXPORT_API = IF(WINDOWS, '__declspec(dllexport)', '')

DEFS = {
  IF(DEBUG,  {'_DEBUG', 'DEBUG'},'NDEBUG');
  IF(DEBUG,  'LUASOCKET_DEBUG');
  IF(WINDOWS,{'WIN32','_WIN32','_WINDOWS'});
  IF(MSVC,   {'_CRT_SECURE_NO_WARNINGS', '_WIN32_WINNT=0x' .. WINVER});
}

socket = c.shared{'socket',
  base='src';
  src='*.c';
  exclude = L('mime inet_ntop', IF(WINDOWS, {'usocket', 'unix'}, 'wsocket')); --<- split and append
  defines  = L({ -- <- append new list with DEFS (DEFS can hold the holes)
    'LUASOCKET_EXPORTS';
    'LUASOCKET_API=' .. EXPORT_API
  },DEFS);
  llua = 'socket.core';
  needs={'lua',IF(WINDOWS,'winsock2','sockets')};
}
  1. Join function. path.join is too long name and can take only two parameters. this is my implimentation
J = function(...)
  local t = L({}, ...)
  local r = t[1]
  for i = 2, #t do r = path.join(r,t[i]) end
  return r
end
stevedonovan commented 12 years ago

I like the idea of L, but it should be a function (since {} constructors with holes are unreliable.) That is

DEFS = L(IF(DEBUG,...),IF(WINDOWS,...)...)

And it will 'flatten', that is L({1,2},{3,4},5) is {1,2,3,4,6}

I will update path.join to handle multiple paths, and people may just say J = path.join.

New Lake will be out in the next week, any other comments?

moteus commented 12 years ago

And it will 'flatten', that is L({1,2},{3,4},5) is {1,2,3,4,6}

This is what i mean. But in my implementation i change first parameter (if it is the table) and remove holse from each table. I use this function to detect if table is list:

local ikeys = function (t)
  local keys = {}
  for k in pairs(t) do  assert(type(k) == 'number') table.insert(keys,k) end
  return keys
end

local ensure_list = function(t)
  local keys = ikeys(t)
  if #keys == #t then return t end
  table.sort(keys);
  local list = {}
  for _,key in ipairs(keys) do table.insert(list,t[key]) end
  return list
end

L function shuld recognize targets and nested tables.

some_target = target(...)
c.shared{'mylib',src=L('*.c', some_target) ...}

any other comments?

1 export function to start process: for exampele test target in luasocket:

target('test', install, function()
  if not winapi then quit('Test needs winapi') end
  print("run " .. J(INSTALL_DIR,'test','testsrvr.lua'))
  print("run " .. J(INSTALL_DIR,'test','testclnt.lua'))
  if not TESTING then
    assert(winapi.shell_exec(nil, LUA_EXE, J(INSTALL_DIR,'test','testsrvr.lua'), J(INSTALL_DIR,'test')))
    os.execute( LUA_EXE .. ' ' .. J(INSTALL_DIR,'test','testclnt.lua') )
  end
end)

2.add global object env. ENV = setmetatable({},{_index = function(,key) return os.getenv(key) end}) But it can be extendet to set env with winapi. Also this object can be used to install variable in system environment. I have implementation to do this on windows. ENV.PROC set/get env variable to current process ENV.USER set/get env variable to current user ENV.SYS set/get env variable to system. (to install lua i use: install_params = { ... env = {LUA_DIR='...', LUA_INIT='...'} ...} for k,v in pairs(install_params.env) do env.sys[k] = v end

stevedonovan commented 12 years ago

L function shuld recognize targets and nested tables.

I would prefer if src got more clever and understood targets as valid source files.

1 export function to start process:

Something to launch in the background - yes, we can do that with luaposix as well.

2.add global object env.

Something like this works - there is a posix.setenv as well, so it can be cross-platform.

require 'winapi'

ENV = setmetatable({},{
    __index = function(t,key)
        return os.getenv(key)
    end,
    __newindex = function(t,key,value)
        winapi.setenv(key,value)
    end
})

print(ENV.PATH)

ENV.NEW = 'dog'
os.execute 'echo %NEW%'
moteus commented 12 years ago

print(ENV.PATH) ENV.NEW = 'dog'

I mean ENV.PROC.NEW='dog' - set env for curren process ENV.USER.NEW='dog' - set enf for currnt user (for windows in reg key (HKEY_CURRENT_USER\Environment)) it can be useful for install

stevedonovan commented 12 years ago

winapi can certainly set the environment for the current user, but I don't know how much support we should give to installation; it's so different on other platforms. Do you see lake as useful for installation?

moteus commented 12 years ago

I have some utils which require env variables. Lua also need them. I agree - its not necessary, and it culd be implemented like external addon to ENV.

stevedonovan commented 12 years ago

I think basic ENV is a good idea, we often want to give a new process a new environment.

Can always do (if on Windows) this to set/get user environment

local k = winapi.open_reg_key "HKEY_CURRENT_USER\\Environment"
local path = k:get_value("PATH")
print(path)
k:set_value("PATH",path..";d:\\mypath")
k:close()