Skip to content

Instantly share code, notes, and snippets.

@ImaginaryDevelopment
Created December 12, 2022 15:42
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ImaginaryDevelopment/164173c193f30207cc55c9160a3dcbe8 to your computer and use it in GitHub Desktop.
Save ImaginaryDevelopment/164173c193f30207cc55c9160a3dcbe8 to your computer and use it in GitHub Desktop.
clone a project structure for repro
// clone project structure/some files
let src = @"C:\projects\YourProject\"
// assuming existing folder
let target = @"C:\projects\ReproFolder"
let wipeTarget = true
if wipeTarget then
// assumes deleting the dir and recreating it won't blow away permissions
if Directory.Exists target then
Directory.Delete(target,true)
Directory.CreateDirectory target |> ignore
// desired feature, ignore things that .gitignore does
let directoryIgnores = [
".vs"
".fable"
"node_modules"
"packages"
"obj"
]
// assumes no // or \\
let segmentPath (x:string) =
x.Split(Array.ofList [ Path.DirectorySeparatorChar; Path.AltDirectorySeparatorChar], StringSplitOptions.None)
// copy sln, csproj/fsproj
Environment.CurrentDirectory <- src
let after (delim:string) (x:string) =
let start = x.IndexOf delim + delim.Length
x.[start..]
let equalsI x y =
match x, y with
| null, _
| _, null -> false
| x, y when String.Equals(x,y,StringComparison.InvariantCultureIgnoreCase) -> true
| x, y when String.Equals(x,y,StringComparison.CurrentCultureIgnoreCase) -> true
| _ -> x = y
type TargetType =
| Extension of string
// full filename no directory parts
| Filename of string
| ExactRelativePath of string
let toTargetRelative (path:string) =
let rel = after src path
let target = Path.Combine(target,rel)
let targetDir = Path.GetDirectoryName(target)
targetDir, target
let filterBlacklist =
Seq.filter(fun (x:string) ->
let segments = segmentPath x
directoryIgnores
|> Seq.exists(fun di ->
segments |> Seq.exists(equalsI di)
)
|> not
)
let copyFile(srcF) =
let targetDir, target = toTargetRelative srcF
printfn "copying %s to %s" srcF target
if not <| Directory.Exists targetDir then
Directory.CreateDirectory targetDir |> ignore<DirectoryInfo>
// desired feature copyIfNewer, don't overwrite, or overwrite options
File.Copy(srcF,target,true)
let cloneStructure =
function
| Extension extension ->
Directory.EnumerateFiles(src,"*." + extension, SearchOption.AllDirectories )
|> filterBlacklist
|> Seq.iter copyFile
| Filename fn ->
Directory.EnumerateFiles(src, fn, SearchOption.AllDirectories)
|> filterBlacklist
|> Seq.iter copyFile
// extensions to copy
[
Extension "sln"
Extension "csproj"
Extension "fsproj"
Extension "dependencies"
Extension "references"
Extension "lock"
Extension "cmd"
Extension "targets"
Filename "Dockerfile"
Filename "docker-compose.yml"
] |> Seq.iter cloneStructure
// zip it?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment