Compare commits
30 Commits
Author | SHA1 | Date |
---|---|---|
Miro Hrončok | d4a234f1e2 | 12 months ago |
Orion Poplawski | b52ef20b2b | 1 year ago |
Miro Hrončok | 7761cacd3a | 2 years ago |
Miro Hrončok | 6a548935a5 | 2 years ago |
Maxwell G | 7c1824e99a | 2 years ago |
Maxwell G | 59caa90b5f | 2 years ago |
Jitka Plesnikova | 62c9018653 | 2 years ago |
Jitka Plesnikova | b6dbd20fc7 | 2 years ago |
Todd Zullinger | 945f3703f2 | 2 years ago |
Maxwell G | 12d369f153 | 2 years ago |
Maxwell G | ba3cef50bb | 2 years ago |
Iñaki Úcar | 5aa786f208 | 2 years ago |
Maxwell G | 73454ac54c | 2 years ago |
Maxwell G | fe7e34ff91 | 2 years ago |
Maxwell G | 8ba0536651 | 2 years ago |
Miro Hrončok | fcd61e6767 | 2 years ago |
Maxwell G | e3b1254b4b | 3 years ago |
Maxwell G | 653db1df00 | 3 years ago |
Maxwell G | c2cea18f09 | 3 years ago |
Maxwell G | a8c53aa651 | 3 years ago |
Maxwell G | b29f7a38f1 | 3 years ago |
Maxwell G | 5384f530ca | 3 years ago |
Maxwell G | e8644934b9 | 3 years ago |
Miro Hrončok | 0fef179a9d | 3 years ago |
Maxwell G | 54c1f931b6 | 3 years ago |
Maxwell G | 3d7226a416 | 3 years ago |
Miro Hrončok | 73629be078 | 3 years ago |
Pablo Greco | d733fbe476 | 3 years ago |
Karolina Surma | 4ce1a695cf | 3 years ago |
Tomas Orsava | 367f6266ab | 3 years ago |
@ -0,0 +1,3 @@
|
||||
addFilter("no-%build-section")
|
||||
addFilter("no-documentation")
|
||||
addFilter("only-non-binary-in-usr-lib")
|
@ -0,0 +1,171 @@
|
||||
'''Script to perform import of each module given to %%py_check_import
|
||||
'''
|
||||
import argparse
|
||||
import importlib
|
||||
import fnmatch
|
||||
import os
|
||||
import re
|
||||
import site
|
||||
import sys
|
||||
|
||||
from contextlib import contextmanager
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def read_modules_files(file_paths):
|
||||
'''Read module names from the files (modules must be newline separated).
|
||||
|
||||
Return the module names list or, if no files were provided, an empty list.
|
||||
'''
|
||||
|
||||
if not file_paths:
|
||||
return []
|
||||
|
||||
modules = []
|
||||
for file in file_paths:
|
||||
file_contents = file.read_text()
|
||||
modules.extend(file_contents.split())
|
||||
return modules
|
||||
|
||||
|
||||
def read_modules_from_cli(argv):
|
||||
'''Read module names from command-line arguments (space or comma separated).
|
||||
|
||||
Return the module names list.
|
||||
'''
|
||||
|
||||
if not argv:
|
||||
return []
|
||||
|
||||
# %%py3_check_import allows to separate module list with comma or whitespace,
|
||||
# we need to unify the output to a list of particular elements
|
||||
modules_as_str = ' '.join(argv)
|
||||
modules = re.split(r'[\s,]+', modules_as_str)
|
||||
# Because of shell expansion in some less typical cases it may happen
|
||||
# that a trailing space will occur at the end of the list.
|
||||
# Remove the empty items from the list before passing it further
|
||||
modules = [m for m in modules if m]
|
||||
return modules
|
||||
|
||||
|
||||
def filter_top_level_modules_only(modules):
|
||||
'''Filter out entries with nested modules (containing dot) ie. 'foo.bar'.
|
||||
|
||||
Return the list of top-level modules.
|
||||
'''
|
||||
|
||||
return [module for module in modules if '.' not in module]
|
||||
|
||||
|
||||
def any_match(text, globs):
|
||||
'''Return True if any of given globs fnmatchcase's the given text.'''
|
||||
|
||||
return any(fnmatch.fnmatchcase(text, g) for g in globs)
|
||||
|
||||
|
||||
def exclude_unwanted_module_globs(globs, modules):
|
||||
'''Filter out entries which match the either of the globs given as argv.
|
||||
|
||||
Return the list of filtered modules.
|
||||
'''
|
||||
|
||||
return [m for m in modules if not any_match(m, globs)]
|
||||
|
||||
|
||||
def read_modules_from_all_args(args):
|
||||
'''Return a joined list of modules from all given command-line arguments.
|
||||
'''
|
||||
|
||||
modules = read_modules_files(args.filename)
|
||||
modules.extend(read_modules_from_cli(args.modules))
|
||||
if args.exclude:
|
||||
modules = exclude_unwanted_module_globs(args.exclude, modules)
|
||||
|
||||
if args.top_level:
|
||||
modules = filter_top_level_modules_only(modules)
|
||||
|
||||
# Error when someone accidentally managed to filter out everything
|
||||
if len(modules) == 0:
|
||||
raise ValueError('No modules to check were left')
|
||||
|
||||
return modules
|
||||
|
||||
|
||||
def import_modules(modules):
|
||||
'''Procedure to perform import check for each module name from the given list of modules.
|
||||
'''
|
||||
|
||||
for module in modules:
|
||||
print('Check import:', module, file=sys.stderr)
|
||||
importlib.import_module(module)
|
||||
|
||||
|
||||
def argparser():
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Generate list of all importable modules for import check.'
|
||||
)
|
||||
parser.add_argument(
|
||||
'modules', nargs='*',
|
||||
help=('Add modules to check the import (space or comma separated).'),
|
||||
)
|
||||
parser.add_argument(
|
||||
'-f', '--filename', action='append', type=Path,
|
||||
help='Add importable module names list from file.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'-t', '--top-level', action='store_true',
|
||||
help='Check only top-level modules.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'-e', '--exclude', action='append',
|
||||
help='Provide modules globs to be excluded from the check.',
|
||||
)
|
||||
return parser
|
||||
|
||||
|
||||
@contextmanager
|
||||
def remove_unwanteds_from_sys_path():
|
||||
'''Remove cwd and this script's parent from sys.path for the import test.
|
||||
Bring the original contents back after import is done (or failed)
|
||||
'''
|
||||
|
||||
cwd_absolute = Path.cwd().absolute()
|
||||
this_file_parent = Path(__file__).parent.absolute()
|
||||
old_sys_path = list(sys.path)
|
||||
for path in old_sys_path:
|
||||
if Path(path).absolute() in (cwd_absolute, this_file_parent):
|
||||
sys.path.remove(path)
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
sys.path = old_sys_path
|
||||
|
||||
|
||||
def addsitedirs_from_environ():
|
||||
'''Load directories from the _PYTHONSITE environment variable (separated by :)
|
||||
and load the ones already present in sys.path via site.addsitedir()
|
||||
to handle .pth files in them.
|
||||
|
||||
This is needed to properly import old-style namespace packages with nspkg.pth files.
|
||||
See https://bugzilla.redhat.com/2018551 for a more detailed rationale.'''
|
||||
for path in os.getenv('_PYTHONSITE', '').split(':'):
|
||||
if path in sys.path:
|
||||
site.addsitedir(path)
|
||||
|
||||
|
||||
def main(argv=None):
|
||||
|
||||
cli_args = argparser().parse_args(argv)
|
||||
|
||||
if not cli_args.modules and not cli_args.filename:
|
||||
raise ValueError('No modules to check were provided')
|
||||
|
||||
modules = read_modules_from_all_args(cli_args)
|
||||
|
||||
with remove_unwanteds_from_sys_path():
|
||||
addsitedirs_from_environ()
|
||||
import_modules(modules)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -0,0 +1,42 @@
|
||||
# Macros to constrain resource use during the build process
|
||||
|
||||
# outputs build flag overrides to be used in conjunction with
|
||||
# %%make_build, %%cmake_build etc.
|
||||
#
|
||||
# if no override is needed, this macro outputs nothing
|
||||
#
|
||||
# - m memory limit in MBs per core; default is 1024
|
||||
#
|
||||
# Usage:
|
||||
# e.g. %make_build %{limit_build -m 2048}
|
||||
# => /usr/bin/make -O -j16 V=1 VERBOSE=1
|
||||
# %make_build %{limit_build -m 40960}
|
||||
# => /usr/bin/make -O -j16 V=1 VERBOSE=1 -j1
|
||||
#
|
||||
%limit_build(m:) %{lua:
|
||||
local mem_per_process=rpm.expand("%{-m*}")
|
||||
if mem_per_process == "" then
|
||||
mem_per_process = 1024
|
||||
else
|
||||
mem_per_process = tonumber(mem_per_process)
|
||||
end
|
||||
local mem_total = 0
|
||||
for line in io.lines('/proc/meminfo') do
|
||||
if line:sub(1, 9) == "MemTotal:" then
|
||||
local tokens = {}
|
||||
for token in line:gmatch("%w+") do
|
||||
tokens[#tokens + 1] = token
|
||||
end
|
||||
mem_total = tonumber(tokens[2])
|
||||
break
|
||||
end
|
||||
end
|
||||
local max_jobs = mem_total // (mem_per_process * 1024)
|
||||
if max_jobs < 1 then
|
||||
max_jobs = 1
|
||||
end
|
||||
cur_max_jobs=tonumber(rpm.expand("%{_smp_build_ncpus}"))
|
||||
if cur_max_jobs > max_jobs then
|
||||
print("-j" .. max_jobs)
|
||||
end
|
||||
}
|
@ -1,9 +1,109 @@
|
||||
# epel macros
|
||||
|
||||
%epel 9
|
||||
%epel 8
|
||||
|
||||
# Mono macros requested in rhbz 1295117
|
||||
%mono_arches %{ix86} x86_64 sparc sparcv9 ia64 %{arm} alpha s390x ppc ppc64 ppc64le
|
||||
%_monodir %{_prefix}/lib/mono
|
||||
%_monogacdir %{_monodir}/gac
|
||||
|
||||
# Bash completions; not in bash to not intefere with install ordering
|
||||
%bash_completion_dir /usr/share/bash-completion/completions/
|
||||
#
|
||||
# NOTE: This macro is deprecated; point to the preferred macro from
|
||||
# macros.shell-completions
|
||||
%bash_completion_dir %{bash_completions_dir}
|
||||
|
||||
# Use the non-underscored Python macros to refer to Python in spec, etc.
|
||||
%python2 %__python2
|
||||
|
||||
# Users can use %%python only if they redefined %%__python (e.g. to %%__python3)
|
||||
%python() %{lua:\
|
||||
__python = rpm.expand("%__python")\
|
||||
if __python == "/usr/bin/python" then\
|
||||
rpm.expand("%{error:Cannot use %%python if %%__python wasn't redefined to something other than /usr/bin/python.}")\
|
||||
else\
|
||||
print(__python)\
|
||||
end\
|
||||
}
|
||||
|
||||
# With $PATH and $PYTHONPATH set to the %%buildroot,
|
||||
# try to import the given Python module(s).
|
||||
# Useful as a smoke test in %%check when running tests is not feasible.
|
||||
# Use spaces or commas as separators.
|
||||
%py_check_import(e:tf:) %{expand:\\\
|
||||
%{-e:echo 'WARNING: The -e option of %%%%py_check_import is not currently supported on EPEL.' >&2}
|
||||
%{-t:echo 'WARNING: The -t option of %%%%py_check_import is not currently supported on EPEL.' >&2}
|
||||
%{-f:echo 'WARNING: The -f option of %%%%py_check_import is not currently supported on EPEL.' >&2}
|
||||
(cd %{_topdir} &&\\\
|
||||
PATH="%{buildroot}%{_bindir}:$PATH"\\\
|
||||
PYTHONPATH="${PYTHONPATH:-%{buildroot}%{python_sitearch}:%{buildroot}%{python_sitelib}}"\\\
|
||||
PYTHONDONTWRITEBYTECODE=1\\\
|
||||
%{__python} -c "import %{lua:local m=rpm.expand('%{?*}'):gsub('[%s,]+', ', ');print(m)}"
|
||||
)
|
||||
}
|
||||
%py2_check_import(e:tf:) %{expand:\\\
|
||||
%{-e:echo 'WARNING: The -e option of %%%%py2_check_import is not currently supported on EPEL.' >&2}
|
||||
%{-t:echo 'WARNING: The -t option of %%%%py2_check_import is not currently supported on EPEL.' >&2}
|
||||
%{-f:echo 'WARNING: The -f option of %%%%py2_check_import is not currently supported on EPEL.' >&2}
|
||||
(cd %{_topdir} &&\\\
|
||||
PATH="%{buildroot}%{_bindir}:$PATH"\\\
|
||||
PYTHONPATH="${PYTHONPATH:-%{buildroot}%{python2_sitearch}:%{buildroot}%{python2_sitelib}}"\\\
|
||||
PYTHONDONTWRITEBYTECODE=1\\\
|
||||
%{__python2} -c "import %{lua:local m=rpm.expand('%{?*}'):gsub('[%s,]+', ', ');print(m)}"
|
||||
)
|
||||
}
|
||||
# With $PATH and $PYTHONPATH set to the %%buildroot,
|
||||
# try to import the Python 3 module(s) given as command-line args or read from file (-f).
|
||||
# Respect the custom values of %%py3_shebang_flags or set nothing if it's undefined.
|
||||
# Filter and check import on only top-level modules using -t flag.
|
||||
# Exclude unwanted modules by passing their globs to -e option.
|
||||
# Useful as a smoke test in %%check when running tests is not feasible.
|
||||
# Use spaces or commas as separators if providing list directly.
|
||||
# Use newlines as separators if providing list in a file.
|
||||
%py3_check_import(e:tf:) %{expand:\\\
|
||||
PATH="%{buildroot}%{_bindir}:$PATH"\\\
|
||||
PYTHONPATH="${PYTHONPATH:-%{buildroot}%{python3_sitearch}:%{buildroot}%{python3_sitelib}}"\\\
|
||||
_PYTHONSITE="%{buildroot}%{python3_sitearch}:%{buildroot}%{python3_sitelib}"\\\
|
||||
PYTHONDONTWRITEBYTECODE=1\\\
|
||||
%{lua:
|
||||
local command = "%{__python3} "
|
||||
if rpm.expand("%{?py3_shebang_flags}") ~= "" then
|
||||
command = command .. "-%{py3_shebang_flags}"
|
||||
end
|
||||
command = command .. " %{_rpmconfigdir}/redhat/import_all_modules.py "
|
||||
-- handle multiline arguments correctly, see https://bugzilla.redhat.com/2018809
|
||||
local args=rpm.expand('%{?**}'):gsub("[%s\\\\]*%s+", " ")
|
||||
print(command .. args)
|
||||
}
|
||||
}
|
||||
|
||||
# When packagers go against the Packaging Guidelines and disable the runtime
|
||||
# dependency generator, we want it to fall back to only creating the python(abi)
|
||||
# Requires instead of none at all.
|
||||
#
|
||||
# This macro is EPEL 8 only, as the pythondist dependency generator
|
||||
# is already disabled by the default in RHEL.
|
||||
%python_disable_dependency_generator() \
|
||||
%undefine __pythondist_requires \
|
||||
%{nil}
|
||||
|
||||
# Define where Python wheels will be stored and the prefix of -wheel packages
|
||||
# - In Fedora we want wheel subpackages named e.g. `python-pip-wheel` that
|
||||
# install packages into `/usr/share/python-wheels`. Both names are not
|
||||
# versioned, because they're used by all Python 3 stacks.
|
||||
# - In RHEL we want wheel packages named e.g. `python3-pip-wheel` and
|
||||
# `python3.11-pip-wheel` that install packages into similarly versioned
|
||||
# locations. We want each Python stack in RHEL to have their own wheels,
|
||||
# because the main python3 wheels (which we can't upgrade) will likely be
|
||||
# quite old by the time we're adding new alternate Python stacks.
|
||||
# - In ELN we want to follow Fedora, because builds for ELN and Fedora rawhide
|
||||
# need to be interoperable.
|
||||
%python_wheel_pkg_prefix python%{?rhel:%{!?eln:%{python3_pkgversion}}}
|
||||
%python_wheel_dir %{_datadir}/%{python_wheel_pkg_prefix}-wheels
|
||||
|
||||
# qt5 macro removed from RHEL8 but needed to ensure qtwebengine, and
|
||||
# its dependencies build on supported arches.
|
||||
%qt5_qtwebengine_arches %{ix86} x86_64 %{arm} aarch64 mips mipsel mips64el
|
||||
|
||||
# Arches that OpenJDK and dependent packages run on
|
||||
%java_arches aarch64 ppc64le s390x x86_64
|
||||
|
@ -0,0 +1,16 @@
|
||||
%autorelease(e:s:pb:n) %{?-p:0.}%{lua:
|
||||
release_number = tonumber(rpm.expand("%{?_rpmautospec_release_number}%{!?_rpmautospec_release_number:1}"));
|
||||
base_release_number = tonumber(rpm.expand("%{?-b*}%{!?-b:1}"));
|
||||
print(release_number + base_release_number - 1);
|
||||
}%{?-e:.%{-e*}}%{?-s:.%{-s*}}%{!?-n:%{?dist}}
|
||||
%autochangelog %{lua:
|
||||
locale = os.setlocale(nil)
|
||||
os.setlocale("C.utf8")
|
||||
date = os.date("%a %b %d %Y")
|
||||
os.setlocale(locale)
|
||||
packager = rpm.expand("%{?packager}%{!?packager:John Doe <packager@example.com>}")
|
||||
evr = rpm.expand("%{?epoch:%{epoch}:}%{version}-%{release}")
|
||||
print("* " .. date .. " " .. packager .. " - " .. evr .. "\\n")
|
||||
print("- local build")
|
||||
}
|
||||
|
@ -0,0 +1,10 @@
|
||||
# RPM macros for packages creating system accounts
|
||||
#
|
||||
# Turn a sysusers.d file into macros specified by
|
||||
# https://docs.fedoraproject.org/en-US/packaging-guidelines/UsersAndGroups/#_dynamic_allocation
|
||||
|
||||
%sysusers_requires_compat Requires(pre): shadow-utils
|
||||
|
||||
%sysusers_create_compat() \
|
||||
%(%{_rpmconfigdir}/sysusers.generate-pre.sh %{?*}) \
|
||||
%{nil}
|
@ -1,3 +1,27 @@
|
||||
# This file is used _only_ to override macros which exist in RHEL.
|
||||
# It should be used very sparingly.
|
||||
|
||||
# Override %__python3 here based on %%python3_pkgversion to avoid relying on the finicky
|
||||
# python3X-rpm-macros packages.
|
||||
# Backported from https://src.fedoraproject.org/rpms/python-rpm-macros/c/a8b26546eb699afe0dbfcef913a2aa7085fc5afb?branch=rawhide
|
||||
#
|
||||
# EPEL specific, RHEL defines this in the python3X-rpm-macros packages
|
||||
# and the default is /usr/libexec/platform-python.
|
||||
# Usually, we don't want EPEL packages to use platform-python.
|
||||
# Packages that want to do that can explicitly override this.
|
||||
#
|
||||
# When %%python3_pkgveresion is set to 3 (i.e. the default), we override
|
||||
# %%__python3 to /usr/bin/python3.6 to ensure that programs are always run with
|
||||
# python3.6, even if /usr/bin/python3 is a symlink to a different interpreter.
|
||||
#
|
||||
# See https://lists.fedoraproject.org/archives/list/epel-devel@lists.fedoraproject.org/thread/RE3PG72B5AX7NTACPDSBGOWCMN7I3OQJ/
|
||||
|
||||
%__python3 %{lua:
|
||||
local bin = "/usr/bin/python"
|
||||
if rpm.expand("%python3_pkgversion") == "3" then
|
||||
bin = bin .. "3.6"
|
||||
else
|
||||
bin = bin .. rpm.expand("%{_python3_pkgversion_with_dot}")
|
||||
end
|
||||
print(bin)
|
||||
}
|
||||
|
@ -0,0 +1,2 @@
|
||||
%__pythondist_requires %{_rpmconfigdir}/pythondistdeps.py --requires
|
||||
%__pythondist_path ^/usr/lib(64)?/python[[:digit:]]\\.[[:digit:]]+/site-packages/[^/]+\\.(dist-info|egg-info|egg-link)$
|
@ -0,0 +1,2 @@
|
||||
%__sysusers_provides %{_rpmconfigdir}/sysusers.prov
|
||||
%__sysusers_path ^%{_sysusersdir}/.*\\.conf$
|
@ -0,0 +1,79 @@
|
||||
#!/bin/bash
|
||||
|
||||
# This script turns sysuser.d files into scriptlets mandated by Fedora
|
||||
# packaging guidelines. The general idea is to define users using the
|
||||
# declarative syntax but to turn this into traditional scriptlets.
|
||||
|
||||
user() {
|
||||
user="$1"
|
||||
uid="$2"
|
||||
desc="$3"
|
||||
group="$4"
|
||||
home="$5"
|
||||
shell="$6"
|
||||
|
||||
[ "$desc" = '-' ] && desc=
|
||||
{ [ "$home" = '-' ] || [ "$home" = '' ]; } && home=/
|
||||
{ [ "$shell" = '-' ] || [ "$shell" = '' ]; } && shell=/sbin/nologin
|
||||
|
||||
if [ "$uid" = '-' ] || [ "$uid" = '' ]; then
|
||||
cat <<EOF
|
||||
getent passwd '$user' >/dev/null || \\
|
||||
useradd -r -g '$group' -d '$home' -s '$shell' -c '$desc' '$user'
|
||||
EOF
|
||||
else
|
||||
cat <<EOF
|
||||
if ! getent passwd '$user' >/dev/null ; then
|
||||
if ! getent passwd '$uid' >/dev/null ; then
|
||||
useradd -r -u '$uid' -g '$group' -d '$home' -s /sbin/nologin -c '$desc' '$user'
|
||||
else
|
||||
useradd -r -g '$group' -d '$home' -s /sbin/nologin -c '$desc' '$user'
|
||||
fi
|
||||
fi
|
||||
|
||||
EOF
|
||||
fi
|
||||
}
|
||||
|
||||
group() {
|
||||
group="$1"
|
||||
gid="$2"
|
||||
if [ "$gid" = '-' ]; then
|
||||
cat <<-EOF
|
||||
getent group '$group' >/dev/null || groupadd -r '$group'
|
||||
EOF
|
||||
else
|
||||
cat <<-EOF
|
||||
getent group '$group' >/dev/null || groupadd -f -g '$gid' -r '$group'
|
||||
EOF
|
||||
fi
|
||||
}
|
||||
|
||||
parse() {
|
||||
while read -r line || [ -n "$line" ] ; do
|
||||
{ [ "${line:0:1}" = '#' ] || [ "${line:0:1}" = ';' ]; } && continue
|
||||
line="${line## *}"
|
||||
[ -z "$line" ] && continue
|
||||
eval "arr=( $line )"
|
||||
case "${arr[0]}" in
|
||||
('u')
|
||||
group "${arr[1]}" "${arr[2]}"
|
||||
user "${arr[1]}" "${arr[2]}" "${arr[3]}" "${arr[1]}" "${arr[4]}" "${arr[5]}"
|
||||
# TODO: user:group support
|
||||
;;
|
||||
('g')
|
||||
group "${arr[1]}" "${arr[2]}"
|
||||
;;
|
||||
('m')
|
||||
group "${arr[2]}" "-"
|
||||
user "${arr[1]}" "-" "" "${arr[2]}"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
for fn in "$@"; do
|
||||
[ -e "$fn" ] || continue
|
||||
echo "# generated from $(basename "$fn")"
|
||||
parse <"$fn"
|
||||
done
|
@ -0,0 +1,28 @@
|
||||
#!/bin/bash
|
||||
|
||||
parse() {
|
||||
while read line; do
|
||||
[ "${line:0:1}" = '#' -o "${line:0:1}" = ';' ] && continue
|
||||
line="${line## *}"
|
||||
[ -z "$line" ] && continue
|
||||
set -- $line
|
||||
case "$1" in
|
||||
('u')
|
||||
echo "user($2)"
|
||||
echo "group($2)"
|
||||
# TODO: user:group support
|
||||
;;
|
||||
('g')
|
||||
echo "group($2)"
|
||||
;;
|
||||
('m')
|
||||
echo "user($2)"
|
||||
echo "group($3)"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
while read fn; do
|
||||
parse < "$fn"
|
||||
done
|
Loading…
Reference in new issue