cabal替代脚本

由于网络原因,直接使用cabal update不成功,只能自己写脚本直接从网上拖包下来,自己安装。

但是这样做的缺点是需要手动处理dependency,当然,也可以把脚本写的复杂些,自动来处理dependency。

cabal.sh

1 cat<<EOF > .tmp_sed_script
2 s/<\/[^>]*>/&\n/g
3 s/></>\n</g
4 s/a href="\([^"]*\)"/\n[URL: \1 ]\n/g
5 EOF
6 
7 home_url="https://hackage.haskell.org"
8 
9 item_url=$home_url/"package/"$1
10 
11 target_dir=""
12 
13 curl $item_url 1> .tmp_page_content 2> /dev/null
14 
15 for link in $(sed -f .tmp_sed_script .tmp_page_content | grep URL | awk '{print $2}')
16 do
17 if [[ $link == /*.tar.gz ]]
18 then
19 full_link=$home_url$link
20 echo "wget " $full_link " --no-check-certificate ......"
21 wget $full_link --no-check-certificate
22 archive_file=$(basename $full_link)
23 if [ -f $archive_file ]
24 then
25 tar -xvzf $archive_file 2>&1 > /dev/null
26 fi
27 target_dir=$(tar tzf $archive_file | awk 'NR==1{print}')
28 fi
29 done
30 
31 rm .tmp_*
32 rm *.tar.gz*
33 
34 cd $target_dir
35 sudo cabal configure
36 sudo cabal install
37 cd ..

  


 

不过好像必须要处理dependency了,这样才能真正自动化。

 

ghc-pkg list | sed -e '/[\/(]/d' | awk 'BEGIN{FS="-"}{print $1}' | sed -e '/Cabal/d' | awk 'NF!=0{print}' | sed 's/ //g' > .installed_pkgs

  

if [ ! -f .tmp_sed_script ]
then
cat<<EOF > .tmp_sed_script
s/<\/[^>]*>/&\n/g
s/></>\n</g
s/a href="\([^"]*\)"/\n[URL: \1 ]\n/g
EOF
fi

if [ ! -f .tmp_installed_pkgs ]
then
ghc-pkg list | sed -e '/[\/(]/d' | awk 'BEGIN{FS="-"}{print $1}' | sed -e '/Cabal/d' | awk 'NF!=0{print}' | sed 's/ //g' > .tmp_installed_pkgs
fi

home_url="https://hackage.haskell.org"

item_url=$home_url/"package/"$1

target_dir=""

if [ ! -f $.tmp_page_content_"$1" ]
then
curl $item_url 1> .tmp_page_content_"$1" 2> /dev/null 
fi

sed -f .tmp_sed_script .tmp_page_content_"$1" | grep "URL: /package/" | sed -e "/$1/d" > .tmp_dependency_"$1"

# we should make sure that all the package in .tmp_dependency_XXX file should be installed first than this package
#
#


for dependency in $(cat .tmp_dependency_"$1")
do
	if [[ $dependency == /package/* ]]
	then
		#echo $dependency
		dep=$(echo $dependency | cut -b 10-)
		b_installed=false
		for installed in $(cat .tmp_installed_pkgs)
		do
			if [[ $installed == $dep ]]
			then
				b_installed=true
			fi
		done
		#echo $b_installed " for " $dep
		
		if [[ $b_installed == "false" ]]
		then
			echo "$1 depends on $dep"
			echo "$dep" >> .tmp_installed_pkgs
			bash cabal_ex.sh $dep
		fi
	fi
done

  

但是这种以脚本为单位的recursion效率又有点问题,所以最好将其写成一个函数。


 

home_url="https://hackage.haskell.org"

function prepare()
{
	if [ ! -f .tmp_installed_pkgs ]
	then
		ghc-pkg list | sed -e '/[\/(]/d' | awk 'BEGIN{FS="-"}{print $1}' | sed -e '/Cabal/d' | awk 'NF!=0{print}' | sed 's/ //g' > .tmp_installed_pkgs
	fi
}

function pull_info_page()
{
	# This function will pull info page from web
	echo "[CABAL_SCRIPT:]Parsing info page for $1 ......"
	item_url=$home_url/"package/"$1

	if [ ! -f .tmp_sed_script_"$1" ]
	then
cat<<EOF > .tmp_sed_script_"$1"
s/<\/[^>]*>/&\n/g
s/></>\n</g
s/a href="\([^"]*\)"/\n[URL: \1 ]\n/g
EOF
	fi

	if [ ! -f .tmp_page_content_"$1" ]
	then
		curl $item_url 1> .tmp_page_content_"$1" 2> /dev/null 
	fi

	if [ ! -f .tmp_dependency_"$1" ]
	then
		sed -f .tmp_sed_script_"$1" .tmp_page_content_"$1" | grep "URL: /package/" | sed -e "/$1/d" > .tmp_dependency_"$1"
	fi
}

function calc_dependency()
{
	# This function just calculate the dependency packages of $1
	# and append it to the global list	
	echo "[CABAL_SCRIPT:]Resolving dependencies for $1 ......"
	pull_info_page $1

	for dependency in $(cat .tmp_dependency_"$1")
	do
		if [[ $dependency == /package/* ]]
		then
			#echo $dependency
			dep=$(echo $dependency | cut -b 10-)
			b_installed=false
			for installed in $(cat .tmp_installed_pkgs)
			do
				if [[ $installed == $dep ]]
				then
					b_installed=true
				fi
			done
			#echo $b_installed " for " $dep
			
			if [[ $b_installed == "false" ]]
			then
				echo "$1 depends on $dep"
				echo "$dep" >> .tmp_installed_pkgs
				#bash cabal_ex.sh $dep
				install_package $dep
			fi
		fi
	done
}

function install_package()
{
	# This function just download and install a package $1
	# it doesn't care about dependency
	target_dir=""

	calc_dependency $1	

	# Download package
	for link in $(sed -f .tmp_sed_script_"$1" .tmp_page_content_"$1" | grep URL | awk '{print $2}')
	do
		if [[ $link == /*.tar.gz ]]
		then
			full_link=$home_url$link
			archive_file=$(basename $full_link)
			#target_dir=$(tar tzf $archive_file | awk 'NR==1{print}')
			target_dir=$(echo $archive_file | sed -re 's/(.*)\.tar\.gz$/\1/g')
			#echo "target_dir is $target_dir"

			if [ ! -d $target_dir ]
			then
				if [ ! -f $archive_file ]
				then
					#echo "wget " $full_link " --no-check-certificate ......"
					echo "[CABAL_SCRIPT:]Downloading $full_link ......"
					wget $full_link --no-check-certificate
				fi
	
				if [ -f $archive_file ]
				then
					echo "[CABAL_SCRIPT:]Extracting $archive_file ......"
					tar -xvzf $archive_file 2> /dev/null 1> /dev/null
				fi
			fi
		fi
	done

#	rm .tmp_*
#	rm *.tar.gz*

	# Install package
	cd $target_dir
	echo "[CABAL_SCRIPT:]Installing $1 ......"
	sudo cabal configure
	sudo cabal install
	cd ..
}

prepare
install_package $1
rm .tmp_*

  

但是仍然有问题,这里没有对dependency的版本做判定,因此仍然失败。

posted @ 2014-07-16 16:06  Daniel King  阅读(383)  评论(0编辑  收藏  举报