162306a36Sopenharmony_ci#!/usr/bin/env perl 262306a36Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0-or-later 362306a36Sopenharmony_ciuse strict; 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci# Copyright (c) 2017-2020 Mauro Carvalho Chehab <mchehab@kernel.org> 662306a36Sopenharmony_ci# 762306a36Sopenharmony_ci 862306a36Sopenharmony_cimy $prefix = "./"; 962306a36Sopenharmony_ci$prefix = "$ENV{'srctree'}/" if ($ENV{'srctree'}); 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_cimy $conf = $prefix . "Documentation/conf.py"; 1262306a36Sopenharmony_cimy $requirement_file = $prefix . "Documentation/sphinx/requirements.txt"; 1362306a36Sopenharmony_cimy $virtenv_prefix = "sphinx_"; 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci# 1662306a36Sopenharmony_ci# Static vars 1762306a36Sopenharmony_ci# 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_cimy %missing; 2062306a36Sopenharmony_cimy $system_release; 2162306a36Sopenharmony_cimy $need = 0; 2262306a36Sopenharmony_cimy $optional = 0; 2362306a36Sopenharmony_cimy $need_symlink = 0; 2462306a36Sopenharmony_cimy $need_sphinx = 0; 2562306a36Sopenharmony_cimy $need_pip = 0; 2662306a36Sopenharmony_cimy $need_virtualenv = 0; 2762306a36Sopenharmony_cimy $rec_sphinx_upgrade = 0; 2862306a36Sopenharmony_cimy $verbose_warn_install = 1; 2962306a36Sopenharmony_cimy $install = ""; 3062306a36Sopenharmony_cimy $virtenv_dir = ""; 3162306a36Sopenharmony_cimy $python_cmd = ""; 3262306a36Sopenharmony_cimy $activate_cmd; 3362306a36Sopenharmony_cimy $min_version; 3462306a36Sopenharmony_cimy $cur_version; 3562306a36Sopenharmony_cimy $rec_version = "1.7.9"; # PDF won't build here 3662306a36Sopenharmony_cimy $min_pdf_version = "2.4.4"; # Min version where pdf builds 3762306a36Sopenharmony_cimy $latest_avail_ver; 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci# 4062306a36Sopenharmony_ci# Command line arguments 4162306a36Sopenharmony_ci# 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_cimy $pdf = 1; 4462306a36Sopenharmony_cimy $virtualenv = 1; 4562306a36Sopenharmony_cimy $version_check = 0; 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci# 4862306a36Sopenharmony_ci# List of required texlive packages on Fedora and OpenSuse 4962306a36Sopenharmony_ci# 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_cimy %texlive = ( 5262306a36Sopenharmony_ci 'amsfonts.sty' => 'texlive-amsfonts', 5362306a36Sopenharmony_ci 'amsmath.sty' => 'texlive-amsmath', 5462306a36Sopenharmony_ci 'amssymb.sty' => 'texlive-amsfonts', 5562306a36Sopenharmony_ci 'amsthm.sty' => 'texlive-amscls', 5662306a36Sopenharmony_ci 'anyfontsize.sty' => 'texlive-anyfontsize', 5762306a36Sopenharmony_ci 'atbegshi.sty' => 'texlive-oberdiek', 5862306a36Sopenharmony_ci 'bm.sty' => 'texlive-tools', 5962306a36Sopenharmony_ci 'capt-of.sty' => 'texlive-capt-of', 6062306a36Sopenharmony_ci 'cmap.sty' => 'texlive-cmap', 6162306a36Sopenharmony_ci 'ecrm1000.tfm' => 'texlive-ec', 6262306a36Sopenharmony_ci 'eqparbox.sty' => 'texlive-eqparbox', 6362306a36Sopenharmony_ci 'eu1enc.def' => 'texlive-euenc', 6462306a36Sopenharmony_ci 'fancybox.sty' => 'texlive-fancybox', 6562306a36Sopenharmony_ci 'fancyvrb.sty' => 'texlive-fancyvrb', 6662306a36Sopenharmony_ci 'float.sty' => 'texlive-float', 6762306a36Sopenharmony_ci 'fncychap.sty' => 'texlive-fncychap', 6862306a36Sopenharmony_ci 'footnote.sty' => 'texlive-mdwtools', 6962306a36Sopenharmony_ci 'framed.sty' => 'texlive-framed', 7062306a36Sopenharmony_ci 'luatex85.sty' => 'texlive-luatex85', 7162306a36Sopenharmony_ci 'multirow.sty' => 'texlive-multirow', 7262306a36Sopenharmony_ci 'needspace.sty' => 'texlive-needspace', 7362306a36Sopenharmony_ci 'palatino.sty' => 'texlive-psnfss', 7462306a36Sopenharmony_ci 'parskip.sty' => 'texlive-parskip', 7562306a36Sopenharmony_ci 'polyglossia.sty' => 'texlive-polyglossia', 7662306a36Sopenharmony_ci 'tabulary.sty' => 'texlive-tabulary', 7762306a36Sopenharmony_ci 'threeparttable.sty' => 'texlive-threeparttable', 7862306a36Sopenharmony_ci 'titlesec.sty' => 'texlive-titlesec', 7962306a36Sopenharmony_ci 'ucs.sty' => 'texlive-ucs', 8062306a36Sopenharmony_ci 'upquote.sty' => 'texlive-upquote', 8162306a36Sopenharmony_ci 'wrapfig.sty' => 'texlive-wrapfig', 8262306a36Sopenharmony_ci 'ctexhook.sty' => 'texlive-ctex', 8362306a36Sopenharmony_ci); 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci# 8662306a36Sopenharmony_ci# Subroutines that checks if a feature exists 8762306a36Sopenharmony_ci# 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_cisub check_missing(%) 9062306a36Sopenharmony_ci{ 9162306a36Sopenharmony_ci my %map = %{$_[0]}; 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ci foreach my $prog (sort keys %missing) { 9462306a36Sopenharmony_ci my $is_optional = $missing{$prog}; 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci # At least on some LTS distros like CentOS 7, texlive doesn't 9762306a36Sopenharmony_ci # provide all packages we need. When such distros are 9862306a36Sopenharmony_ci # detected, we have to disable PDF output. 9962306a36Sopenharmony_ci # 10062306a36Sopenharmony_ci # So, we need to ignore the packages that distros would 10162306a36Sopenharmony_ci # need for LaTeX to work 10262306a36Sopenharmony_ci if ($is_optional == 2 && !$pdf) { 10362306a36Sopenharmony_ci $optional--; 10462306a36Sopenharmony_ci next; 10562306a36Sopenharmony_ci } 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci if ($verbose_warn_install) { 10862306a36Sopenharmony_ci if ($is_optional) { 10962306a36Sopenharmony_ci print "Warning: better to also install \"$prog\".\n"; 11062306a36Sopenharmony_ci } else { 11162306a36Sopenharmony_ci print "ERROR: please install \"$prog\", otherwise, build won't work.\n"; 11262306a36Sopenharmony_ci } 11362306a36Sopenharmony_ci } 11462306a36Sopenharmony_ci if (defined($map{$prog})) { 11562306a36Sopenharmony_ci $install .= " " . $map{$prog}; 11662306a36Sopenharmony_ci } else { 11762306a36Sopenharmony_ci $install .= " " . $prog; 11862306a36Sopenharmony_ci } 11962306a36Sopenharmony_ci } 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci $install =~ s/^\s//; 12262306a36Sopenharmony_ci} 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_cisub add_package($$) 12562306a36Sopenharmony_ci{ 12662306a36Sopenharmony_ci my $package = shift; 12762306a36Sopenharmony_ci my $is_optional = shift; 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_ci $missing{$package} = $is_optional; 13062306a36Sopenharmony_ci if ($is_optional) { 13162306a36Sopenharmony_ci $optional++; 13262306a36Sopenharmony_ci } else { 13362306a36Sopenharmony_ci $need++; 13462306a36Sopenharmony_ci } 13562306a36Sopenharmony_ci} 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_cisub check_missing_file($$$) 13862306a36Sopenharmony_ci{ 13962306a36Sopenharmony_ci my $files = shift; 14062306a36Sopenharmony_ci my $package = shift; 14162306a36Sopenharmony_ci my $is_optional = shift; 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci for (@$files) { 14462306a36Sopenharmony_ci return if(-e $_); 14562306a36Sopenharmony_ci } 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ci add_package($package, $is_optional); 14862306a36Sopenharmony_ci} 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_cisub findprog($) 15162306a36Sopenharmony_ci{ 15262306a36Sopenharmony_ci foreach(split(/:/, $ENV{PATH})) { 15362306a36Sopenharmony_ci return "$_/$_[0]" if(-x "$_/$_[0]"); 15462306a36Sopenharmony_ci } 15562306a36Sopenharmony_ci} 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_cisub find_python_no_venv() 15862306a36Sopenharmony_ci{ 15962306a36Sopenharmony_ci my $prog = shift; 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_ci my $cur_dir = qx(pwd); 16262306a36Sopenharmony_ci $cur_dir =~ s/\s+$//; 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_ci foreach my $dir (split(/:/, $ENV{PATH})) { 16562306a36Sopenharmony_ci next if ($dir =~ m,($cur_dir)/sphinx,); 16662306a36Sopenharmony_ci return "$dir/python3" if(-x "$dir/python3"); 16762306a36Sopenharmony_ci } 16862306a36Sopenharmony_ci foreach my $dir (split(/:/, $ENV{PATH})) { 16962306a36Sopenharmony_ci next if ($dir =~ m,($cur_dir)/sphinx,); 17062306a36Sopenharmony_ci return "$dir/python" if(-x "$dir/python"); 17162306a36Sopenharmony_ci } 17262306a36Sopenharmony_ci return "python"; 17362306a36Sopenharmony_ci} 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_cisub check_program($$) 17662306a36Sopenharmony_ci{ 17762306a36Sopenharmony_ci my $prog = shift; 17862306a36Sopenharmony_ci my $is_optional = shift; 17962306a36Sopenharmony_ci 18062306a36Sopenharmony_ci return $prog if findprog($prog); 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_ci add_package($prog, $is_optional); 18362306a36Sopenharmony_ci} 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_cisub check_perl_module($$) 18662306a36Sopenharmony_ci{ 18762306a36Sopenharmony_ci my $prog = shift; 18862306a36Sopenharmony_ci my $is_optional = shift; 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci my $err = system("perl -M$prog -e 1 2>/dev/null /dev/null"); 19162306a36Sopenharmony_ci return if ($err == 0); 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ci add_package($prog, $is_optional); 19462306a36Sopenharmony_ci} 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_cisub check_python_module($$) 19762306a36Sopenharmony_ci{ 19862306a36Sopenharmony_ci my $prog = shift; 19962306a36Sopenharmony_ci my $is_optional = shift; 20062306a36Sopenharmony_ci 20162306a36Sopenharmony_ci return if (!$python_cmd); 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ci my $err = system("$python_cmd -c 'import $prog' 2>/dev/null /dev/null"); 20462306a36Sopenharmony_ci return if ($err == 0); 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_ci add_package($prog, $is_optional); 20762306a36Sopenharmony_ci} 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_cisub check_rpm_missing($$) 21062306a36Sopenharmony_ci{ 21162306a36Sopenharmony_ci my @pkgs = @{$_[0]}; 21262306a36Sopenharmony_ci my $is_optional = $_[1]; 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci foreach my $prog(@pkgs) { 21562306a36Sopenharmony_ci my $err = system("rpm -q '$prog' 2>/dev/null >/dev/null"); 21662306a36Sopenharmony_ci add_package($prog, $is_optional) if ($err); 21762306a36Sopenharmony_ci } 21862306a36Sopenharmony_ci} 21962306a36Sopenharmony_ci 22062306a36Sopenharmony_cisub check_pacman_missing($$) 22162306a36Sopenharmony_ci{ 22262306a36Sopenharmony_ci my @pkgs = @{$_[0]}; 22362306a36Sopenharmony_ci my $is_optional = $_[1]; 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_ci foreach my $prog(@pkgs) { 22662306a36Sopenharmony_ci my $err = system("pacman -Q '$prog' 2>/dev/null >/dev/null"); 22762306a36Sopenharmony_ci add_package($prog, $is_optional) if ($err); 22862306a36Sopenharmony_ci } 22962306a36Sopenharmony_ci} 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_cisub check_missing_tex($) 23262306a36Sopenharmony_ci{ 23362306a36Sopenharmony_ci my $is_optional = shift; 23462306a36Sopenharmony_ci my $kpsewhich = findprog("kpsewhich"); 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_ci foreach my $prog(keys %texlive) { 23762306a36Sopenharmony_ci my $package = $texlive{$prog}; 23862306a36Sopenharmony_ci if (!$kpsewhich) { 23962306a36Sopenharmony_ci add_package($package, $is_optional); 24062306a36Sopenharmony_ci next; 24162306a36Sopenharmony_ci } 24262306a36Sopenharmony_ci my $file = qx($kpsewhich $prog); 24362306a36Sopenharmony_ci add_package($package, $is_optional) if ($file =~ /^\s*$/); 24462306a36Sopenharmony_ci } 24562306a36Sopenharmony_ci} 24662306a36Sopenharmony_ci 24762306a36Sopenharmony_cisub get_sphinx_fname() 24862306a36Sopenharmony_ci{ 24962306a36Sopenharmony_ci my $fname = "sphinx-build"; 25062306a36Sopenharmony_ci return $fname if findprog($fname); 25162306a36Sopenharmony_ci 25262306a36Sopenharmony_ci $fname = "sphinx-build-3"; 25362306a36Sopenharmony_ci if (findprog($fname)) { 25462306a36Sopenharmony_ci $need_symlink = 1; 25562306a36Sopenharmony_ci return $fname; 25662306a36Sopenharmony_ci } 25762306a36Sopenharmony_ci 25862306a36Sopenharmony_ci return ""; 25962306a36Sopenharmony_ci} 26062306a36Sopenharmony_ci 26162306a36Sopenharmony_cisub get_sphinx_version($) 26262306a36Sopenharmony_ci{ 26362306a36Sopenharmony_ci my $cmd = shift; 26462306a36Sopenharmony_ci my $ver; 26562306a36Sopenharmony_ci 26662306a36Sopenharmony_ci open IN, "$cmd --version 2>&1 |"; 26762306a36Sopenharmony_ci while (<IN>) { 26862306a36Sopenharmony_ci if (m/^\s*sphinx-build\s+([\d\.]+)((\+\/[\da-f]+)|(b\d+))?$/) { 26962306a36Sopenharmony_ci $ver=$1; 27062306a36Sopenharmony_ci last; 27162306a36Sopenharmony_ci } 27262306a36Sopenharmony_ci # Sphinx 1.2.x uses a different format 27362306a36Sopenharmony_ci if (m/^\s*Sphinx.*\s+([\d\.]+)$/) { 27462306a36Sopenharmony_ci $ver=$1; 27562306a36Sopenharmony_ci last; 27662306a36Sopenharmony_ci } 27762306a36Sopenharmony_ci } 27862306a36Sopenharmony_ci close IN; 27962306a36Sopenharmony_ci return $ver; 28062306a36Sopenharmony_ci} 28162306a36Sopenharmony_ci 28262306a36Sopenharmony_cisub check_sphinx() 28362306a36Sopenharmony_ci{ 28462306a36Sopenharmony_ci my $default_version; 28562306a36Sopenharmony_ci 28662306a36Sopenharmony_ci open IN, $conf or die "Can't open $conf"; 28762306a36Sopenharmony_ci while (<IN>) { 28862306a36Sopenharmony_ci if (m/^\s*needs_sphinx\s*=\s*[\'\"]([\d\.]+)[\'\"]/) { 28962306a36Sopenharmony_ci $min_version=$1; 29062306a36Sopenharmony_ci last; 29162306a36Sopenharmony_ci } 29262306a36Sopenharmony_ci } 29362306a36Sopenharmony_ci close IN; 29462306a36Sopenharmony_ci 29562306a36Sopenharmony_ci die "Can't get needs_sphinx version from $conf" if (!$min_version); 29662306a36Sopenharmony_ci 29762306a36Sopenharmony_ci open IN, $requirement_file or die "Can't open $requirement_file"; 29862306a36Sopenharmony_ci while (<IN>) { 29962306a36Sopenharmony_ci if (m/^\s*Sphinx\s*==\s*([\d\.]+)$/) { 30062306a36Sopenharmony_ci $default_version=$1; 30162306a36Sopenharmony_ci last; 30262306a36Sopenharmony_ci } 30362306a36Sopenharmony_ci } 30462306a36Sopenharmony_ci close IN; 30562306a36Sopenharmony_ci 30662306a36Sopenharmony_ci die "Can't get default sphinx version from $requirement_file" if (!$default_version); 30762306a36Sopenharmony_ci 30862306a36Sopenharmony_ci $virtenv_dir = $virtenv_prefix . $default_version; 30962306a36Sopenharmony_ci 31062306a36Sopenharmony_ci my $sphinx = get_sphinx_fname(); 31162306a36Sopenharmony_ci if ($sphinx eq "") { 31262306a36Sopenharmony_ci $need_sphinx = 1; 31362306a36Sopenharmony_ci return; 31462306a36Sopenharmony_ci } 31562306a36Sopenharmony_ci 31662306a36Sopenharmony_ci $cur_version = get_sphinx_version($sphinx); 31762306a36Sopenharmony_ci die ("$sphinx returned an error") if (!$cur_version); 31862306a36Sopenharmony_ci 31962306a36Sopenharmony_ci die "$sphinx didn't return its version" if (!$cur_version); 32062306a36Sopenharmony_ci 32162306a36Sopenharmony_ci if ($cur_version lt $min_version) { 32262306a36Sopenharmony_ci printf "ERROR: Sphinx version is %s. It should be >= %s (recommended >= %s)\n", 32362306a36Sopenharmony_ci $cur_version, $min_version, $default_version; 32462306a36Sopenharmony_ci $need_sphinx = 1; 32562306a36Sopenharmony_ci return; 32662306a36Sopenharmony_ci } 32762306a36Sopenharmony_ci 32862306a36Sopenharmony_ci return if ($cur_version lt $rec_version); 32962306a36Sopenharmony_ci 33062306a36Sopenharmony_ci # On version check mode, just assume Sphinx has all mandatory deps 33162306a36Sopenharmony_ci exit (0) if ($version_check); 33262306a36Sopenharmony_ci} 33362306a36Sopenharmony_ci 33462306a36Sopenharmony_ci# 33562306a36Sopenharmony_ci# Ancillary subroutines 33662306a36Sopenharmony_ci# 33762306a36Sopenharmony_ci 33862306a36Sopenharmony_cisub catcheck($) 33962306a36Sopenharmony_ci{ 34062306a36Sopenharmony_ci my $res = ""; 34162306a36Sopenharmony_ci $res = qx(cat $_[0]) if (-r $_[0]); 34262306a36Sopenharmony_ci return $res; 34362306a36Sopenharmony_ci} 34462306a36Sopenharmony_ci 34562306a36Sopenharmony_cisub which($) 34662306a36Sopenharmony_ci{ 34762306a36Sopenharmony_ci my $file = shift; 34862306a36Sopenharmony_ci my @path = split ":", $ENV{PATH}; 34962306a36Sopenharmony_ci 35062306a36Sopenharmony_ci foreach my $dir(@path) { 35162306a36Sopenharmony_ci my $name = $dir.'/'.$file; 35262306a36Sopenharmony_ci return $name if (-x $name ); 35362306a36Sopenharmony_ci } 35462306a36Sopenharmony_ci return undef; 35562306a36Sopenharmony_ci} 35662306a36Sopenharmony_ci 35762306a36Sopenharmony_ci# 35862306a36Sopenharmony_ci# Subroutines that check distro-specific hints 35962306a36Sopenharmony_ci# 36062306a36Sopenharmony_ci 36162306a36Sopenharmony_cisub give_debian_hints() 36262306a36Sopenharmony_ci{ 36362306a36Sopenharmony_ci my %map = ( 36462306a36Sopenharmony_ci "python-sphinx" => "python3-sphinx", 36562306a36Sopenharmony_ci "ensurepip" => "python3-venv", 36662306a36Sopenharmony_ci "virtualenv" => "virtualenv", 36762306a36Sopenharmony_ci "dot" => "graphviz", 36862306a36Sopenharmony_ci "convert" => "imagemagick", 36962306a36Sopenharmony_ci "Pod::Usage" => "perl-modules", 37062306a36Sopenharmony_ci "xelatex" => "texlive-xetex", 37162306a36Sopenharmony_ci "rsvg-convert" => "librsvg2-bin", 37262306a36Sopenharmony_ci ); 37362306a36Sopenharmony_ci 37462306a36Sopenharmony_ci if ($pdf) { 37562306a36Sopenharmony_ci check_missing_file(["/usr/share/texlive/texmf-dist/tex/latex/ctex/ctexhook.sty"], 37662306a36Sopenharmony_ci "texlive-lang-chinese", 2); 37762306a36Sopenharmony_ci 37862306a36Sopenharmony_ci check_missing_file(["/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf"], 37962306a36Sopenharmony_ci "fonts-dejavu", 2); 38062306a36Sopenharmony_ci 38162306a36Sopenharmony_ci check_missing_file(["/usr/share/fonts/noto-cjk/NotoSansCJK-Regular.ttc", 38262306a36Sopenharmony_ci "/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc", 38362306a36Sopenharmony_ci "/usr/share/fonts/opentype/noto/NotoSerifCJK-Regular.ttc"], 38462306a36Sopenharmony_ci "fonts-noto-cjk", 2); 38562306a36Sopenharmony_ci } 38662306a36Sopenharmony_ci 38762306a36Sopenharmony_ci check_program("dvipng", 2) if ($pdf); 38862306a36Sopenharmony_ci check_missing(\%map); 38962306a36Sopenharmony_ci 39062306a36Sopenharmony_ci return if (!$need && !$optional); 39162306a36Sopenharmony_ci printf("You should run:\n") if ($verbose_warn_install); 39262306a36Sopenharmony_ci printf("\n\tsudo apt-get install $install\n"); 39362306a36Sopenharmony_ci} 39462306a36Sopenharmony_ci 39562306a36Sopenharmony_cisub give_redhat_hints() 39662306a36Sopenharmony_ci{ 39762306a36Sopenharmony_ci my %map = ( 39862306a36Sopenharmony_ci "python-sphinx" => "python3-sphinx", 39962306a36Sopenharmony_ci "virtualenv" => "python3-virtualenv", 40062306a36Sopenharmony_ci "dot" => "graphviz", 40162306a36Sopenharmony_ci "convert" => "ImageMagick", 40262306a36Sopenharmony_ci "Pod::Usage" => "perl-Pod-Usage", 40362306a36Sopenharmony_ci "xelatex" => "texlive-xetex-bin", 40462306a36Sopenharmony_ci "rsvg-convert" => "librsvg2-tools", 40562306a36Sopenharmony_ci ); 40662306a36Sopenharmony_ci 40762306a36Sopenharmony_ci my @fedora26_opt_pkgs = ( 40862306a36Sopenharmony_ci "graphviz-gd", # Fedora 26: needed for PDF support 40962306a36Sopenharmony_ci ); 41062306a36Sopenharmony_ci 41162306a36Sopenharmony_ci my @fedora_tex_pkgs = ( 41262306a36Sopenharmony_ci "texlive-collection-fontsrecommended", 41362306a36Sopenharmony_ci "texlive-collection-latex", 41462306a36Sopenharmony_ci "texlive-xecjk", 41562306a36Sopenharmony_ci "dejavu-sans-fonts", 41662306a36Sopenharmony_ci "dejavu-serif-fonts", 41762306a36Sopenharmony_ci "dejavu-sans-mono-fonts", 41862306a36Sopenharmony_ci ); 41962306a36Sopenharmony_ci 42062306a36Sopenharmony_ci # 42162306a36Sopenharmony_ci # Checks valid for RHEL/CentOS version 7.x. 42262306a36Sopenharmony_ci # 42362306a36Sopenharmony_ci my $old = 0; 42462306a36Sopenharmony_ci my $rel; 42562306a36Sopenharmony_ci $rel = $1 if ($system_release =~ /release\s+(\d+)/); 42662306a36Sopenharmony_ci 42762306a36Sopenharmony_ci if (!($system_release =~ /Fedora/)) { 42862306a36Sopenharmony_ci $map{"virtualenv"} = "python-virtualenv"; 42962306a36Sopenharmony_ci 43062306a36Sopenharmony_ci if ($rel && $rel < 8) { 43162306a36Sopenharmony_ci $old = 1; 43262306a36Sopenharmony_ci $pdf = 0; 43362306a36Sopenharmony_ci 43462306a36Sopenharmony_ci printf("Note: texlive packages on RHEL/CENTOS <= 7 are incomplete. Can't support PDF output\n"); 43562306a36Sopenharmony_ci printf("If you want to build PDF, please read:\n"); 43662306a36Sopenharmony_ci printf("\thttps://www.systutorials.com/241660/how-to-install-tex-live-on-centos-7-linux/\n"); 43762306a36Sopenharmony_ci } 43862306a36Sopenharmony_ci } else { 43962306a36Sopenharmony_ci if ($rel && $rel < 26) { 44062306a36Sopenharmony_ci $old = 1; 44162306a36Sopenharmony_ci } 44262306a36Sopenharmony_ci } 44362306a36Sopenharmony_ci if (!$rel) { 44462306a36Sopenharmony_ci printf("Couldn't identify release number\n"); 44562306a36Sopenharmony_ci $old = 1; 44662306a36Sopenharmony_ci $pdf = 0; 44762306a36Sopenharmony_ci } 44862306a36Sopenharmony_ci 44962306a36Sopenharmony_ci if ($pdf) { 45062306a36Sopenharmony_ci check_missing_file(["/usr/share/fonts/google-noto-cjk/NotoSansCJK-Regular.ttc"], 45162306a36Sopenharmony_ci "google-noto-sans-cjk-ttc-fonts", 2); 45262306a36Sopenharmony_ci } 45362306a36Sopenharmony_ci 45462306a36Sopenharmony_ci check_rpm_missing(\@fedora26_opt_pkgs, 2) if ($pdf && !$old); 45562306a36Sopenharmony_ci check_rpm_missing(\@fedora_tex_pkgs, 2) if ($pdf); 45662306a36Sopenharmony_ci check_missing_tex(2) if ($pdf); 45762306a36Sopenharmony_ci check_missing(\%map); 45862306a36Sopenharmony_ci 45962306a36Sopenharmony_ci return if (!$need && !$optional); 46062306a36Sopenharmony_ci 46162306a36Sopenharmony_ci if (!$old) { 46262306a36Sopenharmony_ci # dnf, for Fedora 18+ 46362306a36Sopenharmony_ci printf("You should run:\n") if ($verbose_warn_install); 46462306a36Sopenharmony_ci printf("\n\tsudo dnf install -y $install\n"); 46562306a36Sopenharmony_ci } else { 46662306a36Sopenharmony_ci # yum, for RHEL (and clones) or Fedora version < 18 46762306a36Sopenharmony_ci printf("You should run:\n") if ($verbose_warn_install); 46862306a36Sopenharmony_ci printf("\n\tsudo yum install -y $install\n"); 46962306a36Sopenharmony_ci } 47062306a36Sopenharmony_ci} 47162306a36Sopenharmony_ci 47262306a36Sopenharmony_cisub give_opensuse_hints() 47362306a36Sopenharmony_ci{ 47462306a36Sopenharmony_ci my %map = ( 47562306a36Sopenharmony_ci "python-sphinx" => "python3-sphinx", 47662306a36Sopenharmony_ci "virtualenv" => "python3-virtualenv", 47762306a36Sopenharmony_ci "dot" => "graphviz", 47862306a36Sopenharmony_ci "convert" => "ImageMagick", 47962306a36Sopenharmony_ci "Pod::Usage" => "perl-Pod-Usage", 48062306a36Sopenharmony_ci "xelatex" => "texlive-xetex-bin", 48162306a36Sopenharmony_ci ); 48262306a36Sopenharmony_ci 48362306a36Sopenharmony_ci # On Tumbleweed, this package is also named rsvg-convert 48462306a36Sopenharmony_ci $map{"rsvg-convert"} = "rsvg-view" if (!($system_release =~ /Tumbleweed/)); 48562306a36Sopenharmony_ci 48662306a36Sopenharmony_ci my @suse_tex_pkgs = ( 48762306a36Sopenharmony_ci "texlive-babel-english", 48862306a36Sopenharmony_ci "texlive-caption", 48962306a36Sopenharmony_ci "texlive-colortbl", 49062306a36Sopenharmony_ci "texlive-courier", 49162306a36Sopenharmony_ci "texlive-dvips", 49262306a36Sopenharmony_ci "texlive-helvetic", 49362306a36Sopenharmony_ci "texlive-makeindex", 49462306a36Sopenharmony_ci "texlive-metafont", 49562306a36Sopenharmony_ci "texlive-metapost", 49662306a36Sopenharmony_ci "texlive-palatino", 49762306a36Sopenharmony_ci "texlive-preview", 49862306a36Sopenharmony_ci "texlive-times", 49962306a36Sopenharmony_ci "texlive-zapfchan", 50062306a36Sopenharmony_ci "texlive-zapfding", 50162306a36Sopenharmony_ci ); 50262306a36Sopenharmony_ci 50362306a36Sopenharmony_ci $map{"latexmk"} = "texlive-latexmk-bin"; 50462306a36Sopenharmony_ci 50562306a36Sopenharmony_ci # FIXME: add support for installing CJK fonts 50662306a36Sopenharmony_ci # 50762306a36Sopenharmony_ci # I tried hard, but was unable to find a way to install 50862306a36Sopenharmony_ci # "Noto Sans CJK SC" on openSUSE 50962306a36Sopenharmony_ci 51062306a36Sopenharmony_ci check_rpm_missing(\@suse_tex_pkgs, 2) if ($pdf); 51162306a36Sopenharmony_ci check_missing_tex(2) if ($pdf); 51262306a36Sopenharmony_ci check_missing(\%map); 51362306a36Sopenharmony_ci 51462306a36Sopenharmony_ci return if (!$need && !$optional); 51562306a36Sopenharmony_ci printf("You should run:\n") if ($verbose_warn_install); 51662306a36Sopenharmony_ci printf("\n\tsudo zypper install --no-recommends $install\n"); 51762306a36Sopenharmony_ci} 51862306a36Sopenharmony_ci 51962306a36Sopenharmony_cisub give_mageia_hints() 52062306a36Sopenharmony_ci{ 52162306a36Sopenharmony_ci my %map = ( 52262306a36Sopenharmony_ci "python-sphinx" => "python3-sphinx", 52362306a36Sopenharmony_ci "virtualenv" => "python3-virtualenv", 52462306a36Sopenharmony_ci "dot" => "graphviz", 52562306a36Sopenharmony_ci "convert" => "ImageMagick", 52662306a36Sopenharmony_ci "Pod::Usage" => "perl-Pod-Usage", 52762306a36Sopenharmony_ci "xelatex" => "texlive", 52862306a36Sopenharmony_ci "rsvg-convert" => "librsvg2", 52962306a36Sopenharmony_ci ); 53062306a36Sopenharmony_ci 53162306a36Sopenharmony_ci my @tex_pkgs = ( 53262306a36Sopenharmony_ci "texlive-fontsextra", 53362306a36Sopenharmony_ci ); 53462306a36Sopenharmony_ci 53562306a36Sopenharmony_ci $map{"latexmk"} = "texlive-collection-basic"; 53662306a36Sopenharmony_ci 53762306a36Sopenharmony_ci my $packager_cmd; 53862306a36Sopenharmony_ci my $noto_sans; 53962306a36Sopenharmony_ci if ($system_release =~ /OpenMandriva/) { 54062306a36Sopenharmony_ci $packager_cmd = "dnf install"; 54162306a36Sopenharmony_ci $noto_sans = "noto-sans-cjk-fonts"; 54262306a36Sopenharmony_ci @tex_pkgs = ( "texlive-collection-fontsextra" ); 54362306a36Sopenharmony_ci } else { 54462306a36Sopenharmony_ci $packager_cmd = "urpmi"; 54562306a36Sopenharmony_ci $noto_sans = "google-noto-sans-cjk-ttc-fonts"; 54662306a36Sopenharmony_ci } 54762306a36Sopenharmony_ci 54862306a36Sopenharmony_ci 54962306a36Sopenharmony_ci if ($pdf) { 55062306a36Sopenharmony_ci check_missing_file(["/usr/share/fonts/google-noto-cjk/NotoSansCJK-Regular.ttc", 55162306a36Sopenharmony_ci "/usr/share/fonts/TTF/NotoSans-Regular.ttf"], 55262306a36Sopenharmony_ci $noto_sans, 2); 55362306a36Sopenharmony_ci } 55462306a36Sopenharmony_ci 55562306a36Sopenharmony_ci check_rpm_missing(\@tex_pkgs, 2) if ($pdf); 55662306a36Sopenharmony_ci check_missing(\%map); 55762306a36Sopenharmony_ci 55862306a36Sopenharmony_ci return if (!$need && !$optional); 55962306a36Sopenharmony_ci printf("You should run:\n") if ($verbose_warn_install); 56062306a36Sopenharmony_ci printf("\n\tsudo $packager_cmd $install\n"); 56162306a36Sopenharmony_ci} 56262306a36Sopenharmony_ci 56362306a36Sopenharmony_cisub give_arch_linux_hints() 56462306a36Sopenharmony_ci{ 56562306a36Sopenharmony_ci my %map = ( 56662306a36Sopenharmony_ci "virtualenv" => "python-virtualenv", 56762306a36Sopenharmony_ci "dot" => "graphviz", 56862306a36Sopenharmony_ci "convert" => "imagemagick", 56962306a36Sopenharmony_ci "xelatex" => "texlive-bin", 57062306a36Sopenharmony_ci "latexmk" => "texlive-core", 57162306a36Sopenharmony_ci "rsvg-convert" => "extra/librsvg", 57262306a36Sopenharmony_ci ); 57362306a36Sopenharmony_ci 57462306a36Sopenharmony_ci my @archlinux_tex_pkgs = ( 57562306a36Sopenharmony_ci "texlive-core", 57662306a36Sopenharmony_ci "texlive-latexextra", 57762306a36Sopenharmony_ci "ttf-dejavu", 57862306a36Sopenharmony_ci ); 57962306a36Sopenharmony_ci check_pacman_missing(\@archlinux_tex_pkgs, 2) if ($pdf); 58062306a36Sopenharmony_ci 58162306a36Sopenharmony_ci if ($pdf) { 58262306a36Sopenharmony_ci check_missing_file(["/usr/share/fonts/noto-cjk/NotoSansCJK-Regular.ttc"], 58362306a36Sopenharmony_ci "noto-fonts-cjk", 2); 58462306a36Sopenharmony_ci } 58562306a36Sopenharmony_ci 58662306a36Sopenharmony_ci check_missing(\%map); 58762306a36Sopenharmony_ci 58862306a36Sopenharmony_ci return if (!$need && !$optional); 58962306a36Sopenharmony_ci printf("You should run:\n") if ($verbose_warn_install); 59062306a36Sopenharmony_ci printf("\n\tsudo pacman -S $install\n"); 59162306a36Sopenharmony_ci} 59262306a36Sopenharmony_ci 59362306a36Sopenharmony_cisub give_gentoo_hints() 59462306a36Sopenharmony_ci{ 59562306a36Sopenharmony_ci my %map = ( 59662306a36Sopenharmony_ci "virtualenv" => "dev-python/virtualenv", 59762306a36Sopenharmony_ci "dot" => "media-gfx/graphviz", 59862306a36Sopenharmony_ci "convert" => "media-gfx/imagemagick", 59962306a36Sopenharmony_ci "xelatex" => "dev-texlive/texlive-xetex media-fonts/dejavu", 60062306a36Sopenharmony_ci "rsvg-convert" => "gnome-base/librsvg", 60162306a36Sopenharmony_ci ); 60262306a36Sopenharmony_ci 60362306a36Sopenharmony_ci check_missing_file(["/usr/share/fonts/dejavu/DejaVuSans.ttf"], 60462306a36Sopenharmony_ci "media-fonts/dejavu", 2) if ($pdf); 60562306a36Sopenharmony_ci 60662306a36Sopenharmony_ci if ($pdf) { 60762306a36Sopenharmony_ci check_missing_file(["/usr/share/fonts/noto-cjk/NotoSansCJKsc-Regular.otf", 60862306a36Sopenharmony_ci "/usr/share/fonts/noto-cjk/NotoSerifCJK-Regular.ttc"], 60962306a36Sopenharmony_ci "media-fonts/noto-cjk", 2); 61062306a36Sopenharmony_ci } 61162306a36Sopenharmony_ci 61262306a36Sopenharmony_ci check_missing(\%map); 61362306a36Sopenharmony_ci 61462306a36Sopenharmony_ci return if (!$need && !$optional); 61562306a36Sopenharmony_ci 61662306a36Sopenharmony_ci printf("You should run:\n") if ($verbose_warn_install); 61762306a36Sopenharmony_ci printf("\n"); 61862306a36Sopenharmony_ci 61962306a36Sopenharmony_ci my $imagemagick = "media-gfx/imagemagick svg png"; 62062306a36Sopenharmony_ci my $cairo = "media-gfx/graphviz cairo pdf"; 62162306a36Sopenharmony_ci my $portage_imagemagick = "/etc/portage/package.use/imagemagick"; 62262306a36Sopenharmony_ci my $portage_cairo = "/etc/portage/package.use/graphviz"; 62362306a36Sopenharmony_ci 62462306a36Sopenharmony_ci if (qx(grep imagemagick $portage_imagemagick 2>/dev/null) eq "") { 62562306a36Sopenharmony_ci printf("\tsudo su -c 'echo \"$imagemagick\" > $portage_imagemagick'\n") 62662306a36Sopenharmony_ci } 62762306a36Sopenharmony_ci if (qx(grep graphviz $portage_cairo 2>/dev/null) eq "") { 62862306a36Sopenharmony_ci printf("\tsudo su -c 'echo \"$cairo\" > $portage_cairo'\n"); 62962306a36Sopenharmony_ci } 63062306a36Sopenharmony_ci 63162306a36Sopenharmony_ci printf("\tsudo emerge --ask $install\n"); 63262306a36Sopenharmony_ci 63362306a36Sopenharmony_ci} 63462306a36Sopenharmony_ci 63562306a36Sopenharmony_cisub check_distros() 63662306a36Sopenharmony_ci{ 63762306a36Sopenharmony_ci # Distro-specific hints 63862306a36Sopenharmony_ci if ($system_release =~ /Red Hat Enterprise Linux/) { 63962306a36Sopenharmony_ci give_redhat_hints; 64062306a36Sopenharmony_ci return; 64162306a36Sopenharmony_ci } 64262306a36Sopenharmony_ci if ($system_release =~ /CentOS/) { 64362306a36Sopenharmony_ci give_redhat_hints; 64462306a36Sopenharmony_ci return; 64562306a36Sopenharmony_ci } 64662306a36Sopenharmony_ci if ($system_release =~ /Scientific Linux/) { 64762306a36Sopenharmony_ci give_redhat_hints; 64862306a36Sopenharmony_ci return; 64962306a36Sopenharmony_ci } 65062306a36Sopenharmony_ci if ($system_release =~ /Oracle Linux Server/) { 65162306a36Sopenharmony_ci give_redhat_hints; 65262306a36Sopenharmony_ci return; 65362306a36Sopenharmony_ci } 65462306a36Sopenharmony_ci if ($system_release =~ /Fedora/) { 65562306a36Sopenharmony_ci give_redhat_hints; 65662306a36Sopenharmony_ci return; 65762306a36Sopenharmony_ci } 65862306a36Sopenharmony_ci if ($system_release =~ /Ubuntu/) { 65962306a36Sopenharmony_ci give_debian_hints; 66062306a36Sopenharmony_ci return; 66162306a36Sopenharmony_ci } 66262306a36Sopenharmony_ci if ($system_release =~ /Debian/) { 66362306a36Sopenharmony_ci give_debian_hints; 66462306a36Sopenharmony_ci return; 66562306a36Sopenharmony_ci } 66662306a36Sopenharmony_ci if ($system_release =~ /openSUSE/) { 66762306a36Sopenharmony_ci give_opensuse_hints; 66862306a36Sopenharmony_ci return; 66962306a36Sopenharmony_ci } 67062306a36Sopenharmony_ci if ($system_release =~ /Mageia/) { 67162306a36Sopenharmony_ci give_mageia_hints; 67262306a36Sopenharmony_ci return; 67362306a36Sopenharmony_ci } 67462306a36Sopenharmony_ci if ($system_release =~ /OpenMandriva/) { 67562306a36Sopenharmony_ci give_mageia_hints; 67662306a36Sopenharmony_ci return; 67762306a36Sopenharmony_ci } 67862306a36Sopenharmony_ci if ($system_release =~ /Arch Linux/) { 67962306a36Sopenharmony_ci give_arch_linux_hints; 68062306a36Sopenharmony_ci return; 68162306a36Sopenharmony_ci } 68262306a36Sopenharmony_ci if ($system_release =~ /Gentoo/) { 68362306a36Sopenharmony_ci give_gentoo_hints; 68462306a36Sopenharmony_ci return; 68562306a36Sopenharmony_ci } 68662306a36Sopenharmony_ci 68762306a36Sopenharmony_ci # 68862306a36Sopenharmony_ci # Fall-back to generic hint code for other distros 68962306a36Sopenharmony_ci # That's far from ideal, specially for LaTeX dependencies. 69062306a36Sopenharmony_ci # 69162306a36Sopenharmony_ci my %map = ( 69262306a36Sopenharmony_ci "sphinx-build" => "sphinx" 69362306a36Sopenharmony_ci ); 69462306a36Sopenharmony_ci check_missing_tex(2) if ($pdf); 69562306a36Sopenharmony_ci check_missing(\%map); 69662306a36Sopenharmony_ci print "I don't know distro $system_release.\n"; 69762306a36Sopenharmony_ci print "So, I can't provide you a hint with the install procedure.\n"; 69862306a36Sopenharmony_ci print "There are likely missing dependencies.\n"; 69962306a36Sopenharmony_ci} 70062306a36Sopenharmony_ci 70162306a36Sopenharmony_ci# 70262306a36Sopenharmony_ci# Common dependencies 70362306a36Sopenharmony_ci# 70462306a36Sopenharmony_ci 70562306a36Sopenharmony_cisub deactivate_help() 70662306a36Sopenharmony_ci{ 70762306a36Sopenharmony_ci printf "\n If you want to exit the virtualenv, you can use:\n"; 70862306a36Sopenharmony_ci printf "\tdeactivate\n"; 70962306a36Sopenharmony_ci} 71062306a36Sopenharmony_ci 71162306a36Sopenharmony_cisub get_virtenv() 71262306a36Sopenharmony_ci{ 71362306a36Sopenharmony_ci my $ver; 71462306a36Sopenharmony_ci my $min_activate = "$ENV{'PWD'}/${virtenv_prefix}${min_version}/bin/activate"; 71562306a36Sopenharmony_ci my @activates = glob "$ENV{'PWD'}/${virtenv_prefix}*/bin/activate"; 71662306a36Sopenharmony_ci 71762306a36Sopenharmony_ci @activates = sort {$b cmp $a} @activates; 71862306a36Sopenharmony_ci 71962306a36Sopenharmony_ci foreach my $f (@activates) { 72062306a36Sopenharmony_ci next if ($f lt $min_activate); 72162306a36Sopenharmony_ci 72262306a36Sopenharmony_ci my $sphinx_cmd = $f; 72362306a36Sopenharmony_ci $sphinx_cmd =~ s/activate/sphinx-build/; 72462306a36Sopenharmony_ci next if (! -f $sphinx_cmd); 72562306a36Sopenharmony_ci 72662306a36Sopenharmony_ci my $ver = get_sphinx_version($sphinx_cmd); 72762306a36Sopenharmony_ci 72862306a36Sopenharmony_ci if (!$ver) { 72962306a36Sopenharmony_ci $f =~ s#/bin/activate##; 73062306a36Sopenharmony_ci print("Warning: virtual environment $f is not working.\nPython version upgrade? Remove it with:\n\n\trm -rf $f\n\n"); 73162306a36Sopenharmony_ci } 73262306a36Sopenharmony_ci 73362306a36Sopenharmony_ci if ($need_sphinx && ($ver ge $min_version)) { 73462306a36Sopenharmony_ci return ($f, $ver); 73562306a36Sopenharmony_ci } elsif ($ver gt $cur_version) { 73662306a36Sopenharmony_ci return ($f, $ver); 73762306a36Sopenharmony_ci } 73862306a36Sopenharmony_ci } 73962306a36Sopenharmony_ci return ("", ""); 74062306a36Sopenharmony_ci} 74162306a36Sopenharmony_ci 74262306a36Sopenharmony_cisub recommend_sphinx_upgrade() 74362306a36Sopenharmony_ci{ 74462306a36Sopenharmony_ci my $venv_ver; 74562306a36Sopenharmony_ci 74662306a36Sopenharmony_ci # Avoid running sphinx-builds from venv if $cur_version is good 74762306a36Sopenharmony_ci if ($cur_version && ($cur_version ge $rec_version)) { 74862306a36Sopenharmony_ci $latest_avail_ver = $cur_version; 74962306a36Sopenharmony_ci return; 75062306a36Sopenharmony_ci } 75162306a36Sopenharmony_ci 75262306a36Sopenharmony_ci # Get the highest version from sphinx_*/bin/sphinx-build and the 75362306a36Sopenharmony_ci # corresponding command to activate the venv/virtenv 75462306a36Sopenharmony_ci ($activate_cmd, $venv_ver) = get_virtenv(); 75562306a36Sopenharmony_ci 75662306a36Sopenharmony_ci # Store the highest version from Sphinx existing virtualenvs 75762306a36Sopenharmony_ci if (($activate_cmd ne "") && ($venv_ver gt $cur_version)) { 75862306a36Sopenharmony_ci $latest_avail_ver = $venv_ver; 75962306a36Sopenharmony_ci } else { 76062306a36Sopenharmony_ci $latest_avail_ver = $cur_version if ($cur_version); 76162306a36Sopenharmony_ci } 76262306a36Sopenharmony_ci 76362306a36Sopenharmony_ci # As we don't know package version of Sphinx, and there's no 76462306a36Sopenharmony_ci # virtual environments, don't check if upgrades are needed 76562306a36Sopenharmony_ci if (!$virtualenv) { 76662306a36Sopenharmony_ci return if (!$latest_avail_ver); 76762306a36Sopenharmony_ci } 76862306a36Sopenharmony_ci 76962306a36Sopenharmony_ci # Either there are already a virtual env or a new one should be created 77062306a36Sopenharmony_ci $need_pip = 1; 77162306a36Sopenharmony_ci 77262306a36Sopenharmony_ci return if (!$latest_avail_ver); 77362306a36Sopenharmony_ci 77462306a36Sopenharmony_ci # Return if the reason is due to an upgrade or not 77562306a36Sopenharmony_ci if ($latest_avail_ver lt $rec_version) { 77662306a36Sopenharmony_ci $rec_sphinx_upgrade = 1; 77762306a36Sopenharmony_ci } 77862306a36Sopenharmony_ci 77962306a36Sopenharmony_ci return $latest_avail_ver; 78062306a36Sopenharmony_ci} 78162306a36Sopenharmony_ci 78262306a36Sopenharmony_ci# 78362306a36Sopenharmony_ci# The logic here is complex, as it have to deal with different versions: 78462306a36Sopenharmony_ci# - minimal supported version; 78562306a36Sopenharmony_ci# - minimal PDF version; 78662306a36Sopenharmony_ci# - recommended version. 78762306a36Sopenharmony_ci# It also needs to work fine with both distro's package and venv/virtualenv 78862306a36Sopenharmony_cisub recommend_sphinx_version($) 78962306a36Sopenharmony_ci{ 79062306a36Sopenharmony_ci my $virtualenv_cmd = shift; 79162306a36Sopenharmony_ci 79262306a36Sopenharmony_ci # Version is OK. Nothing to do. 79362306a36Sopenharmony_ci if ($cur_version && ($cur_version ge $rec_version)) { 79462306a36Sopenharmony_ci if ($cur_version lt $min_pdf_version) { 79562306a36Sopenharmony_ci print "note: If you want pdf, you need at least Sphinx $min_pdf_version.\n"; 79662306a36Sopenharmony_ci } 79762306a36Sopenharmony_ci return; 79862306a36Sopenharmony_ci }; 79962306a36Sopenharmony_ci 80062306a36Sopenharmony_ci if (!$need_sphinx) { 80162306a36Sopenharmony_ci # sphinx-build is present and its version is >= $min_version 80262306a36Sopenharmony_ci 80362306a36Sopenharmony_ci #only recommend enabling a newer virtenv version if makes sense. 80462306a36Sopenharmony_ci if ($latest_avail_ver gt $cur_version) { 80562306a36Sopenharmony_ci printf "\nYou may also use the newer Sphinx version $latest_avail_ver with:\n"; 80662306a36Sopenharmony_ci printf "\tdeactivate\n" if ($ENV{'PWD'} =~ /${virtenv_prefix}/); 80762306a36Sopenharmony_ci printf "\t. $activate_cmd\n"; 80862306a36Sopenharmony_ci deactivate_help(); 80962306a36Sopenharmony_ci 81062306a36Sopenharmony_ci return; 81162306a36Sopenharmony_ci } 81262306a36Sopenharmony_ci return if ($latest_avail_ver ge $rec_version); 81362306a36Sopenharmony_ci } 81462306a36Sopenharmony_ci 81562306a36Sopenharmony_ci if (!$virtualenv) { 81662306a36Sopenharmony_ci # No sphinx either via package or via virtenv. As we can't 81762306a36Sopenharmony_ci # Compare the versions here, just return, recommending the 81862306a36Sopenharmony_ci # user to install it from the package distro. 81962306a36Sopenharmony_ci return if (!$latest_avail_ver); 82062306a36Sopenharmony_ci 82162306a36Sopenharmony_ci # User doesn't want a virtenv recommendation, but he already 82262306a36Sopenharmony_ci # installed one via virtenv with a newer version. 82362306a36Sopenharmony_ci # So, print commands to enable it 82462306a36Sopenharmony_ci if ($latest_avail_ver gt $cur_version) { 82562306a36Sopenharmony_ci printf "\nYou may also use the Sphinx virtualenv version $latest_avail_ver with:\n"; 82662306a36Sopenharmony_ci printf "\tdeactivate\n" if ($ENV{'PWD'} =~ /${virtenv_prefix}/); 82762306a36Sopenharmony_ci printf "\t. $activate_cmd\n"; 82862306a36Sopenharmony_ci deactivate_help(); 82962306a36Sopenharmony_ci 83062306a36Sopenharmony_ci return; 83162306a36Sopenharmony_ci } 83262306a36Sopenharmony_ci print "\n"; 83362306a36Sopenharmony_ci } else { 83462306a36Sopenharmony_ci $need++ if ($need_sphinx); 83562306a36Sopenharmony_ci } 83662306a36Sopenharmony_ci 83762306a36Sopenharmony_ci # Suggest newer versions if current ones are too old 83862306a36Sopenharmony_ci if ($latest_avail_ver && $latest_avail_ver ge $min_version) { 83962306a36Sopenharmony_ci # If there's a good enough version, ask the user to enable it 84062306a36Sopenharmony_ci if ($latest_avail_ver ge $rec_version) { 84162306a36Sopenharmony_ci printf "\nNeed to activate Sphinx (version $latest_avail_ver) on virtualenv with:\n"; 84262306a36Sopenharmony_ci printf "\t. $activate_cmd\n"; 84362306a36Sopenharmony_ci deactivate_help(); 84462306a36Sopenharmony_ci 84562306a36Sopenharmony_ci if ($latest_avail_ver lt $min_pdf_version) { 84662306a36Sopenharmony_ci print "note: If you want pdf, you need at least Sphinx $min_pdf_version.\n"; 84762306a36Sopenharmony_ci } 84862306a36Sopenharmony_ci 84962306a36Sopenharmony_ci return; 85062306a36Sopenharmony_ci } 85162306a36Sopenharmony_ci 85262306a36Sopenharmony_ci # Version is above the minimal required one, but may be 85362306a36Sopenharmony_ci # below the recommended one. So, print warnings/notes 85462306a36Sopenharmony_ci 85562306a36Sopenharmony_ci if ($latest_avail_ver lt $rec_version) { 85662306a36Sopenharmony_ci print "Warning: It is recommended at least Sphinx version $rec_version.\n"; 85762306a36Sopenharmony_ci } 85862306a36Sopenharmony_ci } 85962306a36Sopenharmony_ci 86062306a36Sopenharmony_ci # At this point, either it needs Sphinx or upgrade is recommended, 86162306a36Sopenharmony_ci # both via pip 86262306a36Sopenharmony_ci 86362306a36Sopenharmony_ci if ($rec_sphinx_upgrade) { 86462306a36Sopenharmony_ci if (!$virtualenv) { 86562306a36Sopenharmony_ci print "Instead of install/upgrade Python Sphinx pkg, you could use pip/pypi with:\n\n"; 86662306a36Sopenharmony_ci } else { 86762306a36Sopenharmony_ci print "To upgrade Sphinx, use:\n\n"; 86862306a36Sopenharmony_ci } 86962306a36Sopenharmony_ci } else { 87062306a36Sopenharmony_ci print "\nSphinx needs to be installed either:\n1) via pip/pypi with:\n\n"; 87162306a36Sopenharmony_ci } 87262306a36Sopenharmony_ci 87362306a36Sopenharmony_ci $python_cmd = find_python_no_venv(); 87462306a36Sopenharmony_ci 87562306a36Sopenharmony_ci printf "\t$virtualenv_cmd $virtenv_dir\n"; 87662306a36Sopenharmony_ci 87762306a36Sopenharmony_ci printf "\t. $virtenv_dir/bin/activate\n"; 87862306a36Sopenharmony_ci printf "\tpip install -r $requirement_file\n"; 87962306a36Sopenharmony_ci deactivate_help(); 88062306a36Sopenharmony_ci 88162306a36Sopenharmony_ci printf "\n2) As a package with:\n"; 88262306a36Sopenharmony_ci 88362306a36Sopenharmony_ci my $old_need = $need; 88462306a36Sopenharmony_ci my $old_optional = $optional; 88562306a36Sopenharmony_ci %missing = (); 88662306a36Sopenharmony_ci $pdf = 0; 88762306a36Sopenharmony_ci $optional = 0; 88862306a36Sopenharmony_ci $install = ""; 88962306a36Sopenharmony_ci $verbose_warn_install = 0; 89062306a36Sopenharmony_ci 89162306a36Sopenharmony_ci add_package("python-sphinx", 0); 89262306a36Sopenharmony_ci 89362306a36Sopenharmony_ci check_distros(); 89462306a36Sopenharmony_ci 89562306a36Sopenharmony_ci $need = $old_need; 89662306a36Sopenharmony_ci $optional = $old_optional; 89762306a36Sopenharmony_ci 89862306a36Sopenharmony_ci printf "\n Please note that Sphinx >= 3.0 will currently produce false-positive\n"; 89962306a36Sopenharmony_ci printf " warning when the same name is used for more than one type (functions,\n"; 90062306a36Sopenharmony_ci printf " structs, enums,...). This is known Sphinx bug. For more details, see:\n"; 90162306a36Sopenharmony_ci printf "\thttps://github.com/sphinx-doc/sphinx/pull/8313\n"; 90262306a36Sopenharmony_ci} 90362306a36Sopenharmony_ci 90462306a36Sopenharmony_cisub check_needs() 90562306a36Sopenharmony_ci{ 90662306a36Sopenharmony_ci # Check if Sphinx is already accessible from current environment 90762306a36Sopenharmony_ci check_sphinx(); 90862306a36Sopenharmony_ci 90962306a36Sopenharmony_ci if ($system_release) { 91062306a36Sopenharmony_ci print "Detected OS: $system_release.\n"; 91162306a36Sopenharmony_ci } else { 91262306a36Sopenharmony_ci print "Unknown OS\n"; 91362306a36Sopenharmony_ci } 91462306a36Sopenharmony_ci printf "Sphinx version: %s\n\n", $cur_version if ($cur_version); 91562306a36Sopenharmony_ci 91662306a36Sopenharmony_ci # Check python command line, trying first python3 91762306a36Sopenharmony_ci $python_cmd = findprog("python3"); 91862306a36Sopenharmony_ci $python_cmd = check_program("python", 0) if (!$python_cmd); 91962306a36Sopenharmony_ci 92062306a36Sopenharmony_ci # Check the type of virtual env, depending on Python version 92162306a36Sopenharmony_ci if ($python_cmd) { 92262306a36Sopenharmony_ci if ($virtualenv) { 92362306a36Sopenharmony_ci my $tmp = qx($python_cmd --version 2>&1); 92462306a36Sopenharmony_ci if ($tmp =~ m/(\d+\.)(\d+\.)/) { 92562306a36Sopenharmony_ci if ($1 < 3) { 92662306a36Sopenharmony_ci # Fail if it finds python2 (or worse) 92762306a36Sopenharmony_ci die "Python 3 is required to build the kernel docs\n"; 92862306a36Sopenharmony_ci } 92962306a36Sopenharmony_ci if ($1 == 3 && $2 < 3) { 93062306a36Sopenharmony_ci # Need Python 3.3 or upper for venv 93162306a36Sopenharmony_ci $need_virtualenv = 1; 93262306a36Sopenharmony_ci } 93362306a36Sopenharmony_ci } else { 93462306a36Sopenharmony_ci die "Warning: couldn't identify $python_cmd version!"; 93562306a36Sopenharmony_ci } 93662306a36Sopenharmony_ci } else { 93762306a36Sopenharmony_ci add_package("python-sphinx", 0); 93862306a36Sopenharmony_ci } 93962306a36Sopenharmony_ci } 94062306a36Sopenharmony_ci 94162306a36Sopenharmony_ci my $venv_ver = recommend_sphinx_upgrade(); 94262306a36Sopenharmony_ci 94362306a36Sopenharmony_ci my $virtualenv_cmd; 94462306a36Sopenharmony_ci 94562306a36Sopenharmony_ci if ($need_pip) { 94662306a36Sopenharmony_ci # Set virtualenv command line, if python < 3.3 94762306a36Sopenharmony_ci if ($need_virtualenv) { 94862306a36Sopenharmony_ci $virtualenv_cmd = findprog("virtualenv-3"); 94962306a36Sopenharmony_ci $virtualenv_cmd = findprog("virtualenv-3.5") if (!$virtualenv_cmd); 95062306a36Sopenharmony_ci if (!$virtualenv_cmd) { 95162306a36Sopenharmony_ci check_program("virtualenv", 0); 95262306a36Sopenharmony_ci $virtualenv_cmd = "virtualenv"; 95362306a36Sopenharmony_ci } 95462306a36Sopenharmony_ci } else { 95562306a36Sopenharmony_ci $virtualenv_cmd = "$python_cmd -m venv"; 95662306a36Sopenharmony_ci check_python_module("ensurepip", 0); 95762306a36Sopenharmony_ci } 95862306a36Sopenharmony_ci } 95962306a36Sopenharmony_ci 96062306a36Sopenharmony_ci # Check for needed programs/tools 96162306a36Sopenharmony_ci check_perl_module("Pod::Usage", 0); 96262306a36Sopenharmony_ci check_program("make", 0); 96362306a36Sopenharmony_ci check_program("gcc", 0); 96462306a36Sopenharmony_ci check_program("dot", 1); 96562306a36Sopenharmony_ci check_program("convert", 1); 96662306a36Sopenharmony_ci 96762306a36Sopenharmony_ci # Extra PDF files - should use 2 for is_optional 96862306a36Sopenharmony_ci check_program("xelatex", 2) if ($pdf); 96962306a36Sopenharmony_ci check_program("rsvg-convert", 2) if ($pdf); 97062306a36Sopenharmony_ci check_program("latexmk", 2) if ($pdf); 97162306a36Sopenharmony_ci 97262306a36Sopenharmony_ci # Do distro-specific checks and output distro-install commands 97362306a36Sopenharmony_ci check_distros(); 97462306a36Sopenharmony_ci 97562306a36Sopenharmony_ci if (!$python_cmd) { 97662306a36Sopenharmony_ci if ($need == 1) { 97762306a36Sopenharmony_ci die "Can't build as $need mandatory dependency is missing"; 97862306a36Sopenharmony_ci } elsif ($need) { 97962306a36Sopenharmony_ci die "Can't build as $need mandatory dependencies are missing"; 98062306a36Sopenharmony_ci } 98162306a36Sopenharmony_ci } 98262306a36Sopenharmony_ci 98362306a36Sopenharmony_ci # Check if sphinx-build is called sphinx-build-3 98462306a36Sopenharmony_ci if ($need_symlink) { 98562306a36Sopenharmony_ci printf "\tsudo ln -sf %s /usr/bin/sphinx-build\n\n", 98662306a36Sopenharmony_ci which("sphinx-build-3"); 98762306a36Sopenharmony_ci } 98862306a36Sopenharmony_ci 98962306a36Sopenharmony_ci recommend_sphinx_version($virtualenv_cmd); 99062306a36Sopenharmony_ci printf "\n"; 99162306a36Sopenharmony_ci 99262306a36Sopenharmony_ci print "All optional dependencies are met.\n" if (!$optional); 99362306a36Sopenharmony_ci 99462306a36Sopenharmony_ci if ($need == 1) { 99562306a36Sopenharmony_ci die "Can't build as $need mandatory dependency is missing"; 99662306a36Sopenharmony_ci } elsif ($need) { 99762306a36Sopenharmony_ci die "Can't build as $need mandatory dependencies are missing"; 99862306a36Sopenharmony_ci } 99962306a36Sopenharmony_ci 100062306a36Sopenharmony_ci print "Needed package dependencies are met.\n"; 100162306a36Sopenharmony_ci} 100262306a36Sopenharmony_ci 100362306a36Sopenharmony_ci# 100462306a36Sopenharmony_ci# Main 100562306a36Sopenharmony_ci# 100662306a36Sopenharmony_ci 100762306a36Sopenharmony_ciwhile (@ARGV) { 100862306a36Sopenharmony_ci my $arg = shift(@ARGV); 100962306a36Sopenharmony_ci 101062306a36Sopenharmony_ci if ($arg eq "--no-virtualenv") { 101162306a36Sopenharmony_ci $virtualenv = 0; 101262306a36Sopenharmony_ci } elsif ($arg eq "--no-pdf"){ 101362306a36Sopenharmony_ci $pdf = 0; 101462306a36Sopenharmony_ci } elsif ($arg eq "--version-check"){ 101562306a36Sopenharmony_ci $version_check = 1; 101662306a36Sopenharmony_ci } else { 101762306a36Sopenharmony_ci print "Usage:\n\t$0 <--no-virtualenv> <--no-pdf> <--version-check>\n\n"; 101862306a36Sopenharmony_ci print "Where:\n"; 101962306a36Sopenharmony_ci print "\t--no-virtualenv\t- Recommend installing Sphinx instead of using a virtualenv\n"; 102062306a36Sopenharmony_ci print "\t--version-check\t- if version is compatible, don't check for missing dependencies\n"; 102162306a36Sopenharmony_ci print "\t--no-pdf\t- don't check for dependencies required to build PDF docs\n\n"; 102262306a36Sopenharmony_ci exit -1; 102362306a36Sopenharmony_ci } 102462306a36Sopenharmony_ci} 102562306a36Sopenharmony_ci 102662306a36Sopenharmony_ci# 102762306a36Sopenharmony_ci# Determine the system type. There's no standard unique way that would 102862306a36Sopenharmony_ci# work with all distros with a minimal package install. So, several 102962306a36Sopenharmony_ci# methods are used here. 103062306a36Sopenharmony_ci# 103162306a36Sopenharmony_ci# By default, it will use lsb_release function. If not available, it will 103262306a36Sopenharmony_ci# fail back to reading the known different places where the distro name 103362306a36Sopenharmony_ci# is stored 103462306a36Sopenharmony_ci# 103562306a36Sopenharmony_ci 103662306a36Sopenharmony_ci$system_release = qx(lsb_release -d) if which("lsb_release"); 103762306a36Sopenharmony_ci$system_release =~ s/Description:\s*// if ($system_release); 103862306a36Sopenharmony_ci$system_release = catcheck("/etc/system-release") if !$system_release; 103962306a36Sopenharmony_ci$system_release = catcheck("/etc/redhat-release") if !$system_release; 104062306a36Sopenharmony_ci$system_release = catcheck("/etc/lsb-release") if !$system_release; 104162306a36Sopenharmony_ci$system_release = catcheck("/etc/gentoo-release") if !$system_release; 104262306a36Sopenharmony_ci 104362306a36Sopenharmony_ci# This seems more common than LSB these days 104462306a36Sopenharmony_ciif (!$system_release) { 104562306a36Sopenharmony_ci my %os_var; 104662306a36Sopenharmony_ci if (open IN, "cat /etc/os-release|") { 104762306a36Sopenharmony_ci while (<IN>) { 104862306a36Sopenharmony_ci if (m/^([\w\d\_]+)=\"?([^\"]*)\"?\n/) { 104962306a36Sopenharmony_ci $os_var{$1}=$2; 105062306a36Sopenharmony_ci } 105162306a36Sopenharmony_ci } 105262306a36Sopenharmony_ci $system_release = $os_var{"NAME"}; 105362306a36Sopenharmony_ci if (defined($os_var{"VERSION_ID"})) { 105462306a36Sopenharmony_ci $system_release .= " " . $os_var{"VERSION_ID"} if (defined($os_var{"VERSION_ID"})); 105562306a36Sopenharmony_ci } else { 105662306a36Sopenharmony_ci $system_release .= " " . $os_var{"VERSION"}; 105762306a36Sopenharmony_ci } 105862306a36Sopenharmony_ci } 105962306a36Sopenharmony_ci} 106062306a36Sopenharmony_ci$system_release = catcheck("/etc/issue") if !$system_release; 106162306a36Sopenharmony_ci$system_release =~ s/\s+$//; 106262306a36Sopenharmony_ci 106362306a36Sopenharmony_cicheck_needs; 1064