App
This commit is contained in:
24
src/Alma.App/Command/Help/HelpCommand.cs
Normal file
24
src/Alma.App/Command/Help/HelpCommand.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
namespace Alma.Command.Help;
|
||||
|
||||
public class HelpCommand : ICommand
|
||||
{
|
||||
private readonly Func<IEnumerable<ICommand>> _commandsProvider;
|
||||
public string CommandString => "help";
|
||||
|
||||
public HelpCommand(Func<IEnumerable<ICommand>> commandsProvider)
|
||||
{
|
||||
_commandsProvider = commandsProvider;
|
||||
}
|
||||
|
||||
public Task Run(List<string> parameters)
|
||||
{
|
||||
Console.WriteLine("Commands:" + Environment.NewLine);
|
||||
|
||||
foreach (var command in _commandsProvider().OrderBy(c => c.CommandString))
|
||||
{
|
||||
Console.WriteLine(command.CommandString);
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
10
src/Alma.App/Command/Info/ModuleInfoCommand.cs
Normal file
10
src/Alma.App/Command/Info/ModuleInfoCommand.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
namespace Alma.Command.Info;
|
||||
|
||||
public class ModuleInfoCommand : ICommand
|
||||
{
|
||||
public string CommandString => "info";
|
||||
public Task Run(List<string> parameters)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
193
src/Alma.App/Command/Link/LinkCommand.cs
Normal file
193
src/Alma.App/Command/Link/LinkCommand.cs
Normal file
@@ -0,0 +1,193 @@
|
||||
using Alma.Configuration.Module;
|
||||
using Alma.Configuration.Repository;
|
||||
using Alma.Data;
|
||||
using Alma.Services;
|
||||
|
||||
namespace Alma.Command.Link;
|
||||
|
||||
public class LinkCommand : ICommand
|
||||
{
|
||||
private readonly IRepositoryConfiguration _repositoryConfiguration;
|
||||
private readonly IModuleConfigurationResolver _moduleConfigurationResolver;
|
||||
private readonly IFolderService _folderService;
|
||||
private readonly IMetadataHandler _metadataHandler;
|
||||
public string CommandString => "link";
|
||||
|
||||
public LinkCommand(
|
||||
IRepositoryConfiguration repositoryConfiguration,
|
||||
IModuleConfigurationResolver moduleConfigurationResolver,
|
||||
IFolderService folderService,
|
||||
IMetadataHandler metadataHandler)
|
||||
{
|
||||
_repositoryConfiguration = repositoryConfiguration;
|
||||
_moduleConfigurationResolver = moduleConfigurationResolver;
|
||||
_folderService = folderService;
|
||||
_metadataHandler = metadataHandler;
|
||||
}
|
||||
|
||||
public async Task Run(List<string> parameters)
|
||||
{
|
||||
if (parameters.Count == 0)
|
||||
{
|
||||
Console.WriteLine("No module specified");
|
||||
return;
|
||||
}
|
||||
|
||||
string moduleName = parameters[0];
|
||||
|
||||
string sourceDirectory = Path.Combine(Environment.CurrentDirectory);
|
||||
string targetDirectory = Path.Combine(Environment.CurrentDirectory, "..");
|
||||
|
||||
var repoName = GetRepositoryName(parameters);
|
||||
if (repoName is not null
|
||||
&& _repositoryConfiguration.Configuration.Repositories.FirstOrDefault(r => r.Name == repoName) is { } repoConfig)
|
||||
{
|
||||
sourceDirectory = repoConfig.RepositoryPath ?? sourceDirectory;
|
||||
targetDirectory = repoConfig.LinkPath ?? targetDirectory;
|
||||
}
|
||||
|
||||
if (!Directory.Exists(sourceDirectory))
|
||||
{
|
||||
Console.WriteLine("Source directory not exists: " + sourceDirectory);
|
||||
return;
|
||||
}
|
||||
|
||||
string moduleNameAsPath = moduleName.Replace('/', Path.DirectorySeparatorChar);
|
||||
string moduleDirectory = Path.Combine(sourceDirectory, moduleNameAsPath);
|
||||
|
||||
if (!Directory.Exists(moduleDirectory))
|
||||
{
|
||||
Console.WriteLine("Module directory not exists: " + moduleDirectory);
|
||||
return;
|
||||
}
|
||||
|
||||
var moduleConfigFileStub = Path.Combine(moduleDirectory, Constants.ModuleConfigFileStub);
|
||||
var (moduleConfiguration, moduleConfigurationFile) = await _moduleConfigurationResolver.ResolveModuleConfiguration(moduleConfigFileStub);
|
||||
|
||||
if (moduleConfiguration?.Target is string moduleTargetDir)
|
||||
{
|
||||
targetDirectory = ResolvePath(moduleTargetDir, targetDirectory);
|
||||
}
|
||||
|
||||
if (!Directory.Exists(targetDirectory))
|
||||
{
|
||||
Directory.CreateDirectory(targetDirectory);
|
||||
}
|
||||
|
||||
var moduleConfigurationFileFullPath = moduleConfigurationFile is null ? null : Path.Combine(moduleDirectory, moduleConfigurationFile);
|
||||
|
||||
var moduleDir = new DirectoryInfo(moduleDirectory);
|
||||
var currentTargetDirectory = new DirectoryInfo(targetDirectory);
|
||||
var itemsToLink = (await TraverseTree(
|
||||
moduleDir,
|
||||
currentTargetDirectory,
|
||||
moduleDir,
|
||||
currentTargetDirectory,
|
||||
moduleConfiguration)).ToList();
|
||||
if (moduleConfigurationFile is not null) itemsToLink.RemoveAll(i => i.SourcePath == moduleConfigurationFileFullPath);
|
||||
|
||||
foreach (var itemToLink in itemsToLink)
|
||||
{
|
||||
Console.WriteLine($"Link: '{itemToLink.SourcePath}' '{itemToLink.TargetPath}'");
|
||||
}
|
||||
|
||||
var successfulLinks = CreateLinks(itemsToLink);
|
||||
|
||||
await _metadataHandler.SaveLinkedItemsAsync(successfulLinks, moduleDir, currentTargetDirectory);
|
||||
//await _metadataHandler.SaveLinkedItemsAsync(itemsToLink, moduleDir, currentTargetDirectory);
|
||||
}
|
||||
|
||||
private List<ItemToLink> CreateLinks(List<ItemToLink> itemsToLink)
|
||||
{
|
||||
var successfulLinks = new List<ItemToLink>();
|
||||
|
||||
foreach (var itemToLink in itemsToLink)
|
||||
{
|
||||
if (File.Exists(itemToLink.TargetPath) || Directory.Exists(itemToLink.TargetPath))
|
||||
{
|
||||
Console.WriteLine("Item already exists: " + itemToLink.TargetPath);
|
||||
continue;
|
||||
}
|
||||
|
||||
var sourceFileExists = File.Exists(itemToLink.SourcePath);
|
||||
var sourceDirectoryExists = Directory.Exists(itemToLink.SourcePath);
|
||||
|
||||
if (sourceFileExists)
|
||||
{
|
||||
File.CreateSymbolicLink(itemToLink.TargetPath, itemToLink.SourcePath);
|
||||
}
|
||||
else if (sourceDirectoryExists)
|
||||
{
|
||||
File.CreateSymbolicLink(itemToLink.TargetPath, itemToLink.SourcePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Source not exists: " + itemToLink.SourcePath);
|
||||
continue;
|
||||
}
|
||||
|
||||
successfulLinks.Add(itemToLink);
|
||||
}
|
||||
|
||||
return successfulLinks;
|
||||
}
|
||||
|
||||
private async Task<IEnumerable<ItemToLink>> TraverseTree(
|
||||
DirectoryInfo currentDirectory,
|
||||
DirectoryInfo currentTargetDirectory,
|
||||
DirectoryInfo moduleDirectory,
|
||||
DirectoryInfo targetDirectory,
|
||||
ModuleConfiguration? moduleConfiguration)
|
||||
{
|
||||
var filesToLink = new List<ItemToLink>();
|
||||
foreach (var file in currentDirectory.GetFiles())
|
||||
{
|
||||
filesToLink.Add(new ItemToLink(Path.Combine(currentDirectory.FullName, file.Name), Path.Combine(currentTargetDirectory.FullName, file.Name)));
|
||||
}
|
||||
|
||||
var subDirLinksToAdd = Enumerable.Empty<ItemToLink>();
|
||||
|
||||
foreach (var subDir in currentDirectory.GetDirectories())
|
||||
{
|
||||
var relativePath = GetRelativePath(subDir.FullName, moduleDirectory.FullName);
|
||||
if (moduleConfiguration?.Links?.ContainsKey(relativePath) ?? false)
|
||||
{
|
||||
filesToLink.Add(new ItemToLink(subDir.FullName, ResolvePath(moduleConfiguration.Links[relativePath], targetDirectory.FullName)));
|
||||
}
|
||||
else
|
||||
{
|
||||
var subDirLinks = await TraverseTree(
|
||||
subDir,
|
||||
new DirectoryInfo(Path.Combine(currentTargetDirectory.FullName, subDir.Name)),
|
||||
moduleDirectory,
|
||||
targetDirectory,
|
||||
moduleConfiguration
|
||||
);
|
||||
subDirLinksToAdd = subDirLinksToAdd.Concat(subDirLinks);
|
||||
}
|
||||
}
|
||||
|
||||
return filesToLink.Concat(subDirLinksToAdd);
|
||||
}
|
||||
|
||||
private static string? GetRepositoryName(List<string> parameters)
|
||||
{
|
||||
//TODO: handle parameters
|
||||
if (parameters.Count < 2) return null;
|
||||
return parameters[1];
|
||||
}
|
||||
|
||||
private static string ResolvePath(string path, string currentDirectory)
|
||||
{
|
||||
if (path.StartsWith("~"))
|
||||
{
|
||||
path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), path.Substring(2));
|
||||
}
|
||||
|
||||
//TODO: more special character
|
||||
|
||||
return Path.Combine(currentDirectory, path);
|
||||
}
|
||||
|
||||
private static string GetRelativePath(string full, string parent) => full.Substring(parent.Length).TrimStart(Path.DirectorySeparatorChar);
|
||||
}
|
||||
90
src/Alma.App/Command/List/ListCommand.cs
Normal file
90
src/Alma.App/Command/List/ListCommand.cs
Normal file
@@ -0,0 +1,90 @@
|
||||
using Alma.Configuration.Repository;
|
||||
using Alma.Data;
|
||||
using Alma.Services;
|
||||
|
||||
namespace Alma.Command.List;
|
||||
|
||||
public class ListCommand : ICommand
|
||||
{
|
||||
private readonly IRepositoryConfiguration _repositoryConfiguration;
|
||||
private readonly IModuleConfigurationResolver _moduleConfigurationResolver;
|
||||
public string CommandString => "ls";
|
||||
|
||||
public ListCommand(
|
||||
IRepositoryConfiguration repositoryConfiguration,
|
||||
IModuleConfigurationResolver moduleConfigurationResolver)
|
||||
{
|
||||
_repositoryConfiguration = repositoryConfiguration;
|
||||
_moduleConfigurationResolver = moduleConfigurationResolver;
|
||||
}
|
||||
|
||||
public async Task Run(List<string> parameters)
|
||||
{
|
||||
if (parameters.Count > 0)
|
||||
{
|
||||
await ListModulesByRepoName(parameters[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
await ListRepositories();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ListRepositories()
|
||||
{
|
||||
Console.WriteLine("Repositories:" + Environment.NewLine);
|
||||
foreach (var repository in _repositoryConfiguration.Configuration.Repositories)
|
||||
{
|
||||
Console.WriteLine(repository.Name);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ListModulesByRepoName(string repositoryName)
|
||||
{
|
||||
var repo = _repositoryConfiguration.Configuration.Repositories.FirstOrDefault(r => r.Name == repositoryName);
|
||||
if (repo is null)
|
||||
{
|
||||
Console.WriteLine($"No repository found with name '{repositoryName}'");
|
||||
return;
|
||||
}
|
||||
|
||||
if (repo.RepositoryPath is null)
|
||||
{
|
||||
Console.WriteLine($"No repository path is specified in repository settings '{repositoryName}'");
|
||||
return;
|
||||
}
|
||||
|
||||
await ListModules(repo.RepositoryPath, repositoryName);
|
||||
}
|
||||
|
||||
private async Task ListModules(string repositoryPath, string repositoryName)
|
||||
{
|
||||
var repositoryDirectory = new DirectoryInfo(repositoryPath);
|
||||
var moduleDirectories = await TraverseRepositoryFolder(repositoryDirectory);
|
||||
|
||||
Console.WriteLine($"Modules in repository '{repositoryName}':" + Environment.NewLine);
|
||||
foreach (var modulePath in moduleDirectories)
|
||||
{
|
||||
Console.WriteLine(modulePath.FullName.Substring(repositoryDirectory.FullName.Length).Replace(Path.DirectorySeparatorChar, '/'));
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<IEnumerable<DirectoryInfo>> TraverseRepositoryFolder(DirectoryInfo currentDirectory)
|
||||
{
|
||||
var moduleConfigFileStub = Path.Combine(currentDirectory.FullName, Constants.ModuleConfigFileStub);
|
||||
var (moduleConfiguration, moduleConfigurationFile) = await _moduleConfigurationResolver.ResolveModuleConfiguration(moduleConfigFileStub);
|
||||
|
||||
var result = Enumerable.Empty<DirectoryInfo>();
|
||||
if (moduleConfigurationFile is not null)
|
||||
{
|
||||
result = new List<DirectoryInfo> {currentDirectory};
|
||||
}
|
||||
|
||||
foreach (var subDir in currentDirectory.GetDirectories())
|
||||
{
|
||||
result = result.Concat(await TraverseRepositoryFolder(subDir));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
10
src/Alma.App/Command/Unlink/UnlinkCommand.cs
Normal file
10
src/Alma.App/Command/Unlink/UnlinkCommand.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
namespace Alma.Command.Unlink;
|
||||
|
||||
public class UnlinkCommand : ICommand
|
||||
{
|
||||
public string CommandString => "unlink";
|
||||
public Task Run(List<string> parameters)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user