├── .gitignore
├── doc
├── README
├── AUTHORS
└── FAQ
├── share
├── icons
│ └── hicolor
│ │ ├── 16x16
│ │ └── mimetypes
│ │ │ ├── application-x-gobo-recipe.png
│ │ │ └── text-x-gobo-recipe-source.png
│ │ ├── 22x22
│ │ └── mimetypes
│ │ │ ├── application-x-gobo-recipe.png
│ │ │ └── text-x-gobo-recipe-source.png
│ │ ├── 32x32
│ │ └── mimetypes
│ │ │ ├── application-x-gobo-recipe.png
│ │ │ └── text-x-gobo-recipe-source.png
│ │ ├── 48x48
│ │ └── mimetypes
│ │ │ ├── application-x-gobo-recipe.png
│ │ │ └── text-x-gobo-recipe-source.png
│ │ └── 64x64
│ │ └── mimetypes
│ │ ├── application-x-gobo-recipe.png
│ │ └── text-x-gobo-recipe-source.png
├── applications
│ ├── Compile.desktop
│ └── MakeRecipe.desktop
├── mime-info
│ └── Compile.keys
├── mime
│ └── packages
│ │ └── Compile.xml
└── mimelnk
│ ├── text
│ └── x-gobo-recipe-source.desktop
│ └── application
│ └── x-gobo-recipe.desktop
├── Functions
├── BuildType_meta
├── BuildType_makefile
├── BuildType_manifest
├── BuildType_xmkmf
├── BuildType_scons
├── BuildType_cmake
├── BuildType_meson
├── BuildType_waf
├── BuildType_cabal
├── BuildType_configure
├── UnionFS
├── BuildType_python
├── RecipeTools
└── Compile
├── lib
└── ruby
│ └── site_ruby
│ └── 1.8
│ ├── gobo
│ ├── template.rb
│ ├── commandapplication.rb
│ ├── logconsole.rb
│ └── parseconfig.rb
│ └── gobo.rb
├── bin
├── ColorMake
├── GoboPath2Ruby
├── NoRecipe
├── GetRecipe
├── EditRecipe
├── ApplyVariables
├── UpdateRecipes
├── AutoPatch
├── PrepareProgram
├── FetchArchive
├── UnionSandbox
├── NewVersion
├── SandboxInstall
├── ContributeRecipe
├── MakeRecipe
└── RecipeLint
├── Resources
├── Defaults
│ └── Settings
│ │ └── Compile
│ │ └── Compile.conf
└── Dependencies
├── Makefile
└── examples
├── GoboSimpleExample.rb
└── GoboBigExample.rb
/.gitignore:
--------------------------------------------------------------------------------
1 | *.swp
2 | *~
3 | Resources/MetaData
4 | share/man/
5 |
--------------------------------------------------------------------------------
/doc/README:
--------------------------------------------------------------------------------
1 |
2 | For documentation on supported options in recipes, see
3 | http://gobo.kundor.org/wiki/Recipe_format_specification
4 |
5 |
--------------------------------------------------------------------------------
/share/icons/hicolor/16x16/mimetypes/application-x-gobo-recipe.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gobolinux/Compile/HEAD/share/icons/hicolor/16x16/mimetypes/application-x-gobo-recipe.png
--------------------------------------------------------------------------------
/share/icons/hicolor/16x16/mimetypes/text-x-gobo-recipe-source.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gobolinux/Compile/HEAD/share/icons/hicolor/16x16/mimetypes/text-x-gobo-recipe-source.png
--------------------------------------------------------------------------------
/share/icons/hicolor/22x22/mimetypes/application-x-gobo-recipe.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gobolinux/Compile/HEAD/share/icons/hicolor/22x22/mimetypes/application-x-gobo-recipe.png
--------------------------------------------------------------------------------
/share/icons/hicolor/22x22/mimetypes/text-x-gobo-recipe-source.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gobolinux/Compile/HEAD/share/icons/hicolor/22x22/mimetypes/text-x-gobo-recipe-source.png
--------------------------------------------------------------------------------
/share/icons/hicolor/32x32/mimetypes/application-x-gobo-recipe.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gobolinux/Compile/HEAD/share/icons/hicolor/32x32/mimetypes/application-x-gobo-recipe.png
--------------------------------------------------------------------------------
/share/icons/hicolor/32x32/mimetypes/text-x-gobo-recipe-source.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gobolinux/Compile/HEAD/share/icons/hicolor/32x32/mimetypes/text-x-gobo-recipe-source.png
--------------------------------------------------------------------------------
/share/icons/hicolor/48x48/mimetypes/application-x-gobo-recipe.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gobolinux/Compile/HEAD/share/icons/hicolor/48x48/mimetypes/application-x-gobo-recipe.png
--------------------------------------------------------------------------------
/share/icons/hicolor/48x48/mimetypes/text-x-gobo-recipe-source.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gobolinux/Compile/HEAD/share/icons/hicolor/48x48/mimetypes/text-x-gobo-recipe-source.png
--------------------------------------------------------------------------------
/share/icons/hicolor/64x64/mimetypes/application-x-gobo-recipe.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gobolinux/Compile/HEAD/share/icons/hicolor/64x64/mimetypes/application-x-gobo-recipe.png
--------------------------------------------------------------------------------
/share/icons/hicolor/64x64/mimetypes/text-x-gobo-recipe-source.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gobolinux/Compile/HEAD/share/icons/hicolor/64x64/mimetypes/text-x-gobo-recipe-source.png
--------------------------------------------------------------------------------
/Functions/BuildType_meta:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | meta_do_install() {
4 | # All installation is performed by the recipes declared
5 | # in the include=() array. We just have to return success
6 | # to keep the caller happy.
7 | true
8 | }
9 |
--------------------------------------------------------------------------------
/share/applications/Compile.desktop:
--------------------------------------------------------------------------------
1 | [Desktop Entry]
2 | Encoding=UTF-8
3 | Version=1.0
4 | Name=Compile
5 | GenericName=Compilation tool
6 | Type=Application
7 | Comment=GoboLinux compilation tool
8 | Exec=Compile
9 | ShowOnlyIn=
10 | Terminal=true
11 | NoDisplay=true
12 | MultipleArgs=false
13 | InitialPreference=5
14 | MimeType=application/x-gobo-recipe;
15 |
--------------------------------------------------------------------------------
/share/mime-info/Compile.keys:
--------------------------------------------------------------------------------
1 | application/x-gobo-recipe
2 | category=Archive
3 | description=GoboLinux recipe
4 | icon_filename=application-x-gobo-recipe
5 | open=Compile %f
6 | short_list_application_ids_for_novice_user_level=Compile
7 | short_list_application_ids_for_intermediate_user_level=Compile
8 | short_list_application_ids_for_advanced_user_level=Compile
--------------------------------------------------------------------------------
/lib/ruby/site_ruby/1.8/gobo/template.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/ruby (require)
2 |
3 | # GoboLinux template for creating Ruby classes/libraries
4 |
5 | class GoboFoo
6 | public # Public attributes
7 | private # Private instance/class variables
8 | public # Public methods
9 | def initialize()
10 | end
11 | protected # Protected methods
12 | private # Private methods
13 | end
14 |
15 |
--------------------------------------------------------------------------------
/share/applications/MakeRecipe.desktop:
--------------------------------------------------------------------------------
1 | [Desktop Entry]
2 | Encoding=UTF-8
3 | Version=1.0
4 | Name=MakeRecipe
5 | GenericName=Recipe creation tool
6 | Type=Application
7 | Comment=Tool to create a GoboLinux recipe
8 | Exec=MakeRecipe
9 | ShowOnlyIn=
10 | Terminal=true
11 | NoDisplay=true
12 | MultipleArgs=false
13 | InitialPreference=15
14 | MimeType=application/x-bzip2-compressed-tar;application/x-bzip;application/x-bzip-compressed-tar;application/x-gzip;application/x-tbz;application/x-bzip2;application/x-compressed-tar;application/x-tar;application/x-gzip;
15 |
--------------------------------------------------------------------------------
/bin/ColorMake:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | . ScriptFunctions
4 | Import File
5 | Import GoboLinux
6 |
7 | makecmd="$(which make)"
8 |
9 | for i in "$@"
10 | do
11 | if [ "$i" = "menuconfig" ]
12 | then exec $makecmd "$@"
13 | fi
14 | done
15 |
16 | if Quiet which mtail; then
17 | $makecmd "$@" 2>&1 | mtail --config="`Find_Conf ColorMake.mtailrc`" -q
18 | exit ${PIPESTATUS[0]}
19 | elif Quiet which ccze; then
20 | $makecmd "$@" 2>&1 | ccze --raw-ansi
21 | else
22 | Log_Terse "mtail not found. Unable to colorize output."
23 | $makecmd "$@"
24 | fi
25 |
--------------------------------------------------------------------------------
/Functions/BuildType_makefile:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | makefile_do_configuration() {
4 | Add_Use_Flags_Options_To_Array buildmerged
5 | }
6 |
7 | makefile_do_build() {
8 | $make $build_target ${buildmerged:+"${buildmerged[@]}"} -f $makefile || wrap_fail "Build process failed."
9 | }
10 |
11 | makefile_do_install() {
12 | SandboxInstall $verbose ${unmanagedlist:+--unmanaged-files "${unmanagedlist}"} ${sandboxopts:+"${sandboxopts[@]}"} --make "$make" --makefile $makefile --target "$install_target" "$1" "$2" -- "${installmerged[@]}" || wrap_fail "Installation step failed."
13 | }
14 |
--------------------------------------------------------------------------------
/Resources/Defaults/Settings/Compile/Compile.conf:
--------------------------------------------------------------------------------
1 |
2 | # Add your name here so that credit is added to recipes.
3 | #compileRecipeAuthor=""
4 |
5 | compileDir="${goboPrefix}/Data/Compile"
6 | compileArchivesDir="$compileDir/Archives"
7 | compileSourcesDir="$compileDir/Sources"
8 | compileRecipesDir="$compileDir/Recipes"
9 |
10 | # Main free software repositories
11 | ftpGnu=ftp://ftp.gnu.org/gnu
12 | ftpAlphaGnu=ftp://alpha.gnu.org/gnu
13 | httpSourceforge=https://downloads.sourceforge.net
14 |
15 | compileRecipesRepository=https://github.com/gobolinux/Recipes.git
16 | compileUpstreamBranch=master
17 |
--------------------------------------------------------------------------------
/share/mime/packages/Compile.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | GoboLinux recipe
6 |
7 |
8 |
9 |
10 | GoboLinux recipe source file
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/bin/GoboPath2Ruby:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | . GoboPath
4 |
5 | echo "Users = \"${goboUsers}\""
6 | echo "Mount = \"${goboMount}\""
7 | echo "Programs = \"${goboPrograms}\""
8 | echo "System = \"${goboSystem}\""
9 | echo "Links = \"${goboLinks}\""
10 | echo "Scripts = \"${goboScripts}\""
11 | echo "Variable = \"${goboVariable}\""
12 | echo "Settings = \"${goboSettings}\""
13 | echo "Executables = \"${goboExecutables}\""
14 | echo "Libraries = \"${goboLibraries}\""
15 | echo "Headers = \"${goboHeaders}\""
16 | echo "Manuals = \"${goboManuals}\""
17 | echo "Shared = \"${goboShared}\""
18 | echo "Boot = \"${goboBoot}\""
19 | echo "Temp = \"${goboTemp}\""
20 | echo "Devices = \"${goboDevices}\""
21 | echo "Status = \"${goboStatus}\""
22 | echo "Environment = \"${goboEnvironment}\""
23 | echo "UserSettings = \"${goboUserSettings}\""
24 |
25 |
--------------------------------------------------------------------------------
/Functions/BuildType_manifest:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | manifest_do_install() {
4 | for i in "${manifest[@]}"
5 | do
6 | src=`echo $i | cut -d: -f1`
7 | dst=`echo $i | cut -d: -f2-`
8 | if [ $(basename $(pwd)) != $(basename "${dir}") ]
9 | then
10 | fullsrc="${dir}/${src}"
11 | else
12 | fullsrc="${src}"
13 | fi
14 | fulldst="${installprefix}/${dst}"
15 | mkdir -p $(dirname "$fulldst")
16 | if Ends_With "/" "$fulldst"
17 | then
18 | mkdir -p "$fulldst"
19 | fi
20 | Log_Normal "Installing ${fullsrc} into ${fulldst}"
21 | if [ -d "${fullsrc}" -a -d "${fulldst}" ]
22 | then cp -Rv --no-preserve=ownership "${fullsrc}"/* "${fulldst}"
23 | else cp -Rv --no-preserve=ownership ${fullsrc} "${fulldst}"
24 | fi
25 | done
26 | }
27 |
--------------------------------------------------------------------------------
/bin/NoRecipe:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | . ScriptFunctions
3 | Import GoboLinux
4 | Import RecipeTools
5 |
6 | Parse_Conf Compile.conf
7 | cat <= 3.0.0 # Meson build type
22 | Scripts > 2.9.8
23 | Sed
24 | Sudo
25 | Wget # used by FetchArchive script
26 | PIP3:meson # used by BuildType_meson
27 | PIP3:ninja # used by BuildType_cmake|meson
28 |
--------------------------------------------------------------------------------
/Functions/BuildType_xmkmf:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | Import BuildType_makefile
4 |
5 | xmkmf_do_configuration() {
6 | xmkmf
7 | buildmerged=(
8 | "BINDIR=$target/bin"
9 | "LIBDIR=$target/lib"
10 | "LIBEXECDIR=$target/libexec"
11 | "INCDIR=$target/include"
12 | "IRULESRC=$goboLibraries/X11/config"
13 | "${buildmerged[@]}"
14 | )
15 | installmerged=(
16 | "BINDIR=$installprefix/bin"
17 | "LIBDIR=$installprefix/lib"
18 | "LIBEXECDIR=$installprefix/libexec"
19 | "INCDIR=$installprefix/include"
20 | "IRULESRC=$goboLibraries/X11/config"
21 | "${installmerged[@]}"
22 | )
23 |
24 | buildmerged=(`echo ${buildmerged[@]} | sed "s,$target,$goboIndex,g"`)
25 | installmerged=(`echo ${installmerged[@]} | sed "s,$target,$goboIndex,g"`)
26 | $make Makefiles "${buildmerged[@]}"
27 | }
28 |
29 | xmkmf_do_build() {
30 | makefile_do_build
31 | }
32 |
33 | xmkmf_do_install() {
34 | makefile_do_install "${1}" "${2}"
35 | }
36 |
--------------------------------------------------------------------------------
/Functions/BuildType_scons:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | scons_sane_check() {
3 | Quiet scons --version || Die "This is a scons type recipe and you don't seem to have scons installed."
4 | }
5 |
6 | scons_init() {
7 | create_dirs_first="yes"
8 | scons="scons"
9 | }
10 |
11 | scons_do_build() {
12 | if [ ! "$override_default_options" = "yes" ]
13 | then
14 | scons_variables=(
15 | "${scons_variables[@]}"
16 | "PREFIX=$target"
17 | "prefix=$target"
18 | )
19 | fi
20 | Add_Use_Flags_Options_To_Array scons_variables
21 |
22 | scons_variables=(`echo ${scons_variables[@]} | sed "s,$target,$goboIndex,g"`)
23 | $scons "${scons_variables[@]}" "${build_variables[@]}" $build_target || wrap_fail "Build failed."
24 | }
25 |
26 | scons_do_install() {
27 | SandboxInstall $verbose ${unmanagedlist:+--unmanaged-files "${unmanagedlist}"} ${sandboxopts:+"${sandboxopts[@]}"} -c $scons "$appname" "$versionnumber" -- "${scons_variables[@]}" "${install_variables[@]}" $install_target || wrap_fail "Installation failed"
28 | }
29 |
--------------------------------------------------------------------------------
/doc/AUTHORS:
--------------------------------------------------------------------------------
1 |
2 | Compile development is led by Hisham Muhammad.
3 | See the --version option for authors of specific scripts.
4 |
5 | These are the people who contributed recipe entries,
6 | and help make Compile what it is today:
7 |
8 | Hisham Muhammad
9 | Giusepe Casagrande
10 | Guilherme Bedin
11 | Carlo Calica
12 | Jonatan Liljedahl
13 | Andre Detsch
14 | Jason Stubbs
15 | Jeremy Vernon
16 | Felix Breuer
17 | Fabio Mierlo
18 | Leandro Motta Barros
19 | Bill Burdick
20 | Mika Pesu
21 | Michael Homer
22 | Dave Dodge
23 | Lucas Correia Villa Real
24 | Maglan C. Diemer
25 | Thomas Krawczyk
26 | Taeber Rapczak
27 | Volker Wieban
28 | Julio Biason
29 | Rafael G. Jeffman
30 | Gen Wangden
31 | Peter Eriksen
32 |
33 | See the Recipe files in the various recipes for the
34 | specific authors.
35 |
36 | If your name is missing from this list, please contact
37 | me and I'll add you right away.
38 |
39 | Thanks to all!
40 |
41 | -- Hisham Muhammad, 13 may 2004.
42 | -- Lucas Lucas Correia Villa Real, 16 august 2004.
43 |
--------------------------------------------------------------------------------
/lib/ruby/site_ruby/1.8/gobo/commandapplication.rb:
--------------------------------------------------------------------------------
1 | =begin
2 |
3 | gobo/commandapplication.rb - GoboLinux CommandApplication Ruby Module
4 |
5 | Mostly stubs
6 |
7 | =end
8 | require 'gobo'
9 |
10 | class GoboCommandApplication < GoboApplication
11 | public # Public attributes
12 | private # Private instance/class variables
13 | public # Public methods
14 | def initialize()
15 | super()
16 | @commands = GoboCallbacks.new
17 | @descriptions = Hash.new
18 | end
19 |
20 | def addCommand(cmdName, description, aProc = nil)
21 | aProc = proc {|args|
22 | yield *args
23 | } if aProc == nil
24 | @commands.addCallback(cmdName, aProc)
25 | @descriptions[cmdName] = cmdDescription
26 | end
27 |
28 | def run()
29 | super()
30 | command = ARGV.shift
31 | if @commands[command]
32 | @commands[command].call()
33 | else
34 | puts "#{command} not a valid command"
35 | end
36 | end
37 | private # Private methods
38 | end
39 |
--------------------------------------------------------------------------------
/bin/GetRecipe:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | ##################################################
4 | # Imports
5 | ##################################################
6 |
7 | . ScriptFunctions
8 | Import OptionParser
9 | Import File
10 | Import GoboLinux
11 | Import Compile
12 | Import RecipeTools
13 |
14 | ##################################################
15 | # Options and configuration
16 | ##################################################
17 |
18 | Parse_Conf Compile.conf
19 |
20 | helpOnNoArguments=yes
21 | scriptDescription="Fetch a recipe and insert it in the recipes tree."
22 | scriptCredits="(C) 2003-2004 Carlo Calica et al. Released under the GNU GPL."
23 | scriptUsage=" [program-version]"
24 | Add_Option_Boolean "W" "no-web" "fully offline operation."
25 |
26 | Parse_Options "$@"
27 |
28 | ##################################################
29 | # Prepare Environment
30 | ##################################################
31 |
32 | cd $compileRecipesDir
33 |
34 | # sets 'recipedir', 'program' and 'version'
35 | # fails if recipe is not found
36 | Set_Recipe_Program_And_Version_From_Args $(Boolean "no-web" && echo none)
37 |
38 | echo "$recipedir"
39 | exit 0
40 |
--------------------------------------------------------------------------------
/Functions/BuildType_cmake:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | Import BuildType_makefile
3 |
4 | cmake_sane_check() {
5 | Quiet cmake --version || Die "This is a CMake type recipe and you don't seem to have CMake installed."
6 | }
7 |
8 | cmake_init() {
9 | needs_build_directory="yes"
10 | }
11 |
12 | cmake_do_configuration(){
13 | eval $(Combine_Arrays config cmake_options userconfigureoptions)
14 | Add_Use_Flags_Options_To_Array config
15 | # cmake always use its own build directory
16 | for i in "${cmake_variables[@]}"
17 | do
18 | var=`echo $i | cut -d= -f 1`
19 | val=`echo $i | cut -d= -f 2-`
20 | eval export $var=\'$val\'
21 | done
22 | cmake \
23 | -DCMAKE_VERBOSE_MAKEFILE=ON \
24 | -DCMAKE_INSTALL_PREFIX="${target}" \
25 | -DCMAKE_INSTALL_SYSCONFDIR="${settings_target}" \
26 | -DCMAKE_INSTALL_LOCALSTATEDIR="${variable_target}" \
27 | -DCMAKE_INSTALL_MANDIR="${target}/man" \
28 | -DCMAKE_INSTALL_LIBEXECDIR="${target}/libexec" \
29 | -DSYSCONFDIR="${settings_target}" \
30 | ${config[@]} "${sourcedir}"
31 | }
32 |
33 | cmake_do_build() {
34 | makefile_do_build
35 | }
36 |
37 | cmake_do_install() {
38 | makefile_do_install "${1}" "${2}"
39 | }
40 |
--------------------------------------------------------------------------------
/Functions/BuildType_meson:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | meson_sane_check() {
4 | Quiet meson --help || Die "This is a meson type recipe and you don't seem to have meson installed."
5 | Quiet ninja --version || Die "This is a meson type recipe and you don't seem to have ninja installed."
6 | }
7 |
8 | meson_init() {
9 | needs_build_directory="yes"
10 | meson="meson"
11 | ninja="ninja"
12 | }
13 |
14 | meson_do_build() {
15 | # Unless the recipe author overrides it, set "--prefix=/usr"
16 | if [[ ! "$meson_options" == --prefix=* ]]
17 | then
18 | meson_options=(
19 | "${meson_options[@]}"
20 | "--prefix=$goboIndex"
21 | )
22 | fi
23 | Add_Use_Flags_Options_To_Array meson_variables
24 | Add_Use_Flags_Options_To_Array ninja_variables
25 |
26 | $meson setup "${sourcedir}" "${meson_options[@]}" "${build_variables[@]}" $build_target || wrap_fail "Build failed."
27 | $ninja || wrap_fail "Build failed."
28 | }
29 |
30 | meson_do_install() {
31 | SandboxInstall $verbose ${unmanagedlist:+--unmanaged-files "${unmanagedlist}"} ${sandboxopts:+"${sandboxopts[@]}"} -c "$ninja install" "$appname" "$versionnumber" -- "${ninja_variables[@]}" "${install_variables[@]}" $install_target || wrap_fail "Installation failed"
32 | }
33 |
--------------------------------------------------------------------------------
/Functions/BuildType_waf:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | waf_init() {
3 | waf="./waf"
4 | build_target="build"
5 | }
6 |
7 |
8 | waf_do_configuration() {
9 | if [ ! "$override_default_options" = "yes" ]
10 | then
11 | eval $(Combine_Arrays wafconfig waf_options userconfigureoptions)
12 | wafconfig=(configure --prefix="$target" "${wafconfig[@]}")
13 | else
14 | wafconfig=("${waf_options[@]}")
15 | fi
16 | Add_Use_Flags_Options_To_Array wafconfig
17 |
18 | [ -f "$waf" ] && chmod +x "$waf" 2>/dev/null
19 | (
20 | for i in "${waf_variables[@]}"
21 | do
22 | var=`echo $i | cut -d= -f 1`
23 | val=`echo $i | cut -d= -f 2-`
24 | eval export $var=\'$val\'
25 | done
26 |
27 | $waf "${wafconfig[@]}" || return 1
28 | ) || return 1
29 | }
30 |
31 | waf_do_build() {
32 | waf_variables=(`echo ${waf_variables[@]} | sed "s,$target,$goboIndex,g"`)
33 | $waf "${waf_variables[@]}" "${build_variables[@]}" $build_target || wrap_fail "Build failed."
34 | }
35 |
36 | waf_do_install() {
37 | SandboxInstall $verbose ${unmanagedlist:+--unmanaged-files "${unmanagedlist}"} ${sandboxopts:+"${sandboxopts[@]}"} -c "$waf" "$appname" "$versionnumber" -- "${waf_variables[@]}" "${install_variables[@]}" $install_target || wrap_fail "Installation failed"
38 | }
39 |
--------------------------------------------------------------------------------
/bin/EditRecipe:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | ##################################################
4 | # Imports
5 | ##################################################
6 |
7 | . ScriptFunctions
8 | Import OptionParser
9 | Import File
10 | Import GoboLinux
11 | Import Compile
12 | Import RecipeTools
13 |
14 | ##################################################
15 | # Options and configuration
16 | ##################################################
17 |
18 | Parse_Conf Compile.conf
19 |
20 | helpOnNoArguments=yes
21 | scriptDescription="Fetch a recipe and place it in $compileRecipesDir, chopping its revision number.
22 | Calls a text editor on the Recipe file afterwards."
23 | scriptCredits="(C) 2006 Andre Detsch. Released under the GNU GPL."
24 | scriptUsage="[|| [program-version]]"
25 | Add_Option_Boolean "E" "no-edit" "Do not edit Recipe file, just place the recipe in $compileRecipesDir."
26 | Parse_Options "$@"
27 |
28 | ##################################################
29 | # Prepare Environment
30 | ##################################################
31 |
32 | recipe=`GetRecipe $(Arg 1) $(Arg 2)` || Die "Error while getting recipe."
33 |
34 | Set_Recipe_Program_And_Version_From_Args
35 |
36 | if Boolean "no-edit"
37 | then
38 | echo $recipedir
39 | else
40 | [ "$EDITOR" ] || Die 'Please set your $EDITOR variable using `export EDITOR='...'`.'
41 | $EDITOR "$recipedir/Recipe"
42 | fi
43 |
--------------------------------------------------------------------------------
/lib/ruby/site_ruby/1.8/gobo/logconsole.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/ruby (require)
2 |
3 | # This is a mixin for logging purposes. Dependent on @logLevel
4 | module GoboLogConsole
5 | LogLevelError=10
6 | LogLevelTerse=20
7 | LogLevelNormal=30
8 | LogLevelVerbose=40
9 | LogLevelDebug=50
10 |
11 | attr_reader :logLevel
12 |
13 | def setLogLevel(level)
14 | @logLevel = level
15 | end
16 |
17 | def logFunction(stream, message, color = "")
18 | stream.puts message
19 | stream.flush
20 | end
21 |
22 | def ask(message)
23 | $stdout << message
24 | $stdout.flush
25 | return $stdin.readline.chomp
26 | end # End of ask
27 |
28 | def askContinue(message = nil)
29 | return if @logLevel < LogLevelNormal
30 | puts message if message
31 | response = ask("Press Enter to continue or Ctrl-C to cancel.")
32 | stop if response.downcase == "n"
33 | end # End of askContinue
34 |
35 | def logError(message = "")
36 | logFunction($stderr, message) if @logLevel >= LogLevelError
37 | end
38 | def logTerse(message = "")
39 | logFunction($stdout, message) if @logLevel >= LogLevelTerse
40 | end
41 | def logNormal(message = "")
42 | logFunction($stdout, message) if @logLevel >= LogLevelNormal
43 | end
44 | def logVerbose(message = "")
45 | logFunction($stdout, message) if @logLevel >= LogLevelVerbose
46 | end
47 | def logDebug(message = "")
48 | logFunction($stderr, message) if @logLevel >= LogLevelDebug
49 | end
50 |
51 |
52 | end # End of module GoboLogConsole
53 |
--------------------------------------------------------------------------------
/bin/ApplyVariables:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | ### Imports ###################################################################
4 |
5 | source ScriptFunctions
6 | Import OptionParser
7 |
8 | ### Options ###################################################################
9 |
10 | helpOnNoArguments=yes
11 | scriptNotes="$scriptName processes a file replacing instances of variables marked
12 | with special indicators ('@%', '%@' by default) with the contents of equivalent
13 | environment variables."
14 | Add_Option_Entry "o" "open" "Opening mark." "@%"
15 | Add_Option_Entry "c" "close" "Closing mark." "%@"
16 | Add_Option_Entry "i" "identifier" "Add a prefix identifier in the form of '_' to the opening markup."
17 | Parse_Options "$@"
18 |
19 | ### Operation #################################################################
20 |
21 | open=`Entry "open"`
22 | close=`Entry "close"`
23 | if Is_Entry "identifier"
24 | then
25 | open="${open}`Entry identifier`_"
26 | fi
27 |
28 | cat "$(Arg 1)" | python3 -c '
29 | import os,sys,string
30 |
31 | op=sys.argv[1]
32 | cl=sys.argv[2]
33 | for line in sys.stdin.readlines():
34 | while 1:
35 | op_index=line.find(op)
36 | if op_index == -1:
37 | break
38 | cl_index=line.find(cl)
39 | if cl_index == -1:
40 | break
41 | var = line[op_index + len(op):cl_index]
42 | try:
43 | val = os.environ[var]
44 | except:
45 | val = ""
46 | line = line.replace(op + var + cl, val)
47 | print(line, end=" ")
48 | ' "$open" "$close"
49 |
--------------------------------------------------------------------------------
/lib/ruby/site_ruby/1.8/gobo/parseconfig.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/ruby (require)
2 |
3 | # This class reads and parses shell script config file
4 | # copied from Michael Homer's Freshen
5 |
6 | require 'shellwords'
7 |
8 | class GoboParseConfig < Hash
9 | public # Public attributes
10 | private # Private instance/class variables
11 | public # Public methods
12 | def initialize(filename, inheritfrom=nil)
13 | super(inheritfrom)
14 | # if inheritfrom
15 | # self = inheritfrom.vars
16 | # else
17 | # self = Hash.new
18 | # end
19 | inarray = false
20 | thisarray = "" #look, I know these are dirty blah blah
21 | file = File.open(filename)
22 | file.readlines.each {
23 | |line|
24 | line.strip!
25 | if !line.empty? and line.slice(0,1) != "#"
26 | words = Shellwords.shellwords(line)
27 | words[0].gsub!(/\$([a-zA-Z]+)/) {self[$1]}
28 | words[0].gsub!(/\$\{([a-zA-Z]+)\}/) {self[$1]}
29 | spl = words[0].split("=", 2)
30 | if spl[1] == "("
31 | inarray = true
32 | self.store spl[0], Array.new
33 | thisarray = spl[0]
34 | elsif inarray
35 | if words[0] == ")"
36 | inarray = false
37 | else
38 | self[thisarray].push words[0]
39 | end
40 | else
41 | self.store(spl[0], spl[1])
42 | end
43 | end
44 | }
45 | end # End of initialize()
46 | # def [] (x)
47 | # @vars[x]
48 | # end # End of [](x)
49 | # def member? (x)
50 | # @vars.member?(x)
51 | # end # End of member?
52 | protected # Protected methods
53 | private # Private methods
54 | end
55 |
56 |
--------------------------------------------------------------------------------
/Functions/BuildType_cabal:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | cabal_sane_check() {
3 | Quiet ghc -V || Die "This is a cabal recipe and you don't seem to have GHC installed."
4 | }
5 |
6 | cabal_init() {
7 | create_dirs_first="yes"
8 | post_install_message="Package registered via ghc-pkg; manual update required on package changes (InstallPackage, RemoveProgram, etc.)"
9 | [ "$runhaskell" ] || runhaskell="runhaskell"
10 | }
11 |
12 | cabal_do_configuration(){
13 | if [ ! "$override_default_options" = "yes" ]
14 | then
15 | cabal_options=(
16 | "${cabal_options[@]}"
17 | "--prefix=$target"
18 | )
19 | fi
20 | Add_Use_Flags_Options_To_Array cabal_options
21 | cabal_options=(`echo ${cabal_options[@]} | sed "s,$target,$goboIndex,g"`)
22 |
23 | for f in Setup.lhs Setup.hs ; do
24 | [ -e ${sourcedir}/${f} ] && cabal_setup="$f";
25 | done
26 | [ ! -z "$cabal_setup" ] || Die "Cabal Setup.hs or Setup.lhs not found"
27 |
28 | $runhaskell "$cabal_setup" configure "${cabal_options[@]}" || wrap_fail "Configure failed"
29 | }
30 |
31 | cabal_do_build() {
32 | $runhaskell "$cabal_setup" build "${build_variables[@]}" || wrap_fail "Build failed."
33 | }
34 |
35 | cabal_do_install() {
36 | # The package db should really be moved outside of ghc installation and functions should be added to Scripts to udpate the db
37 | pkg_dbloc=$(dirname `ghc-pkg list | head -n 1 | cut -f1 -d:`)
38 | SandboxInstall $verbose ${unmanagedlist:+--unmanaged-files "${unmanagedlist}"} ${sandboxopts:+"${sandboxopts[@]}"} -a $pkg_dbloc -c $runhaskell "$appname" "$versionnumber" -- "$cabal_setup" install "${install_variables[@]}" || wrap_fail "Installation failed."
39 | }
40 |
41 |
--------------------------------------------------------------------------------
/Functions/BuildType_configure:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | Import BuildType_makefile
4 |
5 | configure_init() {
6 | [ -n "${configure}" ] || configure="./configure"
7 | [ -n "${autogen}" ] || autogen="autogen.sh"
8 | }
9 |
10 | configure_do_configuration() {
11 | eval $(Combine_Arrays config configure_options userconfigureoptions)
12 | Add_Use_Flags_Options_To_Array config
13 | [ "$needs_build_directory" = "yes" ] && configure="${sourcedir}/$configure"
14 |
15 | [ -f "$configure" ] && chmod +x "$configure" 2>/dev/null
16 | (
17 | for i in "${configure_variables[@]}"
18 | do
19 | var=`echo $i | cut -d= -f 1`
20 | val=`echo $i | cut -d= -f 2-`
21 | eval export $var=\'$val\'
22 | done
23 |
24 | [ -e "./$autogen" ] && autogen="./$autogen" && chmod +x $autogen
25 | [ "$autogen_before_configure" = "yes" ] && yes "" | $autogen
26 | prepareoptions=(
27 | --verbose
28 | --configure $configure
29 | `[ "$override_default_options" = "yes" ] && echo "--no-default-options"`
30 | `[ "$build_in_programs" = "yes" ] && echo "--programs"`
31 | )
32 | PrepareProgram $batch $keep ${prepareoptions[*]} "$appname" "$versionnumber" ${config:+"--" "${config[@]}"} || return 1
33 | ) || return 1
34 | }
35 |
36 | configure_do_build() {
37 | # Configure generates libtool with hardcoded linking behaviour, but we are using our own libtool.
38 | # If option --disable-static is present pass it explicitly:
39 | if Array_Contains config "--disable-static"; then
40 | export LIBTOOLFLAGS="--tag=disable-static"
41 | Log_Debug "Recognized configure option --disable-static, setting LIBTOOLFLAGS=--tag=disable-static"
42 | fi
43 | makefile_do_build
44 | }
45 |
46 | configure_do_install() {
47 | makefile_do_install "${1}" "${2}"
48 | }
49 |
--------------------------------------------------------------------------------
/bin/UpdateRecipes:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | ##################################################
4 | # Imports
5 | ##################################################
6 |
7 | . ScriptFunctions
8 | Import OptionParser
9 | Import File
10 | Import GoboLinux
11 | Import Compile
12 |
13 | ##################################################
14 | # Options and configuration
15 | ##################################################
16 |
17 | Parse_Conf Compile.conf
18 |
19 | scriptDescription="Update local recipe list from recipe stores."
20 | scriptCredits="(C) 2003-2004 Carlo Calica et al. Released under the GNU GPL."
21 | scriptUsage="[]"
22 | scriptNotes="When updating a single program, $scriptName will download "\
23 | "all its available recipes. When no program is specified, $scriptName will "\
24 | "fetch the recipe list and populate $compileRecipesDir with directory "\
25 | "entries (and download the recipes only if --all is used)."
26 | Add_Option_Boolean "a" "all" "Download contents of updated recipes. "\
27 | "By default, $scriptName will only fetch the recipe list and generate "\
28 | "empty recipe directories (except when updating a single program)."
29 | Add_Option_Boolean "l" "all-latest" "Like --all, but only fetch the latest "\
30 | "versions of each recipe."
31 | Add_Option_Boolean "t" "thorough" "Check all availabe mirrors for updates. "\
32 | "By default, only the first working mirror (as configured in Compile.conf) is used."
33 | Parse_Options "$@"
34 |
35 | if Is_Writable "$compileRecipesDir"
36 | then sudo=
37 | else sudo="sudo -u #0"
38 | fi
39 |
40 | ##################################################
41 | # Prepare Environment
42 | ##################################################
43 |
44 | Check_Dir_Variable compileRecipesDir
45 | Check_Dir_Variable compileRecipesRepository
46 |
47 | if [ ! -d "${compileRecipesDir}/.git" ]
48 | then
49 | Log_Normal "Initializing recipes repository"
50 | git clone "${compileRecipesRepository}" "${compileRecipesDir}"
51 | else
52 | cd $compileRecipesDir
53 | git pull
54 | fi
55 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | PROGRAM = Compile
2 | VERSION = git-$(shell date +%Y%m%d)
3 | goboPrograms ?= /Programs
4 | PREFIX ?=
5 | DESTDIR = $(PREFIX)/$(goboPrograms)/$(PROGRAM)/$(VERSION)
6 | INSTALL_DIR = install -d
7 | INSTALL_FILE = install
8 | man_files = $(shell grep -l Parse_Options bin/* | xargs -i echo {}.1)
9 | scripts = ApplyVariables Compile FetchArchive GoboPath2Ruby NewVersion PrepareProgram AutoPatch ContributeRecipe NoRecipe RecipeLint UnionSandbox ColorMake EditRecipe GetRecipe MakeRecipe SandboxInstall UpdateRecipes
10 |
11 | .PHONY: all clean install uninstall
12 |
13 | default: all
14 |
15 | manuals: $(man_files)
16 |
17 | $(man_files): %.1: %
18 | @echo "Generating man page $@"
19 | help2man --name=" " --source="GoboLinux" --no-info $< --output $@
20 |
21 | clean_manuals:
22 | @echo "Cleaning man pages"
23 | echo $(man_files) | tr '\n' ' ' | xargs -d ' ' -n 1 rm -f
24 |
25 | clean_resources:
26 | rm -rf Resources/FileHash*
27 |
28 | clean: clean_manuals clean_resources
29 |
30 | install_manuals: manuals
31 | @$(INSTALL_DIR) -d -m 755 $(DESTDIR)/share/man/man1
32 | echo $(man_files) | tr '\n' ' ' | xargs -d ' ' -n 1 -i \
33 | $(INSTALL_FILE) -m 644 {} $(DESTDIR)/share/man/man1
34 |
35 | install_scripts:
36 | @echo "Installing scripts"
37 | $(INSTALL_DIR) -d -m 755 $(DESTDIR)/bin
38 | echo $(scripts) | tr '\n' ' ' | xargs -d ' ' -n 1 -i \
39 | $(INSTALL_FILE) -m 755 bin/{} $(DESTDIR)/bin
40 |
41 | install_lib:
42 | @echo "Installing lib"
43 | $(INSTALL_DIR) -d -m 755 $(DESTDIR)
44 | cp -r lib $(DESTDIR)
45 |
46 | install_resources:
47 | @echo "Installing Resources"
48 | cp -r Resources $(DESTDIR)
49 |
50 | install_share_data:
51 | @echo "Installing share data"
52 | cp -rf share $(DESTDIR)
53 |
54 | install_functions:
55 | @echo "Installing Functions"
56 | cp -rf Functions $(DESTDIR)
57 |
58 | install_docs:
59 | @echo "Installing docs"
60 | cp -rf doc $(DESTDIR)
61 | cp -rf examples $(DESTDIR)/doc
62 |
63 | prepare_install:
64 | @echo "Installing $(PROGRAM) into $(DESTDIR)"
65 | $(INSTALL_DIR) -d -m 755 $(DESTDIR)
66 |
67 | install: install_scripts install_manuals prepare_install install_lib install_resources install_share_data install_functions
68 | @echo "Installed $(PROGRAM) into $(DESTDIR)"
69 |
--------------------------------------------------------------------------------
/Functions/UnionFS:
--------------------------------------------------------------------------------
1 | #!/bin/bash (source)
2 |
3 | # unionImplementation is defined in Scripts/Directories.conf
4 |
5 | function Union_Backend() {
6 | local union=
7 | for union in "${unionImplementations[@]}"
8 | do
9 | case "$union" in
10 | "funionfs") GetSupportedFilesystems | grep -q "fuse" && funionfs -V &> /dev/null ;;
11 | "overlayfs") GetSupportedFilesystems | grep -q "overlay" ;;
12 | "unionfs") GetSupportedFilesystems | grep -q "unionfs" ;;
13 | "unionfs-fuse") GetSupportedFilesystems | grep -q "fuse" && unionfs -V &> /dev/null ;;
14 | esac
15 | [ $? = 0 ] && echo "$union" && break
16 | done
17 | }
18 |
19 | function Union_Is_Supported() {
20 | local union=`Union_Backend`
21 | [ "$union" ] && return 0 || return 1
22 | }
23 |
24 | function Union_Mount() {
25 | local union="$1"
26 | local rw_ro=`echo $2 | sed 's/\(.*\)=rw:\(.*\)=ro:\(.*\)=tmp/\1=rw:\2=ro/g'`
27 | case "$union" in
28 | "funionfs") funionfs -o dirs="$rw_ro" -o nonempty none "$3" ;;
29 | "overlayfs")
30 | upper=`echo $2 | sed 's/\(.*\)=rw:\(.*\)=ro:\(.*\)=tmp/\1/g'`
31 | lower=`echo $2 | sed 's/\(.*\)=rw:\(.*\)=ro:\(.*\)=tmp/\2/g'`
32 | work=`echo $2 | sed 's/\(.*\)=rw:\(.*\)=ro:\(.*\)=tmp/\3/g'`
33 | mount -t overlay none -o "lowerdir=$lower,upperdir=$upper,workdir=$work" "$3" ;;
34 | "unionfs") mount -t unionfs -o dirs="$rw_ro" none "$3" ;;
35 | "unionfs-fuse")
36 | dirs=`echo "$rw_ro" | sed 's/=[^:]*//g'`
37 | unionfs -o cow -o nonempty "$rw_ro" "$3";;
38 | esac
39 | }
40 |
41 | function Union_Add() {
42 | local union="$1"
43 | case "$union" in
44 | "funionfs") false ;;
45 | "overlayfs") false ;;
46 | "unionfs") mount -t unionfs -o remount,add=:"$2" none "$3" ;;
47 | "unionfs-fuse") false ;;
48 | esac
49 | }
50 |
51 | function Union_Umount() {
52 | local mp=
53 | local union="$1"
54 | shift
55 | case "$union" in
56 | "funionfs") for mp in $@; do fusermount -u "$mp"; done ;;
57 | "overlayfs") for mp in $@; do umount "$mp"; done ;;
58 | "unionfs") for mp in $@; do umount "$mp"; done ;;
59 | "unionfs-fuse") for mp in $@; do fusermount -u "$mp"; done ;;
60 | esac
61 | }
62 |
--------------------------------------------------------------------------------
/Functions/BuildType_python:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | python_sane_check() {
3 | Quiet python${python_major} -V || wrap_fail "This is a python type recipe and you don't seem to have python installed."
4 | }
5 |
6 | # Can be overridden by the recipe
7 | python_major=${python_major:-}
8 |
9 | set_python_vars() {
10 | python=python${python_major}
11 | pythonversion=$($python -V 2>&1 | sed 's,Python \([0-9]*\.[0-9]*\).*,\1,')
12 | sitepackages="${target}/lib/python${pythonversion}/site-packages"
13 | }
14 |
15 | python_init() {
16 | create_dirs_first="yes"
17 | build_target="build"
18 | set_python_vars
19 | }
20 |
21 | build_python_options() {
22 | # need to update python vars in case $python_major is overriden
23 | set_python_vars
24 | # should exist in other modes too (eg, configure)
25 | if [ "$override_default_options" = "yes" ]
26 | then default_python_options=()
27 | else
28 | case "$1" in
29 | build)
30 | default_python_options=()
31 | ;;
32 | build_ext)
33 | default_python_options=(
34 | "--build-lib $sitepackages"
35 | )
36 | ;;
37 | install)
38 | default_python_options=(
39 | "--prefix $target"
40 | "--exec-prefix $target"
41 | )
42 | ;;
43 | esac
44 | fi
45 | eval $(Combine_Arrays opts python_options default_python_options)
46 | Add_Use_Flags_Options_To_Array opts
47 |
48 | opts=(`echo ${opts[@]} | sed "s,$target,$goboIndex,g"`)
49 |
50 | # This must occur after the source is unpacked, so it can't go in _init.
51 | # We have to guard against build_script being set from the recipe, or
52 | # earlier in the compile process.
53 | if ! [ "${build_script}" ]
54 | then
55 | for i in setup.py configure.py build.py
56 | do [ -e "${sourcedir}/${i}" ] && build_script="$i"
57 | done
58 | fi
59 | }
60 |
61 | python_do_build() {
62 | mkdir -p "$sitepackages"
63 | build_python_options $build_target
64 | $python $build_script $build_target ${opts[*]} || wrap_fail "Build failed."
65 | }
66 |
67 | python_do_install() {
68 | build_python_options $install_target
69 | SandboxInstall $verbose ${unmanagedlist:+--unmanaged-files "${unmanagedlist}"} ${sandboxopts:+"${sandboxopts[@]}"} -c $python "$appname" "$versionnumber" -- $build_script $install_target --root / ${opts[*]} || wrap_fail "Installation failed"
70 | }
71 |
--------------------------------------------------------------------------------
/examples/GoboSimpleExample.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/ruby
2 |
3 | # Workaround lack of ruby Environment
4 | $: << "/System/Index/lib/ruby/site_ruby/1.8"
5 |
6 | require 'gobo'
7 |
8 |
9 | ### App Info ##################################################################
10 | #
11 | # Create a GoboApplication object and set
12 | app = GoboApplication.new()
13 |
14 | app.description = "Simple example showing GoboLinux's Ruby Framework."
15 | app.credits = "Released under the GNU GPL."
16 | app.usage = ""
17 | app.example = "foo bar baz"
18 | app.notes = <&2
11 | )
12 | fi
13 |
14 | if ! echo $entry | grep -q /
15 | then
16 | entry=`ls "$compileRecipesDir" | grep -i "^$entry$"`
17 | [ "$entry" ] || return 1
18 | entry="$compileRecipesDir/$entry"
19 | else
20 | if [ -f "$entry/Recipe" ]
21 | then
22 | version=$(basename $entry)
23 | entry=$(dirname $entry)
24 | fi
25 | fi
26 |
27 | [ -d "$entry" ] || return 2
28 |
29 | program=`basename $entry`
30 | recipedir="$entry/$version"
31 |
32 | if ! [ "$version" ]
33 | then
34 | [ `ls "$entry" | wc -l` -eq 1 ] || {
35 | # pick latest
36 | version=$(GuessLatest $(ls "$compileRecipesDir/$program"))
37 | if [ "$version" ]
38 | then
39 | recipedir="$compileRecipesDir/$program/$version"
40 | return 0
41 | else
42 | return 3
43 | fi
44 | }
45 | version=`ls "$entry"`
46 | fi
47 |
48 | recipedir="$entry/$version"
49 | [ -d "$recipedir" ] || return 4
50 |
51 | return 0
52 | }
53 |
54 | # if you only want to know if where a recipe is without the side effects
55 | function Which_Recipe() {
56 | saverecipedir=$recipedir
57 | saveprogram=$program
58 | saveversion=$version
59 |
60 | Find_Recipe_Program_And_Version "$@"
61 | ret=$?
62 | if [ "$ret" = 0 ]
63 | then
64 | echo $recipedir
65 | fi
66 |
67 | recipedir=$saverecipedir
68 | program=$saveprogram
69 | version=$saveversion
70 |
71 | return $ret
72 | }
73 |
74 | # if you only want to know if a recipe exists without the side effects
75 | function Has_Recipe() {
76 | Which_Recipe "$@" &>/dev/null
77 | return $?
78 | }
79 |
80 | function Set_Recipe_Program_And_Version_From_Args() {
81 | action=$1
82 | [ "$action" ] || action=pull
83 |
84 | if file "$(Arg 1)" | grep -q bzip2
85 | then
86 | Die "Recipe files are not supported."
87 | fi
88 |
89 | Find_Recipe_Program_And_Version "$action" "$(Arg 1)" "$(Arg 2)"
90 | case $? in
91 | 1) Die "Could not find $(Arg 1) in $compileRecipesDir."
92 | ;;
93 | 2) Die "Could not read $(Arg 1)."
94 | ;;
95 | 3) Die "Could not find a version of $(Arg 1) in $compileRecipesDir."
96 | ;;
97 | 4) Die "Version $(Arg 2) does not exist for $(Arg 1). Available versions are:\n$(ls $recipedir/..)"
98 | ;;
99 | esac # esac is still ridiculous!
100 |
101 | return 0
102 | }
103 |
--------------------------------------------------------------------------------
/bin/AutoPatch:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | source ScriptFunctions
4 | Import OptionParser
5 | Import GoboLinux
6 |
7 | helpOnNoArguments=yes
8 | scriptDescription="Compile patch streamlining tool. Run it once, edit the sources and run it again."
9 | scriptCredits="Copyright (C) Hisham Muhammad, 2014 - Released under the GNU GPL."
10 | scriptUsage=""
11 | scriptExample="Bullet"
12 | Add_Option_Boolean "c" "clean" "Cleanup directories in Archives."
13 | Parse_Options "$@"
14 |
15 | Parse_Conf Compile.conf
16 |
17 | cd "$compileSourcesDir"
18 |
19 | if [ $(basename $(readlink -f .)) != "Sources" ]
20 | then
21 | echo "This is designed to run in the Sources directory."
22 | exit 1
23 | fi
24 |
25 | recipedir=`GetRecipe $(Arg 1) $(Arg 2)`
26 | source "$recipedir/Recipe"
27 |
28 | if [ -z "$dir" ]
29 | then
30 | dir=`basename "$url" .tar.gz`
31 | dir=`basename "$dir" .tar.bz2`
32 | dir=`basename "$dir" .tar.xz`
33 | dir=`basename "$dir" .tgz`
34 | dir=`basename "$dir" .tbz2`
35 | fi
36 | if [ -z "$file" ]
37 | then
38 | file=`basename "$url"`
39 | fi
40 |
41 | while Has_Substring "$dir" "/"
42 | do
43 | dir=`dirname "$dir"`
44 | done
45 |
46 | function cleanup() {
47 | if [ -d "$dir" -o -d "$dir.old" ]
48 | then
49 | Log_Question "Delete $dir and $dir.old? "
50 | read yn
51 | if [ "$yn" = "y" ]
52 | then
53 | rm -rf "$dir"
54 | rm -rf "$dir.old"
55 | else
56 | exit 1
57 | fi
58 | fi
59 | }
60 |
61 | # Step one: generate two clean directories
62 | # to start a diff.
63 | function step_one() {
64 | Log_Normal "Directory: $dir"
65 | cleanup
66 | Log_Normal "Extracting ../Archives/$file"
67 | aunpack "../Archives/$file"
68 | cp -a "$dir" "$dir.old"
69 | }
70 |
71 | function step_two() {
72 |
73 | packagename=`Get_Token "$recipedir" "/" "-2"`
74 | versionandrevision=`Get_Token "$recipedir" "/" "-1"`
75 | newrecipedir="$compileRecipesDir/$packagename/$versionandrevision"
76 | if [ "$recipedir" != "$newrecipedir" ]
77 | then
78 | Log_Normal "Copying recipe from $recipedir to $newrecipedir"
79 | mkdir -p "$compileRecipesDir/$packagename"
80 | cp -R "$recipedir" "$newrecipedir"
81 | recipedir="$newrecipedir"
82 | fi
83 |
84 | diff -Nur "$dir.old" "$dir" | mtail --config /System/Settings/Scripts/diff.mtailrc
85 | echo "*******************************************************************************"
86 | echo
87 | ls "$recipedir"/*.patch &> /dev/null && {
88 | echo "Existing patches:"
89 | ls "$recipedir"/*.patch
90 | echo
91 | }
92 | Log_Question "Enter patch name (without path or .patch extension): "
93 | read patchname
94 | if [ "$patchname" != "" ]
95 | then
96 | Log_Question "Please write a description: "
97 | read description
98 | for i in `seq -w 20`
99 | do
100 | ls "$recipedir/$i"*".patch" &> /dev/null || break
101 | done
102 | patchfilename="$recipedir/$i-$patchname.patch"
103 | Log_Normal "Writing $patchfilename ..."
104 | echo "$description" > "$patchfilename"
105 | echo >> "$patchfilename"
106 | diff -Nur "$dir.old" "$dir" >> "$patchfilename"
107 | fi
108 | cleanup
109 | }
110 |
111 | if Boolean "clean"
112 | then
113 | cleanup
114 | elif [ -e "$dir.old" ]
115 | then
116 | step_two
117 | else
118 | step_one
119 | fi
120 |
121 |
--------------------------------------------------------------------------------
/doc/FAQ:
--------------------------------------------------------------------------------
1 |
2 | Compile FAQ
3 | maintained by Rafael Jeffman
4 |
5 | Questions
6 |
7 | 1. About Compile
8 |
9 | 1.1. What are Compile, Recipes and source packages?
10 | 1.2. Why should I use source packages instead of binary ones?
11 |
12 | 2. How to use Compile
13 |
14 | 2.1. How do I create a Recipe for a program based on GNU Autotools?
15 | 2.2. Does Compile support dependencies?
16 | 2.3. How do I create a program which is based of many source archives?
17 | 2.4. How do I make it download and use a file when the resulting file is not
18 | a part of the URL?
19 | 2.5. I've already downloaded the source URL. How do I use it?
20 |
21 | 1. About Compile
22 |
23 | 1.1. What are Compile, Recipes and source packages?
24 |
25 | Compile is the system used by GoboLinux to
26 | install programs using their source code distribution instead of a
27 | pre-compiled binary version. Altough inspired by Gentoo's Portage, it
28 | was built from scratch to reflect the philosophy of GoboLinux
29 | and to be easily integrated to it.
30 |
31 | Recipes are how the configuration files used by Compile are called. They
32 | contain a recipe on how to obtain and compile a program from its
33 | sources. A Recipe may also contain patches to be applied to the source
34 | code in order to make the program work properly.
35 |
36 | Source packages in GoboLinux differ a little from other distributions.
37 | Apart from possible patches that are released with a Recipe, the sources
38 | for a given program is obtained from the official distribution site.
39 | There is no "GoboLinux Repository" for sources.
40 |
41 | 1.2. Why should I use source packages instead of binary ones?
42 |
43 | There might be many reasons for installing software from the source
44 | code. The most common are:
45 |
46 | * *Optimization* Some software is very sensible to machine
47 | optimization. For these, compiling for a specific target may
48 | enhance its usage. A good example is MPlayer.
49 | * *Compilation Options/Dependencies* Most software has many
50 | compilation options that may alter its avaiable features,
51 | optimization parameters and runtime dependencies. Binary
52 | distributions are released with a pre-selected set of compilation
53 | options that may not be the optimal one neither the ones required
54 | in a specific usage scenario.
55 | * *Consistency* It is easier to keep the system consistency
56 | installing all software from source code.
57 |
58 | 2. How to use Compile
59 |
60 | 2.1. How do I create a Recipe for a program based on GNU Autotools?
61 |
62 | Most of the open source software available today, when installed from
63 | the source code uses the GNU Autotools for configuring its compile
64 | options and to generate system dependent code. Their installation is
65 | often performed by issuing three commands: configure, make and make
66 | install. For example, most - if not all - of the software avaiable at
67 | GNU.org can be installed this way.
68 |
69 | For what can be called "well behaved" programs, that is those programs
70 | that respect the configuration of installation paths, a Recipe would be
71 | like:
72 |
73 | url=ftp://ftp.gtk.org/pub/gtk/v2.0/pango-1.0.5.tar.bz2
74 | is_compileprogram=yes
75 |
76 | This Recipe tells Compile where this program (Pango--1.0.5) can be found
77 | using the *url* directive and that it can be compiled using standard GNU
78 | Autotools procedure by setting *is_compileprogram* to /yes/.
79 | *is_compileprogram* is derived from the old method for installing
80 | program from sources called CompileProgram.
81 |
82 | To select configure options set *configure_options*, as in the
83 | ImageMagick--5.5.7-10 Recipe:
84 |
85 | url=ftp://ftp.imagemagick.org/pub/ImageMagick/ImageMagick-5.5.7-10.tar.bz2
86 | dir=ImageMagick-5.5.7
87 | is_compileprogram=yes
88 | configure_options=(
89 | "--enable-shared"
90 | "--with-x"
91 | "--without-perl"
92 | )
93 |
94 | 2.2. Does Compile support dependencies?
95 |
96 | Yes. It is the same as in the /Programs hierarchy: through a
97 | Resources/Dependencies file. In fact, the Resources/ directory inside,
98 | say, Recipes/Foo/1.0 is copied directly to /Programs/Foo/1.0 after
99 | compilation. This way you can set Environment variables, configuration
100 | Defaults, etc. The Compile program verifies the Dependencies file and,
101 | if there is a program which is not in /Programs and a recipe for it is
102 | available, it gets compiled first.
103 |
104 | 2.3. How do I create a program which is based of many source archives?
105 |
106 | You can use a meta-recipe. KDE and Enlightenment, for example, are done
107 | this way. Create a separate recipe for each component. Then, in the
108 | meta-recipe, specify the recipe type as is_meta=yes and list the recipes
109 | to be included in the include array. When you compile the meta-recipe,
110 | all subpackages will be built into the same /Programs entry. (For
111 | example, all components of KDE will be installed at /Programs/KDE , but
112 | if you don't use KDE and only want to build ARTS separately, you can
113 | just 'Compile ARTS' and it will get installed at /Programs/ARTS).
114 |
115 | 2.4. How do I make it download and use a file when the resulting file
116 | is not a part of the URL?
117 |
118 | Specify both the "url" variable and the "file" variable.
119 |
120 | 2.5. I've already downloaded the source URL. How do I use it?
121 |
122 | Put the file in the Archives directory.
123 |
--------------------------------------------------------------------------------
/bin/PrepareProgram:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | ### Imports ##############################################################
4 |
5 | source ScriptFunctions
6 | Import File
7 | Import GoboLinux
8 | Import Log
9 | Import OptionParser
10 | Import Directories
11 | Import Array
12 | Import String
13 |
14 | ### Options ##############################################################
15 |
16 | helpOnNoArguments=yes
17 | scriptDescription="prepares applications for instalation, running the 'configure' script."
18 | scriptCredits="Copyright (C) 2001-2005 Hisham Muhammad - Released under the GNU GPL."
19 | scriptUsage=" [ -- ]"
20 | scriptExample="KDE 2.2"
21 | scriptNotes="The directory hierarchy for the program is only created with --tree."
22 |
23 | # This option should be removed; there's no more interaction in this script.
24 | Add_Option_Boolean "b" "batch" "batch mode: no user interaction"
25 |
26 | Add_Option_Boolean "t" "tree" "Prepare directories only, do not attempt to run configure."
27 | Add_Option_Boolean "T" "tree-cleanup" "Like --tree, but instead of creating directories, remove empty ones"
28 | Add_Option_Boolean "k" "keep" "Keep the directory if it already exists in the directory hierarchy."
29 | Add_Option_Boolean "r" "remove" "Remove the directory if it already exists in the directory hierarchy."
30 | Add_Option_Entry "c" "configure" "Specify program to be used as 'configure' script." "./configure"
31 | Add_Option_Boolean "a" "autoconf" "Assume configure is based on autoconf, skipping detection."
32 | Add_Option_Boolean "A" "no-autoconf" "Assume configure is NOT based on autoconf, skipping detection."
33 | Add_Option_Boolean "D" "no-default-options" "Skip detection altogether, use only configure options passed on the command-line."
34 | Add_Option_Boolean "p" "programs" "Prepare for build directly in /Programs, not $goboIndex"
35 |
36 | Parse_Options "$@"
37 |
38 | Is_Entry "configure" && export PATH="$PATH:."
39 |
40 | ### Functions ############################################################
41 |
42 | # TODO: this function is now in Compile and should probably disappear in the future
43 | function config_is_autoconf() {
44 | Boolean "autoconf" && return 0
45 | Boolean "no-autoconf" && return 1
46 | grep -i "Generated .* autoconf" "$configureprogram" &> /dev/null
47 | }
48 |
49 | function config_accepts_prefix() {
50 | grep -- "--prefix" "$configureprogram" &> /dev/null
51 | }
52 |
53 | function config_accepts_sysconfdir() {
54 | grep -- "--sysconfdir" "$configureprogram" &> /dev/null
55 | }
56 |
57 | function config_accepts_mandir() {
58 | grep -- "--mandir" "$configureprogram" &> /dev/null
59 | }
60 |
61 | function config_accepts_libexecdir() {
62 | grep -- "--libexecdir" "$configureprogram" &> /dev/null
63 | }
64 |
65 | function build_change() {
66 | echo "/-L/!s/"$1"/"$2"/g;"
67 | }
68 |
69 | ### Operation #############################################################
70 |
71 | programname="$(Arg 1)"
72 | [ -z "$programname" ] && Die "Missing argument."
73 | Dir_Set Case && {
74 | # Respect capitalization passed, if any.
75 | if [ "$programname" = `echo "$programname" | tr '[:upper:]' '[:lower:]'` ]
76 | then programname=`GuessProgramCase "$programname"`
77 | fi
78 | }
79 |
80 | if [ "$(Arg 2)" ]
81 | then
82 | versionnumber="$(Arg 2)"
83 | else
84 | Die "Please specify version."
85 | fi
86 |
87 | programname=`NamingConventions "$programname"`
88 |
89 | baseprogramdir=`Get_Dir runtime "$programname" ''`
90 | programdir=`Get_Dir runtime "$programname" "$versionnumber"`
91 | settingsdir=`Get_Dir runtimeSettings "$programname" "$versionnumber"`
92 | variabledir=`Get_Dir runtimeVariable "$programname" "$versionnumber"`
93 |
94 | Dir_Set Install && installdir=`Get_Dir install "$programname" "$versionnumber"`
95 |
96 | if Boolean "tree"
97 | then
98 | Dir_Set Install && Create_Program_Tree "$installdir" || Create_Program_Tree "$programdir"
99 | exit $?
100 | elif Boolean "tree-cleanup"
101 | then
102 | Clean_Program_Tree "$programdir"
103 | exit $?
104 | fi
105 |
106 | configureprogram=`Entry "configure"`
107 |
108 | echo
109 | Log_Normal "Preparing..."
110 | rm -f config.cache
111 |
112 | Exists "$configureprogram" || Die "configure script "`[ $configureprogram != "./configure" ] && echo " ($configureprogram) "`"not found."
113 |
114 | if ! Boolean "programs"
115 | then
116 | configureprefix="$goboIndex"
117 | configuresettings="$goboSettings"
118 | configuremandir="${goboShared}/man"
119 | else
120 | configureprefix="$programdir"
121 | configuresettings="$settingsdir"
122 | configuremandir="${target}/Shared/man"
123 | fi
124 | configurevariable="$goboVariable"
125 |
126 | if Boolean "no-default-options"
127 | then
128 | configure_options=()
129 | elif config_is_autoconf
130 | then
131 | Log_Normal "Autoconf configure script detected."
132 | configure_options=(
133 | --prefix="$configureprefix"
134 | --sysconfdir="$configuresettings"
135 | --localstatedir="$configurevariable"
136 | --mandir="${configuremandir}"
137 | --libexecdir="${configureprefix}/lib/$(Downcase ${programname})"
138 | )
139 | elif config_accepts_prefix
140 | then
141 | Log_Normal "Non-autoconf configure script detected (accepts --prefix)."
142 | configure_options=(
143 | --prefix="$configureprefix"
144 | )
145 | if config_accepts_sysconfdir
146 | then
147 | configure_options=(
148 | "${configure_options[@]}"
149 | --sysconfdir="$configuresettings"
150 | )
151 | fi
152 | if config_accepts_mandir
153 | then
154 | configure_options=(
155 | "${configure_options[@]}"
156 | --mandir="$configuremandir"
157 | )
158 | fi
159 | if config_accepts_libexecdir
160 | then
161 | configure_options=(
162 | "${configure_options[@]}"
163 | --libexecdir="${configureprefix}/lib/$(Downcase ${programname})"
164 | )
165 | fi
166 | else
167 | configure_options=()
168 | fi
169 |
170 | eval `Args_To_Array args 3`
171 | if [ -n "$args" ]
172 | then
173 | for a in "${args[@]}"
174 | do
175 | if echo "${a}" | grep -q "/Resources/Defaults/Settings"
176 | then
177 | tmpargs=(
178 | "${tmpargs[@]}"
179 | "$(echo "${a}")"
180 | )
181 | else
182 | tmpargs=(
183 | "${tmpargs[@]}"
184 | "$(echo "${a}" | sed "s,$programdir,$goboIndex,g")"
185 | )
186 | fi
187 | done
188 | args=("${tmpargs[@]}")
189 | fi
190 |
191 | "$configureprogram" ${configure_options:+"${configure_options[@]}"} ${args:+"${args[@]}"} 2>&1 | Color_Output configure >&$normalFD
192 | if [ "${PIPESTATUS[0]}" != 0 ]
193 | then Die "configure failed."
194 | fi
195 |
196 | exit 0
197 |
--------------------------------------------------------------------------------
/bin/FetchArchive:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | ##################################################
4 | # Imports
5 | ##################################################
6 |
7 | . ScriptFunctions
8 | Import OptionParser
9 | Import File
10 | Import Terminal
11 | Import GoboLinux
12 | Import Array
13 |
14 | ##################################################
15 | # Options and configuration
16 | ##################################################
17 |
18 | Parse_Conf Compile.conf
19 | Import Compile
20 |
21 | helpOnNoArguments=yes
22 | scriptDescription="Given a recipe, download the files required to compile it."
23 | scriptUsage=" [arch-recipe]"
24 | scriptExample="$compileRecipeDir/K3B/0.10/Recipe"
25 | Add_Option_Entry "d" "save-directory" "Rename the directory into which the archive is unpacked/files checked out." ""
26 | Add_Option_Entry "s" "save-to" "Save the files to the given directory" "$compileArchivesDir"
27 | Add_Option_Entry "P" "program" "Program name" "Bash"
28 | Add_Option_Entry "V" "version-number" "Version number with revision" "4.0-r1"
29 | Add_Option_Boolean "b" "batch" "Avoid asking questions."
30 | Add_Option_Boolean "" "no-check-certificate" "Do not check certificates when downloading files. NOTE: This can be dangerous!"
31 | Add_Option_Boolean "" "no-verify-files" "Do not verify downloaded files, this flag is normally passed when creating a new recipe"
32 | Parse_Options "$@"
33 |
34 | savedir=$(Entry "save-to")
35 | sourcedir=$(Entry "save-directory")
36 | programname=$(Entry "program")
37 | versionnumber=$(Entry "version-number")
38 |
39 | wget_bin="wget"
40 | git_bin="git"
41 | if Boolean "no-check-certificate"
42 | then
43 | Log_Normal "NOTE: Ignoring certificates when downloading sources"
44 | wget_bin="wget --no-check-certificate"
45 | git_bin="GIT_SSL_NO_VERIFY=true git"
46 | fi
47 |
48 | ##################################################
49 | # Fundamental variables
50 | ##################################################
51 |
52 | recipe="$(Arg 1)"
53 | [ "$recipe" ] || Die "Missing argument. Usage: $scriptName . See --help."
54 | [ -e "$recipe" ] || Die "File not found: $recipe"
55 | . "$recipe"
56 |
57 | archrecipe="$(Arg 2)"
58 | [ -e "$archrecipe" ] && source "$archrecipe"
59 |
60 | [ -z "${sourcedir}" ] && sourcedir="${dir%%/*}"
61 |
62 | ##################################################
63 | # Get sources
64 | ##################################################
65 |
66 | for var in url mirror_url file file_size file_md5 file_sha cvs cvs_module svn git bzr hg
67 | do
68 | eval '
69 | if [ -n "$'$var'" -a ! -n "${'$var's[*]}" ]
70 | then '$var's=("$'$var'")
71 | fi
72 | '
73 | done
74 |
75 | [ ! -w "${savedir}" -o ! -x "${savedir}" ] && chown `whoami` "${savedir}"
76 |
77 | savesourcedir="${sourcedir}"
78 | [ -z "${sourcedir}" ] && sourcedir="$(echo ${recipe} | sed 's,.*/\([^/]*\)/\([^/]*\)/Recipe,\1-\2,')"
79 |
80 | [ -d "${sourcedir}" ] && [ ! -w "${sourcedir}" -o ! -x "${sourcedir}" ] && chown -R `whoami` "${sourcedir}"
81 |
82 | cd "$savedir"
83 |
84 | if [ "${cvss[*]}" ]
85 | then
86 | for cvs in "${cvss[@]}"
87 | do
88 | if echo "$cvs" | grep -q " "
89 | then
90 | origcvs="$cvs"
91 | cvs="${origcvs% *}"
92 | cvs_modules=("${origcvs#* }")
93 | fi
94 | if [ "$cvs_password" ]
95 | then Log_Normal "When asked for a password, enter \"$cvs_password\"."
96 | else Log_Normal "If asked for a password, just press Enter."
97 | fi
98 |
99 | login_method=`echo ${cvs} | cut -b-5`
100 | [ "$cvs_rsh" ] && export CVS_RSH=$cvs_rsh || export CVS_RSH=ssh
101 | [ "$login_method" != ":ext:" ] && cvs -d${cvs} login || exit $?
102 | for cvs_module in "${cvs_modules[@]}"
103 | do
104 | checkout_dir=`basename "$sourcedir"`
105 | cvs -d${cvs} ${cvs_opts} ${cvs_options} checkout -d"$checkout_dir" ${cvs_checkout_options} ${cvs_module} || exit $?
106 | done
107 | done
108 | exit 0
109 | elif [ "${svns[*]}" ]
110 | then
111 | for svn in "${svns[@]}"
112 | do
113 | if [ "$svn_username" ]
114 | then svn checkout "${svn}" "${sourcedir}" --username "${svn_username}" --password "${svn_password}" || exit $?
115 | else svn checkout "${svn}" "${sourcedir}" || exit $?
116 | fi
117 | done
118 | exit 0
119 | elif [ "${gits[*]}" ]
120 | then
121 | for git in "${gits[@]}"
122 | do
123 | bflag=""
124 | if [ "${branch}" ]
125 | then bflag="-b ${branch}"
126 | elif [ "${tag}" ]
127 | then bflag="-b ${tag}"
128 | fi
129 | if [ ! -d "${sourcedir}" ]
130 | then
131 | $git_bin clone --depth=1 ${bflag} "${git}" "${sourcedir}" || exit $?
132 | cd "${sourcedir}" && $git_bin submodule update --init || true
133 | else cd "${sourcedir}" && $git_bin pull || exit $?
134 | fi
135 | done
136 | exit 0
137 | elif [ "${bzrs[*]}" ]
138 | then
139 | for bzr in "${bzrs[@]}"
140 | do
141 | if [ ! -d "${sourcedir}" ]
142 | then bzr branch "${bzr}" "${sourcedir}" || exit $?
143 | else cd "${sourcedir}" && bzr pull || exit $?
144 | fi
145 | done
146 | exit 0
147 | elif [ "${hgs[*]}" ]
148 | then
149 | for hg in "${hgs[@]}"
150 | do
151 | if [ ! -d "${sourcedir}" ]
152 | then hg clone ${hg} "${sourcedir}" || exit $?
153 | else cd "${sourcedir}" && hg update || exit $?
154 | fi
155 | done
156 | exit 0
157 | elif ! [ -n "${urls[*]}" ]
158 | then
159 | Die "Missing URL in recipe '$recipe'."
160 | else
161 | sourcedir="${savesourcedir}"
162 | fi
163 |
164 | if ! [ "${files[*]}" ]
165 | then files=(`Map basename "${urls[@]}"`)
166 | fi
167 |
168 | if [ ! -z ${file_shas} ];
169 | then
170 | file_sums=${file_shas}
171 | use_sha=1
172 | else
173 | file_sums=${file_md5s}
174 | use_sha=0
175 | fi
176 |
177 | for url_index in `seq 0 $[${#urls[@]}-1]`
178 | do
179 | file="${files[url_index]}"
180 | [ -f "${file}" -a ! -w "${file}" ] && chown `whoami` "$file"
181 | # First verification to know if we need to download it again
182 | if Boolean "no-verify-files"
183 | then
184 | if [ -f "${file}" ]
185 | then result=2 # incomplete
186 | else result=3 # missing
187 | fi
188 | else
189 | Verify_Files "$file" "${file_sizes[url_index]}" "${file_sums[url_index]}" $use_sha
190 | result=$?
191 | fi
192 | # File was ok
193 | if [ "$result" = "0" ]
194 | then
195 | continue
196 | # File was corrupted, delete it
197 | elif [ "$result" = "1" ]
198 | then
199 | Log_Normal "File $file is corruped, downloading it again!"
200 | rm -f -- ${file}
201 | elif [ "$result" = "2" ]
202 | then
203 | if Boolean "batch" || { Log_Normal "File ${file} has been already downloaded"; Ask "Remove and download again?"; }
204 | then rm -f ${file}
205 | else continue
206 | fi
207 | fi
208 |
209 | function wget_url() {
210 | fileindex=$1
211 | mirrorlevel=$2
212 | urlcount="${#urls[@]}"
213 | if [ "$mirrorlevel" = 0 ]
214 | then fetch="${urls[fileindex]}"
215 | else fetch="${mirror_urls[(mirrorlevel-1)*urlcount+fileindex]}"
216 | fi
217 | if [ -z "$fetch" ]
218 | then
219 | # No more mirrors in recipe
220 | if [ -n "$programname" -a -n "$versionnumber" ]
221 | then
222 | version_no_rev="${versionnumber%-r*}"
223 | # Try gobolinux.org mirror
224 | $wget_bin -O "$file" -c --passive-ftp "https://gobolinux.org/mirror_url/$programname/$version_no_rev/$file"
225 | return $?
226 | else
227 | return 1
228 | fi
229 | fi
230 | local file="${files[fileindex]}"
231 | unset LANG LC_ALL # So that wget's output is not translated
232 | if [ -e "$file" ]
233 | then
234 | if Starts_With "http:" "$fetch"
235 | then
236 | expectedlength=`$wget_bin --spider "$fetch" 2>&1 | grep "Length:" | tr -d ".," | cut -d" " -f2`
237 | locallength=`wc -c "$file" | cut -d" " -f1`
238 | if [ "$expectedlength" = "$locallength" ]
239 | then
240 | Log_Verbose "$file is already fully retrieved."
241 | return 0
242 | fi
243 | fi
244 | fi
245 | $wget_bin -O "$file" -c --passive-ftp "$fetch" || {
246 | wget_url "$fileindex" "$[mirrorlevel+1]"
247 | }
248 | }
249 |
250 | # Note: calling this function modifies the value of $file!
251 | wget_url "$url_index" 0 || {
252 | Die "Could not fetch '$url'."
253 | }
254 |
255 | # Verify the new downloaded file
256 | # Since file variable has been modified by wget_url(!?) we need to
257 | # set it again
258 | if Boolean "no-verify-files"
259 | then
260 | result=0
261 | else
262 | file=${files[url_index]}
263 | Verify_Files "$file" "${file_sizes[url_index]}" "${file_sums[url_index]}" $use_sha
264 | result=$?
265 | fi
266 | case $result in
267 | 1) Die "File $file is corrupted. Exiting." ;;
268 | 2) Die "File $file is incomplete. Exiting." ;;
269 | 3) Die "Files $file is not available. Exiting." ;;
270 | esac
271 | done
272 |
--------------------------------------------------------------------------------
/bin/UnionSandbox:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | ### Imports ###################################################################
4 |
5 | source ScriptFunctions
6 | Import Array
7 | Import File
8 | Import GoboLinux
9 | Import Log
10 | Import OptionParser
11 | Import UnionFS
12 |
13 | ### Options ###################################################################
14 |
15 | scriptDescription="Run the program in a protected sandbox, as superuser, using unionfs"
16 | scriptCredits="Copyright (C) 2003. Released under the GNU GPL."
17 | helpOnNoArguments=yes
18 | scriptUsage="[] []"
19 | scriptExample="-r 0.0 -s '.:${goboPrograms}/NaughtyApp/Current' make install"
20 | scriptNotes="
21 | To allow mobility within the sandbox, the '.' directory is mounted at
22 | a sandbox root (like $sandboxroot). For this reason, use of relative paths like '..' to reach
23 | directories higher in the hierarchy than '.' may produce unexpected results.
24 | It may also confuse symbolic links that flow through the sandbox.
25 | "
26 |
27 | Add_Option_Entry "w" "writedir" "The dir where writes outside sandbox are written."
28 | Add_Option_Entry "d" "directory" "The program should be run at . "\
29 | "This path should be either absolute, or relative to the sandbox root."
30 | Add_Option_List "s" "sandbox" "Colon-separated list of areas where the restricted process has write access to." "."
31 | Add_Option_List "m" "map" "Colon-separated mapping (lhs=rhs) where writes to rhs are mapped to lhs." ""
32 | Parse_Options "$@"
33 |
34 | Parse_Conf Directories.conf
35 |
36 | Boolean "verbose" && verbose="--verbose"
37 |
38 | ### Operation #################################################################
39 |
40 | Is_Writable "${goboPrograms}" || Die "Needs write access to ${goboPrograms}"
41 |
42 | [ "$1" ] || Die "Please specify a command to be executed inside the sandbox."
43 | Union_Is_Supported || Die "unionfs is unavailabe on this system."
44 | unionbackend=`Union_Backend`
45 |
46 | [ "${unionSandbox[0]}" = "" ] && Die "Please set unionSandbox in Settings/Scripts/Directories.conf"
47 | [ "$unionSandboxMP" = "" ] && Die "Please set unionSandboxMP in Settings/Scripts/Directories.conf"
48 | [ "$unionSandboxRW" = "" ] && Die "Please set unionSandboxRW in Settings/Scripts/Directories.conf"
49 |
50 | sandbox_mp=`mktemp -d "${unionSandboxMP}.tmp.XXXXXXXXXXX"` 2>/dev/null || Die "Unable to create UnionSandbox mount point at $unionSandboxMP"
51 | sandbox_rw=`mktemp -d "${unionSandboxRW}.tmp.XXXXXXXXXXX"` 2>/dev/null || Die "Unable to create UnionSandbox read/write mount point at $unionSandboxRW"
52 | sandbox_tmp=`mktemp -d "${unionSandboxRW}.tmp.XXXXXXXXXXX"` 2>/dev/null || Die "Unable to create UnionSandbox workdir mount point at $unionSandboxRW"
53 | chmod a+rx "$sandbox_mp" "$sandbox_rw" "$sandbox_tmp"
54 |
55 | function RealPath {
56 | readlink -f $@
57 | }
58 |
59 | List_To_Array "sandbox" bindmounts
60 | bindmounts=(`Map RealPath "${bindmounts[@]}"`)
61 | List_To_Array "map" mapmounts
62 |
63 | # Preset cmd status
64 | result=0
65 |
66 | function symlinks_in_root() {
67 | # If we have a host running GoboLinux with gobohidden entries and a chroot environment
68 | # where packages are being compiled with no hidden entries, then the same directory can
69 | # be returned more than once. We use sort+uniq as a filter to workaround that problem.
70 | find `gobohide --list 2> /dev/null | tail -n +1 | grep "^/"` /* -maxdepth 0 -type l | sort -n | uniq
71 | }
72 |
73 | # Called at end of script and by signal handler
74 | function cleanup() {
75 | Log_Normal "Cleaning up."
76 | Quiet pushd ${unionfsPackageDir}
77 | find . -name "*__dir_opaque" | xargs rm -f
78 | Quiet popd
79 |
80 | # Remove wrapper
81 | rm -f -- "$sandbox_mp/.wrapper"
82 |
83 | # Clean up mountpoints
84 |
85 | # unionfs-fuse keeps a few programs busy, so we need to make sure all ocurrences created by us are finished
86 | for entry in $(ps xaw | awk {'print $1 " " $5'} | grep "unionfs" | grep ${sandbox_mp} | grep unionfs)
87 | do
88 | local pid=$(echo "$entry" | cut -d" " -f1)
89 | local unionapp=$(echo $entry | cut -d" " -f2)
90 | [ "$unionapp" = "unionfs" ] && Quiet kill -9 $pid
91 | done
92 | umount "$sandbox_mp/$goboStatus"
93 | umount "$sandbox_mp/$goboDevices"
94 | error=false
95 | For_Each_Reverse mapmounts '
96 | rhs=$(echo $each | cut -d= -f2)
97 | umount ${sandbox_mp}$rhs || { echo "Error unmounting ${sandbox_mp}${rhs}"; error=true; }
98 | '
99 | For_Each_Reverse bindmounts '
100 | umount ${sandbox_mp}${each} || { echo "Error unmounting ${sandbox_mp}${each}"; error=true; }
101 | '
102 | For_Each_Reverse unionSandbox '
103 | Union_Umount ${unionbackend} ${sandbox_mp}${each} || { echo "Error unmounting ${sandbox_mp}${each}"; error=true; }
104 | Quiet rmdir ${sandbox_mp}${each}
105 | Quiet rmdir ${sandbox_rw}${each}
106 | Quiet rmdir ${sandbox_tmp}${each}
107 | '
108 | # Do not attempt to 'rm -rf' if some unmount failed.
109 | [ "$error" = "true" ] && exit 1
110 |
111 | # Clean up legacy links
112 | rm -rf ${sandbox_mp}/usr
113 | rm `find ${sandbox_mp} -maxdepth 1 -type l`
114 |
115 | # Remove tmp dirs
116 | if Is_Entry_Set "writedir"
117 | then
118 | writedir=`Entry "writedir"`
119 | Log_Normal "Moving entries to: $writedir"
120 | Assert_Dir $writedir
121 | cp -ra --no-preserve=xattr $verbose "$sandbox_rw/." "$writedir"
122 | Quiet mv -v $sandbox_mp/* $writedir
123 | fi
124 | rm -rf $sandbox_rw $sandbox_tmp
125 | rmdir $sandbox_mp
126 |
127 | exit $result
128 | }
129 |
130 | function sandbox_die() {
131 | message=$1
132 | Log_Error $message
133 | result=1
134 | cleanup
135 | }
136 |
137 | function mount_union() {
138 | dir=$1
139 | Assert_Dir ${sandbox_mp}${dir}
140 | Assert_Dir ${sandbox_rw}${dir}
141 | Assert_Dir ${sandbox_tmp}${dir}
142 | uniondirs=`echo "${sandbox_rw}${dir}=rw:${dir}=ro:${sandbox_tmp}${dir}=tmp"`
143 | # Dev Note:
144 | # $unionfsPackageDir is empty in PostInstall which was causing sed to garble $uniondirs!
145 | # Upon further investigation, it turned out this sed operation is redundant.
146 | # See https://github.com/gobolinux/Compile/issues/67.
147 | # However this was tested only for the "unionImplementations" "overlayfs" and "unionfs-fuse".
148 | # I did not verify whether this sed operation is *possibly* useful for other implementations like "unionfs" or "funionfs."
149 | # ... therefore I am leaving it here but wrapped securely (sed only if $unionfsPackageDir is non-empty).
150 | if [[ -n "$unionfsPackageDir" ]]
151 | then
152 | uniondirs=`echo $uniondirs | sed "s,$unionfsPackageDir=ro,$unionfsPackageDir=rw,g"`
153 | fi
154 | Union_Mount "$unionbackend" "$uniondirs" "${sandbox_mp}${dir}"
155 | [ "$?" = "0" ] || sandbox_die "Unable to mount unionfs"
156 | }
157 |
158 | trap "sandbox_die 'Interrupted...'" SIGHUP SIGINT SIGTERM
159 |
160 | Log_Verbose "Preparing the sandbox..."
161 |
162 | # Mount unionfs
163 |
164 | unionSandbox=( ${unionSandbox[@]} "$goboIndex" )
165 | For_Each unionSandbox 'mount_union $each'
166 |
167 | # Bind mount writable areas
168 | error=false
169 | For_Each bindmounts 'mkdir -p ${sandbox_mp}/${each}; mount -o bind $each ${sandbox_mp}/${each}; [ "$?" = "0" ] || error=true'
170 | [ "$error" = "false" ] || sandbox_die "Unable to mount writable areas in chroot"
171 |
172 | error=false
173 | For_Each mapmounts 'lhs=$(echo $each | cut -d= -f1)
174 | rhs=$(echo $each | cut -d= -f2)
175 | Assert_Dir $lhs
176 | Assert_Dir ${sandbox_mp}$rhs
177 | mount -o bind $lhs ${sandbox_mp}$rhs
178 | [ "$?" = "0" ] || error=true
179 | '
180 | [ "$error" = "false" ] || sandbox_die "Unable to mount map areas in chroot"
181 |
182 | # Create legacy links and directories
183 | cp -a $verbose `symlinks_in_root` "$sandbox_mp"
184 | mkdir -p "${sandbox_mp}/run"
185 |
186 | # Create wrapper
187 | newpwd="$PWD"
188 | Is_Entry_Set "directory" && newpwd=`Entry "directory"`
189 | echo "#!/bin/bash" >"${sandbox_mp}/.wrapper"
190 | echo "cd $newpwd" >>"${sandbox_mp}/.wrapper"
191 | Args_To_Array command >> "${sandbox_mp}/.wrapper"
192 | if [ "$unionbackend" != "unionfs" ]
193 | then
194 | # delete entries in sandbox if they are legacy symlinks
195 | echo "[ -L $goboDevices ] && rm $goboDevices" >> "${sandbox_mp}/.wrapper"
196 | echo "[ -L $goboStatus ] && rm $goboStatus" >> "${sandbox_mp}/.wrapper"
197 | if grep -q devtmpfs "$goboStatus/filesystems"
198 | then devfs=devtmpfs
199 | else devfs=tmpfs
200 | fi
201 | echo "mkdir -p $goboDevices; mount -t $devfs none $goboDevices" >> "${sandbox_mp}/.wrapper"
202 | echo "mkdir -p $goboStatus; mount -t proc none $goboStatus" >> "${sandbox_mp}/.wrapper"
203 | echo "[ -e \"${goboLibraries}/udev/devices/\" ] && cp -aR \"${goboLibraries}/udev/devices/\"* $goboDevices" >> "${sandbox_mp}/.wrapper"
204 |
205 | # We check if udevadm is also available at runtime. This is needed when building Udev itself.
206 | if Executable_Exists_In_Path "udevadm"
207 | then echo "which udevadm >& /dev/null && udevadm trigger && udevadm settle --timeout=10" >> "${sandbox_mp}/.wrapper"
208 | else echo "which udevtrigger >& /dev/null && udevtrigger && udevsettle" >> "${sandbox_mp}/.wrapper"
209 | fi
210 |
211 | # The following line is a kludge in order to partially mitigate https://github.com/gobolinux/Compile/issues/51.
212 | # This should be fixed properly by running Pre_Installation_Preparation outside of Runner.
213 | echo "find /System/Index | RemoveBroken > /dev/null" >>"${sandbox_mp}/.wrapper"
214 | fi
215 | echo "\"\${command[@]}\"" >>"${sandbox_mp}/.wrapper"
216 |
217 | # Useful for debugging:
218 | #echo "res=\$?" >>"${sandbox_mp}/.wrapper"
219 | #echo "echo DEBUG SHELL; bash" >>"${sandbox_mp}/.wrapper"
220 | #echo "exit \$res" >>"${sandbox_mp}/.wrapper"
221 |
222 | chmod a+x "${sandbox_mp}/.wrapper"
223 |
224 | # Run program in chrooted sandbox
225 | chroot $sandbox_mp /.wrapper
226 | result=$?
227 |
228 | # Cleanup
229 | cleanup
230 |
231 |
--------------------------------------------------------------------------------
/lib/ruby/site_ruby/1.8/gobo.rb:
--------------------------------------------------------------------------------
1 | ### Changelog #################################################################
2 |
3 | # 30/08/2003 - Initial Version
4 |
5 | =begin
6 |
7 | gobo.rb - GoboLinux Ruby Module
8 |
9 | =end
10 | require 'getoptlong'
11 | require 'gobo/logconsole.rb'
12 | require "open3"
13 | #require 'process'
14 |
15 | def Dir.empty?(dir)
16 | begin
17 | return Dir.entries(dir).length == 2
18 | rescue Errno::ENOENT
19 | return true
20 | end
21 | end
22 |
23 | module Gobo
24 | DEFAULT_ARCH = "i686"
25 | def Gobo.RealPath (symLink)
26 | return `readlink -f #{symLink}`.chomp
27 | end
28 |
29 | def Gobo.goodLink?(symlink)
30 | return false unless FileTest.symlink?(symlink)
31 | return FileTest.exists?(File.readlink(symlink))
32 | end
33 |
34 | def Gobo.brokenLink?(symlink)
35 | return false unless FileTest.symlink?(symlink)
36 | return ! FileTest.exists?(File.readlink(symlink))
37 | end
38 |
39 | def Gobo.smartNumber(number)
40 | string = number.to_s
41 | return string unless string.include? "."
42 | string[0, string.index('.') + 3]
43 | end
44 |
45 | def Gobo.smartSize(size)
46 | return size.to_s + " bytes" if size > 0 and size < 1023.99
47 | return "#{smartNumber(size / 1024.to_f)} Kb (#{smartNumber(size)} bytes)" if size >= 1024 and size < 1048576
48 | return "#{smartNumber(size / 1048576.to_f)} Mb (#{smartNumber(size)} bytes)" if size >= 1048576 and size < 1073741824
49 | return "#{smartNumber(size / 1073741824.to_f)} Gb (#{smartNumber(size)} bytes)" if size >= 1073741824 and size < 1099511627776
50 | return "#{smartNumber(size / 1099511627776.to_f)} Tb (#{smartNumber(size)} bytes)" if size >= 1099511627776 and size < 1125899906842624
51 | return "#{smartNumber(size / 1125899906842624.to_f)} Pb (#{smartNumber(size)} bytes)" if size >= 1125899906842624
52 | end
53 |
54 | def Gobo.getUsername
55 | name = ENV['USER']
56 | if Process.uid == 0 && (name == "gobo" || name == "root")
57 | if ENV["SUDO_USER"]
58 | name = ENV["SUDO_USER"]
59 | else
60 | puts "You are currently logged in as #{ENV['USER']}."
61 | puts "Please enter your regular user name so this devel version"
62 | $stdout.print "can be properly tagged: "
63 | $stdout.flush
64 | name = $stdin.gets
65 | end
66 | end
67 | return name
68 | end
69 |
70 | def Gobo.chdir(dir, &block)
71 | Dir.chdir(dir) {
72 | block.call
73 | }
74 | # begin
75 | # pwd = Dir.getwd
76 | # Dir.chdir(dir)
77 | # block.call(pwd)
78 | # rescue
79 | # raise
80 | # ensure
81 | # Dir.chdir(pwd)
82 | # end
83 | end # End of Gobo.chdir
84 |
85 | def Gobo.smartPOpen(cmd, txt, block = nil)
86 | $stdout << "exec:" << cmd << "\n"
87 | IO.popen(cmd, "r") { |io|
88 | io.each { |msg|
89 | block.call("STDOUT:#{txt}#{msg}")
90 | }
91 | }
92 | # stdin, stdout, stderr = Open3.popen3(cmd)
93 | # readers = Array[stdout, stderr, $stdin]
94 | # $stdout << readers.inspect << "\n"
95 | # $stdout << readers.inspect << "\n"
96 | # # (read, write, error) = select(readers,10)
97 | # select(readers,10)
98 | end # End of Gobo.smartPOpen
99 |
100 | def Gobo.parseConfig(filename)
101 | conf = Hash.new
102 | File.open(filename) { |file|
103 | data = file.read().chomp!
104 | data.gsub!(/\n(\s+)/, '\1')
105 | data.split(/\n/).each { |entry|
106 | (name, value) = entry.split(/: /)
107 | conf[name] = value
108 | }
109 | }
110 | return conf
111 | end # End of Gobo.parseConfig
112 | end # End of Module Gobo
113 |
114 | module GoboPath
115 | rubyblock = `GoboPath2Ruby`
116 | eval rubyblock
117 | end
118 |
119 | class GoboApplication
120 | include GoboLogConsole
121 | public
122 | attr_accessor :description, :credits, :usage, :example
123 | attr_accessor :notes, :helpOnNoArguments
124 | attr_reader :name, :version, :startDir
125 |
126 | public
127 | def initialize()
128 | # Add default switches
129 | @options = Hash.new
130 | addOptionBoolean("help", ["-h"], "Display this help")
131 | addOptionBoolean("version", ["-v"], "Show program version")
132 | addOptionBoolean("verbose", ["-V"], "Enable verbose mode")
133 | addOptionBoolean("debug", [], "Enable debug mode")
134 |
135 | @name = File.basename($0)
136 | @version = File.basename(File.dirname(File.dirname(Gobo.RealPath("#{$0}"))))
137 | @startDir = Dir.getwd
138 | $startDir = @startDir
139 | setLogLevel(LogLevelNormal)
140 | # setLogLevel(LogLevelDebug)
141 | end
142 |
143 | def start()
144 | # Save argument list
145 | @savedArgs = ARGV.clone
146 | # Fill getopts with array of arrays for GetoptLong
147 | getopts = Array.new
148 | @options.each do |key, value|
149 | if value["type"] == "entry"
150 | if value["value"] == nil
151 | flag = GetoptLong::REQUIRED_ARGUMENT
152 | else
153 | flag = GetoptLong::OPTIONAL_ARGUMENT
154 | end
155 | elsif value["type"] == "list"
156 | flag = GetoptLong::OPTIONAL_ARGUMENT
157 | else
158 | flag = GetoptLong::NO_ARGUMENT
159 | end
160 | getopts.push( ["--#{key}", value["switches"], flag].flatten)
161 | end
162 |
163 | # Process options
164 | begin
165 | opts = GetoptLong.new(*getopts)
166 | opts.quiet=true
167 | opts.each { |opt, arg|
168 | value = @options[opt[2..-1]]
169 | case value["type"]
170 | when "boolean"
171 | value["value"] = true
172 | when "entry"
173 | value["value"] = arg if arg.length > 0
174 | when "list"
175 | value["value"] = arg.split(":")
176 | end
177 | }
178 | rescue GetoptLong::InvalidOption =>msg
179 | logVerbose "Invalid option: #{msg}"
180 | end
181 |
182 | help if options("help")
183 | help if ARGV.size == 0 && helpOnNoArguments == true
184 | version if options("version")
185 | setLogLevel(LogLevelVerbose) if options("verbose")
186 | setLogLevel(LogLevelDebug) if options("debug")
187 | run()
188 | end
189 |
190 | def stop(msg = nil)
191 | logError "#{msg}" if msg
192 | exit(0)
193 | end
194 |
195 | def run()
196 | end
197 |
198 | def options(key)
199 | @options[key]["value"]
200 | end
201 |
202 | def setOption (name, value = true)
203 | @options[name]["value"] = value
204 | end
205 |
206 | def addOption (type, name, switches, description, default)
207 | # Make sure switches is an array
208 | switches = [switches] unless switches.is_a?(Array)
209 | @options[name] = {"switches" => switches, "type" => type,
210 | "description" => description, "value" => default}
211 | end
212 | def addOptionBoolean (name, switches, description)
213 | addOption("boolean", name, switches, description, false)
214 | end
215 |
216 | def addOptionEntry (name, switches, description, default = nil)
217 | addOption("entry", name, switches, description, default)
218 | end
219 |
220 | def addOptionList (name, switches, description, default = nil)
221 | addOption("list", name, switches, description, default)
222 | end
223 |
224 | def version()
225 | logNormal "#{@name} #{@version}"
226 | logNormal ""
227 | logNormal @credits if @credits
228 | stop()
229 | end
230 |
231 | def help()
232 | logNormal @description if @description
233 | logNormal ""
234 | logNormal "Usage: #{@name} #{@usage}"
235 | logNormal
236 | logNormal "Options:"
237 | @options.sort.each do |x|
238 | (key, value) = x
239 | case value["type"]
240 | when "boolean"
241 | logNormal " --#{key}, " << value["switches"].join(", ")
242 | logNormal " #{value["description"]}"
243 | when "entry"
244 | logNormal " --#{key}, " << value["switches"].join(", ") << ""
245 | logNormal " #{value["description"]}"
246 | logNormal " The default value is #{value["value"]}" if value["value"]
247 | when "list"
248 | logNormal " --#{key}, " << value["switches"].join(", ") << "[:...]"
249 | logNormal " #{value["description"]}"
250 | logNormal " The default value is #{value["value"]}" if value["value"]
251 | end
252 | end
253 | logNormal "\n\nNotes:\n #{@notes}\n" if @notes
254 | logNormal "Examples:\n #{@name} #{@example}" if @example
255 | stop()
256 | end
257 |
258 | def verifySuperuser
259 | if Process.uid != 0
260 | logVerbose "Running as superuser..."
261 | # Revalidate password for another 5 mins"
262 | system 'sudo -u "#0" -v'
263 | # Run with superuser's HOME.
264 | exec "sudo " << ["-u", "\"#0\"", "-H", $0, "#{@savedArgs.join(' ')}"].join(" ")
265 | end
266 | end # End of verifySuperuser
267 |
268 | end # End of GoboApplication
269 |
270 | class GoboCallbacks < Hash
271 | public
272 | def initialize()
273 | super()
274 | end
275 |
276 | def addCallback(callName, aProc = nil)
277 | if (aProc != nil)
278 | if aProc.respond_to? :call
279 | self[callName] = aProc
280 | else
281 | raise "#{callName} callback has no call method"
282 | end
283 | else
284 | self[callName] = proc { |args|
285 | yield *args
286 | }
287 | end
288 | end
289 |
290 | def call(callName, *args)
291 | self[callName].call(*args) if self[callName]
292 | end
293 |
294 | protected
295 | def []=(callName, aProc)
296 | if callName && (aProc.respond_to? :call)
297 | super
298 | else
299 | raise "#{callName} callback has no call method"
300 | end
301 | end
302 | private
303 | def checkSelf
304 | self.each { |callName, aProc|
305 | raise "#{callName} callback has no call method" if aProc.respond_to? :call
306 | }
307 | end
308 | end
309 |
--------------------------------------------------------------------------------
/bin/NewVersion:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | source ScriptFunctions
4 | Import File
5 | Import Log
6 | Import OptionParser
7 | Import GoboLinux
8 | Import Array
9 |
10 | ### Options ###################################################################
11 |
12 | scriptDescription="Update a recipe to a new version."
13 | scriptCredits="Copyright (C) 2003, Hisham Muhammad - Released under the GNU GPL."
14 | helpOnNoArguments=yes
15 | scriptUsage=" (url)"
16 | scriptNotes="Optimistically, it assumes only the version number has changed, "\
17 | "and the compilation process is still identical. The generated recipe is "\
18 | "better understood as a 'template' for the new version recipe."
19 | scriptExample='Allegro 4.1.12, NewVersion --source 0.9.7 Wine 0.9.14'
20 |
21 | Add_Option_Entry "s" "source" "Recipe version number to use as a base for the new version" ""
22 | Add_Option_Entry "n" "former-name" "App name of the Recipe to use as a base. Only necessary if it's different from the name of the new Recipe" ""
23 | Add_Option_Boolean "k" "keep-existing" "Keep existing recipe if one already exists"
24 | Parse_Options "$@"
25 |
26 | Parse_Conf Compile.conf
27 | Import Compile
28 |
29 | unset packagename versionnumber
30 |
31 | Check_Dir_Variable compileRecipesDir
32 | [ ! -w "$compileRecipesDir" -o ! -x "$compileRecipesDir" ] && chown `whoami` "${compileRecipesDir}"
33 |
34 | if [ -z "$(Arg 2)" ]
35 | then
36 | Die "Please specify a package and version number. See --help."
37 | fi
38 |
39 | app="$(Arg 1)"
40 | newversion="$(Arg 2)"
41 | newurl="$(Arg 3)"
42 |
43 | [ -d "$compileRecipesDir/$app" ] && [ ! -w "$compileRecipesDir/$app" -o ! -x "$compileRecipesDir/$app" ] && chown `whoami` "$compileRecipesDir/$app"
44 | [ -d "$compileRecipesDir/$app/$newversion" ] && [ ! -w "$compileRecipesDir/$app/$newversion" -o ! -x "$compileRecipesDir/$app/$newversion" ] && chown -R `whoami` "$compileRecipesDir/$app/$newversion"
45 |
46 | if Is_Entry "former-name"
47 | then srcApp="`Entry "former-name"`"
48 | else srcApp="$app"
49 | fi
50 |
51 | if Is_Entry "source"
52 | then sourceVersion="`Entry "source"`"
53 | else sourceVersion=''
54 | fi
55 |
56 | bakedrecipedir=`GetRecipe "$srcApp" "$sourceVersion"`
57 | [ "$bakedrecipedir" ] || Die "Error getting recipe"
58 | Log_Normal "Recipe found in $bakedrecipedir"
59 |
60 | [ -f "$bakedrecipedir/Recipe" ] || Die "$bakedrecipedir/Recipe not found"
61 | oldrecipe=$bakedrecipedir/Recipe
62 | source $oldrecipe
63 |
64 | if Is_Entry "former-name"
65 | then packagename="$app"
66 | else packagename=`Get_Token "$bakedrecipedir" "/" "-2"`
67 | fi
68 |
69 | oldversionandrevision=`Get_Token "$bakedrecipedir" "/" "-1"`
70 | oldversion=`String_Version "$oldversionandrevision"`
71 |
72 | oldrecipedir="$bakedrecipedir"
73 |
74 | if [ "$oldversion" = "$newversion" -a ! "$newurl" ] || [ "$newversion" = "$oldversionandrevision" -a ! "$newurl" ]
75 | then
76 | Die "Current version is already $newversion."
77 | elif [ "$cvs" -o "$svn" -o "$git" -o "$bzr" -o "$hg" ]
78 | then
79 | Die "NewVersion does not support upgrading cvs/svn/git/bzr/hg recipes."
80 | fi
81 |
82 | Log_Normal "Creating recipe for $packagename $newversion based on $oldversionandrevision."
83 |
84 | destinationDir="$compileRecipesDir"
85 | newrecipedir="$destinationDir/$packagename/$newversion"
86 |
87 | mkdir -p "$destinationDir/$packagename"
88 | if [ "$oldrecipedir" = "$newrecipedir" ]
89 | then
90 | Log_Question "There is already a recipe for $packagename $newversion, at"
91 | Log_Question "$oldrecipedir"
92 | Boolean "keep-existing" && exit 0
93 | if ! Ask "Create another?"
94 | then
95 | exit 0
96 | fi
97 | else
98 | cp -R "$oldrecipedir" "$newrecipedir"
99 | fi
100 |
101 | cd "$newrecipedir" || Die "Failed creating new recipe dir."
102 |
103 | [ -e "Recipe" ] || Die "Recipe file not found."
104 |
105 | # Use -a to avoid considering the file as binary if there are multibyte characters
106 | grep -av '# Recipe for version' Recipe > Recipe.old
107 |
108 | if [ "$compileRecipeAuthor" != "" ]
109 | then
110 | echo "# Recipe for version $newversion by $compileRecipeAuthor, on" `date` > Recipe
111 | cat Recipe.old >> Recipe
112 | else
113 | Log_Terse "Please fill in the 'compileRecipeAuthor' variable in $goboSettings/Compile/Compile.conf"
114 | mv Recipe.old Recipe
115 | fi
116 |
117 | # update compile_version
118 | sed -i '/^compile_version=/d' Recipe
119 | grep -a '# Recipe for version\|# Recipe (MakeRecipe)' Recipe > Recipe.new
120 | grep -av '# Recipe for version\|# Recipe (MakeRecipe)' Recipe > Recipe.old
121 | echo "compile_version=$scriptVersion" >> Recipe.new
122 | cat Recipe.old >> Recipe.new
123 | mv Recipe.new Recipe
124 | # Note: For a future version it might make sense to "sort" the resulting Recipe as the last step.
125 | # This way we could add/edit values in-place without worrying about order and get consistend results.
126 |
127 | if [ "$newurl" ]
128 | then
129 | # TODO: generalize mirror system
130 | newurl=`echo "$newurl" | sed 's|http://.*\.dl.sourceforge.net/sourceforge/|$httpSourceforge/|'`
131 | newurl=`echo "$newurl" | sed 's|ftp://ftp\.gnu\.org/gnu/|$ftpGnu/|'`
132 |
133 | source Recipe
134 | switchurls="s|$url|$newurl|g;"
135 | switchurls="${switchurls}s|^url=.*$|url=\"$newurl\"|g;"
136 | fi
137 |
138 | # if both old and new version are in "x.y.z" format...
139 | if echo "$oldversion;;;$newversion" | grep -aq "^[^.]\+\.[^.]\+\.[^.]\+;;;[^.]\+\.[^.]\+\.[^.]\+$"
140 | then
141 | # ...replace all "x.y" occurrences too
142 | oldmajormiddle=`echo "$oldversion" | cut -d. -f 1-2`
143 | newmajormiddle=`echo "$newversion" | cut -d. -f 1-2`
144 | switchmajormiddle="s|$oldmajormiddle|$newmajormiddle|g;"
145 | fi
146 |
147 | # convert old recipe type to new recipe type
148 | # recipe type compileprogram is renamed to configure
149 | sed -i 's/is_\(.*\)=yes/recipe_type=\1/
150 | s/compileprogram/configure/' Recipe
151 |
152 | Escaped() {
153 | echo "$@" | sed 's,\.,\\.,g'
154 | }
155 |
156 | Update_Recipe() {
157 | recipedir=$1
158 | arch=$2
159 | oldversion_escaped=$(Escaped $oldversion)
160 | newversion_escaped=$(Escaped $newversion)
161 | if [ "$compileRecipeAuthor" != "" ]
162 | then startline=2
163 | else startline=1
164 | fi
165 | Quiet pushd $recipedir
166 | # Version-specific data should be stripped out
167 | mv Recipe Recipe.old
168 | if [ "${switchmajormiddle}" -a "${switchurls}" ]
169 | then
170 | # Test case note: use a different minor on the version and on the url
171 | # e.g., for minor in $(seq 9); do NewVersion Lua 5.1.9 http://www.lua.org/ftp/lua-5.1.${minor}.tar.gz; done
172 | switchvar="${switchurls}${startline}~1$(Escaped ${switchmajormiddle})"
173 | sed_args="${switchvar};s:${oldversion_escaped%_bin}:${newversion_escaped%_bin}:g"
174 | elif [ "${switchmajormiddle}" ]
175 | then
176 | # Test case note: use a minor different from that of the oldversion
177 | # e.g., for minor in $(seq 9); do NewVersion Lua 5.1.$minor; done
178 | switchvar="$(Escaped ${switchmajormiddle})"
179 | sed_args="s:${oldversion_escaped%_bin}:${newversion_escaped%_bin}:g;${switchvar}"
180 | elif [ "${switchurls}" ]
181 | then
182 | # Test case note: remove or add a digit from the last known version, and provide a URL
183 | # e.g., NewVersion Lua 5.9 http://www.lua.org/ftp/lua-5.9.tar.gz
184 | switchvar=${switchurls}
185 | sed_args="${switchvar};s:${oldversion_escaped%_bin}:${newversion_escaped%_bin}:g"
186 | else
187 | # Test case note: remove or add a digit from the last known version
188 | # e.g., NewVersion Lua 5.9, NewVersion Lua 5.9.0.1
189 | sed_args="s:${oldversion_escaped%_bin}:${newversion_escaped%_bin}:g"
190 | fi
191 | sed "${sed_args}" Recipe.old |\
192 | awk '
193 | BEGIN { skip=0; }
194 | /^file_md5s=\([^)]*$/ { skip=2; }
195 | /^file_sizes=\([^)]*$/ { skip=2; }
196 | /^file_md5s=\(.*\)$/ { skip=1; }
197 | /^file_sizes=\(.*\)$/ { skip=1; }
198 | /^file_md5=.*$/ { skip=1; }
199 | /^file_size=.*$/ { skip=1; }
200 | /^\)$/ { skip--; }
201 | { if (skip<1) print; else if (skip==1) skip=0; }
202 | ' >> Recipe
203 |
204 | rm Recipe.old
205 |
206 | unset url urls file files
207 | source Recipe
208 |
209 | if [ "$newurl" ]
210 | then
211 | [ -z "$arch" ] && url="$newurl" || Log_Terse "Not updating $arch arch with passed URL. Please check."
212 | fi
213 |
214 | if Starts_With "http:" $url
215 | then
216 | Quiet pushd "$compileArchivesDir"
217 | Log_Normal "Checking URL '$url'..."
218 | quietflag="--quiet"
219 | Boolean "verbose" && unset quietflag
220 | if ! wget -t 5 $quietflag --spider "$url"
221 | then
222 | Log_Terse "URL may be invalid. Please check."
223 | fi
224 | Quiet popd
225 | fi
226 |
227 | if ls *.patch &> /dev/null
228 | then
229 | Log_Terse "This recipe contains $arch patches. Please check if they still apply."
230 | fi
231 |
232 | if [ "$url" -o "$urls" ]
233 | then
234 | if [ "$newversion" = "git" ]
235 | then
236 | sed -i "s,\(^url=.*\),git=\"$url\",g" "$recipedir/Recipe"
237 | fi
238 | Log_Normal "Downloading source code..."
239 | if ! FetchArchive --program "$packagename" --version-number "$newversion" --no-verify-files "$recipedir/Recipe"
240 | then
241 | rm -rf "$recipedir"
242 | Die "Could not download $arch source code, aborting."
243 | fi
244 | if [ "$newversion" = "git" ]
245 | then
246 | # Do not append new file_size/file_md5 entries
247 | true
248 | elif [ "$url" ]
249 | then
250 | [ -z "${file}" ] && file="`basename $url`"
251 | filesize="`Get_Size $compileArchivesDir/$file`"
252 | filemd5="`Get_MD5 $compileArchivesDir/$file`"
253 | sed -i "s,\(^url=.*\),\1\nfile_size=$filesize\nfile_md5=$filemd5,g" "$recipedir/Recipe"
254 | else # There are multiple URLs
255 | echo "file_sizes=(" > file_sizes.tmp
256 | echo "file_md5s=(" > file_md5s.tmp
257 | Zip '
258 | [ -z "$file" ] && file="`basename $url`"
259 | echo "`Get_Size $compileArchivesDir/$file`" >> file_sizes.tmp
260 | echo "`Get_MD5 $compileArchivesDir/$file`" >> file_md5s.tmp
261 | ' urls url files file
262 | echo ")" >> file_sizes.tmp
263 | echo ")" >> file_md5s.tmp
264 | cat Recipe file_sizes.tmp file_md5s.tmp > Recipe.new
265 | mv -f Recipe.new Recipe
266 | rm -f file_sizes.tmp file_md5s.tmp
267 | fi
268 | fi
269 | Quiet popd
270 | }
271 |
272 | Update_Recipe $newrecipedir ""
273 | for arch in ${compileSupportedArchitectures[@]}
274 | do
275 | if [ -f $newrecipedir/$arch/Recipe ]
276 | then
277 | Update_Recipe $newrecipedir/$arch $arch
278 | fi
279 | done
280 |
281 | Log_Normal "Recipe template for $packagename $newversion created"
282 | Log_Normal "Printing result ($newrecipedir/Recipe):"
283 | cat "$newrecipedir/Recipe" >&$normalFD
284 | for arch in ${compileSupportedArchitectures[@]}
285 | do
286 | if [ -f $newrecipedir/$arch/Recipe ]
287 | then
288 | Log_Normal "Printing recipe for $arch architecture:"
289 | cat "$newrecipedir/$arch/Recipe" >&$normalFD
290 | fi
291 | done
292 | Log_Normal "Done"
293 |
--------------------------------------------------------------------------------
/bin/SandboxInstall:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | source ScriptFunctions
4 | Import File
5 | Import GoboLinux
6 | Import OptionParser
7 | Import String
8 | Import Directories
9 | Import UnionFS
10 |
11 | helpOnNoArguments=yes
12 | scriptDescription="Runs 'make install', using a sandbox environment."
13 | scriptCredits="Copyright (C) Hisham Muhammad, 2001-2005 - Released under the GNU GPL."
14 | scriptUsage="[] [ -- ]"
15 | scriptExample="--makefile makefile.unix --target install_shared WeirdSuperLib 2.4"
16 | scriptNotes="
17 | Normally you'll want to use Compile(1) instead.
18 | '$scriptName' is called by Compile(1).
19 | "
20 | Add_Option_Entry "t" "target" "Makefile target to be used." "install"
21 | Add_Option_Entry "f" "makefile" "Specify which makefile to use." "Makefile"
22 | Add_Option_Entry "m" "make" "Use the given variant of make (ie: cmake). Use in recipe_type={makefile,configure}" "ColorMake"
23 | Add_Option_Entry "c" "command" "Use the given command instead of make (ie: python). Options --target and --makefile are then ignored."
24 | Add_Option_Entry "a" "add-allowed" "Specify additional allowed directories or files. Colon separated list."
25 | Add_Option_Entry "u" "unmanaged-files" "Specify allowed directories or files, which should be handled as unmanaged. Colon separated list."
26 | Add_Option_Boolean "F" "no-sandbox" "Do not protect the installation with a sandbox."
27 | Add_Option_Entry "e" "expand-sandbox" "By default, the sandbox is built relative to the current "\
28 | "directory, '.'. Passing 1 to this option will build it relative to the parent directory, '..',"\
29 | "passing 2 relative to '../..', and so on." ""
30 | Add_Option_Boolean "l" "allow-leftovers" "When using UnionFS, do not return a failure code when it catches files outside the sandbox."
31 |
32 | Parse_Options "$@"
33 |
34 | Boolean "verbose" && verbose="--verbose"
35 |
36 | Dir_Set Sandbox || Set_Boolean "no-sandbox"
37 |
38 | if Dir_Set Sandbox
39 | then
40 | Is_Writable "${goboPrograms}" || Die "Needs write access to ${goboPrograms}"
41 | fi
42 |
43 | ### Version ####################################################################
44 |
45 | # TODO: this code is copy-and-pasted from SymlinkProgram.
46 | # It should move into functions.
47 |
48 | [ "$(Arg 2)" ] || Die "Argument missing: specify program and version."
49 |
50 | unset unionsandbox
51 |
52 | if ! Boolean "no-sandbox"
53 | then
54 | if ! Union_Is_Supported
55 | then
56 | Die "unionfs is unavailable. Cannot proceed with the installation."
57 | else
58 | Log_Normal "$(Union_Backend) is available. Using UnionSandbox."
59 | unionsandbox=yes
60 | fi
61 | fi
62 |
63 | package="`basename "$(Arg 1)" /`"
64 | package="`GuessProgramCase "$(Arg 1)"`"
65 | packageDir=`Get_Dir runtime "$package" ''`
66 |
67 | if ! Is_Directory "$packageDir"
68 | then Die "Directory $packageDir does not exist."
69 | fi
70 |
71 | installPackageDir=`Get_Dir install "$package" ''`
72 | current="$packageDir/Current"
73 |
74 | requested_version=$(Arg 2)
75 | vdir=`Get_Dir runtime "$package" "$requested_version"`
76 | if { ! Is_Directory "$vdir" ;} && { ! Boolean "no-sandbox" ;}
77 | then Die "There is no version $requested_version for package $package."
78 | fi
79 |
80 | Dir_Set Current && [ -n "$version" -a "$version" != "$requested_version" ] && ln -sfn `basename "$vdir"` "$current"
81 | version="$requested_version"
82 |
83 | # exports to UnionSandbox
84 | export unionfsPackageDir="$installPackageDir/$version"
85 |
86 | if Dir_Set Current && ! Exists "$current"
87 | then
88 | youngestdir=`ls --sort=time "$packageDir" | head -n 1`
89 | ln -s "$youngestdir" "$current"
90 | fi
91 |
92 | ### Install ####################################################################
93 |
94 | function cleanup() {
95 | # If not using UnionSandbox (i.e., --no-sandbox)
96 | # undo symlink from Settings to Defaults/Settings
97 | settings="$installPackageDir/Settings"
98 | if ! [ "$unionsandbox" ]
99 | then
100 | umount "${default_settings}"
101 | fi
102 | }
103 |
104 | function installation_failed() {
105 | cleanup
106 | Die "${1}"
107 | }
108 |
109 | trap "installation_failed 'Caught signal. Exiting...'" SIGHUP SIGINT SIGTERM
110 |
111 | Log_Normal "Installing $package..."
112 |
113 | unset $expandsandbox
114 | if Is_Entry "expand-sandbox"
115 | then
116 | for i in $(seq $(Entry "expand-sandbox"))
117 | do
118 | expandsandbox=$expandsandbox/..
119 | done
120 | fi
121 |
122 | allowed=".$expandsandbox:$installPackageDir/$version:$packageDir/Settings"
123 | Is_Entry "add-allowed" && allowed="$allowed:$(Entry "add-allowed")"
124 | Is_Entry "unmanaged-files" && eval $(Split_String "unmanagedarray" "$(Entry "unmanaged-files")" ":")
125 | Log_Verbose "Sandbox options:"
126 | Log_Verbose "Allowed directories: ${allowed}"
127 | Log_Verbose "Unmanaged directories: ${unmanagedarray[@]}"
128 | settings="$installPackageDir/Settings"
129 | default_settings="$installPackageDir/$version/Resources/Defaults/Settings"
130 |
131 | for unmanaged in "${unmanagedarray[@]}"
132 | do
133 | # If it's not a directory (it's possible that it's a non-existant directory, but that's ok), strip one level
134 | # Also remove any $goboPrefix, since we will add it later to ensure that it is used even for recipes that don't use it
135 | [ ! -d "${unmanaged}" ] && unmanaged=$(echo "${unmanaged}" | sed -e 's,\(.*\)/[^/]*,\1,')
136 | [ "$goboPrefix" ] && unmanaged=$(echo "${unmanaged}" | sed -e 's,'"$goboPrefix"',,' )
137 | # Make sure the directories exist
138 | Assert_Dir "${goboPrefix}${unmanaged}"
139 | Assert_Dir "${installPackageDir}/${version}/Resources/Unmanaged${unmanaged}"
140 | # Map them
141 | unmanagedmap="${installPackageDir}/${version}/Resources/Unmanaged${unmanaged}=${goboPrefix}${unmanaged}${unmanagedmap:+:${unmanagedmap}}"
142 | done
143 |
144 | if [ -n "$unionsandbox" ]
145 | then
146 | sandbox_rw="$installPackageDir/$version/.SandboxInstall_Root"
147 | rm -rf -- "$sandbox_rw"
148 | #map_settings="--map ${default_settings}=${settings}${unmanagedmap:+:${unmanagedmap}}"
149 | if [ -z "$unmanagedmap" ]
150 | then map_settings=
151 | else map_settings="--map ${unmanagedmap}"
152 | fi
153 | sandbox="UnionSandbox $verbose --writedir $sandbox_rw --sandbox $allowed $map_settings -- "
154 | fi
155 |
156 | Boolean "no-sandbox" && sandbox=
157 |
158 | # If not using UnionSandbox (i.e., --no-sandbox)
159 | # symlink Settings to Defaults/Settings
160 | if [ -z "$unionsandbox" ]
161 | then
162 | Assert_Dir $default_settings
163 | mount --bind "${default_settings}" "${settings}"
164 | fi
165 |
166 | eval `Args_To_Array args 3`
167 |
168 | if Is_Entry_Set "make"
169 | then makecmd=`Entry "make"`
170 | else makecmd="${compileMakeCommand:-ColorMake}"
171 | fi
172 |
173 | if Is_Entry "command"
174 | then $sandbox `Entry "command"` "${args[@]}" || installation_failed
175 | else $sandbox $makecmd -f "`Entry "makefile"`" installprefix="${installPackageDir}/${version}" INSIDE_GOBO_SANDBOX=1 "${args[@]}" `Entry "target"` || installation_failed
176 | fi
177 | result="$?"
178 |
179 | if [ "$unionsandbox" ]
180 | then
181 | # Postprocess contents of $sandbox_rw here
182 | Log_Normal "Postprocessing Sandbox"
183 | Quiet pushd $sandbox_rw
184 | rm -rf ./$goboData/Compile/Sources
185 | rm -rf ./$goboKernel/Objects
186 | rm -f ./$goboKernel/Kernel/Modules/*/modules.*
187 | rm -f ./$goboKernel/Devices/null
188 | rm -f ./$goboKernel/Devices/tty
189 | rm -rf ./$goboVariable/tmp/{*,.*} &> /dev/null
190 | rm -rf ./$goboVariable/cache/*
191 | rm -rf ./$goboVariable/log/*
192 | rm -rf ./$goboVariable/{run,}/mount/utab
193 | rm -rf ./$goboVariable/scrollkeeper
194 | rm -f ./$goboSettings/{passwd,passwd-,group,group-}
195 | rm -f ./$goboSettings/mtab
196 | rm -f Programs/Glibc/Settings/ld.so.cache
197 | if [ "$package" != "Python" -a -d Programs/Python ]
198 | then find Programs/Python -type f -name "*.pyc" -or -name "*.pyo" | xargs rm -f &> /dev/null
199 | fi
200 | rm -rf Users/*/.distcc
201 | rm -rf Users/*/.cache
202 | rm -rf Users/*/.cargo
203 | rm -rf Users/*/.oracle_jre_usage
204 | rmdir Users/* Users &> /dev/null
205 | find -type c | xargs rm -f &> /dev/null
206 | find -type d -name "__pycache__" | xargs rm -rf &> /dev/null
207 | find -type f -name "*__dir_opaque" | xargs rm -f &> /dev/null
208 | find -type f -name "*_HIDDEN~" | xargs rm -f &> /dev/null
209 | find -type f -name "*_DELETED~" | xargs rm -f &> /dev/null
210 | find -type f -name "\.wh.*" | xargs rm -f &> /dev/null
211 | find -type d | xargs rmdir -p --ignore-fail-on-non-empty &> /dev/null
212 |
213 | # Sometimes writes to symlinks let files appear in a previous directory of the same program.
214 | # We try to detect these cases here, moving files written there to the appropriate place.
215 | ls "./$installPackageDir" 2> /dev/null | grep -v "$version\|Current\|Settings\|Variable" | while read wrong_version
216 | do
217 | installPackageDirWrongVersion="./$installPackageDir/$wrong_version"
218 | installPackageDirVersion="$installPackageDir/$version"
219 | Log_Verbose "Fixing files copied into previous version"
220 | for file in $(ls $installPackageDirWrongVersion)
221 | do
222 | Log_Verbose "$installPackageDirWrongVersion/$file -> $installPackageDirVersion/"
223 | cp -a --no-preserve=xattr "$installPackageDirWrongVersion/$file" "$installPackageDirVersion/"
224 | done
225 | done
226 |
227 | # Aggressively move everything that was installed into other programs' dirs
228 | # back into the area of the one we are installing.
229 | [ -d ./Programs ] && for p in `ls ./Programs | grep -v "^$package$"`
230 | do
231 | for entry in ./Programs/$p/*
232 | do
233 | if Ends_With "/Settings" $entry
234 | then
235 | mkdir -p $default_settings
236 | cp -a --no-preserve=xattr $verbose $entry/* $default_settings/
237 | elif Ends_With "/Variable" $entry
238 | then
239 | cp -a --no-preserve=xattr $verbose $entry/* $installPackageDir/Variable/
240 | else
241 | cp -a --no-preserve=xattr $verbose $entry/* $installPackageDir/$version/
242 | fi
243 | done
244 | rm -rf ./Programs/$p
245 | done
246 | rm -rf ./Programs
247 |
248 | # This doesn't use $goboIndex because $goboIndex is actually /usr.
249 | # This is confusing. We should clean this up.
250 | mkdir -p $default_settings
251 | cp -a --no-preserve=xattr $verbose ./$goboSystem/Index/* $installPackageDir/$version 2>/dev/null
252 | cp -a --no-preserve=xattr $verbose ./$goboSettings/* $default_settings 2>/dev/null
253 | cp -a --no-preserve=xattr $verbose ./usr/local/* $installPackageDir/$version 2>/dev/null
254 | rm -rf ./usr/local
255 | cp -a --no-preserve=xattr $verbose ./usr/* $installPackageDir/$version 2>/dev/null
256 | rm -rf ./usr 2> /dev/null
257 | rm -f $installPackageDir/$version/etc/mtab
258 | rmdir --ignore-fail-on-non-empty $installPackageDir/$version/etc 2> /dev/null
259 | rm -rf ./$goboSystem/Index
260 | rm -rf ./$goboSettings
261 | rmdir $sandbox_rw/System 2> /dev/null
262 |
263 | # lib64 -> lib
264 | if [ -d $installPackageDir/$version/lib64 ]
265 | then
266 | libfiles=$(find $installPackageDir/$version/lib -type f 2> /dev/null | wc -l | awk {'print $1'})
267 | if [ $libfiles -eq 0 ]
268 | then
269 | rmdir $installPackageDir/$version/lib
270 | mv $installPackageDir/$version/{lib64,lib}
271 | elif [ -d $installPackageDir/$version/lib ]
272 | then
273 | cp -a --no-preserve=xattr $installPackageDir/$version/lib64/* $installPackageDir/$version/lib
274 | rm -rf -- $installPackageDir/$version/lib64
275 | fi
276 | fi
277 |
278 | # share/pkgconfig -> lib/pkgconfig
279 | if [ -d $installPackageDir/$version/share/pkgconfig ]
280 | then
281 | mkdir -p $installPackageDir/$version/lib/pkgconfig
282 | cp -a --no-preserve=xattr $installPackageDir/$version/share/pkgconfig/* $installPackageDir/$version/lib/pkgconfig/
283 | rm -rf -- $installPackageDir/$version/share/pkgconfig
284 | fi
285 |
286 | # man -> share/man
287 | rmdir $installPackageDir/$version/man 2> /dev/null
288 | if [ -d $installPackageDir/$version/man ]
289 | then
290 | mkdir -p $installPackageDir/$version/share/man
291 | cp -a --no-preserve=xattr $installPackageDir/$version/man/* $installPackageDir/$version/share/man
292 | rm -rf -- $installPackageDir/$version/man
293 | fi
294 |
295 | rm -f $installPackageDir/$version/share/info/dir
296 |
297 | # LibTool .la files are deprecated
298 | rm -f -- $installPackageDir/$version/lib/*.la
299 |
300 | # Remove extended attributes associated with overlayfs -- it's possible that temporary overlayfs xattrs
301 | # used during the installation process marked files or directories opaque. Unless we reset those xattrs,
302 | # we may have problems with Runner when it creates a union sandbox using the overlayfs backend.
303 | fname=
304 | xattr_pattern="trusted.overlay."
305 | getfattr -P -R -d -m "$xattr_pattern" --absolute-names "$installPackageDir/$version" 2> /dev/null | while read i
306 | do
307 | if echo "$i" | grep -q "^# file:"
308 | then
309 | fname="$(echo "$i" | awk {'print $3'})"
310 | elif echo "$i" | grep -q "^${xattr_pattern}"
311 | then
312 | xattr="$(echo "$i" | cut -d= -f1)"
313 | setfattr --remove "$xattr" "$fname"
314 | fi
315 | done
316 |
317 | Quiet popd
318 |
319 | [ -d "$sandbox_rw" ] && leftovers=`(cd $sandbox_rw; find * | grep -v ${installPackageDir}/${version}-safelinking) 2>/dev/null`
320 | [ "$leftovers" ] && {
321 | Log_Normal "Left over files:\n$leftovers"
322 | if ! Boolean "allow-leftovers"
323 | then exit 21 # Remember Fibo.
324 | fi
325 | }
326 | Quiet rmdir $sandbox_rw
327 | fi
328 |
329 | cleanup
330 | exit $result
331 |
--------------------------------------------------------------------------------
/bin/ContributeRecipe:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # ContributeRecipe - submits a GoboLinux recipe for review
3 | # Copyright (C) 2008-2020 Michael Homer
4 | # Copyright (C) 2020 Rune Morling
5 | #
6 | # This program is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 2 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # This program is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with this program. If not, see .
18 |
19 | ### Imports ###################################################################
20 |
21 | source ScriptFunctions
22 | Import GoboLinux
23 | Import OptionParser
24 | Import Versions
25 | Import Archive
26 | Import RecipeTools
27 |
28 | Parse_Conf Compile/Compile.conf
29 |
30 | submissionTarget='http://recipes.gobolinux.org/review/submit?ver=1'
31 | ### Options ###################################################################
32 |
33 | scriptDescription="Contribute a recipe to the global store"
34 | scriptCredits="Copyright (C) 2008-2009 Michael Homer. Released under the GNU GPL."
35 | helpOnNoArguments=yes
36 | scriptUsage="{ | [] }"
37 | scriptExample="firefox"
38 | Add_Option_Boolean "g" "gobo" "GoboLinux developer: push straight to repo."
39 | Add_Option_Boolean "p" "pretend" "Don't really submit, just dump the report to stdout."
40 | Add_Option_Boolean "s" "show-secret" "Show secret GitHub oauth token on stdout."
41 | Parse_Options "$@"
42 |
43 | ### Utils #####################################################################
44 |
45 | # Actually enable pretending to do a command
46 | pretend() {
47 | if Boolean "p"
48 | then
49 | echo "# $@"
50 | else
51 | "$@"
52 | fi
53 | }
54 |
55 | run_fail() {
56 | if Boolean "p"
57 | then
58 | echo "# $@"
59 | else
60 | "$@" || Die "Failed during: $@"
61 | fi
62 | }
63 |
64 | run_retry() {
65 | if Boolean "p"
66 | then
67 | echo "# $@"
68 | else
69 | for i in $(seq 3)
70 | do
71 | "$@" && return
72 | done
73 | Die "Max number of retries reached, aborting."
74 | fi
75 | }
76 |
77 | handle_description() {
78 | local name="$1"
79 | local version="$2"
80 |
81 | # Handle descriptions
82 | description="Resources/Description"
83 | if ! [ -e "$description" ]
84 | then
85 | mkdir -p Resources/
86 | DescribeProgram -m ascii $name > "$description"
87 | if [ `cat $description | wc -c` -eq 0 ]
88 | then
89 | rm $description
90 | license=""
91 | sourcedir="$compileSourcesDir/$(echo $name | tr '[:upper:]' '[:lower:]')-$version"
92 | if [ ! -d "$sourcedir" ]
93 | then
94 | sourcedir="$compileSourcesDir/$name-$version"
95 | fi
96 | if [ -d "$sourcedir" ]
97 | then
98 | for licensefile in $sourcedir/COPYING* $sourcedir/LICENSE* $sourcedir/license*
99 | do
100 | if [ -e $licensefile ]
101 | then
102 | md5license=`md5sum $licensefile | cut -d" " -f1`
103 | case "$md5license" in
104 | # GPL3
105 | f27defe1e96c2e1ecd4e0c9be8967949) newlicense="GNU General Public License version 3" ;;
106 | d32239bcb673463ab874e80d47fae504) newlicense="GNU General Public License version 3" ;;
107 | # GPL2 Mass Ave
108 | 8ca43cbc842c2336e835926c2166c28b) newlicense="GNU General Public License version 2" ;;
109 | 18810669f13b87348459e611d31ab760) newlicense="GNU General Public License version 2" ;;
110 | 7975d4f2e1ca1e9df4dcfd94c6e1ae48) newlicense="GNU General Public License version 2" ;;
111 | cbbd794e2a0a289b9dfcc9f513d1996e) newlicense="GNU General Public License version 2" ;;
112 | e2ab865bd66f4d8e34f31582339c911a) newlicense="GNU General Public License version 2" ;;
113 | 0278281246c1e59af1ef0ae1784a4948) newlicense="GNU General Public License version 2" ;;
114 | # GPL2 Franklin St mentions Library
115 | 59530bdf33659b29e73d4adb9f9f6552) newlicense="GNU General Public License version 2" ;;
116 | 751419260aa954499f7abaabaa882bbe) newlicense="GNU General Public License version 2" ;;
117 | eb723b61539feef013de476e68b5c50a) newlicense="GNU General Public License version 2" ;;
118 | a21edfd959813dc8af8161fe3f7ffaa2) newlicense="GNU General Public License version 2" ;;
119 | 4325afd396febcb659c36b49533135d4) newlicense="GNU General Public License version 2" ;;
120 | eee1a5a93345d061765a5df481d19b7a) newlicense="GNU General Public License version 2" ;;
121 | 6d5a9d4c4d3af25cd68fd83e8a8cb09c) newlicense="GNU General Public License version 2" ;;
122 | 6ddd5335ef96fb858a138230af773710) newlicense="GNU General Public License version 2" ;;
123 | 8ef380476f642c20ebf40fecb0add2ec) newlicense="GNU General Public License version 2" ;;
124 | 9ea3144f04c41cd2eada5d3f472e6ea5) newlicense="GNU General Public License version 2" ;;
125 | 892f569a555ba9c07a568a7c0c4fa63a) newlicense="GNU General Public License version 2" ;;
126 | # GPL2 Temple Place
127 | 94d55d512a9ba36caa9b7df079bae19f) newlicense="GNU General Public License version 2" ;;
128 | 393a5ca445f6965873eca0259a17f833) newlicense="GNU General Public License version 2" ;;
129 | fdafc691aa5fb7f8e2a9e9521fef771b) newlicense="GNU General Public License version 2" ;;
130 | 0636e73ff0215e8d672dc4c32c317bb3) newlicense="GNU General Public License version 2" ;;
131 | a87895c4956801618eb9d3a4f8afe8f8) newlicense="GNU General Public License version 2" ;;
132 | c93c0550bd3173f4504b2cbd8991e50b) newlicense="GNU General Public License version 2" ;;
133 | 5574c6965ae5f583e55880e397fbb018) newlicense="GNU General Public License version 2" ;;
134 | b0c80473f97008e42e29a9f80fcc55ff) newlicense="GNU General Public License version 2" ;;
135 | bae3019b4c6dc4138c217864bd04331f) newlicense="GNU General Public License version 2" ;;
136 | 03b36fdd84f74b8d8189a202b980b67f) newlicense="GNU General Public License version 2" ;;
137 | 7b0683f0a63b15f8cc8273f96fd564a9) newlicense="GNU General Public License version 2" ;;
138 | 15fac19769be7c6091cda2f70757f064) newlicense="GNU General Public License version 2" ;;
139 | 361b6b837cad26c6900a926b62aada5f) newlicense="GNU General Public License version 2" ;;
140 | 878e3965c7b52d85827c75f5a2f3b314) newlicense="GNU General Public License version 2" ;;
141 | 526c29250ae72f6933cdc01414b9943b) newlicense="GNU General Public License version 2" ;;
142 | 9ac2e7cff1ddaf48b6eab6028f23ef88) newlicense="GNU General Public License version 2" ;;
143 | c46082167a314d785d012a244748d803) newlicense="GNU General Public License version 2" ;;
144 | # GPL2 Linux kernel
145 | d7810fab7487fb0aad327b76f1be7cd7) newlicense="GNU General Public License version 2" ;;
146 | # LGPL2 Mass Ave
147 | 55ca817ccb7d5b5b66355690e9abc605) newlicense="GNU Library General Public License version 2" ;;
148 | ac4e4df3bbeacd481df543d2b12860b3) newlicense="GNU Library General Public License version 2" ;;
149 | 252890d9eee26aab7b432e8b8a616475) newlicense="GNU Library General Public License version 2" ;;
150 | # LGPL2 Temple Place
151 | 3bf50002aefd002f49e7bb854063f7e7) newlicense="GNU Library General Public License version 2" ;;
152 | 7be2873b6270e45abacc503abbe2aa3d) newlicense="GNU Library General Public License version 2" ;;
153 | f30a9716ef3762e3467a2f62bf790f0a) newlicense="GNU Library General Public License version 2" ;;
154 | c46bda00ffbb0ba1dac22f8d087f54d9) newlicense="GNU Library General Public License version 2" ;;
155 | 1e992216ed56a0fc1b6ea4a2de2962c7) newlicense="GNU Library General Public License version 2" ;;
156 | 6e29c688d912da12b66b73e32b03d812) newlicense="GNU Library General Public License version 2" ;;
157 | # LGPL2.1
158 | fad9b3332be894bab9bc501572864b29) newlicense="GNU Lesser General Public License version 2.1" ;;
159 | d7b37bf80a3df5a65b355433ae36d206) newlicense="GNU Lesser General Public License version 2.1" ;;
160 | fbc093901857fcd118f065f900982c24) newlicense="GNU Lesser General Public License version 2.1" ;;
161 | 13b7ddb75583d236cf6855762f047e34) newlicense="GNU Lesser General Public License version 2.1" ;;
162 | e3eda01d9815f8d24aae2dbd89b68b06) newlicense="GNU Lesser General Public License version 2.1" ;;
163 | 7fbc338309ac38fefcd64b04bb903e34) newlicense="GNU Lesser General Public License version 2.1" ;;
164 | a049c5e22d3bd7bc3c9a2e9135a6d104) newlicense="GNU Lesser General Public License version 2.1" ;;
165 | # MPL1.1
166 | bfe1f75d606912a4111c90743d6c7325) newlicense="Mozilla Public License 1.1" ;;
167 | # Apache License 2.0
168 | 218532c6a293a0aef9ab37fe496c3cd2) newlicense="Apache License 2.0" ;;
169 | *)
170 | Log_Terse "Could not autodetermine licensing for writing the Description file."
171 | Ask_Continue "Press Enter to view the license file $licensefile."
172 | ${PAGER:-less} $licensefile
173 | ;;
174 | esac # esac is ridiculous.
175 | if [ "$license" = "" ]
176 | then license="$newlicense"
177 | else license="$license, $newlicense"
178 | fi
179 | fi
180 | done
181 | fi
182 | if [ "$license" = "" ]
183 | then license="***REPLACE THIS WITH THE NAME OF THE LICENSE***"
184 | fi
185 | if ! [ "$EDITOR" ]
186 | then
187 | Log_Terse "EDITOR variable is not set. Can't edit description. Use \`export EDITOR='...'\` to set it."
188 | return 0
189 | fi
190 | cat < $description
191 | [Name] $name
192 | [Summary] ***REPLACE THIS WITH A SHORT ONE LINE DESCRIPTION***
193 | [Description] ***REPLACE THIS WITH A MORE DETAILED DESCRIPTION***
194 | [License] $license
195 | [Homepage] ***REPLACE THIS WITH THE HOMEPAGE URL***
196 | EOF
197 | $EDITOR $description
198 | while grep -q "***REPLACE" $description
199 | do
200 | if Ask "Description wasn't filled properly. Retry?"
201 | then $EDITOR $description
202 | else
203 | rm $description
204 | return 1
205 | fi
206 | done
207 | fi
208 | fi
209 | return 0
210 | }
211 |
212 | ### Operation #################################################################
213 |
214 | if Boolean "p"
215 | then
216 | echo ""
217 | Log_Normal "Running with '--pretend': Will show commands but not commit changes to remotes.\n"
218 | fi
219 |
220 | # sets 'recipedir', 'program' and 'version'
221 | Set_Recipe_Program_And_Version_From_Args
222 |
223 | cd "$recipedir"
224 |
225 | handle_description "$program" "$version"
226 |
227 | RecipeLint $program $version
228 | [ $? = 2 ] && Die "Recipe failed validation. Not submitting."
229 |
230 | [ -r "$recipedir/Resources/Description" ] || Die "No description file found. Not submitting."
231 |
232 | [ -r "$recipedir/Recipe" ] || Die "Could not read Recipe file in $recipedir."
233 |
234 | # Perform some simple cleanups
235 | for i in `find $recipedir -name Recipe`
236 | do
237 | [ -w `dirname "$i"` ] || Die "Need write permissions to the recipe."
238 | sed -i.bak -e 's,$target/../Settings,$settings_target,g' \
239 | -e 's,$target/../Variable,$variable_target,g' \
240 | $i
241 | rm $i.bak
242 | done
243 |
244 | branch="submit-$program-$version"
245 |
246 | echo ""
247 | Log_Normal "Creating local branch "$branch" ...\n"
248 |
249 | run_fail git pull
250 | run_fail git checkout -B "$branch"
251 | run_fail git add .
252 | run_fail git commit -m "$program $version"
253 |
254 | if Boolean "gobo"
255 | then
256 |
257 | echo ""
258 | Log_Normal "GoboLinux Maintainer workflow selected ...\n"
259 |
260 | run_fail git stash
261 | run_fail cd "$compileRecipesDir"
262 | run_fail git checkout "$compileUpstreamBranch"
263 | run_fail git pull
264 | run_fail git merge "submit-$program-$version"
265 | run_fail git rebase
266 | run_retry git push
267 | run_fail git stash pop
268 | run_fail git branch -D "submit-$program-$version"
269 |
270 | else
271 |
272 | echo ""
273 | Log_Normal "GoboLinux Contributor workflow selected ...\n"
274 |
275 | pretend git config hub.protocol https
276 | hub --version &> /dev/null || Die "You need to install 'hub' to auto-submit pull-requests"
277 |
278 | echo ""
279 | Log_Normal "When using 2FA, use GITHUB_TOKEN as your password (instead of your normal GitHub password)"
280 |
281 | OAUTH_MSG="Tip: Specify '-s' to have ContributeRecipe print your oauth_token for convenience."
282 |
283 | if Boolean "s"
284 | then
285 | if [ ! -z "${GITHUB_TOKEN}" ]
286 | then
287 | OAUTH_MSG="oauth_token: ${GITHUB_TOKEN}"
288 | elif [ -f ~/.config/hub ]
289 | then
290 | OAUTH_MSG="$(grep oauth ~/.config/hub)"
291 | else
292 | OAUTH_MSG="Could not find a suitable GitHub oauth_token to display?"
293 | fi
294 | fi
295 |
296 | Log_Normal "${OAUTH_MSG}\n"
297 |
298 | run_retry hub fork --remote-name origin-fork
299 | run_retry git push --set-upstream origin-fork "submit-$program-$version"
300 | run_retry hub pull-request -p -h "origin-fork/submit-$program-$version" -m "$program $version"
301 | run_fail git checkout master
302 | fi
303 |
304 | echo ""
305 | Log_Normal "All done.\n"
306 |
--------------------------------------------------------------------------------
/bin/MakeRecipe:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | source ScriptFunctions
4 | Import File
5 | Import Log
6 | Import OptionParser
7 | Import GoboLinux
8 | Import Archive
9 |
10 | scriptsversion=`Get_Version Scripts Current`
11 |
12 | if echo "$scriptsversion" | grep -qi GIT || \
13 | [ "`GuessLatest $scriptsversion 2.9.0`" = "$scriptsversion" ]
14 | then
15 | # Version is valid, proceed.
16 | :
17 | else
18 | Die "Your Scripts package is too old. Please update it by running 'InstallPackage Scripts'."
19 | fi
20 |
21 | ### Options ###################################################################
22 |
23 | scriptDescription="Create a recipe template."
24 | scriptCredits="Copyright (C) 2003, Hisham Muhammad - Released under the GNU GPL."
25 | helpOnNoArguments=yes
26 | scriptUsage="{{[ []] } | { cvs } | { svn } | { git } | { bzr } | { hg }"
27 | scriptNotes="A URL, a cvs, svn, git, bzr or hg command line should be passed as a parameter."
28 | scriptExample=("Help2Man 1.33.1 http://ftp.gnu.org/gnu/help2man/help2man_1.33.1.tar.gz
29 | DirectFB cvs :pserver:anonymous:@cvs.directfb.org:/cvs/directfb DirectFB
30 | SYSLINUX git http://www.kernel.org/pub/scm/boot/syslinux/syslinux.git")
31 | Add_Option_Boolean "F" "no-fetch" "Do not try to download the package. Assume it is already present."
32 | Add_Option_Boolean "C" "no-check" "Do not check for existing recipes for that program."
33 | Add_Option_Boolean "b" "batch" "Do not ask for confirmation."
34 | Add_Option_Boolean "" "no-check-certificate" "Do not check certificates when downloading files. NOTE: This can be dangerous!"
35 |
36 | Parse_Options "$@"
37 |
38 | unset packagename versionnumber
39 |
40 | Import Compile
41 | Parse_Conf Compile.conf
42 |
43 | ##################################################
44 | # Checking Scripts package version
45 | ##################################################
46 |
47 | wget="wget"
48 | if Boolean "no-check-certificate"
49 | then
50 | Log_Normal "NOTE: Ignoring certificates when downloading sources"
51 | wget="wget --no-check-certificate"
52 | fi
53 |
54 | [ "$PAGER" ] || PAGER=less
55 |
56 | Check_Dir_Variable compileRecipesDir
57 | [ ! -w "${compileRecipesDir}" -o ! -x "${compileRecipesDir}" ] && chown $(whoami) "${compileRecipesDir}"
58 |
59 | if [ "$(Arg 3)" ]
60 | then
61 | packagename="$(Arg 1)"
62 | versionnumber="$(Arg 2)"
63 | source_url="$(Arg 3)"
64 | elif [ "$(Arg 2)" ]
65 | then
66 | packagename="$(Arg 1)"
67 | source_url="$(Arg 2)"
68 | else
69 | source_url="$(Arg 1)"
70 | fi
71 |
72 | [ "$source_url" ] || Die "Missing parameter."
73 | echo "$source_url" | grep -q ":" || Die "Expected URL as a last parameter."
74 |
75 | # catch parameter errors using cvs
76 | if [ "$packagename" = "cvs" -a "${versionnumber:0:1}" = ":" ]
77 | then Die "You must pass the program name when using a cvs command."
78 | fi
79 |
80 | svn=no
81 | cvs=no
82 | git=no
83 | bzr=no
84 | hg=no
85 | if [ "$versionnumber" = "cvs" ]
86 | then
87 | cvs=yes
88 | cvs_server="$source_url"
89 | cvs_module="$(Arg 4)"
90 | cvs_server=`echo "$cvs_server" | sed 's,anonymous@,anonymous:@,g'`
91 | elif [ "$versionnumber" = "svn" -o "$versionnumber" = "SVN" ]
92 | then
93 | svn=yes
94 | svn_uri="$source_url"
95 | elif [ "$versionnumber" = "git" ]
96 | then
97 | git=yes
98 | git_repository="$source_url"
99 | elif [ "$versionnumber" = "bzr" ]
100 | then
101 | bzr=yes
102 | bzr_repository="$source_url"
103 | elif [ "$versionnumber" = "hg" ]
104 | then
105 | hg=yes
106 | hg_repository="$source_url"
107 | else
108 | # TODO: generalize mirror system
109 | url=`echo "$source_url" | sed -r 's|http://.*.sourceforge.net(/sourceforge)?/|$httpSourceforge/|'`
110 | url=`echo "$url" | sed 's|ftp://ftp\.gnu\.org/gnu/|$ftpGnu/|'`
111 |
112 | [ "$packagename" ] || packagename=$(Package_Name_From_Url "$source_url")
113 | [ "$versionnumber" ] || versionnumber=$(Version_Number_From_Url "$source_url")
114 | fi
115 |
116 | # Enforce some naming conventions
117 | packagename=`NamingConventions "$packagename"`
118 |
119 | if ! Boolean "no-check" && ! Boolean "batch"
120 | then
121 | if Has_Recipe pull $packagename $versionnumber
122 | then
123 | Log_Question "There is already a recipe for $packagename $versionnumber."
124 | if ! Ask "Create another?"
125 | then
126 | exit 0
127 | fi
128 |
129 | else
130 | ignorelist="\--\(cvs\|svn\|git\|bzr\|hg\)\|/\(cvs\|svn\|git\|bzr\|hg\)-r[0-9]*"
131 | sameprogramrecipe=`Which_Recipe none $packagename | grep -vi "$ignorelist"`
132 | if [ "$sameprogramrecipe" ]
133 | then
134 | Log_Question "There is already a recipe for $packagename, at"
135 | Log_Question "$sameprogramrecipe"
136 | [ "${sameprogramrecipe:0:1}" = "/" ] && packagename=$(basename $(dirname $sameprogramrecipe))
137 | if Ask "Use 'NewVersion $packagename $versionnumber' instead of MakeRecipe?"
138 | then
139 | NewVersion "$packagename" "$versionnumber" "$source_url"
140 | exit 0
141 | fi
142 | fi
143 | fi
144 | fi
145 |
146 | if ! Boolean "batch"
147 | then
148 | unset buildtype
149 | [ "$cvs" = yes ] && buildtype="CVS"
150 | [ "$svn" = yes ] && buildtype="SVN"
151 | [ "$git" = yes ] && buildtype="GIT"
152 | [ "$bzr" = yes ] && buildtype="BZR"
153 | [ "$hg" = yes ] && buildtype="HG"
154 |
155 | if [ ! -z "$buildtype" ]
156 | then Ask_Continue "Creating recipe template for $buildtype build of $packagename."
157 | else Ask_Continue "Creating recipe template for $packagename version $versionnumber."
158 | fi
159 | fi
160 |
161 | recipedir="$compileRecipesDir/$packagename/$versionnumber"
162 |
163 | [ -d "$compileRecipesDir/$packagename" ] && [ ! -w "$compileRecipesDir/$packagename" -o ! -x "$compileRecipesDir/$packagename" ] && chown $(whoami) "$compileRecipesDir/$packagename"
164 | [ -d "$compileRecipesDir/$packagename/$versionnumber" ] && [ ! -w "$compileRecipesDir/$packagename/$versionnumber" -o ! -x "$compileRecipesDir/$packagename/$versionnumber" ] && chown -R $(whoami) "$compileRecipesDir/$packagename/$versionnumber"
165 | mkdir -p $recipedir/Resources
166 |
167 | recipefile="$recipedir/Recipe"
168 | rm -f "$recipefile"
169 |
170 | if [ "$compileRecipeAuthor" != "" ]
171 | then echo "# Recipe (MakeRecipe) for $packagename by $compileRecipeAuthor, on" `date` >> "$recipefile"
172 | echo "# Recipe for version $versionnumber by $compileRecipeAuthor, on" `date` >> "$recipefile"
173 | else Log_Terse "Please fill up 'compileRecipeAuthor' variable at $goboSettings/Compile/Compile.conf"
174 | fi
175 |
176 | echo "compile_version=$scriptVersion" >> "$recipefile"
177 | if [ "$cvs" = "yes" ]
178 | then
179 | echo "cvs=\"$cvs_server\"" >> "$recipefile"
180 | echo "cvs_module=$cvs_module" >> "$recipefile"
181 | checkoutdir="$compileSourcesDir/$packagename-cvs"
182 | fetchparams="--save-to $compileSourcesDir --save-directory $checkoutdir"
183 | elif [ "$svn" = "yes" ]
184 | then
185 | echo "svn=\"$svn_uri\"" >> "$recipefile"
186 | checkoutdir="$compileSourcesDir/$packagename-svn"
187 | fetchparams="--save-to $compileSourcesDir --save-directory $checkoutdir"
188 | elif [ "$git" = "yes" ]
189 | then
190 | echo "git=\"$git_repository\"" >> "$recipefile"
191 | checkoutdir="$compileSourcesDir/$packagename-git"
192 | fetchparams="--save-to $compileSourcesDir --save-directory $checkoutdir"
193 | elif [ "$bzr" = "yes" ]
194 | then
195 | echo "bzr=\"$bzr_repository\"" >> "$recipefile"
196 | checkoutdir="$compileSourcesDir/$packagename-bzr"
197 | fetchparams="--save-to $compileSourcesDir --save-directory $checkoutdir"
198 | elif [ "$hg" = "yes" ]
199 | then
200 | echo "hg=\"$hg_repository\"" >> "$recipefile"
201 | checkoutdir="$compileSourcesDir/$packagename-hg"
202 | fetchparams="--save-to $compileSourcesDir --save-directory $checkoutdir"
203 | else
204 | echo "url=\"$url\"" >> "$recipefile"
205 | basefile=$(basename "$source_url")
206 | file="$compileArchivesDir/$basefile"
207 | fetchparams="--save-to $compileArchivesDir"
208 | if { ! Boolean "no-fetch" ;} && Starts_With "http" "$source_url"
209 | then
210 | # Detect URLs that feature redirects, like funky "...download.php?pkg=1234" URLs.
211 | file_headers=`Temporary_File`
212 | $wget --spider --server-response "$source_url" 2> $file_headers
213 | filename=`grep -i "content-disposition:.*filename=" "$file_headers" | sed 's/.*filename=\([^;]*\).*/\1/;s/^["'\'']//;s/["'\'']$//' | uniq`
214 | if [ -z "$filename" ]
215 | then
216 | filename=`grep -i '=> .*' "$file_headers" | sed 's,.*=> .\(.*\).$,\1,' | tail -n 1`
217 | fi
218 | if [ -n "$filename" -a "$filename" != "$basefile" ]
219 | then
220 | basefile="$filename"
221 | file="$compileArchivesDir/$basefile"
222 | echo "file=\"$basefile\"" >> "$recipefile"
223 | fi
224 | rm $file_headers
225 | fi
226 | fi
227 |
228 | if ! Boolean "no-fetch"
229 | then
230 | programversion="--program $packagename --version-number $versionnumber"
231 | FetchArchive --no-verify-files $programversion $fetchparams "$recipefile" || Die "Could not fetch sources."
232 | elif ! [ -e "$file" ]
233 | then
234 | Die "--no-fetch used, but source archive is not available in ${compileArchivesDir}."
235 | fi
236 |
237 | if [ "$url" ]
238 | then
239 | echo "file_size="`Get_Size "$file"` >> "$recipefile"
240 | echo "file_md5="`Get_MD5 "$file"` >> "$recipefile"
241 |
242 | # TODO: report if multiple directories, tell the user to verify it
243 | file_contents=`Temporary_File`
244 | List_Archive_Files "$file" >> "$file_contents"
245 | # bdir=`grep "^[^/]*/$" "$file_contents" | tr -d "/" | head -n 1`
246 | bdir=`head -n 1 "$file_contents" | sed 's,^\./,,;s,/[^/]*$,,'`
247 | if [ -n "$bdir" -a "$bdir" != "$bname" ]
248 | then
249 | echo "dir='$bdir'" >> "$recipefile"
250 | fi
251 | elif [ "$cvs" = "yes" -o "$svn" = "yes" -o "$git" = "yes" -o "$bzr" = "yes" -o "$hg" = "yes" ]
252 | then
253 | file_contents=`Temporary_File`
254 | find "$checkoutdir" | sed "s,^$compileSourcesDir/,,g" >> "$file_contents"
255 | fi
256 |
257 | exitStatus=0
258 |
259 | if grep -q "CMakeLists.txt" "$file_contents"
260 | then
261 | Log_Normal "$packagename $versionnumber build system seems to be based on CMake."
262 | echo "recipe_type=cmake" >> "$recipefile"
263 | elif grep -E -q "Setup.l?hs" "$file_contents"
264 | then
265 | # Note: check Haskell Cabal before regular configure because cabal
266 | # will often invoke autoconf operations
267 | Log_Normal "$packagename $versionnumber build system seems to be based on Haskell Cabal."
268 | echo "recipe_type=cabal" >> "$recipefile"
269 | elif grep -q "configure.in$" "$file_contents" \
270 | || grep -q "configure.ac$" "$file_contents"
271 | then
272 | Log_Normal "$packagename $versionnumber build system seems to be based on Autoconf."
273 | echo "recipe_type=configure" >> "$recipefile"
274 | if ! grep -q "configure$" "$file_contents"
275 | then echo "autogen_before_configure=yes" >> "$recipefile"
276 | fi
277 | elif grep -q "/configure$" "$file_contents"
278 | then
279 | Log_Terse "$packagename $versionnumber build system seems to have a non-Autoconf configure. You may need to add the configure_options flag."
280 | echo "recipe_type=configure" >> "$recipefile"
281 | elif grep -q "Makefile.PL$" "$file_contents" || grep -q "Build.PL$" "$file_contents"
282 | then
283 | Log_Normal "$packagename $versionnumber seems to be a Perl module."
284 | Die "Use a 'CPAN:' dependency instead."
285 | elif grep -q "Imakefile$" "$file_contents"
286 | then
287 | Log_Normal "$packagename $versionnumber build system seems to be based on imake."
288 | echo "recipe_type=xmkmf" >> "$recipefile"
289 | elif grep -q "meson.build$" "$file_contents"
290 | then
291 | Log_Normal "$packagename $versionnumber build system seems to be based on Meson."
292 | echo "recipe_type=meson" >> "$recipefile"
293 | elif grep -q "SConstruct$" "$file_contents"
294 | then
295 | Log_Normal "$packagename $versionnumber build system seems to be based on SCons."
296 | echo "recipe_type=scons" >> "$recipefile"
297 | elif ! cat "$file_contents" | cut -d"/" -f 1-2 | grep -iq makefile && \
298 | grep -q "\.py$" "$file_contents"
299 | then
300 | Log_Normal "$packagename $versionnumber build system seems to be based on Python."
301 | echo "recipe_type=python" >> "$recipefile"
302 | else
303 | basemakefile=`grep -i "^[^/]*/Makefile$" "$file_contents" 2>/dev/null`
304 | if [ "$basemakefile" ]
305 | then
306 | Log_Normal "$packagename $versionnumber build system seems to be based on Makefiles."
307 | echo "recipe_type=makefile" >> "$recipefile"
308 | if [ "$cvs" = "yes" -o "$svn" = "yes" -o "$git" = "yes" -o "$bzr" = "yes" -o "$hg" = "yes" ]
309 | then basemakefile="$compileSourcesDir/$basemakefile"
310 | else Unpack_Archive "$file" . force "$basemakefile"
311 | fi
312 | if [ "$basemakefile" != "Makefile" ]
313 | then echo "makefile='$(basename $basemakefile)'" >> "$recipefile"
314 | fi
315 | makevars=()
316 | for var in BASEDIR DESTDIR PREFIX basedir destdir prefix
317 | do
318 | if cat "$basemakefile" | grep "^[[:blank:]]*$var[[:blank:]]*=" &> /dev/null || \
319 | cat "$basemakefile" | grep "^[[:blank:]]*$var[[:blank:]]*?=" &> /dev/null
320 | then
321 | makevars=("${makevars[@]}" "\"$var=\$target\"")
322 | Log_Normal "Detected Makefile variable $var."
323 | fi
324 | done
325 | for var in sysconfdir
326 | do
327 | if cat "$basemakefile" | grep "^[[:blank:]]*$var[[:blank:]]*=" &> /dev/null || \
328 | cat "$basemakefile" | grep "^[[:blank:]]*$var[[:blank:]]*?=" &> /dev/null
329 | then
330 | makevars=("${makevars[@]}" "\"$var=\$settings_target\"")
331 | Log_Normal "Detected Makefile variable $var."
332 | fi
333 | done
334 | if [ "${makevars[*]}" ]
335 | then
336 | echo "make_variables=(" >> "$recipefile"
337 | for mv in "${makevars[@]}"
338 | do
339 | echo " $mv" >> "$recipefile"
340 | done
341 | echo ")" >> "$recipefile"
342 | else
343 | Log_Normal "No variables detected. Do you want to look at the top Makefile? (Y/n)"
344 | read
345 | if [ "$REPLY" != "n" ]
346 | then
347 | $PAGER "$basemakefile"
348 | fi
349 | fi
350 | if [ "$cvs" = "no" -a "$svn" = "no" -a "$git" = "no" -a "$bzr" = "no" -a "$hg" = "no" ]
351 | then
352 | rm "$basemakefile"
353 | rmdir -p $(dirname "$basemakefile")
354 | fi
355 | else
356 | Log_Terse "Could not detect recipe type. Recipe needs to be completed manually."
357 | exitStatus=1
358 | fi
359 | fi
360 | rm -f "$file_contents"
361 |
362 | Log_Verbose "Done creating recipe template for $packagename $versionnumber."
363 |
364 | exit $exitStatus
365 |
--------------------------------------------------------------------------------
/Functions/Compile:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | Import File
4 | Import RecipeTools
5 |
6 | ##################################################
7 | # Setting up variables
8 | ##################################################
9 |
10 | if [ -z "$compileRecipeDir" ]
11 | then
12 | compileRecipeDir="${compileRecipesDir}"
13 | fi
14 |
15 | compileSupportedArchitectures=("i686" "x86_64" "ppc" "arm" "sh4")
16 |
17 | ##################################################
18 | # API functions
19 | ##################################################
20 |
21 | function Check_Dir_Variable() {
22 | var="$1"
23 | eval [ "\"\${${var}}\"" ] || Die "Variable \\\$$var is not set. Please update your Compile.conf."
24 | eval Assert_Dir "\"\${${var}}\""
25 | }
26 |
27 | # Return status:
28 | # 0 - Files were verified and are okay.
29 | # 1 - Files are corrupted
30 | # 2 - Files look incomplete
31 | # 3 - Files are missing
32 | # 4 - File cannot be verified
33 | function Verify_Files() {
34 | local myfiles=($1)
35 | local sizes=($2)
36 | local sums=($3)
37 | local use_sha=($4)
38 | if [ $use_sha == 1 ]
39 | then Get_Sum="Get_SHA"
40 | else Get_Sum="Get_MD5"
41 | fi
42 | for i in $(seq 0 $[${#myfiles[@]}-1])
43 | do
44 | file="$compileArchivesDir/${myfiles[i]}"
45 | file_size="${sizes[i]}"
46 | file_sum="${sums[i]}"
47 | if [ -f "$file" ]
48 | then
49 | size=$(Get_Size "$file")
50 | sum=$(${Get_Sum} "$file")
51 | if [ -n "$file_size" ] && [ "$file_size" != "$size" ]
52 | then
53 | Log_Terse "Warning: $file is either not complete or corrupted."
54 | return 2
55 | elif [ -n "$file_size" ]
56 | then
57 | if [ -z "$file_sum" ]
58 | then
59 | Log_Normal "Warning: no MD5/SHA checksum."
60 | Log_Normal "Assuming $file is complete based only on size."
61 | return 0
62 | elif [ "$file_sum" = "$sum" ]
63 | then
64 | Log_Verbose "$file is complete and matches MD5/SHA checksum."
65 | else
66 | Log_Error "According to MD5/SHA checksum, $file is corrupted."
67 | return 1
68 | fi
69 | else
70 | if [ -z "$file_sum" ]
71 | then
72 | Log_Terse "Warning: no file size or MD5/SHA checksum. $file cannot be verified"
73 | return 4
74 | elif [ "$file_sum" = "$sum" ]
75 | then
76 | Log_Normal "Warning: no file size."
77 | Log_Normal "Assuming $file is complete based only on MD5/SHA checksum."
78 | return 0
79 | else
80 | Log_Error "According to MD5/SHA checksum, $file is corrupted."
81 | return 1
82 | fi
83 | fi
84 | else
85 | return 3
86 | fi
87 | done
88 | return 0
89 | }
90 |
91 | function get_url_basename() {
92 | local url="$1"
93 | if [ "$cached_bname_input" = "$url" ]
94 | then
95 | echo "$cached_bname_output"
96 | return
97 | fi
98 | bname=`basename "$url" .tar.gz`
99 | bname=`basename "$bname" .tar.bz2`
100 | bname=`basename "$bname" .tar.xz`
101 | bname=`basename "$bname" .tgz`
102 | bname=`basename "$bname" .tbz2`
103 | bname=`basename "$bname" .zip`
104 | bname=`basename "$bname" .tar.lzma`
105 | cached_bname_input="$url"
106 | cached_bname_output="$bname"
107 | echo "$bname"
108 | }
109 |
110 | function Package_Name_From_Url() {
111 | local url="$1"
112 | local bname=$(get_url_basename "$url")
113 | local packagename=`echo "$bname" | sed 's/-[[:digit:]].*//g'`
114 | local deduced=`DeduceName "README" "$packagename"`
115 | [ "$deduced" ] && packagename=$deduced
116 | echo "$packagename"
117 | }
118 |
119 | function Version_Number_From_Url() {
120 | local url="$1"
121 | local bname=$(get_url_basename "$url")
122 | local versionnumber=`echo "$bname" | sed 's/.*-\([[:digit:]].*\)/\1/;s/\///g;'`
123 | echo "$versionnumber"
124 | }
125 |
126 | Find_Recipe() {
127 | app="$1"
128 | appversion="$2"
129 | tarballurl="$3"
130 |
131 | if Has_Substring "$appversion" ":/"
132 | then
133 | tarballurl="$2"
134 | appversion=$(Version_Number_From_Url "$tarballurl")
135 | fi
136 |
137 | Find_Recipe_Program_And_Version pull "$app" "$appversion"
138 | err=$?
139 | if [ "$err" = 0 ]
140 | then
141 | echo "$recipedir/Recipe"
142 | return 0
143 | fi
144 |
145 | Find_Recipe_Program_And_Version no "$app" ""
146 | err=$?
147 | if [ "$err" = 0 ] && [ "$appversion" ]
148 | then
149 | Log_Terse "Could not find recipe for $app $appversion."
150 | { Boolean "batch" || Ask_Continue "Attempt to create recipe for version $appversion?"
151 | } && NewVersion $app $appversion "${tarballurl}"
152 | Find_Recipe_Program_And_Version no "$app" "" && {
153 | echo "$recipedir/Recipe"
154 | return 0
155 | }
156 | return 1
157 | fi
158 |
159 | Log_Error "Could not find a recipe for $app"
160 | ls $compileRecipesDir | cut -d' ' -f2 | uniq | Corrections --log-name Compile --stdin "$app">&2
161 | if [ "$tarballurl" ]
162 | then
163 | Log_Normal "Will attempt to create one based on URL '$tarballurl'..."
164 | if MakeRecipe --batch "$app" "$appversion" "$tarballurl"
165 | then
166 | Log_Normal "Will attempt to use newly created recipe..."
167 | Find_Recipe_Program_And_Version no "$app" "$appversion" && {
168 | echo "$recipedir/Recipe"
169 | return 0
170 | }
171 | fi
172 | fi
173 |
174 | return 1
175 | }
176 |
177 | Available_BuildTypes() {
178 | sed 's,.*Functions/BuildType_\(.*\)$,\1,' < <(ls "${scriptPath}/../Functions"/BuildType_*)
179 | }
180 |
181 | ##################################################
182 | # Helper functions
183 | ##################################################
184 |
185 | function is_function_set() {
186 | [ "`type -t $1`" = "function" ]
187 | }
188 |
189 | ### Future Scripts functions... ###
190 |
191 | function Run_Hook() {
192 | hook="$1"
193 | ret=0
194 | if is_function_set "$hook"
195 | then
196 | real_run_hook "$hook" || ret=$?
197 | fi
198 | for flag in "${useflags[@]}"
199 | do
200 | if is_function_set "using_${flag}_${hook}"
201 | then
202 | real_run_hook "using_${flag}_${hook}" || ret=$?
203 | fi
204 | done
205 | return $ret
206 | }
207 |
208 | function real_run_hook() {
209 | Parameters "$@" hookname
210 | hookscript=./${hookname}.sh
211 | echo "#!/bin/bash" > ${hookscript}
212 | echo "source ScriptFunctions" >> ${hookscript}
213 | echo "Import GoboLinux" >> ${hookscript}
214 | echo "Import OptionParser" >> ${hookscript}
215 | echo "Import Log" >> ${hookscript}
216 | for v in ${variablestoexport[@]}
217 | do
218 | echo "export ${v}=\"$(eval echo \$${v})\"" >> ${hookscript}
219 | done
220 | echo "source $goboSettings/Compile/Compile.conf" >> ${hookscript}
221 | echo "source ${recipe}" >> ${hookscript}
222 | [ -e "$archrecipe" ] && echo "source ${archrecipe}" >> ${hookscript}
223 | echo "$hookname" >> ${hookscript}
224 | chmod a+x "${hookscript}"
225 | "${hookscript}"
226 | rtn=$?
227 | rm -f ${hookscript}
228 | return ${rtn}
229 | }
230 |
231 | function Add_Use_Flags_Options_To_Array() {
232 | array=$1
233 | for flag in "${useflags[@]}"
234 | do
235 | if [ -n "`eval echo '$'with_$flag`" ]
236 | then
237 | eval $(Combine_Arrays $array $array with_$flag)
238 | fi
239 | done
240 | }
241 |
242 | #
243 | # do_fetch
244 | # Fetches sources
245 | # $1: [0|1] -> 1 to ignore certificates when downloading sources, 0 otherwise
246 | # returns:
247 | # 0 <- success
248 | # 1 <- Error fetching sources
249 | # 2 <- Downloaded files were corrupted
250 | # 3 <- fetch cancelled by user
251 | function do_fetch() {
252 | ignore_certificate=$1
253 | fetch_extra_params=""
254 | [[ $ignore_certificate -eq 1 ]] && fetch_extra_params="--no-check-certificate"
255 |
256 | savedir="--save-to $(echo ${sourcedir}|sed s/"\(.*\)\/${save_directory}.*"/"\1"/) --save-directory ${save_directory}"
257 | if is_scm_recipe
258 | then
259 | # If sources were already fetched, do not patch again
260 | if [ -d "${sourcedir}" ]
261 | then
262 | if [ -z "$(echo "${version}" | grep -qiE "svn|cvs|git|bzr|hg")" ]
263 | then
264 | if Boolean "lazy"
265 | then REPLY=u
266 | elif Boolean "no-web"
267 | then REPLY=u
268 | elif Boolean "batch"
269 | then REPLY=r
270 | else
271 | Log_Question "Directory '${basedir}' already exists."
272 | Ask_Option "What to do? [R]emove and check out/[B]ackup and check out/[U]se it/[C]ancel."
273 | fi
274 | case $REPLY in
275 | [Rr]) rm -rf "${basedir}" 2>/dev/null ;;
276 | [Bb]) mv "${basedir}" "${basedir}.backup"; chown -R `whoami` "${basedir}.backup" ;;
277 | [Uu]) nofetch=yes; skippatching=yes ;;
278 | [Cc]) Log_Error "Fetch cancelled by user."; return 3 ;;
279 | esac # esac is ridiculous.
280 | else skippatching=yes
281 | fi
282 | else
283 | if Boolean "no-web"
284 | then
285 | Log_Error "Files are not available and --no-web was used."
286 | return 1
287 | fi
288 | fi
289 | [ "$nofetch" = "yes" ] || FetchArchive -P "$appname" -V "$versionnumber" $verbose $batch $savedir "$recipe" "$archrecipe" $fetch_extra_params || {
290 | Log_Error "Error fetching snapshot from repository."
291 | return 1
292 | }
293 | else
294 | if ! Boolean "no-web"
295 | then
296 | FetchArchive -P "$appname" -V "$versionnumber" $verbose $batch "$recipe" "$archrecipe" $fetch_extra_params || {
297 | Log_Error "Error fetching archive(s)."
298 | return 1
299 | }
300 | else
301 | # Use sha checksum if available
302 | if [ -n "${file_shas}" ];
303 | then Verify_Files "${files[*]}" "${file_sizes[*]}" "${file_shas[*]}" 1
304 | else Verify_Files "${files[*]}" "${file_sizes[*]}" "${file_md5s[*]}" 0
305 | fi
306 | result=$?
307 | case $result in
308 | 1) Log_Error "Files are corrupted. Exiting."; return 2 ;;
309 | 2) Boolean "batch" || Ask_Continue "Continue anyway?" || return 3 ;;
310 | 3) Log_Error "Files are not available. Exiting."; return 1 ;;
311 | esac
312 | fi
313 | fi
314 | }
315 |
316 | function do_unpack() {
317 | pfiles=`
318 | for i in "${files[@]}"
319 | do ls "$compileArchivesDir"/"$i"
320 | done
321 | `
322 | String_To_Array files "$pfiles"
323 |
324 | if [ "$uncompress" = "no" ]
325 | then
326 | [ "$basedir" ] || basedir=$appname
327 | [ "$unpack_files" ] || unpack_files=files_in_root
328 | fi
329 |
330 | unpack=yes
331 | if [ -d "${basedirs[0]}" ]
332 | then
333 | if Boolean "lazy"
334 | then REPLY=u
335 | elif Boolean "batch"
336 | then REPLY=r
337 | else
338 | Log_Question "Directory '${basedir}' already exists."
339 | Ask_Option "What to do? [R]emove and reunpack/[B]ackup and reunpack/[U]se it/[C]ancel."
340 | fi
341 | case $REPLY in
342 | [Rr]) rm -rf "${basedir}" 2>/dev/null || rm -rf "${basedirs[0]}" ;;
343 | [Bb]) mv "${basedir}" "${basedir}.backup"; chown -R `whoami` "${basedir}.backup" ;;
344 | [Uu]) unpack=no; skippatching="yes" ;;
345 | [Cc]) exit 0 ;;
346 | esac # esac is ridiculous.
347 | fi
348 |
349 | tempdir="$appname.$versionnumber.Compile.temp"
350 | [ "$unpack" = "yes" ] && \
351 | for ((i=0; i < ${#files[@]}; i++))
352 | do
353 | drop=.
354 | skipdir=
355 | if [ "$unpack_files" = "files_in_root" ]
356 | then
357 | drop="${basedirs[0]}"
358 | elif [ "$unpack_files" = "inside_first" ]
359 | then
360 | if [ $i -gt 0 ]
361 | then
362 | drop="${basedirs[0]}"
363 | fi
364 | elif [ "$unpack_files" = "contents_inside_first" ]
365 | then
366 | drop="${basedirs[0]}"
367 | skipdir="${basedirs[i]}"
368 | elif [ "$unpack_files" = "dirs" ]
369 | then
370 | if [ "$i" -eq 0 ]
371 | then
372 | drop=.
373 | else
374 | drop="${basedirs[i]}"
375 | if [ ! "$keep_existing_target" ] && echo "$drop" | Quiet grep "$target"
376 | then keep_existing_target=yes
377 | fi
378 | fi
379 | fi
380 |
381 | if [ "$unpack_files" -o $i -eq 0 ]; then
382 | Quiet pushd "$compileSourcesDir"
383 | [ -d "${tempdir}" ] && rm -rf "${tempdir}"
384 | mkdir "${tempdir}"
385 | fi
386 |
387 | Log_Normal "Unpacking file ${files[i]}..."
388 | if [ "$uncompress" = "no" ]
389 | then Verbose cp -v "${files[i]}" "${tempdir}" || Die "Could not copy '${files[i]}'."
390 | else Verbose Unpack_Archive "${files[i]}" "${tempdir}" || Die "Could not unpack '${files[i]}'."
391 | fi
392 |
393 | if [ "$unpack_files" -o $i -eq $(( ${#files[@]} - 1 )) ]; then
394 | mkdir -p "$drop"
395 | $chown -R --reference="${tempdir}" "${tempdir}"
396 | Quiet mv "${tempdir}"/"$skipdir"/* "${tempdir}"/"$skipdir"/.[A-z]* "$drop"
397 | rm -rf "${tempdir}"
398 | Quiet popd
399 | fi
400 | done
401 | if [ "$unpack" = "no" ]
402 | then skippatching=yes
403 | fi
404 | }
405 |
406 | function do_patch() {
407 | pushd "${basedir}" &> /dev/null
408 |
409 | # Store state of nullglob and then set it explicitly
410 | shopt nullglob &>/dev/null && nullglob=1 || nullglob=0
411 | shopt -s nullglob
412 |
413 | for i in "$recipedir/"*.patch "$archsubdir/"*.patch
414 | do
415 | Log_Normal "Applying patch $i..."
416 | patch -Np1 -i "$i" || Die "Failed on patch $i"
417 | done
418 | # restore state of nullglob
419 | [ "1" = "$nullglob" ] || shopt -u nullglob
420 |
421 | while read patch
422 | do
423 | Log_Verbose "Applying patch generated from ${patch}..."
424 | patch -Np1 < <(export_marked; ApplyVariables -i Compile "${patch}") || Die "Failed on patch generated from $patch"
425 | done < <(find "$recipedir" -name "*.patch.in" | sort)
426 |
427 | popd &> /dev/null
428 | }
429 |
430 | function do_configuration() {
431 | ! is_function_set ${recipe_type}_do_configuration || ${recipe_type}_do_configuration
432 | }
433 |
434 | function do_build() {
435 | ! is_function_set ${recipe_type}_do_build || ${recipe_type}_do_build
436 | }
437 |
438 | function do_install() {
439 | ! is_function_set ${recipe_type}_do_install || ${recipe_type}_do_install "${1}" "${2}"
440 | }
441 |
442 | function do_strip() {
443 | Log_Normal "Stripping executables..."
444 | [ "$STRIP" ] || STRIP=strip
445 | local d
446 | for d in bin sbin
447 | do
448 | Quiet pushd "$target/$d"
449 | for i in *
450 | do
451 | if file "$i" | grep -q -i "ELF .* executable"
452 | then Verbose $STRIP "$i"
453 | fi
454 | done
455 | Quiet popd
456 | done
457 | }
458 |
459 | function do_symlink() {
460 | local forcelink=no
461 | [ "force" == "$(Entry symlink)" ] && forcelink=yes
462 | while true
463 | do
464 | case "$1" in
465 | --force-link) forcelink=yes ; shift ;;
466 | *) break ;;
467 | esac # it still is.
468 | done
469 |
470 | if [ "$(Entry symlink)" == "no" ] && [ "$forcelink" != "yes" ]
471 | then
472 | Clean_Program_Tree "${goboPrograms}/$1/$2" || wrap_fail "Failed cleaning up tree."
473 | else
474 | unset updateoptions
475 | Boolean "batch" && updateoptions="--auto"
476 | if [ ! "$compileMetaRecipe" ] || [ "$compileMetaRecipe" -a "$update_each_settings" = "yes" ]
477 | then
478 | if ! Boolean "no-updatesettings"
479 | then UpdateSettings $updateoptions "$1" "$2" || wrap_fail "Failed updating settings."
480 | fi
481 | fi
482 | [ "$needs_safe_linking" = "yes" ] && safeopts="--libraries safe --executables safe"
483 | [ "$forcelink" = "yes" ] && forcesymlinking="--force"
484 | [ "$batch" ] && unmanaged_opts="--unmanaged install"
485 | Boolean "no-unmanaged" && unmanaged_opts="--unmanaged skip"
486 | SymlinkProgram $safeopts $unmanaged_opts $forcesymlinking ${symlink_options:+"${symlink_options[@]}"} "$1" "$2" || wrap_fail "Linking step failed."
487 | fi
488 | }
489 |
490 | function install_extras() {
491 | if [ -d "$reciperesources" ]
492 | then
493 | cp -Rf "$reciperesources" "$installprefix" || wrap_fail "Failed copying files."
494 | fi
495 | if [ -d "$archreciperesources" ]
496 | then
497 | cp -Rf "$archreciperesources" "$installprefix" || wrap_fail "Failed copying files."
498 | fi
499 | if [ "$revision" ]
500 | then
501 | echo "$revision" | tee "$installprefix/Resources/Revision" >/dev/null || wrap_fail "Failed installing file."
502 | fi
503 |
504 | if [ "$app" = "$appname" ]
505 | then
506 | CheckDependencies --mode=convert --file $recipedir/Resources/Dependencies | tee "$installprefix/Resources/Dependencies" >/dev/null
507 | fi
508 |
509 | if [ "$app" ]
510 | then name=$app
511 | else name=$appname
512 | fi
513 | unixname=`echo $name | tr "[:upper:]" "[:lower:]"`-$version
514 | docdir="$installprefix/doc/$unixname"
515 |
516 | for d in "${dirs[@]}"
517 | do
518 | Quiet pushd "$d" && {
519 | for i in COPYING LICENSE README* NEWS AUTHORS BUGS TODO COPYRIGHT ${docs:+"${docs[@]}"}
520 | do
521 | if [ -e "$d/$i" ]
522 | then
523 | mkdir -p "$docdir" || return 1
524 | cp -a "$d/$i" "$docdir" || return 1
525 | fi
526 | done
527 | Quiet popd
528 | }
529 | done
530 |
531 | if [ "${unmanaged_files[*]}" ]
532 | then
533 | rm -f -- $target/Resources/UnmanagedFiles
534 | for file in "${unmanaged_files[@]}"
535 | do echo $file | sed 's,'"$goboPrefix"'/,/,' | tee -a "$target/Resources/UnmanagedFiles" >/dev/null
536 | done
537 | if echo "${unmanaged_files[@]}" | grep -q "$goboModules" && [ "$app" != "Linux" ]
538 | then
539 | mkdir -p "$target/$(basename $goboShared)/Compile/Recompile/Linux"
540 | touch "$target/$(basename $goboShared)/Compile/Recompile/Linux/$app"
541 | fi
542 | fi
543 | return 0
544 | }
545 |
546 | function assert_requirements() {
547 | Log_Normal "Asserting that requirements are met..."
548 | Process_Requirements_File "$recipedir"
549 | }
550 |
551 | function mark_export() {
552 | export variablestoexport="$variablestoexport $*"
553 | }
554 |
555 | function export_marked() {
556 | for var in $variablestoexport
557 | do
558 | export $var
559 | done
560 | }
561 |
562 | function Get_Dependency_Variables() {
563 | dependencies_file="$1"
564 | if [ -f "$dependencies_file" ]
565 | then
566 | while read dep
567 | do
568 | depname="$(echo $dep | cut -d ' ' -f1)"
569 | depverrev="$(echo $dep | cut -d ' ' -f2)"
570 | depver="$(echo $depverrev | cut -d '-' -f1)"
571 | depdir="$(echo $dep | cut -d' ' -f4)"
572 | lowercasename=`echo $depname | tr '[:upper:]-+:' '[:lower:]___'`
573 | dep_settings_path="$(Get_Dir runtimeSettings ${depname} ${depver})"
574 | dep_variable_path="$(Get_Dir runtimeVariable ${depname} ${depver})"
575 | eval $lowercasename'_path="'"$depdir"'"'
576 | eval $lowercasename'_settings_path="'"$dep_settings_path"'"'
577 | eval $lowercasename'_variable_path="'"$dep_variable_path"'"'
578 | mark_export ${lowercasename}_path ${lowercasename}_settings_path ${lowercasename}_variable_path
579 | done < <(CheckDependencies --no-recursive --types=installed --quiet-progress --mode=all --file "$dependencies_file")
580 | fi
581 | }
582 |
583 | function Fix_Legacy_Recipe_Types() {
584 | # Backwards compability fix
585 | [ "$is_compileprogram" = "yes" ] && recipe_type="configure"
586 | [ "$is_makefile" = "yes" ] && recipe_type="makefile"
587 | [ "$is_python" = "yes" ] && recipe_type="python"
588 | [ "$is_xmkmf" = "yes" ] && recipe_type="xmkmf"
589 | [ "$is_meta" = "yes" ] && recipe_type="meta"
590 | [ "$is_meson" = "yes" ] && recipe_type="meson"
591 | [ "$is_scons" = "yes" ] && recipe_type="scons"
592 | [ "$is_manifest" = "yes" ] && recipe_type="manifest"
593 | }
594 |
--------------------------------------------------------------------------------
/bin/RecipeLint:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | . ScriptFunctions
4 | Import File
5 | Import GoboLinux
6 | Import OptionParser
7 | Import RecipeTools
8 | Parse_Conf Compile/Compile.conf
9 |
10 | helpOnNoArguments=yes
11 | scriptDescription="Perform all sorts of sanity checks on a recipe."
12 | scriptCredits="(C)2005-2020 Hisham Muhammad, released under the GNU GPL."
13 | scriptUsage=" []"
14 | scriptExample="Foo 1.0"
15 | Add_Option_Boolean "t" "thorough" "Perform thorough URL/file testing (don't use cache)."
16 | Add_Option_Boolean "D" "quick-and-dirty" "cut some corners (don't download files, etc; not recommended)."
17 | Add_Option_Boolean "W" "no-web" "fully offline operation (not recommended)."
18 | Add_Option_Boolean "" "no-check-certificate" "Do not check certificates when downloading files. NOTE: This can be dangerous!"
19 |
20 | Parse_Options "$@"
21 |
22 | [ "$httpSourceforge" ] || {
23 | echo -e "\033[41;33;1mFATAL ERROR: could not load initial configuration.\033[0m"
24 | errors=$[errors+1]
25 | exit 1
26 | }
27 |
28 | # sets 'recipedir', 'program' and 'version'
29 | Set_Recipe_Program_And_Version_From_Args $(Boolean "no-web" && echo none)
30 |
31 | if Boolean "no-web"
32 | then noweb=--no-web
33 | else noweb=
34 | fi
35 |
36 | wget="wget"
37 | if Boolean "no-check-certificate"
38 | then
39 | Log_Normal "NOTE: Ignoring certificates when downloading sources"
40 | wget="wget --no-check-certificate"
41 | fi
42 |
43 | workingdir=$PWD
44 | lintdir=`Temporary_Dir`
45 |
46 | function finish() {
47 | cd $workingdir
48 | rm -rf $lintdir
49 | if [ $errors -gt 0 -o $warnings -gt 0 ]
50 | then
51 | echo "$errors error(s), $warnings warning(s)." >> $report
52 | echo "$errors error(s), $warnings warning(s)."
53 | echo "Report in '$report'."
54 | [ $errors -gt 0 ] && exit 2
55 | exit 1
56 | else
57 | echo "Recipe looks sane."
58 | rm $report
59 | exit 0
60 | fi
61 | }
62 |
63 | trap finish EXIT
64 |
65 | # need to get the output of utilities in English.
66 | export LANG=C
67 | export LC_ALL=C
68 |
69 | function msg() {
70 | echo "$@"
71 | echo "$@" >> $report
72 | }
73 |
74 | function WARN() {
75 | echo -e "\033[33;1mWarning: $@\033[0m"
76 | echo "Warning: $@" >> $report
77 | warnings=$[warnings+1]
78 | }
79 |
80 | function ERROR() {
81 | echo -e "\033[31;1mERROR: $@\033[0m"
82 | echo "ERROR: $@" >> $report
83 | errors=$[errors+1]
84 | }
85 |
86 | function FATAL() {
87 | echo -e "\033[41;33;1mFATAL ERROR: $@\033[0m"
88 | echo "FATAL ERROR: $@" >> $report
89 | errors=$[errors+1]
90 | exit 1
91 | }
92 |
93 | errors=0
94 | warnings=0
95 |
96 | report=$goboTemp/$program--$version.report.txt
97 | touch "$report" &> /dev/null
98 | [ -w "$report" ] || {
99 | echo "No write permission for report file '$report'."
100 | exit 1
101 | }
102 |
103 | :> $report
104 |
105 | echo
106 | msg "RecipeLint"
107 | msg "=========="
108 | msg "Checking $program $version on `date`"
109 | ###############################################################################
110 | [ "$program" == `NamingConventions $program` ] || {
111 | ERROR "Name $program does not follow naming conventions."
112 | }
113 | echo "$program--$version" | grep -q " " && {
114 | ERROR "Name or version contains spaces."
115 | }
116 |
117 | msg "Checking version number..."
118 | pureversion=`echo $version | sed 's/^\(.*\)-r[0-9]*$/\1/'`
119 | revision=`echo $version | sed -n 's/^.*-\(r[0-9]*\)$/\1/p'`
120 | echo "$pureversion" | grep -E -q "^[0-9a-z_.]+$" || {
121 | ERROR "Version $pureversion contains invalid characters (only [0-9a-z._] allowed)."
122 | }
123 | echo "$pureversion" | grep -q "[0-9]\|^cvs$\|^svn$\|^git$\|^bzr$\|^hg$" || {
124 | WARN "Version $pureversion does not contain digits, may be incorrect."
125 | }
126 | [ "$revision" ] && {
127 | purerevision="${revision#r}"
128 | [ "$purerevision" -gt 0 ] || {
129 | ERROR "Invalid revision number $revision."
130 | }
131 | } || {
132 | # WARN "No revision id."
133 | :
134 | }
135 |
136 | ###############################################################################
137 | arches=()
138 | function check_dir() {
139 | local file
140 | for file in `ls "$2"`
141 | do
142 | case "$file" in
143 | Recipe)
144 | ;;
145 | Resources)
146 | ;;
147 | *.patch|*.patch.in)
148 | echo "$file" | grep -E -q "^[0-9]+" || {
149 | [ `ls $2/*.patch | wc -l` -gt 1 ] && {
150 | ERROR "Patch file $file is not numbered; unreliable patching order."
151 | }
152 | }
153 | ;;
154 | i686|ppc|arm|sh4|x86_64|cell)
155 | [ "$1" = "root" ] && {
156 | arches=("${arches[@]}" $file)
157 | } || {
158 | WARN "Nested arch subdir $2/$file"
159 | }
160 | ;;
161 | *)
162 | WARN "Unknown file $file."
163 | ;;
164 | esac
165 | done
166 | }
167 | check_dir root "$recipedir"
168 | for arch in "${arches[@]}"
169 | do
170 | check_dir non-root "$recipedir/$arch"
171 | done
172 | ###############################################################################
173 | cd "$recipedir"
174 | msg "Checking recipe contents..."
175 | [ -f Recipe ] || {
176 | FATAL "No Recipe file."
177 | }
178 | msg "Performing basic syntax validation..."
179 |
180 | # Workaround weird bash behavior
181 | temprecipe=`Temporary_File`
182 | echo > $temprecipe
183 | cat ./Recipe >> $temprecipe
184 | bash -n $temprecipe || {
185 | rm $temprecipe
186 | FATAL "Recipe does not parse as valid shell script."
187 | }
188 | rm $temprecipe
189 |
190 | test_recipe=yes
191 | cat Recipe | perl -e '
192 | %decls = (
193 | is_compileprogram => "bool",
194 | is_makefile => "bool",
195 | is_python => "bool",
196 | is_xmkmf => "bool",
197 | is_manifest => "bool",
198 | is_meson => "bool",
199 | is_scons => "bool",
200 | is_meta => "bool",
201 | recipe_type => "string",
202 | compile_version => "string",
203 | environment => "array",
204 | url => "string",
205 | urls => "array",
206 | mirror_url => "string",
207 | mirror_urls => "array",
208 | file => "string",
209 | files => "array",
210 | file_size => "string",
211 | file_md5 => "string",
212 | file_sha => "string",
213 | file_sizes => "array",
214 | file_md5s => "array",
215 | file_shas => "array",
216 | uncompress => "string",
217 | unpack_files => "string",
218 | docs => "array",
219 | dir => "string",
220 | dirs => "array",
221 | include => "array",
222 | keep_existing_target => "bool",
223 | configure_options => "array",
224 | cmake_options => "array",
225 | autogen => "string",
226 | autogen_before_configure => "bool",
227 | build_in_programs => "bool",
228 | build_variables => "array",
229 | install_variables => "array",
230 | make_variables => "array",
231 | meson_variables => "array",
232 | ninja_variables => "array",
233 | scons_variables => "array",
234 | configure => "string",
235 | make => "string",
236 | makefile => "string",
237 | build_target => "string",
238 | install_target => "string",
239 | do_build => "bool",
240 | do_install => "bool",
241 | needs_build_directory => "bool",
242 | needs_safe_linking => "bool",
243 | sandbox_options => "array",
244 | symlink_options => "array",
245 | cabal_options => "array",
246 | runhaskell => "string",
247 | manifest => "array",
248 | without => "array",
249 | create_dirs_first => "bool",
250 | python_options => "array",
251 | python_major => "string",
252 | override_default_options => "bool",
253 | build_script => "string",
254 | cvs => "string",
255 | cvss => "array",
256 | cvs_module => "string",
257 | cvs_modules => "array",
258 | cvs_tag => "string",
259 | cvs_opts => "string",
260 | cvs_options => "string",
261 | cvs_checkout_options => "string",
262 | cvs_rsh => "string",
263 | cvs_password => "string",
264 | svn => "string",
265 | svns => "array",
266 | git => "string",
267 | gits => "array",
268 | bzr => "string",
269 | bzrs => "array",
270 | hg => "string",
271 | hgs => "array",
272 | tag => "string",
273 | branch => "string",
274 | unmanaged_files => "array",
275 | part_of => "string",
276 | post_install_message => "string"
277 | );
278 | sub check_array_name {
279 | my ($name, $num) = @_;
280 | if (($decls{$name} ne "array") && !($name =~ /^with_[a-z0-9_]+$/)) {
281 | print "Error at line ".$num.": ".$name." is not a valid array.\n";
282 | exit 1;
283 | }
284 | }
285 | sub check_var {
286 | my ($name, $value, $num) = @_;
287 | if ($decls{$name} eq "string") {
288 | } elsif ($decls{$name} eq "bool") {
289 | if ($value ne "yes" && $value ne "no") {
290 | print "Error at line ".$num.": ".$value." is not valid for ".$name." (expected yes or no).\n";
291 | exit 1;
292 | }
293 | } elsif ($name =~ m/^with_[a-z0-9_]+$/) {
294 | } else {
295 | print "Error at line ".$num.": ".$name." is not a valid variable.\n";
296 | exit 1;
297 | }
298 | }
299 | %functions = ();
300 | $in_shell = 0;
301 | $in_array = 0;
302 | $n = 0;
303 | while (<>) {
304 | $n++;
305 | if ($in_shell) {
306 | if (/^\}[[:blank:]]*$/) {
307 | $in_shell = 0;
308 | } else {
309 | # ignore shell contents
310 | }
311 | } elsif ($in_array) {
312 | if (/^[[:blank:]]*\)[[:blank:]]*$/) {
313 | $in_array = 0;
314 | } elsif (/^[[:blank:]]*(.*)$/) {
315 | $array_contents = $1;
316 | # TODO: check array contents
317 | } else {
318 | # TODO: check array contents
319 | }
320 | } elsif ($want_bracket) {
321 | $want_bracket = 0;
322 | if (/^[[:blank:]]*\{[[:blank:]]*$/) {
323 | $in_shell = 1;
324 | } else {
325 | print "Error at line ".$n.": expected a {\n";
326 | print;
327 | exit 1;
328 | }
329 | } else {
330 | if (/^[[:blank:]]*#.*$/) {
331 | } elsif (/^[[:blank:]]*$/) {
332 | } elsif (/^((pre|post)_(patch|install|build|link)|private__[a-z0-9_]*)[[:blank:]]*\([[:blank:]]*\)[[:blank:]]*$/) {
333 | $fn_name = $1;
334 | if ($functions{$fn_name} == 1) {
335 | print "Error at line ".$n.": function redefinition:\n";
336 | print;
337 | exit 1;
338 | }
339 | $functions{%fn_name} = 1;
340 | $want_bracket = 1;
341 | } elsif(/^do_(fetch|unpack|patch|configuration|build|install|symlink)\(\)/) {
342 | $fn_name = $1;
343 | if ($functions{$fn_name} == 1) {
344 | print "Error at line ".$n.": function redefinition:\n";
345 | print;
346 | exit 1;
347 | }
348 | $functions{%fn_name} = 1;
349 | $in_shell = 1;
350 | } elsif (/^((pre|post)_(patch|install|build|link)|private__[a-z0-9_]*|using_[a-z0-9_]+|do_(fetch|unpack|patch|configuration|build|install|symlink))[[:blank:]]*\([[:blank:]]*\)[[:blank:]]*\{/) {
351 | $fn_name = $1;
352 | if ($functions{$fn_name} == 1) {
353 | print "Error at line ".$n.": function redefinition:\n";
354 | print;
355 | exit 1;
356 | }
357 | $functions{%fn_name} = 1;
358 | $in_shell = 1;
359 | } elsif (/^([a-z][a-z0-9_]*)=\((.*)\)/) {
360 | check_array_name($1, $n);
361 | $array_contents = $2;
362 | # TODO: check contents
363 | } elsif (/^([a-z][a-z0-9_]*)=\(/) {
364 | check_array_name($1, $n);
365 | $in_array = 1;
366 | } elsif (/^([a-z][a-z0-9_]*)=([^[:blank:]\n]*)[[:blank:]]*$/
367 | || /^([a-z][a-z0-9_]*)="([^"]*)"[[:blank:]]*$/
368 | || /^([a-z][a-z0-9_]*)='\''([^'\'']*)'\''[[:blank:]]*$/) {
369 | check_var($1, $2, $n);
370 | $var_contents = $2;
371 | # TODO: check contents
372 | } else {
373 | print "Error at line ".$n.": unexpected construct:\n";
374 | print;
375 | exit 1;
376 | }
377 | }
378 | }
379 | if ($in_array) {
380 | print "Error at EOF: ) not found for array construct.\n";
381 | print "Parser expects ) by itself in a line.\n";
382 | exit 1;
383 | }
384 | if ($in_shell) {
385 | print "Error at EOF: } not found for shell construct.\n";
386 | print "Parser expects } by itself in the beginning of a line.\n";
387 | exit 1;
388 | }
389 | ' || {
390 | ERROR "Recipe does not pass basic validation. Will not perform recipe tests."
391 | test_recipe=no
392 | }
393 |
394 | test_urls() {
395 | function use_cached_file() {
396 | if [ "$cached" = "yes" ]
397 | then
398 | msg "Using cached file $file from $compileArchivesDir..."
399 | spider=--spider
400 | cp "$compileArchivesDir/$file" .
401 | fi
402 | }
403 |
404 | function get_file() {
405 | if Boolean "no-web"
406 | then
407 | use_cached_file
408 | return
409 | fi
410 | if ! Boolean "thorough"
411 | then
412 | use_cached_file
413 | fi
414 | if [ "$spider" ]
415 | then msg "Checking URL..."
416 | else msg "Downloading file ($file_size bytes)..."
417 | fi
418 | if ! $wget --quiet $spider --timeout=20 --tries=3 "$url"
419 | then
420 | if [ "$mirror_url" ]
421 | then
422 | WARN "Primary URL unreacheable, trying the mirror instead..."
423 | $wget --quiet $spider --timeout=20 --tries=3 "$mirror_url"
424 | fi
425 | fi
426 | }
427 |
428 | for i in `seq 0 $[${#urls[@]}-1]`
429 | do
430 | url="${urls[$i]}"
431 | file="${files[$i]}"
432 | file_md5="${file_md5s[$i]}"
433 | file_size="${file_sizes[$i]}"
434 | if [ "$file_md5" -o "$file_size" ]
435 | then
436 | full_check=yes
437 | spider=
438 | if [ "$file_size" = "0" ]
439 | then
440 | ERROR "Zero file size specified for $url."
441 | fi
442 | else
443 | full_check=no
444 | spider=--spider
445 | fi
446 | [ "$file" ] || file=`basename "$url"`
447 |
448 | Boolean "quick-and-dirty" && continue
449 |
450 | if [ -e "$compileArchivesDir/$file" ]
451 | then cached=yes
452 | else cached=
453 | fi
454 |
455 | if [ ! "$cached" ] && [ "$file_size" ] && [ "$file_size" -gt 5000000 ] && ! Boolean "thorough"
456 | then
457 | WARN "File is big, will not download (to force, run with --thorough)."
458 | full_check=no
459 | spider=--spider
460 | fi
461 |
462 | if get_file "$url"
463 | then
464 | if [ "$full_check" = "yes" ]
465 | then
466 | if [ -e "$file" ]
467 | then
468 | if [ ${file%.gz} != $file -o ${file%.tgz} != $file ]
469 | then
470 | msg "Testing integrity of archive $file..."
471 | gunzip --test $file || {
472 | ERROR "Downloaded file $file is corrupted."
473 | }
474 | elif [ ${file%.bz2} != $file -o ${file%.tbz2} != $file ]
475 | then
476 | msg "Testing integrity of archive $file..."
477 | bunzip2 --test $file || {
478 | ERROR "Downloaded file $file is corrupted."
479 | }
480 | elif [ ${file%.zip} != $file ]
481 | then
482 | msg "Testing integrity of archive $file..."
483 | unzip -t $file || {
484 | ERROR "Downloaded file $file is corrupted."
485 | }
486 | elif [ ${file%.lzma} != $file ]
487 | then
488 | msg "Testing integrity of archive $file..."
489 | lzma -t $file || {
490 | ERROR "Downloaded file $file is corrupted."
491 | }
492 | elif [ ${file%.xz} != $file ]
493 | then
494 | msg "Testing integrity of archive $file..."
495 | xz -t $file || {
496 | ERROR "Downloaded file $file is corrupted."
497 | }
498 | elif [ ${file%.lz} != $file ]
499 | then
500 | msg "Testing integrity of archive $file..."
501 | lzip -t $file || {
502 | ERROR "Downloaded file $file is corrupted."
503 | }
504 | else
505 | WARN "Type of archive $file not detected. No integrity check performed."
506 | fi
507 | if [ "$file_sha" ]
508 | then
509 | msg "Checking SHA for $file..."
510 | [ `sha256sum "$file" | cut -d" " -f1` = "$file_sha" ] || {
511 | ERROR "SHA sum in recipe for $file does not match."
512 | }
513 | elif [ "$file_md5" ]
514 | then
515 | msg "Checking MD5 for $file..."
516 | [ `md5sum "$file" | cut -d" " -f1` = "$file_md5" ] || {
517 | ERROR "MD5 sum in recipe for $file does not match."
518 | }
519 | else
520 | WARN "No MD5/SHA sum in recipe."
521 | fi
522 | if [ "$file_size" ]
523 | then
524 | msg "Checking size for $file..."
525 | [ `wc -c "$file" | cut -d" " -f1` = "$file_size" ] || {
526 | ERROR "File size in recipe for $file does not match."
527 | }
528 | else
529 | WARN "No file size recipe."
530 | fi
531 | mv "$file" "$compileArchivesDir"
532 | else
533 | ERROR "Could not find downloaded file $file"
534 | fi
535 | else
536 | WARN "No MD5 or size -- full check on archive not performed."
537 | fi
538 | else
539 | ERROR "Unreachable URL: $url"
540 | fi
541 | done
542 | }
543 |
544 | test_recipe() {
545 | target="${goboPrograms}/$program/$version"
546 | settings_target="${goboPrograms}/$program/Settings"
547 | variable_target="${goboVariable}"
548 | source Recipe
549 | [ "$1" -a -e "$1/Recipe" ] && source "$1/Recipe"
550 |
551 | msg "Checking recipe declarations..."
552 | if [ ! "$recipe_type" ]
553 | then
554 | {
555 | if [ "$is_compileprogram" -o "$is_makefile" -o "$is_python" \
556 | -o "$is_xmkmf" -o "$is_meta" -o "$is_manifest" ]
557 | then
558 | WARN "Recipe type is declarated in deprecated style."
559 | # Backwards compability fix
560 | [ "$is_compileprogram" = "yes" ] && recipe_type="configure"
561 | [ "$is_makefile" = "yes" ] && recipe_type="makefile"
562 | [ "$is_python" = "yes" ] && recipe_type="python"
563 | [ "$is_xmkmf" = "yes" ] && recipe_type="xmkmf"
564 | [ "$is_meta" = "yes" ] && recipe_type="meta"
565 | [ "$is_meson" = "yes" ] && recipe_type="meson"
566 | [ "$is_scons" = "yes" ] && recipe_type="scons"
567 | [ "$is_manifest" = "yes" ] && recipe_type="manifest"
568 | else
569 | ERROR "Recipe type is not declared."
570 | fi
571 | }
572 | fi
573 | case "$recipe_type" in
574 | (configure | makefile | cmake | python | xmkmf | meta | meson | scons | manifest | cabal | waf)
575 | false;;
576 | esac && ERROR "Unknown Recipe type $recipe_type specified"
577 | [ "$recipe_type" = "meta" ] && {
578 | for inc in "${include[@]}"
579 | do
580 | msg "Checking include $inc..."
581 | echo "$inc" | grep -q -- "--" || {
582 | ERROR "Include $include does not have -- separator."
583 | continue
584 | }
585 | iname="${inc%%--*}"
586 | iversion="${inc#*--}"
587 | [ "$iname" == `NamingConventions $iname` ] || {
588 | WARN "Name $iname does not follow naming conventions."
589 | }
590 | echo "$iversion" | grep -E -q "^[0-9a-z_.]+$" || {
591 | ERROR "Invalid characters in include version $iversion. Only [0-9a-z_.] allowed."
592 | }
593 | Boolean "quick-and-dirty" && continue
594 | msg "Checking availability of sub-recipe $iname $version..."
595 | Has_Recipe none "$iname" "$iversion" || {
596 | ERROR "Required recipe $iname $iversion not found in repository."
597 | }
598 | done
599 | return
600 | }
601 | [ "$url" -o "${urls[0]}" -o "$cvs" -o "$svn" -o "$git" -o "$bzr" -o "$hg" ] || {
602 | ERROR "No download location specified in recipe."
603 | }
604 | if [ "$compile_version" ]
605 | then
606 | echo "$compile_version" | grep -qi "CVS" && {
607 | ERROR "Recipe references CVS version of Compile."
608 | }
609 | echo "$compile_version" | grep -qi "SVN" && {
610 | ERROR "Recipe references SVN version of Compile."
611 | }
612 | else
613 | WARN "Recipe has no compile_version declaration."
614 | fi
615 | if [ "$unpack_files" ]
616 | then
617 | case "$unpack_files" in
618 | inside_first|contents_inside_first)
619 | [ "${#urls[@]}" -gt 1 ] || {
620 | WARN "unpack_files=$unpack_files makes no sense with only one archive."
621 | }
622 | ;;
623 | dirs)
624 | [ "${#urls[@]}" -gt 1 ] || {
625 | WARN "unpack_files=dirs makes no sense with only one archive."
626 | }
627 | [ "${#urls[@]}" -ne ${#dirs[@]} ] || {
628 | ERROR "with unpack_files=dirs, number of entries in urls and dirs must be the same."
629 | }
630 | ;;
631 | files_in_root)
632 | ;;
633 | *)
634 | ERROR "Invalid value '$unpack_files' for unpack_files."
635 | ;;
636 | esac
637 | fi
638 | declarations=(
639 | configure_options=configure
640 | autogen_before_configure=configure
641 | autogen=configure
642 | build_in_programs=configure,makefile,cmake,xmkmf,meson,scons,cabal,waf
643 | build_variables=configure,makefile,cmake,xmkmf,meson,scons,cabal,waf
644 | install_variables=configure,makefile,cmake,xmkmf,meson,scons,cabal,waf
645 | make_variables=configure,makefile,xmkmf
646 | cmake_variables=cmake
647 | configure=configure
648 | makefile=configure,makefile,cmake,xmkmf
649 | build_target=configure,makefile,cmake,xmkmf,python,meson,scons,waf
650 | install_target=configure,makefile,cmake,xmkmf,python,meson,scons,waf
651 | do_build=configure,makefile,cmake,python,cabal,waf
652 | do_install=configure,makefile,cmake,xmkmf,python,meson,scons,cabal,waf
653 | needs_build_directory=configure
654 | create_dirs_first=configure,makefile,cmake,manifest
655 | python_options=python
656 | override_default_options=python,meson,scons,configure,cabal,waf
657 | build_script=python
658 | ninja=meson
659 | ninja_variables=meson
660 | meson=meson
661 | meson_variables=meson
662 | scons=scons
663 | scons_variables=scons
664 | cabal_options=cabal
665 | runhaskell=cabal
666 | waf=waf
667 | waf_options=waf
668 | waf_variables=waf
669 | )
670 | for decl in "${declarations[@]}"
671 | do
672 | dname="${decl%%=*}"
673 | dtypes="${decl#*=}"
674 | dtypes="${dtypes//,/ }"
675 | if eval "[ \"\$$dname\" ]"
676 | then
677 | msg "Checking $dname..."
678 | eval "ok=no
679 | for mode in $dtypes
680 | do
681 | eval '[ \"\$$dname\" -a \"\$recipe_type\" == \"'\$mode'\" ] && { ok=yes; break; }'
682 | done
683 | [ \$ok = yes ] || {
684 | ERROR \"Declaration $dname not valid in this recipes' mode.\"
685 | }"
686 | fi
687 | done
688 |
689 | function check_vars() {
690 | aname="$1"
691 | shift
692 | while [ "$1" ]
693 | do
694 | echo "$1" | grep -q "=" || {
695 | ERROR "Entry '$1' in $aname does not look like a variable assignment."
696 | }
697 | vname="${1%%=*}"
698 | echo "$vname" | grep -E -q "^[A-Za-z_][A-Za-z0-9_]*$" || {
699 | WARN "Entry '$vname' in $aname does not look like a variable name."
700 | }
701 | shift
702 | done
703 | }
704 | for vars in build_variables install_variables make_variables
705 | do
706 | eval "[ \"\${$vars[*]}\" ] && check_vars $vars \"\${$vars[@]}\""
707 | done
708 |
709 | [ "${manifest[*]}" ] && {
710 | for mentry in "${manifest[@]}"
711 | do
712 | echo "$mentry" | grep -q ":" || {
713 | ERROR "Manifest entry '$mentry' is not of the format 'file:dir'."
714 | }
715 | done
716 | }
717 |
718 | urls=($url "${urls[@]}")
719 | files=($file "${files[@]}")
720 | file_md5s=($file_md5 "${file_md5s[@]}")
721 | file_sizes=($file_size "${file_sizes[@]}")
722 | [ "${urls[*]}" ] && test_urls
723 |
724 | msg "Looking for common error patterns..."
725 | grep -q '$goboPrograms' Recipe && {
726 | ERROR "Recipe references \$goboPrograms explicitly. Use \$target and \$_path."
727 | }
728 | # The obscure sed expression excludes url(s) variable from the check
729 | sed -e 's,#.*,,g' -e "/url/ {;/.*(/{;:loop;/.*)/b end;N; b loop;};:end;d}" Recipe | grep -q "/Programs" && {
730 | ERROR "Recipe references /Programs tree explicitly. Use \$target and \$_path."
731 | }
732 | grep -q "\$target/../Settings" Recipe && {
733 | WARN "Recipe uses old \$target/../Settings idiom. Use \$settings_target."
734 | }
735 | grep -q "\$target/../Variable" Recipe && {
736 | WARN "Recipe uses old \$target/../Variable idiom. Use \$variable_target."
737 | }
738 | sed 's,#.*,,g' Recipe | grep -q "/System[^\.]" && {
739 | ERROR "Recipe references /System tree explicitly. Use \$."
740 | }
741 | sed 's,#.*,,g' Recipe | grep "wget" | grep -q -v "url=\|urls=" && {
742 | ERROR "Recipe performs wget explicitly. Use the urls= array instead."
743 | }
744 | unset url
745 | unset file
746 | unset file_size
747 | unset file_md5
748 | unset urls
749 | unset files
750 | unset file_sizes
751 | unset file_md5s
752 | }
753 |
754 | if [ "$test_recipe" = "yes" ]
755 | then
756 | grep -q "url=\|urls=\|cvs=\|svn=\|git=\|bzr=\|hg=" Recipe && test_recipe
757 | for arch in "${arches[@]}"
758 | do
759 | [ -e "$arch/Recipe" ] || continue
760 | grep -q "url=\|urls=\|cvs=\|svn=\|git=\|bzr=\|hg=" "$arch/Recipe" && test_recipe "$arch"
761 | done
762 | fi
763 |
764 | test_resources() {
765 | msg "Checking resources..."
766 | if [ "$part_of" ]
767 | then
768 | meta=`GetRecipe "$noweb" "$part_of"`
769 | [ $? != 0 ] && ERROR "Meta-recipe $part_of not found in repository."
770 | Quiet pushd $meta
771 | fi
772 | [ -d Resources ] || {
773 | ERROR "No Resources directory."
774 | }
775 | [ -e Resources/PostInstall -a ! -x Resources/PostInstall ] && {
776 | ERROR "Resources/PostInstall must have its executable bit set."
777 | }
778 | msg "Checking Dependencies..."
779 | depfile=Resources/Dependencies
780 | if [ -f $depfile ]
781 | then
782 | grep -q "^# \*Warning\*" $depfile && {
783 | ERROR "Dependencies file contains unmatched library dependencies."
784 | }
785 | grep -q "^Perl-" $depfile && {
786 | ERROR "Dependencies file contains deprecated Perl module dependency:\n$(grep "^Perl-" $depfile)\n\nUse instead:\n$(grep "^Perl-" $depfile | sed 's,Perl-,CPAN:,g;s,-,::,g')"
787 | }
788 | missing_deps() {
789 | CheckDependencies $noweb --types=$1 --mode=all --quiet-progress --no-recursive --no-blacklist $program $version recipe $PWD | while read d_program d_version d_type d_url;
790 | do
791 | if [ "$d_type" = "None" ]
792 | then
793 | if [ "$d_version" != "None" ]
794 | then echo \"$d_program $d_version\"
795 | else echo \"$d_program\"
796 | fi
797 | fi
798 | done
799 | }
800 |
801 | eval "no_nothing=(`missing_deps recipe,official_package`)"
802 | eval "no_recipe=(`missing_deps recipe`)"
803 | j=0
804 | for prog in "${no_recipe[@]}"
805 | do
806 | noth="${no_nothing[$j]}"
807 | progname="${prog% *}"
808 | nothname="${noth% *}"
809 | if [ "$progname" = "$nothname" ]
810 | then
811 | if Boolean "no-web"
812 | then
813 | WARN "Dependency $prog not available locally (web access disabled)."
814 | else
815 | if ! $wget -q -O /dev/null http://svn.gobolinux.org/recipes/revisions/$prog
816 | then ERROR "Dependency $prog not available."
817 | else WARN "Dependency $prog is not available for public access yet."
818 | fi
819 | fi
820 | j=$[j+1]
821 | else
822 | WARN "Dependency $prog has no recipe."
823 | fi
824 | done
825 | else
826 | [ ! "$part_of" ] && ERROR "No $depfile file."
827 | fi
828 | [ "$part_of" ] && Quiet popd
829 | if [ -f Resources/Description ]
830 | then
831 | if grep -ie '^\[License\] \(GNU \)\?\(GPL\|General Public Licen[cs]e\)$' Resources/Description
832 | then
833 | ERROR "No version of GPL specified in Resources/Description."
834 | fi
835 | else
836 | WARN "No Resources/Description file."
837 | fi
838 | }
839 |
840 | cat Recipe | grep -q "recipe_type=meta" || test_resources
841 |
842 | valid_vars="
843 | Compile_goboPrefix
844 | Compile_goboDevices
845 | Compile_goboModules
846 | Compile_goboExecutables
847 | Compile_goboHeaders
848 | Compile_goboModules
849 | Compile_goboLibraries
850 | Compile_goboPrograms
851 | Compile_goboSettings
852 | Compile_goboTemp
853 | Compile_goboVariable
854 | Compile_goboSystem
855 | Compile_goboData
856 | Compile_target
857 | Compile_settings_target
858 | Compile_variable_target
859 | "
860 |
861 | read_valid_dep_vars()
862 | {
863 | for i in `cat Resources/Dependencies | cut -d' ' -f1`
864 | do
865 | var=`echo $i | tr A-Z a-z | tr - _`
866 | valid_vars="$valid_vars
867 | Compile_$var""_path
868 | Compile_$var""_settings_path
869 | Compile_$var""_variable_path
870 | "
871 | done
872 | }
873 |
874 | test_patch() {
875 | patchfile=$1
876 | msg "Checking patch ${patchfile}..."
877 | grep -q "/Programs" "${patchfile}" && {
878 | if [ $(basename "${patchfile}" .in) = "${patchfile}" ]
879 | then instruction="Rename to ${patchfile}.in and use @%Compile_target%@ and @%Compile__path%@."
880 | else instruction="Use @%Compile_target%@ and @%Compile__path%@."
881 | fi
882 | ERROR "Patch references /Programs tree explicitly. $instruction"
883 | }
884 | grep -q "/System" "${patchfile}" && {
885 | if [ $(basename "${patchfile}" .in) = "${patchfile}" ]
886 | then instruction="Rename to ${patchfile}.in and use @%Compile_%@."
887 | else instruction="Use @%Compile_%@."
888 | fi
889 | ERROR "Patch references /System tree explicitly. $instruction"
890 | }
891 | firstrow=$(head -n1 "${patchfile}")
892 | echo ${firstrow} | grep -q '^--- ' || echo ${firstrow} | grep -q '^diff ' &&
893 | WARN "Patch file ${patchfile} lacks rationale. Please consider adding reason for patch to the top of the file."
894 |
895 | for i in `sed -r '/@%[^ %]+%@/!d' $1`
896 | do
897 | var=`echo $i | sed -r '/@%[^ %]+%@/!d' | sed -r 's/^.*@%([^ %]+)%@.*$/\1/g'`
898 | if [ -n "$var" ]
899 | then
900 | if [ -z "`echo $valid_vars | grep $var`" ]
901 | then ERROR "Patch uses invalid environment variable (@%$var%@)."
902 | fi
903 | fi
904 | done
905 | }
906 |
907 | read_valid_dep_vars
908 |
909 | ls *.patch *.patch.in 2> /dev/null | while read patch
910 | do
911 | test_patch "$patch"
912 | done
913 |
--------------------------------------------------------------------------------