Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 259318 | Differences between
and this patch

Collapse All | Expand All

(-)/usr/bin/euse (-8 / +248 lines)
Lines 14-19 Link Here
14
MAKE_GLOBALS_PATH=/etc/make.globals
14
MAKE_GLOBALS_PATH=/etc/make.globals
15
MAKE_PROFILE_PATH=/etc/make.profile
15
MAKE_PROFILE_PATH=/etc/make.profile
16
MAKE_CONF_BACKUP_PATH=/etc/make.conf.euse_backup
16
MAKE_CONF_BACKUP_PATH=/etc/make.conf.euse_backup
17
PACKAGE_USE_PATH=/etc/portage/package.use
17
18
18
[ -z "${MODE}" ] && MODE="showhelp"		# available operation modes: showhelp, showversion, showdesc, showflags, modify
19
[ -z "${MODE}" ] && MODE="showhelp"		# available operation modes: showhelp, showversion, showdesc, showflags, modify
19
20
Lines 33-38 Link Here
33
			-E | --enable)         MODE="modify"; ACTION="add";;
34
			-E | --enable)         MODE="modify"; ACTION="add";;
34
			-D | --disable)        MODE="modify"; ACTION="remove";;
35
			-D | --disable)        MODE="modify"; ACTION="remove";;
35
			-P | --prune)          MODE="modify"; ACTION="prune";;
36
			-P | --prune)          MODE="modify"; ACTION="prune";;
37
			-p | --package)	       MODE="modify"; shift; PACKAGE=${1};;
36
			-*)
38
			-*)
37
				echo "ERROR: unknown option ${1} specified."
39
				echo "ERROR: unknown option ${1} specified."
38
				echo
40
				echo
Lines 56-61 Link Here
56
	exit 1
58
	exit 1
57
}
59
}
58
60
61
warn() {
62
	echo "WARNING: ${1}"
63
}
64
59
get_real_path() {
65
get_real_path() {
60
	set -P
66
	set -P
61
	cd "$1"
67
	cd "$1"
Lines 83-88 Link Here
83
	done
89
	done
84
#	[ ! -r "$(get_make_defaults)" ] && error "$(get_make_defaults) is not readable"
90
#	[ ! -r "$(get_make_defaults)" ] && error "$(get_make_defaults) is not readable"
85
	[ "${MODE}" == "modify" -a ! -w "${MAKE_CONF_PATH}" ] && error ""${MAKE_CONF_PATH}" is not writable"
91
	[ "${MODE}" == "modify" -a ! -w "${MAKE_CONF_PATH}" ] && error ""${MAKE_CONF_PATH}" is not writable"
92
	[ "${MODE}" == "modify" -a -s "${PACKAGE_USE_PATH}" -a ! -w "${PACKAGE_USE_PATH}" ] && error ""${PACKAGE_USE_PATH}" is not writable"
86
}
93
}
87
94
88
showhelp() {
95
showhelp() {
Lines 102-108 Link Here
102
         -E, --enable         - enable the given useflags
109
         -E, --enable         - enable the given useflags
103
         -D, --disable        - disable the given useflags
110
         -D, --disable        - disable the given useflags
104
         -P, --prune          - remove all references to the given flags from
111
         -P, --prune          - remove all references to the given flags from
105
                                make.conf to revert to default settings
112
                                make.conf and package.use to revert to default 
113
                                settings
114
         -p, --package        - used with -E, -D, to apply to a specific
115
                                package only
106
116
107
Notes: ${PROGRAM_NAME} currently only works for global flags defined
117
Notes: ${PROGRAM_NAME} currently only works for global flags defined
108
       in make.globals, make.defaults or make.conf, it doesn't handle
118
       in make.globals, make.defaults or make.conf, it doesn't handle
Lines 148-156 Link Here
148
print ' '.join(r)" 
158
print ' '.join(r)" 
149
}
159
}
150
160
161
# Similar to reduce_incrementals except converts lines from package atoms
162
# in /etc/portage/package.use files to lines of "pkg {[-]flag}*"
163
reduce_package_use() {
164
    echo "${@}" | python -c "import sys,re
165
h={}; atom=re.compile(r'[<>]?=?([a-z][\w/-]+[a-z])(-[\dpr._*-]+)?', re.I); 
166
getflags=re.compile(r'(-?[\w*-]+)')
167
for x in sys.stdin.read().split('\n'):
168
	if not x: continue
169
	parts = x.lstrip().split(' ',1)
170
	if len(parts)==1: continue
171
	try:
172
		pkg = atom.match(parts[0]).group(1)
173
	except:
174
		continue
175
	flags = getflags.findall(parts[1])
176
	if not pkg in h: h[pkg]=[]
177
	r=h[pkg]
178
	for x in flags:
179
		if x[0] == '-' and x[1:] in r:
180
			r.remove(x[1:])
181
			r.append(x)
182
		elif x[0] != '-' and '-'+x in r:
183
			r.remove('-'+x)
184
			r.append(x)
185
		elif x == '-*':
186
			r = h[pkg] = ['-*']
187
		elif x not in r:
188
			r.append(x)
189
print '\n'.join([' %s %s ' % (pkg,' '.join(flgs)) for pkg,flgs in h.iteritems() if len(flgs)])"
190
}
191
151
# the following function creates a bash array ACTIVE_FLAGS that contains the
192
# the following function creates a bash array ACTIVE_FLAGS that contains the
152
# global use flags, indexed by origin: 0: environment, 1: make.conf, 
193
# global use flags, indexed by origin: 0: environment, 1: make.conf, 
153
# 2: make.defaults, 3: make.globals
194
# 2: make.defaults, 3: make.globals, 4: package.use
154
get_useflags() {
195
get_useflags() {
155
	# only calculate once as calling emerge is painfully slow
196
	# only calculate once as calling emerge is painfully slow
156
	[ -n "${USE_FLAGS_CALCULATED}" ] && return
197
	[ -n "${USE_FLAGS_CALCULATED}" ] && return
Lines 175-180 Link Here
175
	USE="${ACTIVE_FLAGS[0]}"
216
	USE="${ACTIVE_FLAGS[0]}"
176
	PORTDIR="${portdir_backup}"
217
	PORTDIR="${portdir_backup}"
177
218
219
	# Parse through /etc/portage/package.use
220
	if [[ -d ${PACKAGE_USE_PATH} ]]; then
221
		ACTIVE_FLAGS[4]=$( find ${PACKAGE_USE_PATH} -type f -exec cat {} \; \
222
			-exec echo \; | sed -e "s/#.*$//" )
223
	elif [[ -e ${PACKAGE_USE_PATH} ]]; then
224
		ACTIVE_FLAGS[4]=$( cat ${PACKAGE_USE_PATH} )
225
	fi
226
	# Simplify ACTIVE_FLAGS[4] to be lines of pkg {[-]flag}*
227
	ACTIVE_FLAGS[4]=$(reduce_package_use "${ACTIVE_FLAGS[4]}");
228
178
	# get the currently active USE flags as seen by portage, this has to be after
229
	# get the currently active USE flags as seen by portage, this has to be after
179
	# restoring USE or portage won't see the original environment
230
	# restoring USE or portage won't see the original environment
180
	ACTIVE_FLAGS[9]="$(emerge --info | grep 'USE=' | cut -b 5- | sed -e 's:"::g')" #'
231
	ACTIVE_FLAGS[9]="$(emerge --info | grep 'USE=' | cut -b 5- | sed -e 's:"::g')" #'
Lines 206-211 Link Here
206
	
257
	
207
	[ -f "${curdir}/make.defaults" ] && rvalue="${curdir}/make.defaults ${rvalue}"
258
	[ -f "${curdir}/make.defaults" ] && rvalue="${curdir}/make.defaults ${rvalue}"
208
	if [ -f "${curdir}/parent" ]; then
259
	if [ -f "${curdir}/parent" ]; then
260
		IFS=$' \t\n'
209
		for parent in $(egrep -v '(^#|^ *$)' ${curdir}/parent); do
261
		for parent in $(egrep -v '(^#|^ *$)' ${curdir}/parent); do
210
			pdir="$(get_real_path ${curdir}/${parent})"
262
			pdir="$(get_real_path ${curdir}/${parent})"
211
			rvalue="$(get_all_make_defaults ${pdir}) ${rvalue}"
263
			rvalue="$(get_all_make_defaults ${pdir}) ${rvalue}"
Lines 239-251 Link Here
239
# 3: echo value for positive (and as lowercase for negative) test result, 
291
# 3: echo value for positive (and as lowercase for negative) test result, 
240
# 4 (optional): echo value for "missing" test result, defaults to blank
292
# 4 (optional): echo value for "missing" test result, defaults to blank
241
get_flagstatus_helper() {
293
get_flagstatus_helper() {
242
	if echo " ${ACTIVE_FLAGS[${2}]} " | grep " ${1} " > /dev/null; then
294
	if echo " ${ACTIVE_FLAGS[${2}]} " | grep " ${1} " | grep "${5} " > /dev/null; then
243
		echo -n "${3}"
295
		echo -n "${3}"
244
	elif echo " ${ACTIVE_FLAGS[${2}]} " | grep " -${1} " > /dev/null; then
296
		return 0
245
		echo -n "$(echo ${3} | tr [[:upper:]] [[:lower:]])"
297
	elif echo " ${ACTIVE_FLAGS[${2}]} " | grep " -${1} " | grep "${5} " > /dev/null; then
298
		echo -n "$(echo ${3} | tr [:upper:]+ [:lower:]-)"
299
		return 0
246
	else
300
	else
247
		echo -n "${4:- }"
301
		echo -n "${4:- }"
248
	fi
302
	fi
303
	return 1
249
}
304
}
250
305
251
# prints a status string for the given flag, each column indicating the presence
306
# prints a status string for the given flag, each column indicating the presence
Lines 256-266 Link Here
256
	get_useflags
311
	get_useflags
257
312
258
	echo -n '['
313
	echo -n '['
259
	get_flagstatus_helper "${1}" 9 "+" "-"
314
	if [ "${SCOPE}" == "local" ]; then
315
		if ! get_flagstatus_helper "${1}" 4 "+" "-" "${2}" ; then
316
			echo -n -e "\b"
317
			get_flagstatus_helper "${1}" 9 "+" "-"
318
		fi
319
	else
320
		get_flagstatus_helper "${1}" 9 "+" "-"
321
	fi
260
	get_flagstatus_helper "${1}" 0 "E"
322
	get_flagstatus_helper "${1}" 0 "E"
261
	get_flagstatus_helper "${1}" 1 "C"
323
	get_flagstatus_helper "${1}" 1 "C"
262
	get_flagstatus_helper "${1}" 2 "D"
324
	get_flagstatus_helper "${1}" 2 "D"
263
	get_flagstatus_helper "${1}" 3 "G"
325
	get_flagstatus_helper "${1}" 3 "G"
326
	get_flagstatus_helper "${1}" 4 "P" "" ${2}
264
	echo -n '] '
327
	echo -n '] '
265
}
328
}
266
329
Lines 328-334 Link Here
328
					pkg="$(echo $line | cut -d\| -f 1)"
