[sdk/kdesrc-build] /: Merge kdesrc-build --run and kdesrc-run
Andrew Shark
null at kde.org
Sat Feb 17 17:58:43 GMT 2024
Git commit 301b9b4caf1b84bf2e14bd616fec06683f5a2d18 by Andrew Shark.
Committed on 17/02/2024 at 17:50.
Pushed by ashark into branch 'master'.
Merge kdesrc-build --run and kdesrc-run
This fixes multiple issues with kdesrc-run and kdesrc-build --run
When using the --run parameter, the environment variables of global module were applied (from set-env options). But this is incorrect, since global cannot be treated as usual module. Its build system is defined as generic. In its prepareModuleBuildEnvironment these variables were setted:
- PKG_CONFIG_PATH
- LD_LIBRARY_PATH
- PATH
They have nothing to do with launched module's variables, except PATH, but even that was because of global install-dir matches the module's install-dir in most cases.
The kdesrc-run did sourced module's prefix.sh instead (located in its build-dir). That setted the following variables:
- PATH (the correct, from module)
- XDG_DATA_DIRS
- XDG_CONFIG_DIRS
- QT_PLUGIN_PATH
- QML2_IMPORT_PATH
- QT_QUICK_CONTROLS_STYLE_PATH
This commit fixes the broken behavior of --run, and the broken behavior of kdesrc-run.
Fixes: #145
Fixes: #114
Other fixes:
- Now the parameters after --run that starts with minuses are passed to the start-program, and not considered as options of kdesrc-build
- When setting parameters to the runned executable, they are actually applied. Previously the run script surrounded the $@ in the quotes.
- Fixed indentation and unnecessary semicolons in executable script.
- Made more clear note information when launching. The debug level controls if it will be displayed.
M +0 -1 CMakeLists.txt
M +0 -1 README.md
M +0 -1 completions/zsh/_kdesrc-build
M +4 -4 data/kdesrc-run-completions.sh
M +1 -1 doc/man-kdesrc-build.1.docbook
M +3 -23 doc/supported-cmdline-params.docbook
D +0 -134 kdesrc-run
M +2 -40 modules/ksb/Application.pm
M +22 -5 modules/ksb/Cmdline.pm
A +122 -0 modules/ksb/StartProgram.pm
M +2 -2 modules/ksb/TaskManager.pm
M +1 -1 scripts/gen_zsh_completions.py
https://invent.kde.org/sdk/kdesrc-build/-/commit/301b9b4caf1b84bf2e14bd616fec06683f5a2d18
diff --git a/CMakeLists.txt b/CMakeLists.txt
index bae5fd53..03047adb 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -46,7 +46,6 @@ endif()
# Currently, kdesrc-build real file (not a symlink) expects to be near its data and modules. Need to make a symlink in PKGBUILD then.
install(PROGRAMS ${CMAKE_CURRENT_SOURCE_DIR}/kdesrc-build DESTINATION ${KDE_INSTALL_DATADIR}/kdesrc-build)
-install(PROGRAMS ${CMAKE_CURRENT_SOURCE_DIR}/kdesrc-run DESTINATION ${KDE_INSTALL_DATADIR}/kdesrc-build)
install(DIRECTORY data/ DESTINATION ${KDE_INSTALL_DATADIR}/kdesrc-build/data)
diff --git a/README.md b/README.md
index c95e6d8b..8f253dcc 100644
--- a/README.md
+++ b/README.md
@@ -32,7 +32,6 @@ For other distributions, you will need to make a local installation:
$ cd ~/.local/share
$ git clone https://invent.kde.org/sdk/kdesrc-build.git
$ ln -sf ~/.local/share/kdesrc-build/kdesrc-build ~/.local/bin
-$ ln -sf ~/.local/share/kdesrc-build/kdesrc-run ~/.local/bin
```
- Make sure it works by running:
diff --git a/completions/zsh/_kdesrc-build b/completions/zsh/_kdesrc-build
index bc8202e4..600811e8 100644
--- a/completions/zsh/_kdesrc-build
+++ b/completions/zsh/_kdesrc-build
@@ -75,7 +75,6 @@ _arguments \
"(--run-tests --no-run-tests)"{--run-tests,--no-run-tests}"[Built the modules with support for running their test suite]" \
"--set-module-option-value""[Override an option in your configuration file for a specific module]"":argument:" \
"--source-dir""[Directory that stores the KDE sources]"":argument:" \
- "(--run --start-program)"{--run,--start-program}"[A program to run with kdesrc-build]"":arguments:" \
"(--stop-on-failure --no-stop-on-failure)"{--stop-on-failure,--no-stop-on-failure}"[Stops/Does not stop the build as soon as a package fails to build]" \
"--tag""[Download a specific release of a module]"":argument:" \
"--uninstall""[Uninstalls the module]" \
diff --git a/data/kdesrc-run-completions.sh b/data/kdesrc-run-completions.sh
index 47e222ff..820259e2 100644
--- a/data/kdesrc-run-completions.sh
+++ b/data/kdesrc-run-completions.sh
@@ -1,5 +1,5 @@
-## Autocomplete for kdesrc-run
-function _comp_kdesrc_run
+## Autocomplete for kdesrc-build --run
+function _comp_kdesrc_build_run
{
local cur
COMPREPLY=()
@@ -10,7 +10,7 @@ function _comp_kdesrc_run
return 0
fi
- # Retrieve build modules through kdesrc-run
+ # Retrieve build modules through kdesrc-build
# If the exit status indicates failure, set the wordlist empty to avoid
# unrelated messages.
local modules
@@ -26,4 +26,4 @@ function _comp_kdesrc_run
}
## Register autocomplete function
-complete -o nospace -F _comp_kdesrc_run kdesrc-run
+complete -o nospace -F _comp_kdesrc_build_run kdesrc-build
diff --git a/doc/man-kdesrc-build.1.docbook b/doc/man-kdesrc-build.1.docbook
index f97209c9..5483e425 100644
--- a/doc/man-kdesrc-build.1.docbook
+++ b/doc/man-kdesrc-build.1.docbook
@@ -623,7 +623,7 @@ Generate the &kdesrc-build; configuration file.
<listitem>
<para>
Runs the program named by <replaceable>foo</replaceable> using
- <command>kdesrc-build</command>'s normal build environment. All command
+ prefix.sh environment variables. All command
line arguments present after this option are passed to
<replaceable>foo</replaceable> as it is run.
</para>
diff --git a/doc/supported-cmdline-params.docbook b/doc/supported-cmdline-params.docbook
index fb02d2d3..2a8014b6 100644
--- a/doc/supported-cmdline-params.docbook
+++ b/doc/supported-cmdline-params.docbook
@@ -59,31 +59,11 @@ a few).
</varlistentry>
<varlistentry id="cmdline-run">
-<term><option><link linkend="cmdline-run">--run</link></option> (or <option>--start-program</option>) <parameter>program [parameters ...]</parameter></term>
+<term><option><link linkend="cmdline-run">--run</link></option> (or <option>--start-program</option>) [-e|--exec name] [-f|--fork] <parameter>program [parameters ...]</parameter></term>
<listitem><para>
This option interprets the next item on the command line as a program to run,
-and &kdesrc-build; will then finish reading the configuration file, update the
-environment as normal, and then execute the given program.</para>
-
-<para>This will not work to start a shell with the &kdesrc-build; environment
-in most cases however, since interactive shells typically reset at least part
-of the environment variables (such as <envar>PATH</envar> and
-${install-dir}) in the startup sequence.
-</para>
-
-<tip><para>If you want to see the environment used by &kdesrc-build;, you
-can run the <command>printenv</command> command:</para>
-<informalexample>
-<screen>$ <command>kdesrc-build</command> <parameter>--run</parameter> <parameter>printenv</parameter>
-KDE_SESSION_VERSION=4
-SDL_AUDIODRIVER=alsa
-LANGUAGE=
-XCURSOR_THEME=Oxygen_Blue
-LESS=-R -M --shift 5
-QMAIL_CONTROLDIR=/var/qmail/control
-... etc.
-</screen>
-</informalexample></tip>
+and &kdesrc-build; will then finish reading the configuration file, source the
+prefix.sh to apply environment variables, and then execute the given program.</para>
</listitem>
</varlistentry>
diff --git a/kdesrc-run b/kdesrc-run
deleted file mode 100755
index 90c55560..00000000
--- a/kdesrc-run
+++ /dev/null
@@ -1,134 +0,0 @@
-#!/usr/bin/env perl
-
-=pod
-
-=encoding UTF-8
-
-=head1 NAME
-
-kdesrc-run - Run KDE applications built with kdesrc-build.
-
-=head1 SYNOPSIS
-
-kdesrc-run [options] <module-name> [arguments]
-
-=head1 OPTIONS
-
- -e, --exec <program> Specify program of the module. Default to module name.
- -f, --fork Launch the program in a new session.
- -q, --quiet Do not print run information.
- -h, --help Print usage information and exit.
-
-=head1 EXAMPLES
-
-B<kdesrc-run -f kate -l 5 file1.txt>
-
- Launch kate in a new session with '-l 5 file1.txt' arguments.
-
-B<kdesrc-run -e kate-syntax-highlighter kate --list-themes>
-
- Launch kate-syntax-highlighter of module kate with '--list-themes' argument.
-
-=cut
-
-use 5.014;
-use strict;
-use warnings;
-use autodie;
-
-use Pod::Usage;
-use Getopt::Long qw(:config pass_through require_order);
-use JSON::PP;
-use List::Util qw(first);
-
-binmode STDOUT, 'encoding(UTF-8)';
-binmode STDERR, 'encoding(UTF-8)';
-
-our $optExec;
-our $optFork = 0;
-our $optHelp = 0;
-our $optQuiet = 0;
-
-GetOptions(
- 'exec|e=s' => \$optExec,
- 'fork|f' => \$optFork,
- 'help|h' => sub { pod2usage(0); },
- 'quiet|q' => \$optQuiet,
-);
-
-if ($#ARGV == -1) {
- pod2usage(0);
-}
-
-my $module = shift @ARGV;
-my $exec = $optExec // $module;
-
-# According to XDG spec, if $XDG_STATE_HOME is not set, then we should default
-# to ~/.local/state
-my $xdgStateHome = $ENV{XDG_STATE_HOME} // "$ENV{HOME}/.local/state";
-my $dataFileName = "kdesrc-build-data";
-my @possibleDataPaths = ("./.$dataFileName", "$xdgStateHome/$dataFileName");
-my $buildDataFile = first { -e $_ } (@possibleDataPaths);
-
-if (not defined $buildDataFile) {
- say qq("$dataFileName" file is not available. Exit now.);
- exit 1;
-}
-
-my $buildData = do {
- open my $fh, '<', $buildDataFile;
- local $/ = undef;
- decode_json(<$fh>);
-};
-
-if (not defined $buildData->{$module}) {
- say qq(Module "$module" has not been built yet.);
- exit 1;
-}
-
-my $buildDir = $buildData->{$module}{'build-dir'};
-my $installDir = $buildData->{$module}{'install-dir'};
-my $revision = $buildData->{$module}{'last-build-rev'};
-my $execPath = "$installDir/bin/$exec";
-
-if (not -e $execPath) {
- say qq(Program "$exec" does not exist.);
- say qq(Try to set executable name with -e option.);
- exit 127; # Command not found
-}
-
-# Most of the logic is done by Perl, so the shell script here should be POSIX
-# compliant. Consider using ShellCheck to make sure of that.
-my $script = qq{
- #!/bin/sh
-
- # Set up environment variables (dot command).
- . "$buildDir/prefix.sh";
-
- # Launch the program with optional arguments.
- if [ "$optFork" = 1 ]; then
- setsid -f "$execPath" "\$@";
- else
- "$execPath" "\$@";
- fi;
-};
-
-# Print run information
-if (not $optQuiet) {
- print '#' x 80, "\n";
- print ' ' x 35, 'kdesrc-run', "\n";
- say "Module: $module";
- say "Program: $exec";
- say "Revision: $revision";
- say "Arguments: @ARGV";
- print '#' x 80, "\n";
- print "\n";
-}
-
-# Instead of embedding @ARGV in shell script with string interpolation, pass
-# them as arguments of the script. Let the shell handle the list through "$@",
-# so it will do the quoting on each one of them.
-#
-# Run the script with sh options specification:
-# sh -c command_string command_name $1 $2 $3...
-exec('/bin/sh', '-c', $script, $exec, @ARGV);
diff --git a/modules/ksb/Application.pm b/modules/ksb/Application.pm
index 952f3f8f..fd17662f 100644
--- a/modules/ksb/Application.pm
+++ b/modules/ksb/Application.pm
@@ -38,6 +38,7 @@ use ksb::ModuleSet 0.20;
use ksb::ModuleSet::KDEProjects;
use ksb::ModuleSet::Qt;
use ksb::RecursiveFH;
+use ksb::StartProgram;
use ksb::TaskManager;
use ksb::Updater::Git;
use ksb::Util;
@@ -324,13 +325,8 @@ EOF
# For user convenience, cmdline ignored selectors would not override the config selectors. Instead, they will be merged.
my %ignoredSelectors = (%ignored_in_cmdline, %ignored_in_global_section);
- # Check if we're supposed to drop into an interactive shell instead. If so,
- # here's the stop off point.
-
if (@startProgramAndArgs) {
- $ctx->setupEnvironment(); # Read options from set-env
- $ctx->commitEnvironmentChanges(); # Apply env options to environment
- _executeCommandLineProgram(@startProgramAndArgs); # noreturn
+ StartProgram::executeCommandLineProgram($ctx, @startProgramAndArgs); # noreturn
}
if (!isTesting()) {
@@ -1198,40 +1194,6 @@ sub _readConfigurationOptions ($ctx, $fh, $cmdlineGlobalOptions, $deferredOption
return @module_list;
}
-# Exits out of kdesrc-build, executing the user's preferred shell instead. The
-# difference is that the environment variables should be as set in kdesrc-build
-# instead of as read from .bashrc and friends.
-#
-# You should pass in the options to run the program with as a list.
-#
-# Meant to implement the --run command line option.
-sub _executeCommandLineProgram
-{
- my ($program, @args) = @_;
-
- if (!$program)
- {
- error ("You need to specify a program with the --run option.");
- exit 1; # Can't use finish here.
- }
-
- if (($< != $>) && ($> == 0))
- {
- error ("kdesrc-build will not run a program as root unless you really are root.");
- exit 1;
- }
-
- debug ("Executing b[r[$program] ", join(' ', @args));
-
- exit 0 if pretending();
-
- exec $program, @args or do {
- # If we get to here, that sucks, but don't continue.
- error ("Error executing $program: $!");
- exit 1;
- };
-}
-
# Function: _handle_install
#
# Handles the installation process. Simply calls 'make install' in the build
diff --git a/modules/ksb/Cmdline.pm b/modules/ksb/Cmdline.pm
index 2950c890..cb1666e4 100644
--- a/modules/ksb/Cmdline.pm
+++ b/modules/ksb/Cmdline.pm
@@ -232,7 +232,6 @@ sub readCommandLineOptionsAndSelectors (@options)
# Getopt::Long doesn't set these up for us even though we specify an
# array. Set them up ourselves.
- 'start-program' => [ ],
'ignore-modules' => [ ],
# Module selectors, the <> is Getopt::Long shortcut for an
@@ -256,6 +255,26 @@ sub readCommandLineOptionsAndSelectors (@options)
# build options for Getopt::Long
my @supportedOptions = _supportedOptions();
+ # If we have --run option, grab all the rest arguments to pass to the corresponding parser.
+ # This way the arguments after --run could start with "-" or "--".
+ my $run_index = -1;
+ foreach my $i (0 .. $#options) {
+ if ($options[$i] eq "--run" or $options[$i] eq "--start-program") {
+ $run_index = $i;
+ last;
+ }
+ }
+
+ if ($run_index != -1) {
+ @{ $opts->{"start-program"} } = @options[$run_index+1 .. $#options];
+ @options = @options[0 .. $run_index-1]; # remove all after --run, and the --run itself
+
+ if (! @{ $opts->{"start-program"} }){ # check this here, because later the empty list will be treated as not wanting to start program
+ error ("You need to specify a module with the --run option");
+ exit 1; # Do not continue
+ }
+ }
+
# Actually read the options.
my $optsSuccess = GetOptionsFromArray(\@options, \%foundOptions,
# Options here should not duplicate the flags and options defined below
@@ -269,9 +288,8 @@ sub readCommandLineOptionsAndSelectors (@options)
croak_runtime("Error reading command-line options.");
}
- # Don't get ignore-modules and start-program (i.e. --run) confused with
- # global options
- my @protectedKeys = ('ignore-modules', 'start-program');
+ # Don't get ignore-modules confused with global options
+ my @protectedKeys = ('ignore-modules');
@{$opts}{@protectedKeys} = @foundOptions{@protectedKeys};
delete @foundOptions{@protectedKeys};
@@ -438,7 +456,6 @@ sub _supportedOptions
'set-module-option-value=s',
'show-info',
'show-options-specifiers',
- 'start-program|run=s{,}',
'stop-after|to=s',
'stop-before|until=s',
'version|v',
diff --git a/modules/ksb/StartProgram.pm b/modules/ksb/StartProgram.pm
new file mode 100644
index 00000000..9e97b5a4
--- /dev/null
+++ b/modules/ksb/StartProgram.pm
@@ -0,0 +1,122 @@
+package StartProgram;
+
+use ksb;
+use ksb::Debug;
+
+=pod
+
+=encoding UTF-8
+
+=head1 SYNOPSIS
+
+kdesrc-build --run [options] <module-name> [arguments]
+
+=head1 OPTIONS
+
+ -e, --exec <program> Specify program of the module. Default to module name.
+ -f, --fork Launch the program in a new session.
+
+=head1 EXAMPLES
+
+B<kdesrc-build --run -f kate -l 5 file1.txt>
+
+ Launch kate in a new session with '-l 5 file1.txt' arguments.
+
+B<kdesrc-build --run -e kate-syntax-highlighter kate --list-themes>
+
+ Launch kate-syntax-highlighter of module kate with '--list-themes' argument.
+
+=cut
+
+sub executeCommandLineProgram
+{
+ my ($ctx, @args) = @_;
+
+ my $optExec = undef;
+ my $optFork = 0;
+
+ # We cannot use GetOptionsFromArray here, because -e or -f could be meant to be arguments of module executable. But that would steal them.
+ # We manually care of them, they can only appear in front of module/executable name.
+ my $arg;
+ while ($arg = shift @args) {
+ if ($arg eq "-f" || $arg eq "--fork") {
+ $optFork = 1;
+ next;
+ } elsif ($arg eq "-e" || $arg eq "--exec") {
+ $optExec = shift @args;
+ if (not defined $optExec){
+ error("-e option requires a name of executable");
+ exit(1)
+ }
+ next;
+ }
+ last;
+ }
+
+ my $module = $arg;
+ if (not defined $module) { # the case when user specified -e executable_name and/or -f, but then did not specified the module name
+ error("The module name is missing");
+ exit 1;
+ }
+ my $executable = $optExec // $module;
+ my $buildData = $ctx->{persistent_options};
+
+ if (not defined $buildData->{$module}) {
+ say qq(Module "$module" has not been built yet.);
+ exit 1;
+ }
+
+ my $buildDir = $buildData->{$module}{'build-dir'};
+ my $installDir = $buildData->{$module}{'install-dir'};
+ my $revision = $buildData->{$module}{'last-build-rev'};
+ my $execPath = "$installDir/bin/$executable";
+
+ if (not -e $execPath) {
+ say qq(Executable "$executable" does not exist.);
+ say qq(Try to set executable name with -e option.);
+ exit 127; # Command not found
+ }
+
+ # Most of the logic is done by Perl, so the shell script here should be POSIX
+ # compliant. Consider using ShellCheck to make sure of that.
+ my $script = <<~EOF;
+ #!/bin/sh
+
+ # Set up environment variables (dot command).
+ . "$buildDir/prefix.sh"
+
+ # Launch the program with optional arguments.
+ if [ "$optFork" = 1 ]; then
+ setsid -f "$execPath" \$@
+ else
+ "$execPath" \$@
+ fi
+ EOF
+
+ # Print run information
+ note (
+ "#" x 80, "\n",
+ "Module: $module\n",
+ "Executable: $executable\n",
+ "Revision: $revision\n",
+ "Arguments: @args\n",
+ "#" x 80, "\n",
+ "\n"
+ );
+
+ exit 0 if pretending();
+
+ # Instead of embedding @args in shell script with string interpolation, pass
+ # them as arguments of the script. Let the shell handle the list through "$@",
+ # so it will do the quoting on each one of them.
+ #
+ # Run the script with sh options specification:
+ # sh -c command_string command_name $1 $2 $3...
+ exec('/bin/sh', '-c', $script, "kdesrc-build run script", @args) or do {
+ # If we get to here, that sucks, but don't continue.
+ error ("Error executing $executable: $!");
+ exit 1;
+ };
+}
+
+1;
diff --git a/modules/ksb/TaskManager.pm b/modules/ksb/TaskManager.pm
index b97269b8..765fcf4c 100644
--- a/modules/ksb/TaskManager.pm
+++ b/modules/ksb/TaskManager.pm
@@ -153,7 +153,7 @@ sub _handle_updates ($ipc, $ctx)
# running ->update() from short-circuiting if an error is noted.
$hadError = !$module->update($ipc, $ctx) || $hadError;
- # Cache module directories, e.g. to be consumed in kdesrc-run
+ # Cache module directories, e.g. to be consumed in kdesrc-build --run
# This is needed for --no-async mode where the buildSingleModule won't run
# But the other one is needed for --async mode since persistent options
# only work from within the build process
@@ -173,7 +173,7 @@ sub _buildSingleModule ($ipc, $ctx, $module, $startTimeRef)
$ctx->resetEnvironment();
$module->setupEnvironment();
- # Cache module directories, e.g. to be consumed in kdesrc-run
+ # Cache module directories, e.g. to be consumed in kdesrc-build --run
$module->setPersistentOption('source-dir', $module->fullpath('source'));
$module->setPersistentOption('build-dir', $module->fullpath('build'));
$module->setPersistentOption('install-dir', $module->installationPath());
diff --git a/scripts/gen_zsh_completions.py b/scripts/gen_zsh_completions.py
index 64a392c5..7895130c 100644
--- a/scripts/gen_zsh_completions.py
+++ b/scripts/gen_zsh_completions.py
@@ -178,7 +178,7 @@ short_descriptions = { # contains one of the options (any of them) from set, an
"--resume": "Resume after a build failure",
"--resume-from": "Skips modules until just before or after the given package, then operates as normal",
"--revision": "Checkout a specific numbered revision",
- "--run": "A program to run with kdesrc-build",
+ # "--run": "A program to run with kdesrc-build", # Todo Needs to be added separately
"--run-tests": "Built the modules with support for running their test suite",
"--set-module-option-value": "Override an option in your configuration file for a specific module",
"--source-dir": "Directory that stores the KDE sources",
More information about the kde-doc-english
mailing list