Patchwork [3/7] support/scripts: add a script to automate the migration to _AVAILABLE

login
register
mail settings
Submitter Yann E. MORIN
Date Sept. 9, 2012, 11:40 p.m.
Message ID <1347234052-10527-4-git-send-email-yann.morin.1998@free.fr>
Download mbox | patch
Permalink /patch/182755/
State Rejected
Headers show

Comments

Yann E. MORIN - Sept. 9, 2012, 11:40 p.m.
This script runs three passes on the packages' Config.in files:

1) - introduces a BR2_PACKAGE_XXX_AVAILABLE symbol
   - moves all the package dependencies to this symbol
   - has the package depends only on this symbol

2) - transforms all 'depends on BR2_PACKAGE_XXX' into a dependency
     on the corresponding _AVAILABLE symbol
   - adds a select on the corresponding package

3) - checks and fixes 'select BR2_PACKAGE_XXX' that does not have a
     corresponding 'depends on BR2_PACKAGE_XXX_AVAILABLE'

NOTE: the coverage of this script is NOT 100%. Some manual inspection
and fixers are still required.

Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
---
 support/scripts/pkg-avail |  286 +++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 286 insertions(+), 0 deletions(-)
 create mode 100755 support/scripts/pkg-avail

Patch

diff --git a/support/scripts/pkg-avail b/support/scripts/pkg-avail
new file mode 100755
index 0000000..1f616fd
--- /dev/null
+++ b/support/scripts/pkg-avail
@@ -0,0 +1,286 @@ 
+#!/bin/bash
+set -e
+
+#-----------------------------------------------------------------------------
+# Find all packages and introduce the _AVAILABLE symbols for each of them
+# 10 packages per cset, it's easier to review
+
+AWK_SCRIPT_ADD='
+BEGIN {
+    nb_lines = 0;
+    delete lines;
+}
+
+{ lines[nb_lines++] = $0; }
+
+END {
+    PKG = toupper( pkg );
+    is_pkg = 0;
+    for( i = 0; i < nb_lines; i++ ) {
+        if( lines[i] ~ "^(menu)?config[[:space:]]+BR2_PACKAGE_" PKG "([[:space:]]+.*)?$" ) {
+            pkg_line = lines[i];
+            printf( "config BR2_PACKAGE_%s_AVAILABLE\n", PKG );
+            printf( "\tdef_bool y\n" );
+            is_pkg = 1;
+            break;
+        }
+        printf( "%s\n", lines[i] );
+    }
+
+    if( is_pkg ) {
+        deps_end = i+1;
+        nb_not_deps = 0;
+        while( deps_end < nb_lines ) {
+            if( lines[deps_end] ~ "^([[:space:]]+help)?$" ) {
+                break;
+            } else if ( lines[deps_end] ~ "^[[:space:]]+depends on " ) {
+                print lines[deps_end];
+                while( lines[deps_end] ~ "\\\\$" ) {
+                    deps_end++;
+                    print lines[deps_end];
+                }
+            } else {
+                not_deps[nb_not_deps++] = lines[deps_end];
+            }
+            deps_end++;
+        }
+        printf( "\n" );
+
+        printf( "%s\n", pkg_line );
+        for( i = 0; i < nb_not_deps; i++ ) {
+            printf( "%s\n", not_deps[i] );
+        }
+        printf( "\tdepends on BR2_PACKAGE_%s_AVAILABLE\n", PKG );
+
+        for( i = deps_end; i < nb_lines; i++ ) {
+            printf( "%s\n", lines[i] );
+        }
+    }
+}
+'
+
+#-----------------------------------------------------------------------------
+# Find all packages that depends on another package, and switch that to
+# the new _AVAILABLE dependency, plus a select on the main symbol
+
+AWK_SCRIPT_USE='
+BEGIN {
+    nb_lines = 0;
+    delete lines;
+}
+
+{ lines[nb_lines++] = $0; }
+
+END {
+    PKG = toupper( pkg );
+    nb_depends = 0;
+    delete depends;
+    for( i = 0; i < nb_lines; i++ ) {
+        if( lines[i] == "" ) {
+            break;
+        } else if( lines[i] ~ "^[[:space:]]+depends on BR2_PACKAGE_[^|&[:space:]]+$" ) {
+            pkg = gensub( "^[[:space:]]+depends on BR2_PACKAGE_([^[:space:]]+).*$",
+                          "\\1", "g", lines[i] );
+            depends[nb_depends++] = pkg;
+            printf( "\tdepends on BR2_PACKAGE_%s_AVAILABLE\n", pkg );
+        } else {
+            printf( "%s\n", lines[i] );
+        }
+    }
+
+    for( ; i < nb_lines; i++ ) {
+        printf( "%s\n", lines[i] );
+        if( lines[i] ~ "^(menu)?config BR2_PACKAGE_" PKG "$" ) {
+            while( lines[++i] !~ "^([[:space:]]+(select|help)|[[:space:]]*$)" ) {
+                printf( "%s\n", lines[i] );
+            }
+            break;
+        }
+    }
+
+    for( j=0; j < nb_depends; j++ ) {
+        printf( "\tselect BR2_PACKAGE_%s\n", depends[j] );
+    }
+
+    for( ; i < nb_lines; i++ ) {
+        printf( "%s\n", lines[i] );
+    }
+}
+'
+
+#-----------------------------------------------------------------------------
+# Check that all 'select' on packages have a corresponding 'depends on' the
+# corresponding _AVAILABLE symbol
+
+AWK_SCRIPT_CHECK='
+BEGIN {
+    nb_lines = 0;
+    delete lines;
+}
+
+{ lines[nb_lines++] = $0; }
+
+END {
+    PKG = toupper( pkg );
+    delete selects;
+
+    for( i = 0; i < nb_lines; i++ ) {
+        if( lines[i] ~ "^(menu)?config BR2_PACKAGE_" PKG "$" ) {
+            break;
+        }
+    }
+
+    for( ; i < nb_lines; i++ ) {
+        if( lines[i] ~ "^([[:space:]]+help|$)" ) {
+            break
+        } else if( lines[i] ~ "^[[:space:]]+select BR2_PACKAGE_[^|&[:space:]]+$" ) {
+            pkg = gensub( "^[[:space:]]+select BR2_PACKAGE_([^[:space:]]+)$",
+                          "\\1", "g", lines[i] );
+            selects[pkg] = 1;
+        }
+    }
+
+    for( i = 0; i < nb_lines; i++ ) {
+        printf( "%s\n", lines[i] );
+        if( lines[i] ~ "^config BR2_PACKAGE_" PKG "_AVAILABLE$" ) {
+            break;
+        }
+    }
+
+    for( i++; i < nb_lines; i++ ) {
+        if( lines[i] == "" ) {
+            break;
+        } else if( lines[i] ~ "^[[:space:]]+depends on BR2_PACKAGE_[^|&[:space:]]+_AVAILABLE$" ) {
+            pkg = gensub( "^[[:space:]]+depends on BR2_PACKAGE_([^[:space:]]+)_AVAILABLE$",
+                          "\\1", "g", lines[i] );
+            selects[pkg] = 0;
+        }
+        printf( "%s\n", lines[i] );
+    }
+
+    for( pkg in selects ) {
+        if( selects[pkg] == 1 ) {
+            printf( "\tdepends on BR2_PACKAGE_%s_AVAILABLE\n", toupper( pkg ) );
+        }
+    }
+
+    for( ; i < nb_lines; i++ ) {
+        printf( "%s\n", lines[i] );
+    }
+}
+'
+
+
+#-----------------------------------------------------------------------------
+
+munge_files() {
+    local awk_script="${1}"
+
+    find package -type f -name Config.in    \
+    |sort                                   \
+    |(while read in_file; do
+        pkg="${in_file%/*}"
+        pkg="${pkg##*/}"
+        i=${i:-0}
+        printf "\rMunging package %s (%d)...                                    \r"   \
+               "${pkg}" ${i}
+        gawk -v pkg="${pkg//-/_}" "${awk_script}" "${in_file}" >/tmp/Config.in
+        mv /tmp/Config.in "${in_file}"
+        i=$((i+1))
+      done
+      printf "\n"
+    )
+}
+
+# I have a local patch that updates the doc for the _AVAILABLE stuff,
+# and I want all munging patches to be pushed after that
+stg push -a >/dev/null 2>&1 || true
+
+# Add the _AVAILABLE symbols...
+cat >/tmp/commit.msg <<-_EOF_
+	packages: introduce the _AVAILABLE symbol to all packages
+	
+	Introducing this symbol to all packages will allow other packages
+	to both safely select a package, and inherit its dependency.
+	
+	Given two packages, the mechanism works as follow:
+	
+	    ---8<---
+	    config BR2_PKG_FOO_AVAILABLE
+	    	depends on BR2_LARGEFILE
+	
+	    config BR2_PKG_FOO
+	    	bool "foo"
+	    	depends on BR2_PKG_FOO_AVAILABLE
+	    ---8<---
+	
+	    ---8<---
+	    config BR2_PKG_BAR_AVAILABLE
+	    	def_bool y
+	    	depends on BR2_PKG_FOO_AVAILABLE
+	    	depends on BR2_HAS_THREADS
+	
+	    config BR2_PKG_BAR
+	        bool "bar"
+	    	depends on BR2_PKG_BAR_AVAILABLE
+	    	select BR2_PKG_FOO
+	    ---8<---
+	
+	In this case, the 'select' on package 'foo' from package 'bar' is possible,
+	because package 'bar' inherits, via the BR2_PKG_BAR_AVAILABLE symbol, the
+	same dependencies as package 'foo'. So, package 'bar' can not be visible
+	if package 'foo' is not (although 'bar' may be hidden because of other
+	dependencies of its own, missing threads in the example).
+	
+	This patch only introduces this new symbol for all packages, moves the
+	packages' dependencies to these new symbols, and makes each package depend
+	solely on this new symbol. Cross-package use of 'select' will be introduced
+	in a later patch.
+	
+	With the construct above, using 'select' is now safe.
+_EOF_
+stg new --sign -f /tmp/commit.msg pkg-add-available
+rm /tmp/commit.msg
+munge_files "${AWK_SCRIPT_ADD}"
+stg refresh
+
+# ... and use them, now! ;-)
+cat >/tmp/commit.msg <<-_EOF_
+	packages: use the newly-introduced _AVAILABLE symbol
+	
+	This patch transforms all 'depends on' on a package to a 'depends on'
+	the corresponding _AVAILABLE symbol, and adds a 'select' against the
+	dependant package.
+_EOF_
+stg new --sign -f /tmp/commit.msg pkg-use-available
+rm /tmp/commit.msg
+munge_files "${AWK_SCRIPT_USE}"
+stg refresh
+
+# Finally, check for missing 'depends on ..._AVAILABLE'
+cat >/tmp/commit.msg <<-_EOF_
+	packages: check proper use of 'select' against packages
+	
+	This patch checks that all 'select' on a package have a 'depends on'
+	on the corresponding _AVAILABLE symbol.
+_EOF_
+stg new --sign -f /tmp/commit.msg pkg-check-available
+rm /tmp/commit.msg
+munge_files "${AWK_SCRIPT_CHECK}"
+stg refresh
+
+# And eventually, get rid of ourselves (Seppuku!)
+cat >/tmp/commit.msg <<-_EOF_
+	script/support: get rid of now-useless pkg-avail script
+	
+	This script has done its job, and is no-longer needed.
+	RIP, script!
+_EOF_
+stg new --sign -f /tmp/commit.msg pkg-delete-pkg_avail
+rm /tmp/commit.msg
+rm -f support/scripts/pkg-avail
+git rm support/scripts/pkg-avail
+stg refresh
+
+# And eventually, get rid of ourselves (Seppuku!)
+