391
					pkg="$(echo $line | cut -d\| -f 1)"
329
					flag="$(echo $line | cut -d\| -f 2)"
392
					flag="$(echo $line | cut -d\| -f 2)"
330
					desc="$(echo $line | cut -d\| -f 3)"
393
					desc="$(echo $line | cut -d\| -f 3)"
331
					get_flagstatus "${flag}"
394
					get_flagstatus "${flag}" "${pkg}"
332
					printf "%s (%s):\n%s\n\n" "${flag}" "${pkg}" "${desc}"
395
					printf "%s (%s):\n%s\n\n" "${flag}" "${pkg}" "${desc}"
333
				done
396
				done
334
		fi
397
		fi
Lines 397-403 Link Here
397
					#       exit status of equery instead of a subshell and pipe to wc -l
460
					#       exit status of equery instead of a subshell and pipe to wc -l
398
					if [ $(equery -q -C list -i -e "${pkg}" | wc -l) -gt 0 ]; then
461
					if [ $(equery -q -C list -i -e "${pkg}" | wc -l) -gt 0 ]; then
399
						foundone=1
462
						foundone=1
400
						get_flagstatus "${flag}"
463
						get_flagstatus "${flag}" "${pkg}"
401
						printf "%s (%s):\n%s\n\n" "${flag}" "${pkg}" "${desc#- }"
464
						printf "%s (%s):\n%s\n\n" "${flag}" "${pkg}" "${desc#- }"
402
					fi
465
					fi
403
				done < <(grep ":${1}  *-" "${descdir}/use.local.desc")
466
				done < <(grep ":${1}  *-" "${descdir}/use.local.desc")
Lines 431-436 Link Here
431
			get_flagstatus ${1}
494
			get_flagstatus ${1}
432
			echo
495
			echo
433
		fi
496
		fi
497
		if echo " ${ACTIVE_FLAGS[4]} " | egrep -e " -?${1} " > /dev/null; then
498
			for pkg in $( echo "${ACTIVE_FLAGS[4]}" | \
499
					egrep " -?${1} " | cut -d " " -f 2); do
500
				printf "%-20s" ${1}
501
				SCOPE="local" get_flagstatus ${1} "${pkg}"
