Skip to content

Instantly share code, notes, and snippets.

@jaredly
Last active September 27, 2021 18:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jaredly/284d8b200cd676b0c98615acb5e94e88 to your computer and use it in GitHub Desktop.
Save jaredly/284d8b200cd676b0c98615acb5e94e88 to your computer and use it in GitHub Desktop.
A nice little script for converting gradle dependencies from some external source (ahem jcenter) to a local maven repository.
// Based on info from this post https://brightinventions.pl/blog/migrating-away-from-bintray-jcenter-when-there-is-no-alternative-repository/#setting-up-a-local-maven-repository
/**
* How to use this tool:
* 1. comment out `jcenter()` in your build.gradle
* 2. run `./gradlew :app:dependencies > deps.log`
* 3. mkdir `local-maven`
* 4. add `maven { url = uri("${rootProject.projectDir}/local-maven") }`
* right before the commented-out `jcenter()` calls in your build.gradle.
* 5. run `node missing-deps-to-local.js ./local-maven < deps.log`
* 6. run `./gradlew :app:dependencies > deps.log`
* 7. inspect `deps.log`. If there are still `FAILED` deps, do 5 & 6 again until all have been copied over.
*/
const path = require('path')
const fs = require('fs')
const gradleCache = `${process.env.HOME}/.gradle/caches/modules-2/files-2.1/`
const dest = process.argv[2]
console.log(`Copying into ${dest}`)
if (!fs.existsSync(dest) || !fs.statSync(dest).isDirectory()) {
throw new Error(`${dest} doesn't exist or isn't a directory`)
}
const parseLine = (line) => {
const parts = line.split(/\s+/)
// The format reported by :app:dependencies has a lot of `| | +----` ascii art.
.filter(part => part !== '|' && !part.match(/^[+\\]-+$/));
if (parts[parts.length - 1] != 'FAILED') {
throw new Error(`not failed - how did we get here: ${line}`)
}
let [org, package, version] = parts[0].split(':')
if (!org || !package || !version) {
throw new Error(`Unexpected dependency format ${parts[0]}`)
}
// If it's of the format com.some:thing:1.2.0 -> 1.3.0, we want to use 1.3.0 as the version
if (parts[1] === '->') {
version = parts[2]
}
return {parts, org, package, version}
}
const copyDep = ({parts, org, package, version}) => {
const cacheBase = path.join(gradleCache, org, package, version)
if (!fs.existsSync(cacheBase)) {
throw new Error(`Dep not cached: ${dep.join(':')}, not found at ${cacheBase} - ${parts.join('~')}`)
}
const mavenDest = path.join(dest, ...org.split('.'), package, version)
if (!fs.existsSync(mavenDest)) {
fs.mkdirSync(mavenDest, {recursive: true})
}
fs.readdirSync(cacheBase).forEach(hash => {
fs.readdirSync(path.join(cacheBase, hash)).forEach(name => {
console.log(`${cacheBase}/${hash}/${name} -> ${mavenDest}/${name}`)
fs.copyFileSync(path.join(cacheBase, hash, name), path.join(mavenDest, name))
})
})
}
const getStdin = (done) => {
var content = '';
process.stdin.resume();
process.stdin.on('data', (buf) => { content += buf.toString(); });
process.stdin.on('end', () => done(content));
}
getStdin(text => {
const missing = text.split('\n').filter(line => line.endsWith('FAILED')).map(parseLine)
missing.map(copyDep)
if (!missing.length) {
console.log(`All done! No missing dependencies reported.`)
}
})
@jaredly
Copy link
Author

jaredly commented Sep 27, 2021

NOTE: if you get errors about a missing .jar, but you have an .aar, you might be able to use mvn to install the .aar to make things happy.
For example:

mvn install:install-file -Dfile=~/.gradle/caches/modules-2/files-2.1/tools.fastlane/screengrab/0.5.6/screengrab-0.5.6.aar -DgroupId=tools.fastlane -DartifactId=screengrab -Dversion=0.5.6 -Dpackaging=aar -DlocalRepositoryPath=local-maven

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment