Skip to content

Commit f08f0d7

Browse files
committed
feat: hash resources to track modifications
If you run a tool to modify the generated resource files (e.g. prettier or eslint) before checking in the generated model files there is no way for Anchor to know whether or not it must write to a file again. This means that all generated files will be written to _and_ prettier/whatever codemod tool will have to be run on all the generated files each time a change is made. This can take a while if you have a lot of resources. To reduce time spent on codemod we hash the file content _before_ writing it to the file and save that. Then, on the next generation, we'll check that file and won't write to it. The modified files are returned so they can be used to run the codemods on relevant files. ```sh cd spec/example rails anchor:multigen | xargs prettier --write ```
1 parent 7f070b1 commit f08f0d7

File tree

5 files changed

+46
-8
lines changed

5 files changed

+46
-8
lines changed

lib/anchor/type_script/multifile_save_service.rb

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,38 @@ def initialize(generator:, folder_path:, force: false)
1717
def call
1818
FileUtils.mkdir_p(@folder_path)
1919
results = @generator.call
20-
results.each { |result| save_result(result) }
20+
modified_files = results.filter_map { |result| save_result(result) }
21+
save_sha
22+
modified_files
2123
end
2224

2325
private
2426

27+
def sha_hash_path
28+
Rails.root.join(@folder_path, "hash.json")
29+
end
30+
31+
def sha_hash
32+
return @sha_hash if defined?(@sha_hash)
33+
34+
@sha_hash = File.exist?(sha_hash_path) ? JSON.parse(File.read(sha_hash_path)) : {}
35+
end
36+
37+
def save_sha
38+
File.open(sha_hash_path, "w") { |f| f.write(@generator.sha_hash.to_json) }
39+
end
40+
41+
# @return [String, nil] file name of file that is written to. nil if not written to
2542
def save_result(result)
2643
path = Rails.root.join(@folder_path, result.name)
2744

2845
if @force || !File.exist?(path)
2946
File.open(path, "w") { |f| f.write(result.text) }
30-
return
47+
return result.name
3148
end
3249

50+
return if sha_hash[result.name] == Digest::SHA256.hexdigest(result.text)
51+
3352
existing_content = File.read(path)
3453

3554
new_content = if manually_editable?(existing_content)
@@ -42,6 +61,7 @@ def save_result(result)
4261
end
4362

4463
File.open(path, "w") { |f| f.write(new_content) }
64+
result.name
4565
end
4666

4767
def manually_editable?(text)

lib/anchor/type_script/multifile_schema_generator.rb

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,12 @@ def initialize( # rubocop:disable Lint/MissingSuper
2424
end
2525

2626
def call
27-
[shared_file] + resource_files
27+
@call ||= [shared_file] + resource_files
28+
end
29+
30+
# { res.name => hash(res.text) }
31+
def sha_hash
32+
@sha_hash ||= call.map { |res| [res.name, Digest::SHA256.hexdigest(res.text)] }.to_h
2833
end
2934

3035
private

spec/anchor/example_multifile_schema_snapshot_spec.rb

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
# rubocop:disable RSpec/EmptyExampleGroup
44
RSpec.describe "Example" do
5-
def self.multifile_snapshot_test(filename, generate)
5+
def self.multifile_snapshot_test(filename, generator)
66
it "generates correct #{filename} schema" do
7-
results = generate.call
7+
results = generator.call
88
results.each do |res|
99
filename = res.name
1010

@@ -21,14 +21,13 @@ def self.multifile_snapshot_test(filename, generate)
2121
end
2222
end
2323

24-
multifile_snapshot_test "schema.ts", -> {
25-
Anchor::TypeScript::MultifileSchemaGenerator.call(
24+
multifile_snapshot_test "schema.ts",
25+
Anchor::TypeScript::MultifileSchemaGenerator.new(
2626
register: Schema.register,
2727
context: {},
2828
include_all_fields: true,
2929
exclude_fields: nil,
3030
manually_editable: true,
3131
)
32-
}
3332
end
3433
# rubocop:enable RSpec/EmptyExampleGroup

spec/example/lib/tasks/anchor.rake

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,17 @@ namespace :anchor do
3939
Anchor::JSONSchema::SchemaGenerator.call(register: Schema.register, include_all_fields: true)
4040
}
4141
end
42+
43+
task multigen: :environment do
44+
folder_path = "test/files/multifile"
45+
generator = Anchor::TypeScript::MultifileSchemaGenerator.new(
46+
register: Schema.register,
47+
context: {},
48+
include_all_fields: true,
49+
exclude_fields: nil,
50+
manually_editable: true,
51+
)
52+
modified_files = Anchor::TypeScript::MultifileSaveService.call(generator:, folder_path:)
53+
puts modified_files.join(" ")
54+
end
4255
end
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"shared.ts":"e42275c1453e00f368131821b3e4de915d6c5c789a8fc5c72967ddf8c31ad77b","Comment.ts":"fec6ae5197b65afe3fed510a393b7819e288f33366bc34aca1622833c5030ba6","User.ts":"ce80524eb520622e37af4aa9a2b35e49a50cb80bf4ea9921e818631e8a541738","Post.ts":"74d50a09806ff7496c168f2b9b4d6cea64111f42f38effa12464e5ad933c1303","Exhaustive.ts":"ac90628b54e7278d63839fdd4db3d3cbfae9d9e996fb065e5a5d2b756052fe66"}

0 commit comments

Comments
 (0)