Skip to content

Commit

Permalink
Only update files when they have changed
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelstaib committed Aug 31, 2022
1 parent 1426f80 commit 493242c
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 45 deletions.
Expand Up @@ -26,7 +26,7 @@
</PropertyGroup>

<PropertyGroup>
<GenCommand>dotnet $(GenTool) generate &quot;$(MSBuildProjectDirectory)&quot;</GenCommand>
<GenCommand>dotnet &quot;$(GenTool)&quot; generate &quot;$(MSBuildProjectDirectory)&quot;</GenCommand>
<GenCommand>$(GenCommand) -o $(GraphQLCodeGenerationRoot)</GenCommand>
<GenCommand Condition="'$(RootNamespace)' != ''">$(GenCommand) -n $(RootNamespace)</GenCommand>
<GenCommand Condition="'$(GraphQLPersistedQueryOutput)' != ''">$(GenCommand) -q $(GraphQLQueryGenerationRoot)</GenCommand>
Expand All @@ -43,7 +43,7 @@
<Exec Command="$(GenCommand)" WorkingDirectory="$(MSBuildThisFileDirectory)" ConsoleToMsBuild="true" />

<ItemGroup>
<Compile Include="$(GraphQLCodeGenerationRoot)**\*.cs"/>
<Compile Include="$(GraphQLCodeGenerationRoot)**\*.cs" />
</ItemGroup>
</Target>

Expand Down
119 changes: 76 additions & 43 deletions src/StrawberryShake/Tooling/src/dotnet-graphql/GenerateCommand.cs
@@ -1,3 +1,5 @@
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
using McMaster.Extensions.CommandLineUtils;
using StrawberryShake.CodeGeneration.CSharp;
Expand Down Expand Up @@ -62,35 +64,38 @@ public static void Build(CommandLineApplication generate)
"Console output as JSON.",
CommandOptionType.NoValue);

generate.OnExecuteAsync(ct =>
{
var strategy = RequestStrategy.Default;
var queryOutputDir = queryOutputDirArg.Value();
if (!string.IsNullOrEmpty(queryOutputDir) || relayFormatArg.HasValue())
generate.OnExecuteAsync(
ct =>
{
strategy = RequestStrategy.PersistedQuery;
}
var strategy = RequestStrategy.Default;
var queryOutputDir = queryOutputDirArg.Value();
var arguments = new GenerateCommandArguments(
pathArg.Value ?? CurrentDirectory,
rootNamespaceArg.Value(),
!disableSchemaValidationArg.HasValue(),
hashAlgorithmArg.Value() ?? "md5",
true,
disableStoreArg.HasValue(),
razorComponentsArg.HasValue(),
outputDirArg.Value(),
strategy,
queryOutputDir,
relayFormatArg.HasValue());
var handler = CommandTools.CreateHandler<GenerateCommandHandler>(jsonArg);
return handler.ExecuteAsync(arguments, ct);
});
if (!string.IsNullOrEmpty(queryOutputDir) || relayFormatArg.HasValue())
{
strategy = RequestStrategy.PersistedQuery;
}
var arguments = new GenerateCommandArguments(
pathArg.Value ?? CurrentDirectory,
rootNamespaceArg.Value(),
!disableSchemaValidationArg.HasValue(),
hashAlgorithmArg.Value() ?? "md5",
true,
disableStoreArg.HasValue(),
razorComponentsArg.HasValue(),
outputDirArg.Value(),
strategy,
queryOutputDir,
relayFormatArg.HasValue());
var handler = CommandTools.CreateHandler<GenerateCommandHandler>(jsonArg);
return handler.ExecuteAsync(arguments, ct);
});
}

private sealed class GenerateCommandHandler : CommandHandler<GenerateCommandArguments>
{
private static readonly MD5 _md5 = MD5.Create();

public GenerateCommandHandler(IConsoleOutput output)
{
Output = output;
Expand All @@ -114,13 +119,15 @@ public GenerateCommandHandler(IConsoleOutput output)
var documents = GetGraphQLDocuments(args.Path, config.Documents);
var settings = CreateSettings(config, args, rootNamespace);
var result = GenerateClient(settings.ClientName, documents, settings);
var outputDir = args.OutputDir ?? Path.Combine(
Path.GetDirectoryName(configFileName)!,
config.Extensions.StrawberryShake.OutputDirectoryName ?? "Generated");
var queryOutputDir = args.QueryOutputDir ?? Path.Combine(
Path.GetDirectoryName(configFileName)!,
config.Extensions.StrawberryShake.OutputDirectoryName ?? "Generated",
"Queries");
var outputDir = args.OutputDir ??
Path.Combine(
Path.GetDirectoryName(configFileName)!,
config.Extensions.StrawberryShake.OutputDirectoryName ?? "Generated");
var queryOutputDir = args.QueryOutputDir ??
Path.Combine(
Path.GetDirectoryName(configFileName)!,
config.Extensions.StrawberryShake.OutputDirectoryName ?? "Generated",
"Queries");

if (result.HasErrors())
{
Expand Down Expand Up @@ -160,30 +167,35 @@ public GenerateCommandHandler(IConsoleOutput output)
string outputDir,
CancellationToken cancellationToken)
{
if (Directory.Exists(outputDir))
{
foreach (var oldFile in Directory.GetFiles(outputDir, $"{clientName}.*.cs"))
{
File.Delete(oldFile);
}
}
var deleteList = Directory.Exists(outputDir)
? new HashSet<string>(Directory.GetFiles(outputDir, $"{clientName}.*.cs"))
: new HashSet<string>();

foreach (var doc in result.Documents)
{
if (doc.Kind is SourceDocumentKind.CSharp or SourceDocumentKind.Razor)
{
var fileName = CreateCodeFileName(outputDir, doc.Path, doc.Name, doc.Kind);
deleteList.Remove(fileName);

EnsureWeCanWriteTheFile(fileName);
if (await NeedsUpdateAsync(fileName, doc.SourceText, cancellationToken))
{
EnsureWeCanWriteTheFile(fileName);

await File.WriteAllTextAsync(
fileName,
doc.SourceText,
cancellationToken);
await File.WriteAllTextAsync(
fileName,
doc.SourceText,
cancellationToken);

Output.WriteFileCreated(fileName);
Output.WriteFileCreated(fileName);
}
}
}

foreach (var oldFile in deleteList)
{
File.Delete(oldFile);
}
}

private static async Task WritePersistedQueriesAsync(
Expand Down Expand Up @@ -253,6 +265,27 @@ public GenerateCommandHandler(IConsoleOutput output)
: Path.Combine(outputDir, path, $"{name}.{kindName}.cs");
}

public static async Task<bool> NeedsUpdateAsync(
string fileName,
string sourceText,
CancellationToken cancellationToken)
{
if (File.Exists(fileName))
{
var readTask = File.ReadAllBytesAsync(fileName, cancellationToken);

var source = Encoding.UTF8.GetBytes(sourceText);
var sourceHash = _md5.ComputeHash(source);

var current = await readTask;
var currentHash = _md5.ComputeHash(current);

return !currentHash.AsSpan().SequenceEqual(sourceHash);
}

return true;
}

private static void EnsureWeCanWriteTheFile(string fileName)
{
var dir = Path.GetDirectoryName(fileName)!;
Expand Down

0 comments on commit 493242c

Please sign in to comment.