Created
July 4, 2025 03:29
-
-
Save nvlled/1fd80822c92eb922231febc39dac1cd8 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
#!/usr/bin/env -S dotnet run | |
// About: This is tool to create a zip file from a directory. | |
// If no filename is given, it creates one in the temp directory. | |
// The --git option can be used to add only files committed with git. | |
// Example usages: | |
// $ zip-dir.cs ~/projects/example | |
// /tmp/tree-sitter-c-3483789584290746392.zip | |
// $ zip-dir.cs ~/projects/example example.zip | |
// $ zip-dir.cs ~/projects/example example.zip --git | |
// Dependencies: | |
// To run this script, dotnet must be installed (at least v10.0.0). | |
// If the --git is used, then git must also be installed. | |
using System.Diagnostics; | |
using System.IO.Compression; | |
using Microsoft.VisualBasic; | |
var gitFilesOnly = false; | |
void usage() | |
{ | |
var progName = Path.GetFileName(Environment.GetCommandLineArgs()[0]); | |
Console.WriteLine("usage: {0} <dir-to-zip> [dest-zip-filename] [--git]", progName); | |
Console.WriteLine(@" | |
Options: | |
--git : include git commited files only (requires git) | |
"); | |
Environment.Exit(1); | |
} | |
var posArgs = new List<string>(); | |
foreach (var arg in args) | |
{ | |
if (arg[0] != '-') | |
{ | |
posArgs.Add(arg); | |
continue; | |
} | |
switch (arg.TrimStart('-')) | |
{ | |
case "git": | |
gitFilesOnly = true; | |
break; | |
default: | |
usage(); | |
break; | |
} | |
} | |
if (posArgs.Count == 0) | |
{ | |
Console.WriteLine("directory name is required"); | |
usage(); | |
} | |
var srcDir = Path.TrimEndingDirectorySeparator(posArgs[0]); | |
string destFilename; | |
if (posArgs.Count >= 2) | |
{ | |
destFilename = Path.Combine(Directory.GetCurrentDirectory(), posArgs[1]); | |
if (Path.GetExtension(destFilename) != ".zip") | |
{ | |
Console.WriteLine("invalid destination filename: must have a .zip extension"); | |
usage(); | |
} | |
} | |
else | |
{ | |
var tempPath = Path.GetTempPath(); | |
var basename = Path.GetFileNameWithoutExtension(srcDir); | |
var id = Random.Shared.NextInt64().ToString(); | |
var filename = Path.ChangeExtension(basename + "-" + id, "zip"); | |
destFilename = Path.Combine(tempPath, filename); | |
} | |
Console.WriteLine(destFilename); | |
if (gitFilesOnly) | |
{ | |
Directory.SetCurrentDirectory(srcDir); | |
var info = new ProcessStartInfo() | |
{ | |
FileName = "git", | |
Arguments = string.Join(" ", "ls-files", srcDir), | |
CreateNoWindow = false, | |
}; | |
info.RedirectStandardOutput = true; | |
using (var proc = Process.Start(info)) | |
{ | |
var output = proc?.StandardOutput.ReadToEnd(); | |
var zip = ZipFile.Open(destFilename, ZipArchiveMode.Create); | |
foreach (var name in Strings.Split(output, "\n")) | |
{ | |
if (name.Length == 0) continue; | |
zip.CreateEntryFromFile(name, name); | |
} | |
zip.Dispose(); | |
} | |
} | |
else | |
{ | |
using (var destFile = File.OpenWrite(destFilename)) | |
{ | |
ZipFile.CreateFromDirectory(srcDir, destFile); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment