Skip to content

Commit

Permalink
[qa] Added lua formatter #148
Browse files Browse the repository at this point in the history
Closes #148
  • Loading branch information
devkapilbansal committed Nov 30, 2021
1 parent 34b1e3a commit 21358d6
Show file tree
Hide file tree
Showing 19 changed files with 1,141 additions and 1,128 deletions.
12 changes: 11 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,17 @@ jobs:
run: pip install openwisp-utils[qa]>=0.7

- name: QA-Checks
run: openwisp-qa-check --skip-checkmigrations --skip-isort --skip-flake8 --skip-black
run: ./run-qa-checks
env:
CI: 1

- name: Run sh-checker
uses: luizm/action-sh-checker@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
sh_checker_comment: true
sh_checker_shellcheck_disable: true

- name: Tests
run: ./runtests
Expand Down
17 changes: 17 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,23 @@ You can inspect the version of openwisp-config currently installed with::
openwisp_config --version
Quality Assurance Checks
------------------------
We use `LuaFormatter <https://luarocks.org/modules/tammela/luaformatter>`_ and `shfmt <https://github.com/mvdan/sh#shfmt>`_ to format lua files and shell scripts respectively.
Once they are installed, you can format all files by::
./qa-format
Run quality assurance tests with::
#install openwisp-utils QA tools first
pip install openwisp-utils[qa]
#run QA checks before committing code
./run-qa-checks
Run tests
---------
Expand Down
40 changes: 20 additions & 20 deletions openwisp-config/files/lib/openwisp/net.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,27 @@ local uci = require('uci')
local net = {}

function net.get_interface(name, family)
local uci_cursor = uci.cursor()
local ip_family = family or 'inet'
-- if UCI network name is a bridge, the ifname won't be the name of the bridge
local is_bridge = uci_cursor:get('network', name, 'type') == 'bridge'
local ifname
if is_bridge then
ifname = 'br-' .. name
else
-- get ifname from network configuration or
-- default to supplied name if none is found
ifname = uci_cursor:get('network', name, 'ifname') or name
local uci_cursor = uci.cursor()
local ip_family = family or 'inet'
-- if UCI network name is a bridge, the ifname won't be the name of the bridge
local is_bridge = uci_cursor:get('network', name, 'type') == 'bridge'
local ifname
if is_bridge then
ifname = 'br-' .. name
else
-- get ifname from network configuration or
-- default to supplied name if none is found
ifname = uci_cursor:get('network', name, 'ifname') or name
end
-- get list of interfaces and loop until found
local interfaces = nixio.getifaddrs()
for _, interface in pairs(interfaces) do
if interface.name == ifname and interface.family == ip_family then
return interface
end
-- get list of interfaces and loop until found
local interfaces = nixio.getifaddrs()
for _, interface in pairs(interfaces) do
if interface.name == ifname and interface.family == ip_family then
return interface
end
end
-- return nil if nothing is found
return nil
end
-- return nil if nothing is found
return nil
end

return net
238 changes: 105 additions & 133 deletions openwisp-config/files/lib/openwisp/utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,47 +4,38 @@ local lfs = require('lfs')

local utils = {}

function utils.starts_with_dot(str)
return str:sub(1, 1) == '.'
end
function utils.starts_with_dot(str) return str:sub(1, 1) == '.' end

function utils.split(input, sep)
if input == '' or input == nil then
return {}
end
if sep == nil then
sep = '%s'
end
local t={}; local i=1
for str in string.gmatch(input, '([^' .. sep .. ']+)') do
t[i] = str
i = i + 1
end
return t
if input == '' or input == nil then return {} end
if sep == nil then sep = '%s' end
local t = {};
local i = 1
for str in string.gmatch(input, '([^' .. sep .. ']+)') do
t[i] = str
i = i + 1
end
return t
end

function utils.basename(path)
local parts = utils.split(path, '/')
return parts[table.getn(parts)]
local parts = utils.split(path, '/')
return parts[table.getn(parts)]
end

function utils.dirname(path)
local parts = utils.split(path, '/')
local returnPath = '/'
local length = table.getn(parts)
for i, part in ipairs(parts) do
if i < length then
returnPath = returnPath..part..'/'
end
end
return returnPath
local parts = utils.split(path, '/')
local returnPath = '/'
local length = table.getn(parts)
for i, part in ipairs(parts) do
if i < length then returnPath = returnPath .. part .. '/' end
end
return returnPath
end

function utils.add_values_to_set(set, values)
for _, el in pairs(values) do
set[el] = true
end
return set
for _, el in pairs(values) do set[el] = true end
return set
end

-- writes uci section, eg:
Expand All @@ -64,148 +55,129 @@ end
-- option ifname 'eth0.2'
--
function utils.write_uci_section(cursor, config, section, merge_list)
local name
-- add named section
if not section['.anonymous'] then
name = section['.name']
cursor:set(config, name, section['.type'])
local name
-- add named section
if not section['.anonymous'] then
name = section['.name']
cursor:set(config, name, section['.type'])
-- add anonymous section
else
name = cursor:add(config, section['.type'])
end
-- write options for section
for key, value in utils.sorted_pairs(section) do
utils.write_uci_option(cursor, config, name, key, value, merge_list)
end
else
name = cursor:add(config, section['.type'])
end
-- write options for section
for key, value in utils.sorted_pairs(section) do
utils.write_uci_option(cursor, config, name, key, value, merge_list)
end
end

-- abstraction for "uci set" which handles corner cases
function utils.write_uci_option(cursor, config, name, key, value, merge_list)
-- ignore properties starting with .
if utils.starts_with_dot(key) then
return
end
-- avoid duplicate list settings
if type(value) == 'table' and merge_list then
-- create set with unique values
local set = {}
-- read existing value
local current = cursor:get(config, name, key)
if type(current) == 'table' then
set = utils.add_values_to_set(set, current)
end
set = utils.add_values_to_set(set, value)
-- reset value var with set contents
value = {}
for item_value, present in pairs(set) do
table.insert(value, item_value)
end
end
cursor:set(config, name, key, value)
-- ignore properties starting with .
if utils.starts_with_dot(key) then return end
-- avoid duplicate list settings
if type(value) == 'table' and merge_list then
-- create set with unique values
local set = {}
-- read existing value
local current = cursor:get(config, name, key)
if type(current) == 'table' then set = utils.add_values_to_set(set, current) end
set = utils.add_values_to_set(set, value)
-- reset value var with set contents
value = {}
for item_value, present in pairs(set) do table.insert(value, item_value) end
end
cursor:set(config, name, key, value)
end

-- returns true if uci section is empty
function utils.is_uci_empty(table)
for key, value in pairs(table) do
if not utils.starts_with_dot(key) then return false end
end
return true
for key, value in pairs(table) do
if not utils.starts_with_dot(key) then return false end
end
return true
end

-- removes uci options
-- and removes section if empty
-- this is the inverse operation of `write_uci_section`
function utils.remove_uci_options(cursor, config, section)
local name = section['.name']
-- loop over keys in section and
-- remove each one from cursor
for key, value in pairs(section) do
if not utils.starts_with_dot(key) then
cursor:delete(config, name, key)
end
end
-- remove entire section if empty
local uci = cursor:get_all(config, name)
if uci and utils.is_uci_empty(uci) then
cursor:delete(config, name)
end
local name = section['.name']
-- loop over keys in section and
-- remove each one from cursor
for key, value in pairs(section) do
if not utils.starts_with_dot(key) then cursor:delete(config, name, key) end
end
-- remove entire section if empty
local uci = cursor:get_all(config, name)
if uci and utils.is_uci_empty(uci) then cursor:delete(config, name) end
end

-- returns true if a table is empty
function utils.is_table_empty(t)
if next(t) == nil then
return true
else
return false
end
if next(t) == nil then
return true
else
return false
end
end

-- Code by David Kastrup
-- http://lua-users.org/wiki/DirTreeIterator
function utils.dirtree(dir_param)
assert(dir_param and dir_param ~= '', 'directory parameter is missing or empty')
if string.sub(dir_param, -1) == '/' then
dir_param = string.sub(dir_param, 1, -2)
end
local function yieldtree(dir)
for entry in lfs.dir(dir) do
if entry ~= '.' and entry ~= '..' then
entry = dir .. '/' ..entry
local attr = lfs.attributes(entry)
coroutine.yield(entry,attr)
if attr.mode == 'directory' then
yieldtree(entry)
end
end
end
assert(dir_param and dir_param ~= '', 'directory parameter is missing or empty')
if string.sub(dir_param, -1) == '/' then dir_param = string.sub(dir_param, 1, -2) end
local function yieldtree(dir)
for entry in lfs.dir(dir) do
if entry ~= '.' and entry ~= '..' then
entry = dir .. '/' .. entry
local attr = lfs.attributes(entry)
coroutine.yield(entry, attr)
if attr.mode == 'directory' then yieldtree(entry) end
end
end
return coroutine.wrap(function() yieldtree(dir_param) end)
end
return coroutine.wrap(function() yieldtree(dir_param) end)
end

function utils.file_exists(path)
local f = io.open(path, 'r')
if f ~= nil then io.close(f) return true end
return false
local f = io.open(path, 'r')
if f ~= nil then
io.close(f)
return true
end
return false
end

function utils.file_to_set(path)
local f = io.open(path, 'r')
local set = {}
for line in f:lines() do
set[line] = true
end
return set
local f = io.open(path, 'r')
local set = {}
for line in f:lines() do set[line] = true end
return set
end

function utils.set_to_file(set, path)
local f = io.open(path, 'w')
for file, bool in pairs(set) do
f:write(file, '\n')
end
io.close(f)
return true
local f = io.open(path, 'w')
for file, bool in pairs(set) do f:write(file, '\n') end
io.close(f)
return true
end

function utils.starts_with(str, start)
return str:sub(1, #start) == start
end
function utils.starts_with(str, start) return str:sub(1, #start) == start end

-- iterates over a table in alphabeticaly order
function utils.sorted_pairs(t)
-- collect keys
local keys = {}
for key in pairs(t) do keys[#keys+1] = key end

table.sort(keys)

-- return the iterator function
local i = 0
return function()
i = i + 1
if keys[i] then
return keys[i], t[keys[i]]
end
end
-- collect keys
local keys = {}
for key in pairs(t) do keys[#keys + 1] = key end

table.sort(keys)

-- return the iterator function
local i = 0
return function()
i = i + 1
if keys[i] then return keys[i], t[keys[i]] end
end
end

return utils
Loading

0 comments on commit 21358d6

Please sign in to comment.