Created
December 10, 2015 03:26
-
-
Save bendman/23f7b7e9905106c4ed48 to your computer and use it in GitHub Desktop.
Fix broken symlink binaries to be relative symlinks
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Find symlinks that don't work and fix them. | |
// | |
// This is done by: | |
// 1. Getting a list of all file paths in a directory | |
// 2. Filtering for broken symlinks by reading binary content as unicode | |
// 5. Determining relative path between source and target | |
// 6. Deleting old link file | |
// 7. Creating new relative link file | |
var fs = require('fs'); | |
var path = require('path'); | |
var SYMLINK_ROOT = '!<symlink>/home/Piotr/SVN/freedict/trunk/'; | |
var BROKEN_SYMLINK_PREFIX = /!<symlink>��/; | |
var SKIPPED_FILES = /(\.git|symlinkFixer)/; | |
var ROOT = path.resolve(__dirname, '.'); | |
var IGNORE_UNICODES = [ | |
0, // null | |
65533 // replacement | |
]; | |
// Start | |
recurseDirExecute(ROOT, function(err, filePath) { | |
fs.readFile(filePath, 'utf8', function(err, data) { | |
err && console.log(err); | |
// Filter for broken symlinks | |
if (data.match(BROKEN_SYMLINK_PREFIX)) { | |
var content = getCleanString(data); | |
var targetAbsPath = path.resolve(ROOT, content.replace(SYMLINK_ROOT, './')); | |
handleSymlink(path.resolve(ROOT, filePath), targetAbsPath); | |
} | |
}); | |
}); | |
function handleSymlink(filePath, targetPath) { | |
var relativePath = path.relative(path.resolve(filePath, '..'), targetPath); | |
if (!relativePath.match('../')) return; | |
// console.log('file', relativePath); | |
fs.unlink(filePath, function(err) { | |
if (err) console.error('unlink error:', err); | |
fs.symlink(relativePath, filePath, function(err) { | |
if (err) console.error('symlink error:', err); | |
}); | |
}); | |
} | |
// | |
// Utilities | |
// | |
function recurseDirExecute(dirPath, done) { | |
dirExecute(dirPath, function(err, innerPath) { | |
if (err) { | |
console.error('dirExecute Error:', err); | |
return; | |
} | |
fs.stat(innerPath, function(err, stats) { | |
// handle errors | |
if (err) { | |
console.error('Stat Error:', err); | |
return; | |
} | |
if (innerPath.match(SKIPPED_FILES)) { | |
// skip certain files | |
return; | |
} else if (stats && stats.isDirectory()) { | |
// recurse directories | |
recurseDirExecute(path.join(innerPath), done); | |
} else { | |
// execute remaining | |
done(err, innerPath); | |
} | |
}); | |
}); | |
} | |
function dirExecute(dirpath, done) { | |
fs.readdir(dirpath, function(err, files) { | |
files.forEach(function(file) { | |
done(err, path.join(dirpath, file)); | |
}); | |
}); | |
} | |
function getCleanString(string) { | |
var charCodes = Array.prototype.map.call(string, function(char) { | |
return char.charCodeAt(); | |
}).filter(function(charCode) { | |
return (IGNORE_UNICODES.indexOf(charCode) === -1); | |
}); | |
return String.fromCharCode.apply(String, charCodes); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment