Compare commits
14 Commits
9c05f3ac83
...
rewrite
Author | SHA1 | Date | |
---|---|---|---|
66418b57c0 | |||
688da54ceb
|
|||
787722e72a
|
|||
962a1cb808
|
|||
58ae26b4f7 | |||
e07cdcfeb0 | |||
eb2b1edf29 | |||
8a0c93172c | |||
378c907146 | |||
21b61759d6 | |||
ed5286435a | |||
ebf5b9e304 | |||
fd07d1ce74 | |||
263f69b2b8 |
22
Program.cs
22
Program.cs
@ -1,22 +0,0 @@
|
|||||||
using System.Diagnostics;
|
|
||||||
|
|
||||||
string homePath;
|
|
||||||
if(Environment.OSVersion.Platform == PlatformID.Unix) {
|
|
||||||
homePath = Environment.GetEnvironmentVariable("HOME");
|
|
||||||
} else {
|
|
||||||
Console.WriteLine("This script doesn't support your operating system.");
|
|
||||||
}
|
|
||||||
|
|
||||||
Process process = new Process();
|
|
||||||
|
|
||||||
ProcessStartInfo processStartInfo = new ProcessStartInfo();
|
|
||||||
//processStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
|
|
||||||
processStartInfo.FileName = @"yay";
|
|
||||||
//processStartInfo.WorkingDirectory = homePath;
|
|
||||||
//processStartInfo.Arguments = "--color";
|
|
||||||
processStartInfo.RedirectStandardOutput = false;
|
|
||||||
processStartInfo.RedirectStandardError = false;
|
|
||||||
processStartInfo.UseShellExecute = true;
|
|
||||||
|
|
||||||
process.StartInfo = processStartInfo;
|
|
||||||
process.Start();
|
|
17
README.md
17
README.md
@ -1,6 +1,8 @@
|
|||||||
# update-c#
|
# update-c#
|
||||||
|
|
||||||
A rewrite of the legendary update script in C#
|
A rewrite of the legendary update script in C#
|
||||||
|
|
||||||
|
This time with file handling entirely in C# while keeping all scripting parts in bash.
|
||||||
## Authors
|
## Authors
|
||||||
|
|
||||||
- [@ProfessionalUwU](http://192.168.0.69:3000/ProfessionalUwU)
|
- [@ProfessionalUwU](http://192.168.0.69:3000/ProfessionalUwU)
|
||||||
@ -46,11 +48,20 @@ Run executable
|
|||||||
```bash
|
```bash
|
||||||
./update
|
./update
|
||||||
```
|
```
|
||||||
## Roadmap
|
## Roadmap/ToDo
|
||||||
|
|
||||||
- Figure out how to do options/arguments
|
- Figure out how to do options/arguments
|
||||||
- Backup important files
|
- Backup all necessary files
|
||||||
- Figure out how to make a single executable
|
- Hopefully shrink size of the executable
|
||||||
|
- Potentially speed up file handling
|
||||||
|
- Color output according to state (success = green, failure = red, info = yellow)
|
||||||
|
- Option to change backup location (instead of home)
|
||||||
|
- Keep backups for a configurable amount of days
|
||||||
|
|
||||||
|
## Sites I used to help make this project
|
||||||
|
- [dotnetperls](https://dotnetperls.com)
|
||||||
|
- [stackoverflow](https://stackoverflow.com/questions/tagged/c%23)
|
||||||
|
- [c-sharpcorner](https://www.c-sharpcorner.com)
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
Contributions are always welcome!
|
Contributions are always welcome!
|
||||||
|
31
justfile
Normal file
31
justfile
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
default:
|
||||||
|
@just --list
|
||||||
|
|
||||||
|
project_name := `printf '%s\n' "${PWD##*/}"`
|
||||||
|
uppercase_project_name := capitalize(project_name)
|
||||||
|
|
||||||
|
setup:
|
||||||
|
@mkdir src
|
||||||
|
@dotnet new sln --name src/{{project_name}}
|
||||||
|
@dotnet new classlib -o src/{{uppercase_project_name}}
|
||||||
|
@dotnet new xunit -o src/{{uppercase_project_name}}.Tests
|
||||||
|
@dotnet sln add src/{{uppercase_project_name}}/{{uppercase_project_name}}.csproj
|
||||||
|
@dotnet sln add src/{{uppercase_project_name}}.Tests/{{uppercase_project_name}}.Tests.csproj
|
||||||
|
@dotnet add src/{{uppercase_project_name}}/{{uppercase_project_name}}.csproj reference src/{{uppercase_project_name}}.Tests/{{uppercase_project_name}}.Tests.csproj
|
||||||
|
|
||||||
|
run:
|
||||||
|
@dotnet run
|
||||||
|
|
||||||
|
build:
|
||||||
|
@dotnet build src/{{uppercase_project_name}}/{{uppercase_project_name}}.csproj
|
||||||
|
@dotnet build src/{{uppercase_project_name}}.Tests/{{uppercase_project_name}}.Tests.csproj
|
||||||
|
|
||||||
|
publish:
|
||||||
|
@dotnet publish --configuration Release src/{{uppercase_project_name}}/{{uppercase_project_name}}.csproj
|
||||||
|
|
||||||
|
format:
|
||||||
|
@dotnet format src/{{uppercase_project_name}}
|
||||||
|
@dotnet format src/{{uppercase_project_name}}.Tests
|
||||||
|
|
||||||
|
test: build
|
||||||
|
@dotnet test src/{{uppercase_project_name}}.Tests
|
10
src/Update-csharp.Tests/UnitTest1.cs
Normal file
10
src/Update-csharp.Tests/UnitTest1.cs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
namespace Update_csharp.Tests;
|
||||||
|
|
||||||
|
public class UnitTest1
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void Test1()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
25
src/Update-csharp.Tests/Update-csharp.Tests.csproj
Normal file
25
src/Update-csharp.Tests/Update-csharp.Tests.csproj
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
|
<RootNamespace>Update_csharp.Tests</RootNamespace>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
|
||||||
|
<PackageReference Include="xunit" Version="2.4.2" />
|
||||||
|
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="coverlet.collector" Version="3.1.2">
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
</PackageReference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
1
src/Update-csharp.Tests/Usings.cs
Normal file
1
src/Update-csharp.Tests/Usings.cs
Normal file
@ -0,0 +1 @@
|
|||||||
|
global using Xunit;
|
128
src/Update-csharp/Program.cs
Normal file
128
src/Update-csharp/Program.cs
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
public class Program {
|
||||||
|
static void Main(string[] args) {
|
||||||
|
var exitCommand = "nothing";
|
||||||
|
string backupLocation = "/home/rene/";
|
||||||
|
var pacmanWrapper = "yay";
|
||||||
|
var backupAmount = 2;
|
||||||
|
|
||||||
|
if (args.Length == 0) {
|
||||||
|
beforeUpdate();
|
||||||
|
Console.WriteLine(pacmanWrapper);
|
||||||
|
afterUpdate();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string arg = args[0].TrimStart('-');;
|
||||||
|
if (args[0].StartsWith("--")) {
|
||||||
|
switch (arg) {
|
||||||
|
case "help":
|
||||||
|
Console.WriteLine(help());
|
||||||
|
break;
|
||||||
|
case "preview":
|
||||||
|
// need to execute 'yay -Sy && yay -Qu'
|
||||||
|
break;
|
||||||
|
case "version":
|
||||||
|
Console.WriteLine("version");
|
||||||
|
break;
|
||||||
|
case "backup":
|
||||||
|
beforeUpdate();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
beforeUpdate();
|
||||||
|
|
||||||
|
foreach (var option in arg) {
|
||||||
|
switch (option) {
|
||||||
|
case 'f':
|
||||||
|
// flatpak update -u --noninteractive && flatpak list > "$TMP"/after-backup_"$DATE"/flatpak-after.txt
|
||||||
|
Console.WriteLine("flatpak update");
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
// "$PACMAN_WRAPPER" && pacman -Qq > "$TMP"/after-backup_"$DATE"/pacman-after.txt
|
||||||
|
Console.WriteLine(pacmanWrapper);
|
||||||
|
break;
|
||||||
|
case 'a':
|
||||||
|
// 'p' && 'f'
|
||||||
|
Console.WriteLine("flatpak update && " + pacmanWrapper);
|
||||||
|
break;
|
||||||
|
case 'g':
|
||||||
|
if (args[0].TrimStart('-') == "g") {
|
||||||
|
Console.WriteLine(pacmanWrapper);
|
||||||
|
}
|
||||||
|
exitCommand = "systemctl -i poweroff";
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
if (args[0].TrimStart('-') == "r") {
|
||||||
|
Console.WriteLine(pacmanWrapper);
|
||||||
|
}
|
||||||
|
exitCommand = "systemctl -i reboot";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
help();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
afterUpdate();
|
||||||
|
|
||||||
|
void readConfig() {
|
||||||
|
backupLocation = "/mnt/Hephaistos/update/";
|
||||||
|
pacmanWrapper = "yay";
|
||||||
|
backupAmount = 2;
|
||||||
|
|
||||||
|
if (!Directory.Exists(backupLocation)) {
|
||||||
|
Console.WriteLine("update-csharp: Backup location does not exist or cannot be reached");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//find the amount of backups in the backupLocation and delete the oldest
|
||||||
|
void deleteOldestBackup() {
|
||||||
|
Console.WriteLine(backupAmount);
|
||||||
|
}
|
||||||
|
|
||||||
|
void beforeUpdate() {
|
||||||
|
readConfig();
|
||||||
|
deleteOldestBackup();
|
||||||
|
|
||||||
|
Update.backup("before");
|
||||||
|
Update.zipPacmanDatabase();
|
||||||
|
Update.copyToBackupLocation(backupLocation);
|
||||||
|
|
||||||
|
Console.ForegroundColor = ConsoleColor.Green;
|
||||||
|
Console.WriteLine("pre-backup complete");
|
||||||
|
Console.ResetColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
void afterUpdate() {
|
||||||
|
Update.backup("after");
|
||||||
|
Update.copyToBackupLocation(backupLocation);
|
||||||
|
Directory.Delete("/tmp/update", true);
|
||||||
|
|
||||||
|
Console.ForegroundColor = ConsoleColor.Green;
|
||||||
|
Console.WriteLine("after-backup complete");
|
||||||
|
Console.ResetColor();
|
||||||
|
Console.WriteLine(exitCommand); // execute exitCommand
|
||||||
|
}
|
||||||
|
|
||||||
|
string help() {
|
||||||
|
string helpMessage = "Usage: update [OPTION]\n";
|
||||||
|
helpMessage += "\noptions:\n";
|
||||||
|
helpMessage += "no flag same as -p\n";
|
||||||
|
helpMessage += "-f updates using flatpak update only\n";
|
||||||
|
helpMessage += "-p updates using a pacman-wrapper only\n";
|
||||||
|
helpMessage += "-a updates using flatpak update and a pacman-wrapper\n";
|
||||||
|
helpMessage += "-g shutdowns the computer afterwards\n";
|
||||||
|
helpMessage += "-r reboots the computer afterwards\n";
|
||||||
|
helpMessage += "--help displays this message\n";
|
||||||
|
helpMessage += "--preview shows a preview of which pkg's can be updated\n";
|
||||||
|
helpMessage += "--version prints out the version number\n";
|
||||||
|
helpMessage += "--backup just does the pre-backup without updating";
|
||||||
|
return helpMessage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -3,12 +3,19 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>net7.0</TargetFramework>
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
|
<RootNamespace>Update_csharp</RootNamespace>
|
||||||
<PublishSingleFile>true</PublishSingleFile>
|
<PublishSingleFile>true</PublishSingleFile>
|
||||||
<SelfContained>true</SelfContained>
|
<SelfContained>true</SelfContained>
|
||||||
<RuntimeIdentifier>linux-x64</RuntimeIdentifier>
|
<RuntimeIdentifier>linux-x64</RuntimeIdentifier>
|
||||||
<PublishReadyToRun>true</PublishReadyToRun>
|
<PublishTrimmed>true</PublishTrimmed>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Update-csharp.Tests\Update-csharp.Tests.csproj" />
|
||||||
|
<Reference Include="System.IO.Compression" />
|
||||||
|
<Reference Include="System.IO.Compression.ZipFile" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
115
src/Update-csharp/Update.cs
Normal file
115
src/Update-csharp/Update.cs
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO.Compression;
|
||||||
|
|
||||||
|
public class Update {
|
||||||
|
static string tmpDirectory = "/tmp/update/";
|
||||||
|
public static void backup(string mode) {
|
||||||
|
string backupDir;
|
||||||
|
string pkgList;
|
||||||
|
string flatpakList;
|
||||||
|
List<string> filesToCopy = new List<string>();
|
||||||
|
string zipName;
|
||||||
|
|
||||||
|
switch (mode) {
|
||||||
|
case "before":
|
||||||
|
backupDir = tmpDirectory + "beforeBackup";
|
||||||
|
pkgList = backupDir + "pacman-pre.txt";
|
||||||
|
flatpakList = backupDir + "flatpak-pre.txt";
|
||||||
|
filesToCopy.Add("/etc/fstab");
|
||||||
|
filesToCopy.Add("/etc/makepkg.conf");
|
||||||
|
zipName = tmpDirectory + "beforeBackup.zip";
|
||||||
|
break;
|
||||||
|
case "after":
|
||||||
|
backupDir = tmpDirectory + "afterBackup";
|
||||||
|
pkgList = backupDir + "pacman-after.txt";
|
||||||
|
flatpakList = backupDir + "flatpak-after.txt";
|
||||||
|
zipName = tmpDirectory + "afterBackup.zip";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ArgumentException("No valid mode was given. Valid modes are before and after");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Directory.Exists(tmpDirectory)) {
|
||||||
|
Directory.Delete(tmpDirectory, true);
|
||||||
|
}
|
||||||
|
Directory.CreateDirectory(backupDir);
|
||||||
|
|
||||||
|
foreach (var file in filesToCopy) {
|
||||||
|
FileInfo info = new FileInfo(file);
|
||||||
|
string destFile = Path.Combine(backupDir, info.Name);
|
||||||
|
File.Copy(info.FullName, destFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
ZipFile.CreateFromDirectory(backupDir, zipName);
|
||||||
|
Directory.Delete(backupDir, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void copyToBackupLocation(string backupLocation) {
|
||||||
|
foreach (var zip in Directory.GetFiles(tmpDirectory)) {
|
||||||
|
FileInfo info = new FileInfo(zip);
|
||||||
|
string destFile = Path.Combine(backupLocation, info.Name);
|
||||||
|
File.Copy(info.FullName, destFile, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void zipPacmanDatabase() {
|
||||||
|
string pacmanDatabaseLocation = "/var/lib/pacman/local";
|
||||||
|
string zipName = tmpDirectory + "pacmanDatabase.zip";
|
||||||
|
|
||||||
|
if(dbLockExists()) {
|
||||||
|
throw new ApplicationException("db.lck exists. Please try again later.");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
lockDatabase();
|
||||||
|
|
||||||
|
ZipFile.CreateFromDirectory(pacmanDatabaseLocation, zipName);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Console.ForegroundColor = ConsoleColor.Red;
|
||||||
|
Console.WriteLine(e.Message);
|
||||||
|
} finally {
|
||||||
|
unlockDatabase();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool dbLockExists() {
|
||||||
|
if (File.Exists("/var/lib/pacman/db.lck")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void lockDatabase() {
|
||||||
|
var psi = new ProcessStartInfo
|
||||||
|
{
|
||||||
|
FileName = "/bin/bash",
|
||||||
|
UseShellExecute = false,
|
||||||
|
RedirectStandardOutput = true,
|
||||||
|
Arguments = string.Format("-c \"cd /var/lib/pacman/ && sudo touch db.lck && sudo chmod 000 db.lck\"")
|
||||||
|
};
|
||||||
|
|
||||||
|
using (var p = Process.Start(psi))
|
||||||
|
{
|
||||||
|
if (p != null)
|
||||||
|
{
|
||||||
|
var strOutput = p.StandardOutput.ReadToEnd();
|
||||||
|
p.WaitForExit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void unlockDatabase() {
|
||||||
|
var psi = new ProcessStartInfo {
|
||||||
|
FileName = "/bin/bash",
|
||||||
|
UseShellExecute = false,
|
||||||
|
RedirectStandardOutput = true,
|
||||||
|
Arguments = string.Format("-c \"cd /var/lib/pacman/ && sudo rm -f db.lck\"")
|
||||||
|
};
|
||||||
|
using (var p = Process.Start(psi)) {
|
||||||
|
if (p != null) {
|
||||||
|
var strOutput = p.StandardOutput.ReadToEnd();
|
||||||
|
p.WaitForExit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
28
src/update-csharp.sln
Normal file
28
src/update-csharp.sln
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 17
|
||||||
|
VisualStudioVersion = 17.0.31903.59
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Update-csharp", "Update-csharp\Update-csharp.csproj", "{6FE9BE72-7118-4CC5-AC47-20F5E145FA67}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Update-csharp.Tests", "Update-csharp.Tests\Update-csharp.Tests.csproj", "{F66860FA-9516-458E-87F3-245AC885AB96}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{6FE9BE72-7118-4CC5-AC47-20F5E145FA67}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{6FE9BE72-7118-4CC5-AC47-20F5E145FA67}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{6FE9BE72-7118-4CC5-AC47-20F5E145FA67}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{6FE9BE72-7118-4CC5-AC47-20F5E145FA67}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{F66860FA-9516-458E-87F3-245AC885AB96}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{F66860FA-9516-458E-87F3-245AC885AB96}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{F66860FA-9516-458E-87F3-245AC885AB96}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{F66860FA-9516-458E-87F3-245AC885AB96}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
Reference in New Issue
Block a user