Skip to content

Commit

Permalink
Add migration script
Browse files Browse the repository at this point in the history
Note: This was already reviewed in <unknown commit>. This doesn't mean we cannot apply further changes though.
PiperOrigin-RevId: 460542835
(cherry picked from commit f9a3920)
  • Loading branch information
marcbaechinger authored and rohitjoins committed Jul 12, 2022
1 parent 05a1bbf commit 6180035
Showing 1 changed file with 386 additions and 0 deletions.
386 changes: 386 additions & 0 deletions github/media3-migration.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,386 @@
#!/bin/bash
# Copyright (C) 2022 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
##
shopt -s extglob

PACKAGE_MAPPINGS='com.google.android.exoplayer2 androidx.media3.exoplayer
com.google.android.exoplayer2.analytics androidx.media3.exoplayer.analytics
com.google.android.exoplayer2.audio androidx.media3.exoplayer.audio
com.google.android.exoplayer2.castdemo androidx.media3.demo.cast
com.google.android.exoplayer2.database androidx.media3.database
com.google.android.exoplayer2.decoder androidx.media3.decoder
com.google.android.exoplayer2.demo androidx.media3.demo.main
com.google.android.exoplayer2.drm androidx.media3.exoplayer.drm
com.google.android.exoplayer2.ext.av1 androidx.media3.decoder.av1
com.google.android.exoplayer2.ext.cast androidx.media3.cast
com.google.android.exoplayer2.ext.cronet androidx.media3.datasource.cronet
com.google.android.exoplayer2.ext.ffmpeg androidx.media3.decoder.ffmpeg
com.google.android.exoplayer2.ext.flac androidx.media3.decoder.flac
com.google.android.exoplayer2.ext.ima androidx.media3.exoplayer.ima
com.google.android.exoplayer2.ext.leanback androidx.media3.ui.leanback
com.google.android.exoplayer2.ext.okhttp androidx.media3.datasource.okhttp
com.google.android.exoplayer2.ext.opus androidx.media3.decoder.opus
com.google.android.exoplayer2.ext.rtmp androidx.media3.datasource.rtmp
com.google.android.exoplayer2.ext.vp9 androidx.media3.decoder.vp9
com.google.android.exoplayer2.ext.workmanager androidx.media3.exoplayer.workmanager
com.google.android.exoplayer2.extractor androidx.media3.extractor
com.google.android.exoplayer2.gldemo androidx.media3.demo.gl
com.google.android.exoplayer2.mediacodec androidx.media3.exoplayer.mediacodec
com.google.android.exoplayer2.metadata androidx.media3.extractor.metadata
com.google.android.exoplayer2.offline androidx.media3.exoplayer.offline
com.google.android.exoplayer2.playbacktests androidx.media3.test.exoplayer.playback
com.google.android.exoplayer2.robolectric androidx.media3.test.utils.robolectric
com.google.android.exoplayer2.scheduler androidx.media3.exoplayer.scheduler
com.google.android.exoplayer2.source androidx.media3.exoplayer.source
com.google.android.exoplayer2.source.dash androidx.media3.exoplayer.dash
com.google.android.exoplayer2.source.hls androidx.media3.exoplayer.hls
com.google.android.exoplayer2.source.rtsp androidx.media3.exoplayer.rtsp
com.google.android.exoplayer2.source.smoothstreaming androidx.media3.exoplayer.smoothstreaming
com.google.android.exoplayer2.surfacedemo androidx.media3.demo.surface
com.google.android.exoplayer2.testdata androidx.media3.test.data
com.google.android.exoplayer2.testutil androidx.media3.test.utils
com.google.android.exoplayer2.text androidx.media3.extractor.text
com.google.android.exoplayer2.trackselection androidx.media3.exoplayer.trackselection
com.google.android.exoplayer2.transformer androidx.media3.transformer
com.google.android.exoplayer2.transformerdemo androidx.media3.demo.transformer
com.google.android.exoplayer2.ui androidx.media3.ui
com.google.android.exoplayer2.upstream androidx.media3.datasource
com.google.android.exoplayer2.upstream.cache androidx.media3.datasource.cache
com.google.android.exoplayer2.upstream.crypto androidx.media3.exoplayer.upstream.crypto
com.google.android.exoplayer2.util androidx.media3.common.util
com.google.android.exoplayer2.util androidx.media3.exoplayer.util
com.google.android.exoplayer2.video androidx.media3.exoplayer.video'


CLASS_RENAMINGS='com.google.android.exoplayer2.ui.StyledPlayerView androidx.media3.ui.PlayerView
StyledPlayerView PlayerView
com.google.android.exoplayer2.ui.StyledPlayerControlView androidx.media3.ui.PlayerControlView
StyledPlayerControlView PlayerControlView
com.google.android.exoplayer2.ExoPlayerLibraryInfo androidx.media3.common.MediaLibraryInfo
ExoPlayerLibraryInfo MediaLibraryInfo
com.google.android.exoplayer2.SimpleExoPlayer androidx.media3.exoplayer.ExoPlayer
SimpleExoPlayer ExoPlayer'

CLASS_MAPPINGS='com.google.android.exoplayer2.text.span androidx.media3.common.text HorizontalTextInVerticalContextSpan LanguageFeatureSpan RubySpan SpanUtil TextAnnotation TextEmphasisSpan
com.google.android.exoplayer2.text androidx.media3.common.text CueGroup Cue
com.google.android.exoplayer2.text androidx.media3.exoplayer.text ExoplayerCuesDecoder SubtitleDecoderFactory TextOutput TextRenderer
com.google.android.exoplayer2.upstream.crypto androidx.media3.datasource AesCipherDataSource AesCipherDataSink AesFlushingCipher
com.google.android.exoplayer2.util androidx.media3.common.util AtomicFile Assertions BundleableUtil BundleUtil Clock ClosedSource CodecSpecificDataUtil ColorParser ConditionVariable Consumer CopyOnWriteMultiset EGLSurfaceTexture GlProgram GlUtil HandlerWrapper LibraryLoader ListenerSet Log LongArray MediaFormatUtil NetworkTypeObserver NonNullApi NotificationUtil ParsableBitArray ParsableByteArray RepeatModeUtil RunnableFutureTask SystemClock SystemHandlerWrapper TimedValueQueue TimestampAdjuster TraceUtil UnknownNull UnstableApi UriUtil Util XmlPullParserUtil
com.google.android.exoplayer2.util androidx.media3.common ErrorMessageProvider FlagSet FileTypes MimeTypes PriorityTaskManager
com.google.android.exoplayer2.metadata androidx.media3.common Metadata
com.google.android.exoplayer2.metadata androidx.media3.exoplayer.metadata MetadataDecoderFactory MetadataOutput MetadataRenderer
com.google.android.exoplayer2.audio androidx.media3.common AudioAttributes AuxEffectInfo
com.google.android.exoplayer2.ui androidx.media3.common AdOverlayInfo AdViewProvider
com.google.android.exoplayer2.source.ads androidx.media3.common AdPlaybackState
com.google.android.exoplayer2.source androidx.media3.common MediaPeriodId TrackGroup
com.google.android.exoplayer2.offline androidx.media3.common StreamKey
com.google.android.exoplayer2.ui androidx.media3.exoplayer.offline DownloadNotificationHelper
com.google.android.exoplayer2.trackselection androidx.media3.common TrackSelectionParameters TrackSelectionOverride
com.google.android.exoplayer2.video androidx.media3.common ColorInfo VideoSize
com.google.android.exoplayer2.upstream androidx.media3.common DataReader
com.google.android.exoplayer2.upstream androidx.media3.exoplayer.upstream Allocation Allocator BandwidthMeter CachedRegionTracker DefaultAllocator DefaultBandwidthMeter DefaultLoadErrorHandlingPolicy Loader LoaderErrorThrower ParsingLoadable SlidingPercentile TimeToFirstByteEstimator
com.google.android.exoplayer2.audio androidx.media3.extractor AacUtil Ac3Util Ac4Util DtsUtil MpegAudioUtil OpusUtil WavUtil
com.google.android.exoplayer2.util androidx.media3.extractor NalUnitUtil ParsableNalUnitBitArray
com.google.android.exoplayer2.video androidx.media3.extractor AvcConfig DolbyVisionConfig HevcConfig
com.google.android.exoplayer2.decoder androidx.media3.exoplayer DecoderCounters DecoderReuseEvaluation
com.google.android.exoplayer2.util androidx.media3.exoplayer MediaClock StandaloneMediaClock
com.google.android.exoplayer2 androidx.media3.exoplayer FormatHolder PlayerMessage
com.google.android.exoplayer2 androidx.media3.common BasePlayer BundleListRetriever Bundleable ControlDispatcher C DefaultControlDispatcher DeviceInfo ErrorMessageProvider ExoPlayerLibraryInfo Format ForwardingPlayer HeartRating IllegalSeekPositionException MediaItem MediaMetadata ParserException PercentageRating PlaybackException PlaybackParameters Player PositionInfo Rating StarRating ThumbRating Timeline Tracks
com.google.android.exoplayer2.drm androidx.media3.common DrmInitData'

DEPENDENCY_MAPPINGS='exoplayer media3-exoplayer
exoplayer-common media3-common
exoplayer-core media3-exoplayer
exoplayer-dash media3-exoplayer-dash
exoplayer-database media3-database
exoplayer-datasource media-datasource
exoplayer-decoder media3-decoder
exoplayer-extractor media3-extractor
exoplayer-hls media3-exoplayer-hls
exoplayer-robolectricutils media3-test-utils-robolectric
exoplayer-rtsp media3-exoplayer-rtsp
exoplayer-smoothstreaming media3-exoplayer-smoothstreaming
exoplayer-testutils media3-test-utils
exoplayer-transformer media3-transformer
exoplayer-ui media3-ui
extension-cast media3-cast
extension-cronet media3-datasource-cronet
extension-ima media3-exoplayer-ima
extension-leanback media3-ui-leanback
extension-okhttp media3-datasource-okhttp
extension-rtmp media3-datasource-rtmp
extension-workmanager media3-exoplayer-workmanager'

# Rewrites classes, packages and dependencies from the legacy ExoPlayer package structure
# to androidx.media3 structure.

MEDIA3_VERSION="1.0.0-beta02"
LEGACY_PEER_VERSION="2.18.1"

function usage() {
echo "usage: $0 [-p|-c|-d|-v]|[-m|-l [-x <path>] [-f] PROJECT_ROOT]"
echo " PROJECT_ROOT: path to your project root (location of 'gradlew')"
echo " -p: list package mappings and then exit"
echo " -c: list class mappings (precedence over package mappings) and then exit"
echo " -d: list dependency mappings and then exit"
echo " -m: migrate packages, classes and dependencies to AndroidX Media3"
echo " -l: list files that will be considered for rewrite and then exit"
echo " -x: exclude the path from the list of file to be changed: 'app/src/test'"
echo " -f: force the action even when validation fails"
echo " -v: print the exoplayer2/media3 version strings of this script and exit"
echo " --noclean : Do not call './gradlew clean' in project directory."
echo " -h, --help: show this help text"
}

function print_pairs {
while read -r line;
do
IFS=' ' read -ra PAIR <<< "$line"
printf "%-55s %-30s\n" "${PAIR[0]}" "${PAIR[1]}"
done <<< "$(echo "$@")"
}

function print_class_mappings {
while read -r mapping;
do
old=$(echo "$mapping" | cut -d ' ' -f1)
new=$(echo "$mapping" | cut -d ' ' -f2)
classes=$(echo "$mapping" | cut -d ' ' -f3-)
for clazz in $classes;
do
printf "%-80s %-30s\n" "$old.$clazz" "$new.$clazz"
done
done <<< "$(echo "$CLASS_MAPPINGS" | sort)"
}

ERROR_COUNTER=0
VALIDATION_ERRORS=''

function add_validation_error {
let ERROR_COUNTER++
VALIDATION_ERRORS+="\033[31m[$ERROR_COUNTER] ->\033[0m ${1}"
}

function validate_exoplayer_version() {
has_exoplayer_dependency=''
while read -r file;
do
local version
version=$(grep -m 1 "com\.google\.android\.exoplayer:" "$file" | cut -d ":" -f3 | tr -d \" | tr -d \')
if [[ ! -z $version ]] && [[ ! "$version" =~ $LEGACY_PEER_VERSION ]];
then
add_validation_error "The version does not match '$LEGACY_PEER_VERSION'. \
Update to '$LEGACY_PEER_VERSION' or use the migration script matching your \
current version. Current version '$version' found in\n $file\n"
fi
done <<< "$(find . -type f -name "build.gradle")"
}

function validate_string_not_contained {
local pattern=$1 # regex
local failure_message=$2
while read -r file;
do
if grep -q -e "$pattern" "$file";
then
add_validation_error "$failure_message:\n $file\n"
fi
done <<< "$files"
}

function validate_string_patterns {
validate_string_not_contained \
'com\.google\.android\.exoplayer2\..*\*' \
'Replace wildcard import statements with fully qualified import statements';
validate_string_not_contained \
'com\.google\.android\.exoplayer2\.ui\.PlayerView' \
'Migrate PlayerView to StyledPlayerView before migrating';
validate_string_not_contained \
'LegacyPlayerView' \
'Migrate LegacyPlayerView to StyledPlayerView before migrating';
validate_string_not_contained \
'com\.google\.android\.exoplayer2\.ext\.mediasession' \
'The MediaSessionConnector is integrated in androidx.media3.session.MediaSession'
}

SED_CMD_INPLACE='sed -i '
if [[ "$OSTYPE" == "darwin"* ]]; then
SED_CMD_INPLACE="sed -i '' "
fi

MIGRATE_FILES='1'
LIST_FILES_ONLY='1'
PRINT_CLASS_MAPPINGS='1'
PRINT_PACKAGE_MAPPINGS='1'
PRINT_DEPENDENCY_MAPPINGS='1'
PRINT_VERSION='1'
NO_CLEAN='1'
FORCE='1'
IGNORE_VERSION='1'
EXCLUDED_PATHS=''

while [[ $1 =~ ^-.* ]];
do
case "$1" in
-m ) MIGRATE_FILES='';;
-l ) LIST_FILES_ONLY='';;
-c ) PRINT_CLASS_MAPPINGS='';;
-p ) PRINT_PACKAGE_MAPPINGS='';;
-d ) PRINT_DEPENDENCY_MAPPINGS='';;
-v ) PRINT_VERSION='';;
-f ) FORCE='';;
-x ) shift; EXCLUDED_PATHS="$(printf "%s\n%s" $EXCLUDED_PATHS $1)";;
--noclean ) NO_CLEAN='';;
* ) usage && exit 1;;
esac
shift
done

if [[ -z $PRINT_DEPENDENCY_MAPPINGS ]];
then
print_pairs "$DEPENDENCY_MAPPINGS"
exit 0
elif [[ -z $PRINT_PACKAGE_MAPPINGS ]];
then
print_pairs "$PACKAGE_MAPPINGS"
exit 0
elif [[ -z $PRINT_CLASS_MAPPINGS ]];
then
print_class_mappings
exit 0
elif [[ -z $PRINT_VERSION ]];
then
echo "$LEGACY_PEER_VERSION -> $MEDIA3_VERSION. This script is written to migrate from ExoPlayer $LEGACY_PEER_VERSION to AndroidX Media3 $MEDIA3_VERSION"
exit 0
elif [[ -z $1 ]];
then
usage
exit 1
fi

if [[ ! -f $1/gradlew ]];
then
echo "directory seems not to exist or is not a gradle project (missing 'gradlew')"
usage
exit 1
fi

