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# | ||||
|  | ||||
| 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 | ||||
|  | ||||
| - [@ProfessionalUwU](http://192.168.0.69:3000/ProfessionalUwU) | ||||
| @@ -46,11 +48,20 @@ Run executable | ||||
| ```bash | ||||
|   ./update | ||||
| ``` | ||||
| ## Roadmap | ||||
| ## Roadmap/ToDo | ||||
|  | ||||
| - Figure out how to do options/arguments | ||||
| - Backup important files | ||||
| - Figure out how to make a single executable | ||||
| - Backup all necessary files | ||||
| - 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 | ||||
|  | ||||
| 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> | ||||
|     <OutputType>Exe</OutputType> | ||||
|     <TargetFramework>net7.0</TargetFramework> | ||||
|     <RootNamespace>Update_csharp</RootNamespace> | ||||
|     <PublishSingleFile>true</PublishSingleFile> | ||||
|     <SelfContained>true</SelfContained> | ||||
|     <RuntimeIdentifier>linux-x64</RuntimeIdentifier> | ||||
|     <PublishReadyToRun>true</PublishReadyToRun> | ||||
|     <PublishTrimmed>true</PublishTrimmed> | ||||
|     <ImplicitUsings>enable</ImplicitUsings> | ||||
|     <Nullable>enable</Nullable> | ||||
|   </PropertyGroup> | ||||
| 
 | ||||
|   <ItemGroup> | ||||
|     <ProjectReference Include="..\Update-csharp.Tests\Update-csharp.Tests.csproj" /> | ||||
|     <Reference Include="System.IO.Compression" /> | ||||
|     <Reference Include="System.IO.Compression.ZipFile" /> | ||||
|   </ItemGroup> | ||||
| 
 | ||||
| </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