File 3.6.13.spec of Package gitolite

%global perl_vendorlib %(eval $(perl -V:vendorlib); echo $vendorlib)

%global gitolite_homedir /opt/git/%{name}
%global gitolite_user git

Name:           gitolite3
Epoch:          2
Version:        3.6.13
Release:        7%{?dist}
Summary:        Highly flexible server for git directory version tracker

License:        GPL-2.0-only AND CC-BY-SA-1.0
URL:            https://github.com/sitaramc/gitolite
Source0:        https://github.com/sitaramc/gitolite/archive/v%{version}.tar.gz
Source1:        gitolite3.README
# Upstream: https://github.com/sitaramc/gitolite/commit/c656af01b73a5cc4f80512
Source2:        compile-1

BuildArch:      noarch
BuildRequires:  perl-generators

Provides:       perl(%{name}) = %{version}-%{release}

Requires:       git
Requires:       openssh-clients
Requires:       perl-interpreter
Requires(pre):  shadow-utils
Recommends:     subversion

%description
Gitolite allows a server to host many git repositories and provide access
to many developers, without having to give them real userids on the server.
The essential magic in doing this is ssh's pubkey access and the authorized
keys file, and the inspiration was an older program called gitosis.

Gitolite can restrict who can read from (clone/fetch) or write to (push) a
repository. It can also restrict who can push to what branch or tag, which
is very important in a corporate environment. Gitolite can be installed
without requiring root permissions, and with no additional software than git
itself and perl. It also has several other neat features described below and
elsewhere in the doc/ directory.

%prep
%setup -qn gitolite-%{version}
cp %{SOURCE1} .

%build
# No build steps required.

%install
rm -rf %{buildroot}

# Directory structure
install -d %{buildroot}%{gitolite_homedir}/.ssh \
           %{buildroot}%{_bindir} \
           %{buildroot}%{perl_vendorlib} \
           %{buildroot}%{_datadir}/%{name} \
           %{buildroot}%{_sysconfdir}/profile.d

# Code and data
cp -pr src/lib/Gitolite %{buildroot}%{perl_vendorlib}
echo "%{version}-%{release}" > src/VERSION
cp -a src/* %{buildroot}%{_datadir}/%{name}
install -m 0755 %{SOURCE2} %{buildroot}%{_datadir}/%{name}/commands/

# Public command symlink
ln -s %{_datadir}/%{name}/gitolite %{buildroot}%{_bindir}/gitolite

# Empty authorized_keys file (managed by gitolite)
install -m 0600 /dev/null %{buildroot}%{gitolite_homedir}/.ssh/authorized_keys

# /etc/profile.d for Bourne/POSIX shells only
install -Dm0644 /dev/stdin %{buildroot}%{_sysconfdir}/profile.d/%{name}.sh <<'EOF'
# gitolite3 environment for interactive shells
: "${GL_USER:=git}"; export GL_USER

# Get archlib once using the exact pattern requested
archlib=""
if command -v perl >/dev/null 2>&1; then
  eval "$(perl -V:archlib 2>/dev/null)" || true
fi
# Fallback guesses if perl -V:archlib didn't yield a path
if [ -z "${archlib:-}" ]; then
  for d in /usr/lib64/perl5 /usr/lib/perl5; do
    [ -d "$d" ] && { archlib="$d"; break; }
  done
fi

# Prepend archlib to PERL5LIB if found and not already present
if [ -n "${archlib:-}" ]; then
  case ":${PERL5LIB:-}:" in
    *":$archlib:"*) : ;; # already present
    *) PERL5LIB="$archlib${PERL5LIB:+:$PERL5LIB}"; export PERL5LIB ;;
  esac
fi
EOF

%pre
# Create "gitolite3" service user/group per packaging guidelines.
getent group %{gitolite_user} >/dev/null || groupadd -r %{gitolite_user}
getent passwd %{gitolite_user} >/dev/null || \
  useradd -r -g %{gitolite_user} -d "%{gitolite_homedir}" -s /bin/sh \
          -c "git repo hosting" %{gitolite_user} || \
  chown %{gitolite_user}:%{gitolite_user} %{gitolite_homedir}/..
exit 0

%post

# Create .gitconfig for the gitolite user
if [ -d "%{gitolite_homedir}" ]; then
    cat > "%{gitolite_homedir}/.gitconfig" <<'EOF'
[init]
    defaultBranch = master
EOF

    # Set correct ownership and permissions
    chown %{gitolite_user}:%{gitolite_user} "%{gitolite_homedir}/.gitconfig"
fi
####

# --- fapolicyd integration (idempotent, optional) ---------------------------
# - Only proceed if fapolicyd is installed and configured.
if command -v fagenrules >/dev/null 2>&1 && [ -d /etc/fapolicyd ]; then
  _rules="/etc/fapolicyd/rules.d/70-%{name}.rules"
  _datadir="%{_datadir}/%{name}"

  install -d -m 0755 /etc/fapolicyd/rules.d
  # Write rules (idempotent)
  {
    echo "# %{name} fapolicyd allowances"
    [ -n "$_datadir" ] && echo "allow perm=open uid=%{gitolite_user} : dir=${_datadir}/"
    echo "allow perm=execute uid=%{gitolite_user} : all : path=%{_bindir}/gitolite"
    [ -n "$gitolite_homedir" ] && echo "allow perm=any uid=%{gitolite_user} : dir=${gitolite_homedir}/"
    echo "#Only for gitolite setup by %{name}"
    echo "allow perm=open uid=%{gitolite_user} : dir=/usr/share/git-core/templates/"
  } >"$_rules"

  fagenrules --load || :
  if command -v systemctl >/dev/null 2>&1; then
    systemctl try-reload-or-restart fapolicyd.service >/dev/null 2>&1 || :
  fi
fi

# Only do this on initial install or upgrade; guard for SELinux availability
if command -v selinuxenabled >/dev/null 2>&1 && selinuxenabled; then
    # Add (or modify if it already exists) the context rule for .ssh
    if command -v semanage >/dev/null 2>&1; then
        # Note: escape the dot in .ssh for the regex
        semanage fcontext -a -t ssh_home_t '%{gitolite_homedir}/\.ssh(/.*)?' 2>/dev/null || \
        semanage fcontext -m -t ssh_home_t '%{gitolite_homedir}/\.ssh(/.*)?' 2>/dev/null || :
    fi

    # Apply the labeling to existing files/dirs (no-op if path doesn't exist yet)
    if [ -d '%{gitolite_homedir}/.ssh' ]; then
        restorecon -Rv '%{gitolite_homedir}/.ssh' || :
    fi
fi

exit 0
%preun
# Remove fapolicyd rule on final erase (not on upgrade)
if [ "${1:-0}" -eq 0 ]; then
  if [ -f /etc/fapolicyd/rules.d/70-%{name}.rules ]; then
    rm -f /etc/fapolicyd/rules.d/70-%{name}.rules || :
    command -v fagenrules >/dev/null 2>&1 && fagenrules --load || :
    if command -v systemctl >/dev/null 2>&1; then
      systemctl try-reload-or-restart fapolicyd.service >/dev/null 2>&1 || :
    fi
  fi
fi

# Only on erase, not upgrade
if [ $1 -eq 0 ]; then
    if command -v selinuxenabled >/dev/null 2>&1 && selinuxenabled; then
        if command -v semanage >/dev/null 2>&1; then
            semanage fcontext -d -t ssh_home_t '%{gitolite_homedir}/\.ssh(/.*)?' 2>/dev/null || :
        fi
        # Attempt to relabel back to default contexts if the path still exists
        if [ -d '%{gitolite_homedir}/.ssh' ]; then
            restorecon -Rv '%{gitolite_homedir}/.ssh' || :
        fi
    fi
fi

exit 0

%files
%{_bindir}/gitolite
%dir %{perl_vendorlib}/Gitolite
%{perl_vendorlib}/Gitolite/*
%{_datadir}/%{name}
%doc gitolite3.README README.markdown CHANGELOG
%license COPYING
# Profile script (root:root, 0644). Do NOT make it owned by %{name}.
%config(noreplace) %{_sysconfdir}/profile.d/%{name}.sh
# Gitolite homedir (owned by service user)
%attr(750,%{gitolite_user},%{gitolite_user}) %dir %{gitolite_homedir}
%attr(750,%{gitolite_user},%{gitolite_user}) %dir %{gitolite_homedir}/.ssh
%config(noreplace) %attr(600,%{gitolite_user},%{gitolite_user}) %{gitolite_homedir}/.ssh/authorized_keys

%changelog
* Tue Aug 19 2025 Ganapathi Chidambaram <you@example.com> - 2:%{version}-%{release}
- Use runtime wrapper for persistent GL_USER and PERL5LIB.
- Add /etc/profile.d/gitolite3.sh for global shell sessions.
openSUSE Build Service is sponsored by