PROJECT_ROOT=$1
cd "$PROJECT_ROOT"

# Create the set of files to transform
exclusion="/build/|/.idea/|/res/drawable|/res/color|/res/mipmap|/res/values|"
if [[ ! -z $EXCLUDED_PATHS ]];
then
while read -r path;
do
exclusion="$exclusion./$path|"
done <<< "$EXCLUDED_PATHS"
fi
files=$(find . -name '*\.java' -o -name '*\.kt' -o -name '*\.xml' | grep -Ev "'$exclusion'")

# Validate project and exit in case of validation errors
validate_string_patterns
validate_exoplayer_version "$PROJECT_ROOT"
if [[ ! -z $FORCE && ! -z "$VALIDATION_ERRORS" ]];
then
echo "============================================="
echo "Validation errors (use -f to force execution)"
echo "---------------------------------------------"
echo -e "$VALIDATION_ERRORS"
exit 1
fi

if [[ -z $LIST_FILES_ONLY ]];
then
echo "$files" | cut -c 3-
find . -type f -name 'build\.gradle' | cut -c 3-
exit 0
fi

# start migration after successful validation or when forced to disregard validation
# errors

if [[ ! -z "$MIGRATE_FILES" ]];
then
echo "nothing to do"
usage
exit 0
fi

PWD=$(pwd)
if [[ ! -z $NO_CLEAN ]];
then
cd "$PROJECT_ROOT"
./gradlew clean
cd "$PWD"
fi

# create expressions for class renamings
renaming_expressions=''
while read -r renaming;
do
src=$(echo "$renaming" | cut -d ' ' -f1 | sed -e 's/\./\\\./g')
dest=$(echo "$renaming" | cut -d ' ' -f2)
renaming_expressions+="-e s/$src/$dest/g "
done <<< "$CLASS_RENAMINGS"

# create expressions for class mappings
classes_expressions=''
while read -r mapping;
do
src=$(echo "$mapping" | cut -d ' ' -f1 | sed -e 's/\./\\\./g')
dest=$(echo "$mapping" | cut -d ' ' -f2)
classes=$(echo "$mapping" | cut -d ' ' -f3-)
for clazz in $classes;
do
classes_expressions+="-e s/$src\.$clazz/$dest.$clazz/g "
done
done <<< "$CLASS_MAPPINGS"

# create expressions for package mappings
packages_expressions=''
while read -r mapping;
do
src=$(echo "$mapping" | cut -d ' ' -f1 | sed -e 's/\./\\\./g')
dest=$(echo "$mapping" | cut -d ' ' -f2)
packages_expressions+="-e s/$src/$dest/g "
done <<< "$PACKAGE_MAPPINGS"

# do search and replace with expressions in each selected file
while read -r file;
do
echo "migrating $file"
expr="$renaming_expressions $classes_expressions $packages_expressions"
$SED_CMD_INPLACE $expr $file
done <<< "$files"

# create expressions for dependencies in gradle files
EXOPLAYER_GROUP="com\.google\.android\.exoplayer"
MEDIA3_GROUP="androidx.media3"
dependency_expressions=""
while read -r mapping
do
OLD=$(echo "$mapping" | cut -d ' ' -f1 | sed -e 's/\./\\\./g')
NEW=$(echo "$mapping" | cut -d ' ' -f2)
dependency_expressions="$dependency_expressions -e s/$EXOPLAYER_GROUP:$OLD:.*\"/$MEDIA3_GROUP:$NEW:$MEDIA3_VERSION\"/g -e s/$EXOPLAYER_GROUP:$OLD:.*'/$MEDIA3_GROUP:$NEW:$MEDIA3_VERSION'/"
done <<< "$DEPENDENCY_MAPPINGS"

## do search and replace for dependencies in gradle files
while read -r build_file;
do
echo "migrating build file $build_file"
$SED_CMD_INPLACE $dependency_expressions $build_file
done <<< "$(find . -type f -name 'build\.gradle')"

0 comments on commit 6180035

Please sign in to comment.