502
				printf "(%s)\n" ${pkg}
503
			done;
504
		fi
434
		shift
505
		shift
435
	done
506
	done
436
}
507
}
Lines 444-452 Link Here
444
	NEW_MAKE_CONF_USE="${NEW_MAKE_CONF_USE// ${1} / }"
515
	NEW_MAKE_CONF_USE="${NEW_MAKE_CONF_USE// ${1} / }"
445
}
516
}
446
517
518
# Simple utility to remove empty files from package.use
519
clean_package_use() {
520
if [[ -d ${PACKAGE_USE_PATH} ]]; then
521
	for f in $(find ${PACKAGE_USE_PATH} -size 0); do
522
		echo "Removing empty file ""${f}"""
523
		rm ${f}
524
	done;
525
fi
526
}
527
528
# Utility to remove a use flag from a file in package.use[/]
529
# Args: (1) File, (2) Use flag
530
scrub_use_flag() {
531
	local atom_re="^[<>]?=?([a-z][\da-z/-]+[a-z])(-[0-9pr._*-]+)?"
532
	local filename=${1}
533
	local flag=${2}
534
	local pkg=$(echo "${PACKAGE}" | sed -re "s/${atom_re}/\1/")
535
	local pkg_re="[<>]?=?${pkg}(-[\dpr._*-]+)?"
536
537
	while read line; do
538
		# Skip (preserve) comments on their own lines
539
		if [[ -z $(echo "${line}" | sed -re "s/^ *#.*$//") ]]; then
540
			echo "${line}"
541
		# Detect if requested package is defined on this line
542
		elif [[ -n ${PACKAGE} ]]; then
543
			if [[ -n $(echo ${line} | egrep -re "[^#]*${pkg_re}") ]]; then	
544
				# If this is the only (remaining) use flag defined
545
                # for this package, then remove the whole line
546
                if [[ -z $(echo ${line} | \
547
						egrep -re "[^#]*${pkg_re}.*-?${flag}\s*$") ]]; then
548
					# Remove flag from this line
549
					echo "${line}" | sed -re "s/-?\b${flag}\b//"
550
				fi
551
			else
552
				# Passthru
553
				echo "${line}"
554
			fi
555
		# If line only has this use flag, let it be removed 
556
		# (used if PACKAGE is not defined -- from pruning)
557
		elif [[ -z $(echo ${line} | \
558
				grep -re "[^#]*${atom_re}.*-?${flag}") ]]; then
559
			# Remove flag from this line
560
			echo "${line}" | sed -re "s/-?\b${flag}\b//"
561
		else
562
			# Passthru
563
			echo "${line}"
564
		fi;
565
	done < <(cat "${filename}") > ${filename};
566
}
567
568
modify_package() {
569
	get_useflags
570
571
	local atom_re="^[<>]?=?([a-z][\da-z/-]+[a-z])(-[0-9pr._*-]+)?"
572
	local pkg=$(echo "${PACKAGE}" | sed -re "s/${atom_re}/\1/")
573
	local pkg_re="[<>]?=?${pkg}(-[\dpr._*-]+)?"
574
575
	while [[ -n ${1} ]]; do
576
	local flag=${1}
577
	#
578
	# --- Sanity checks
579
	# (1) make sure ${pkg} exists in portdir
580
	if [[ ! -d "$(get_portdir)/${pkg}" ]]; then
581
		error "Package ""${pkg}"" does not exist"
582
	#
583
	# (2) make sure ${flag} is defined in get_useflaglist
584
	elif [[ ! -n $(echo " $(get_useflaglist) " | grep "${flag}") ]]; then
585
		warn "USE flag ""${flag}"" does not exist"
586
		# Don't bail just because of this, just warn
587
	fi;
588
	# If flag is enabled in portage USE flags (emerge --info), 
589
	# then "remove"ing the flag should be replaced with adding
590
	# the negative flag instead
591
	if [[ "${ACTION}" == "remove" &&
592
			-n $( echo " ${ACTIVE_FLAGS[9]} " | grep " ${flag} " ) ]]; then
593
		flag="-${flag}"
594
		ACTION="add"
595
	# If flag is currently disabled for the package requested 
596
	# to be enabled in, then "remove" the negative
597
	elif [[ "${ACTION}" == "add" &&
598
			-n $( echo " ${ACTIVE_FLAGS[4]} " | egrep -e " ${PACKAGE}.*-${flag}\b" ) ]]; then
599
        echo "CHANGING TO REMOVE"
600
		flag="-${flag}"
601
		ACTION="remove"
602
	fi;
603
	case "${ACTION}" in
604
		"add")
605
			local filename
606
			if [[ -d ${PACKAGE_USE_PATH} ]]; then
607
				# Use naming convention of package.use/package
608
				filename="${PACKAGE_USE_PATH}/${pkg#*/}"
609
				if [[ ! -s "${filename}" ]]; then
610
					# Create new file to contain flag
611
					echo "${PACKAGE} ${flag}" > "${filename}"
612
					echo "Adding ""${PACKAGE}:${flag}"" use flag to new file ""${filename}"""
613
					return
614
				fi;
615
			else	
616
				# Add to package.use file instead
617
				filename=${PACKAGE_USE_PATH}
618
				# Create as necessary
619
				touch "${filename}"
620
			fi;
621
			# Walk through the file and add the flag manually
622
			echo "Adding ""${PACKAGE}:${flag}"" use flag in ""${filename}"""
623
            local added=0
624
			while read line; do
625
				if [[ -n $(echo "${line}" | egrep -e "^[^#]*${pkg_re}") ]]; then
626
					echo "$(reduce_package_use "${line} ${flag}" | cut -d " " -f 2-)"
627
					added=1
628
				else
629
					# Passthru
630
					echo "${line}"
631
				fi;
632
			done < <(cat "${filename}") > ${filename}
633
			if [[ ${added} == 0 ]]; then
634
				echo "${PACKAGE} ${flag}" >> "${filename}"
635
			fi
636
			;;
637
		"remove")
638
			local filename
639
			if [[ -d ${PACKAGE_USE_PATH} ]]; then
640
				# Scan for file containing named package and use flag
641
				filename=$( egrep -rle "${pkg_re}.*[^-]${flag}( |$)" "${PACKAGE_USE_PATH}")
642
				if [[ -z "${filename}" ]]; then
643
					error ""${flag}" is not defined for package "${PACKAGE}""
644
					return
645
				fi;
646
			else
647
				# Remove from package.use instead
648
				filename=${PACKAGE_USE_PATH}
649
				# Create as necessary
650
				touch "${filename}"
651
			fi;
652
			# Scrub use flag from matched files
653
			for f in ${filename}; do
654
				# Remove current flags in file
655
				echo "Removing ""${PACKAGE}:${flag}"" use flag in ""${f}"""
656
				scrub_use_flag ${f} ${flag}
657
			done;
658
			# Remove empty files
659
			clean_package_use
660
			;;
661
	esac;
662
	shift;
663
	done;
664
}
665
447
# USE flag modification function. Mainly a loop with calls to add_flag and 
666
# USE flag modification function. Mainly a loop with calls to add_flag and 
448
# remove_flag to create a new USE string which is then inserted into make.conf.
667
# remove_flag to create a new USE string which is then inserted into make.conf.
449
modify() {
668
modify() {
669
	if [[ -n ${PACKAGE} ]]; then
670
		modify_package ${*}
671
		return;
672
	fi;
673
450
	if [ -z "${*}" ]; then
674
	if [ -z "${*}" ]; then
451
		if [ "${ACTION}" != "prune" ]; then
675
		if [ "${ACTION}" != "prune" ]; then
452
			echo "WARNING: no USE flags listed for modification, do you really"
676
			echo "WARNING: no USE flags listed for modification, do you really"
Lines 486-491 Link Here
486
			elif echo " ${NEW_MAKE_CONF_USE} " | grep " -${1} " > /dev/null; then
710
			elif echo " ${NEW_MAKE_CONF_USE} " | grep " -${1} " > /dev/null; then
487
				remove_flag "-${1}"
711
				remove_flag "-${1}"
488
			fi
712
			fi
713
			# Locate use flag in package.use
714
			local filename
715
			if [[ -d ${PACKAGE_USE_PATH} ]]; then
716
				filename=$( egrep -rle "-?\b${1}\b" "${PACKAGE_USE_PATH}")
717
			else
718
				# Scrub from package.use file
719
				filename=${PACKAGE_USE_PATH}
720
			fi
721
			# Scrub use flag from matched files
722
			for f in ${filename}; do
723
				# Remove current flags in file
724
				echo "Disabling ""${1}"" use flag in ""${f}"""
725
				scrub_use_flag ${f} ${1} 
726
			done;
727
			# Remove empty files from package.use
728
			clean_package_use
489
			shift
729
			shift
490
		fi
730
		fi
491
	done
731
	done

Return to bug 259318