mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-14 09:25:43 +01:00
Merged in feature/migrate_lfs (pull request #275)
Migrate git LFS blob directory
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
package sonia.scm.update;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
|
||||
public interface BlobDirectoryAccess {
|
||||
|
||||
void forBlobDirectories(BlobDirectoryConsumer blobDirectoryConsumer) throws IOException;
|
||||
|
||||
void moveToRepositoryBlobStore(Path blobDirectory, String newDirectoryName, String repositoryId) throws IOException;
|
||||
|
||||
interface BlobDirectoryConsumer {
|
||||
void accept(Path directory) throws IOException;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package sonia.scm.store;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import sonia.scm.SCMContextProvider;
|
||||
import sonia.scm.repository.RepositoryLocationResolver;
|
||||
import sonia.scm.update.BlobDirectoryAccess;
|
||||
import sonia.scm.util.IOUtil;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class DefaultBlobDirectoryAccess implements BlobDirectoryAccess {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(DefaultBlobDirectoryAccess.class);
|
||||
|
||||
private final SCMContextProvider contextProvider;
|
||||
private final RepositoryLocationResolver locationResolver;
|
||||
|
||||
@Inject
|
||||
public DefaultBlobDirectoryAccess(SCMContextProvider contextProvider, RepositoryLocationResolver locationResolver) {
|
||||
this.contextProvider = contextProvider;
|
||||
this.locationResolver = locationResolver;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forBlobDirectories(BlobDirectoryConsumer blobDirectoryConsumer) throws IOException {
|
||||
Path v1blobDir = computeV1BlobDir();
|
||||
if (Files.exists(v1blobDir) && Files.isDirectory(v1blobDir)) {
|
||||
try (Stream<Path> fileStream = Files.list(v1blobDir)) {
|
||||
fileStream.filter(p -> Files.isDirectory(p)).forEach(p -> {
|
||||
try {
|
||||
blobDirectoryConsumer.accept(p);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("could not call consumer for blob directory " + p, e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moveToRepositoryBlobStore(Path blobDirectory, String newDirectoryName, String repositoryId) throws IOException {
|
||||
Path repositoryLocation;
|
||||
try {
|
||||
repositoryLocation = locationResolver
|
||||
.forClass(Path.class)
|
||||
.getLocation(repositoryId);
|
||||
} catch (IllegalStateException e) {
|
||||
LOG.info("ignoring blob directory {} because there is no repository location for repository id {}", blobDirectory, repositoryId);
|
||||
return;
|
||||
}
|
||||
Path target = repositoryLocation
|
||||
.resolve(Store.BLOB.getRepositoryStoreDirectory());
|
||||
IOUtil.mkdirs(target.toFile());
|
||||
Path resolvedSourceDirectory = computeV1BlobDir().resolve(blobDirectory);
|
||||
Path resolvedTargetDirectory = target.resolve(newDirectoryName);
|
||||
LOG.trace("moving directory {} to {}", resolvedSourceDirectory, resolvedTargetDirectory);
|
||||
Files.move(resolvedSourceDirectory, resolvedTargetDirectory);
|
||||
}
|
||||
|
||||
private Path computeV1BlobDir() {
|
||||
return contextProvider.getBaseDirectory().toPath().resolve("var").resolve("blob");
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,6 @@ public class JAXBPropertyFileAccess implements PropertyFileAccess {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(JAXBPropertyFileAccess.class);
|
||||
|
||||
public static final String XML_FILENAME_SUFFIX = ".xml";
|
||||
private final SCMContextProvider contextProvider;
|
||||
private final RepositoryLocationResolver locationResolver;
|
||||
|
||||
@@ -31,8 +30,8 @@ public class JAXBPropertyFileAccess implements PropertyFileAccess {
|
||||
public Target renameGlobalConfigurationFrom(String oldName) {
|
||||
return newName -> {
|
||||
Path configDir = contextProvider.getBaseDirectory().toPath().resolve(StoreConstants.CONFIG_DIRECTORY_NAME);
|
||||
Path oldConfigFile = configDir.resolve(oldName + XML_FILENAME_SUFFIX);
|
||||
Path newConfigFile = configDir.resolve(newName + XML_FILENAME_SUFFIX);
|
||||
Path oldConfigFile = configDir.resolve(oldName + StoreConstants.FILE_EXTENSION);
|
||||
Path newConfigFile = configDir.resolve(newName + StoreConstants.FILE_EXTENSION);
|
||||
Files.move(oldConfigFile, newConfigFile);
|
||||
};
|
||||
}
|
||||
@@ -45,7 +44,7 @@ public class JAXBPropertyFileAccess implements PropertyFileAccess {
|
||||
Path v1storeDir = computeV1StoreDir();
|
||||
if (Files.exists(v1storeDir) && Files.isDirectory(v1storeDir)) {
|
||||
try (Stream<Path> fileStream = Files.list(v1storeDir)) {
|
||||
fileStream.filter(p -> p.toString().endsWith(XML_FILENAME_SUFFIX)).forEach(p -> {
|
||||
fileStream.filter(p -> p.toString().endsWith(StoreConstants.FILE_EXTENSION)).forEach(p -> {
|
||||
try {
|
||||
String storeName = extractStoreName(p);
|
||||
storeFileConsumer.accept(p, storeName);
|
||||
@@ -84,7 +83,7 @@ public class JAXBPropertyFileAccess implements PropertyFileAccess {
|
||||
|
||||
private String extractStoreName(Path p) {
|
||||
String fileName = p.getFileName().toString();
|
||||
return fileName.substring(0, fileName.length() - XML_FILENAME_SUFFIX.length());
|
||||
return fileName.substring(0, fileName.length() - StoreConstants.FILE_EXTENSION.length());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
package sonia.scm.web.lfs;
|
||||
|
||||
import sonia.scm.migration.UpdateStep;
|
||||
import sonia.scm.plugin.Extension;
|
||||
import sonia.scm.update.BlobDirectoryAccess;
|
||||
import sonia.scm.version.Version;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.nio.file.Path;
|
||||
|
||||
@Extension
|
||||
public class LfsV1UpdateStep implements UpdateStep {
|
||||
|
||||
private final BlobDirectoryAccess blobDirectoryAccess;
|
||||
|
||||
@Inject
|
||||
public LfsV1UpdateStep(BlobDirectoryAccess blobDirectoryAccess) {
|
||||
this.blobDirectoryAccess = blobDirectoryAccess;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doUpdate() throws Exception {
|
||||
blobDirectoryAccess.forBlobDirectories(
|
||||
f -> {
|
||||
Path v1Directory = f.getFileName();
|
||||
String v1DirectoryName = v1Directory.toString();
|
||||
if (v1DirectoryName.endsWith("-git-lfs")) {
|
||||
blobDirectoryAccess.moveToRepositoryBlobStore(f, v1DirectoryName, v1DirectoryName.substring(0, v1DirectoryName.length() - "-git-lfs".length()));
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Version getTargetVersion() {
|
||||
return Version.parse("2.0.0");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAffectedDataType() {
|
||||
return "sonia.scm.git.lfs";
|
||||
}
|
||||
}
|
||||
@@ -19,11 +19,13 @@ import sonia.scm.store.BlobStoreFactory;
|
||||
import sonia.scm.store.ConfigurationEntryStoreFactory;
|
||||
import sonia.scm.store.ConfigurationStoreFactory;
|
||||
import sonia.scm.store.DataStoreFactory;
|
||||
import sonia.scm.store.DefaultBlobDirectoryAccess;
|
||||
import sonia.scm.store.FileBlobStoreFactory;
|
||||
import sonia.scm.store.JAXBConfigurationEntryStoreFactory;
|
||||
import sonia.scm.store.JAXBConfigurationStoreFactory;
|
||||
import sonia.scm.store.JAXBDataStoreFactory;
|
||||
import sonia.scm.store.JAXBPropertyFileAccess;
|
||||
import sonia.scm.update.BlobDirectoryAccess;
|
||||
import sonia.scm.update.PropertyFileAccess;
|
||||
import sonia.scm.update.V1PropertyDAO;
|
||||
import sonia.scm.update.xml.XmlV1PropertyDAO;
|
||||
@@ -65,6 +67,7 @@ public class BootstrapModule extends AbstractModule {
|
||||
bind(PluginLoader.class).toInstance(pluginLoader);
|
||||
bind(V1PropertyDAO.class, XmlV1PropertyDAO.class);
|
||||
bind(PropertyFileAccess.class, JAXBPropertyFileAccess.class);
|
||||
bind(BlobDirectoryAccess.class, DefaultBlobDirectoryAccess.class);
|
||||
}
|
||||
|
||||
private <T> void bind(Class<T> clazz, Class<? extends T> defaultImplementation) {
|
||||
|
||||
Reference in New Issue
Block a user