blob: 54263b8d4d73edce842a24be783513d108cee0c5 [file] [log] [blame]
Sasha Smundakb051c4e2020-11-05 20:45:07 -08001// Copyright 2021 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package mk2rbc
16
17import (
18 "bytes"
19 "strings"
20 "testing"
21)
22
23var testCases = []struct {
24 desc string
25 mkname string
26 in string
27 expected string
28}{
29 {
30 desc: "Comment",
31 mkname: "product.mk",
32 in: `
33# Comment
34# FOO= a\
35 b
36`,
37 expected: `# Comment
38# FOO= a
39# b
40load("//build/make/core:product_config.rbc", "rblf")
41
42def init(g, handle):
43 cfg = rblf.cfg(handle)
44`,
45 },
46 {
47 desc: "Name conversion",
48 mkname: "path/bar-baz.mk",
49 in: `
50# Comment
51`,
52 expected: `# Comment
53load("//build/make/core:product_config.rbc", "rblf")
54
55def init(g, handle):
56 cfg = rblf.cfg(handle)
57`,
58 },
59 {
60 desc: "Item variable",
61 mkname: "pixel3.mk",
62 in: `
63PRODUCT_NAME := Pixel 3
64PRODUCT_MODEL :=
65local_var = foo
66`,
67 expected: `load("//build/make/core:product_config.rbc", "rblf")
68
69def init(g, handle):
70 cfg = rblf.cfg(handle)
71 cfg["PRODUCT_NAME"] = "Pixel 3"
72 cfg["PRODUCT_MODEL"] = ""
73 _local_var = "foo"
74`,
75 },
76 {
77 desc: "List variable",
78 mkname: "pixel4.mk",
79 in: `
80PRODUCT_PACKAGES = package1 package2
81PRODUCT_COPY_FILES += file2:target
82PRODUCT_PACKAGES += package3
83PRODUCT_COPY_FILES =
84`,
85 expected: `load("//build/make/core:product_config.rbc", "rblf")
86
87def init(g, handle):
88 cfg = rblf.cfg(handle)
89 cfg["PRODUCT_PACKAGES"] = [
90 "package1",
91 "package2",
92 ]
93 rblf.setdefault(handle, "PRODUCT_COPY_FILES")
94 cfg["PRODUCT_COPY_FILES"] += ["file2:target"]
95 cfg["PRODUCT_PACKAGES"] += ["package3"]
96 cfg["PRODUCT_COPY_FILES"] = []
97`,
98 },
99 {
100 desc: "Unknown function",
101 mkname: "product.mk",
102 in: `
103PRODUCT_NAME := $(call foo, bar)
104`,
105 expected: `# MK2RBC TRANSLATION ERROR: cannot handle invoking foo
106# PRODUCT_NAME := $(call foo, bar)
107load("//build/make/core:product_config.rbc", "rblf")
108
109def init(g, handle):
110 cfg = rblf.cfg(handle)
111 rblf.warning("product.mk", "partially successful conversion")
112`,
113 },
114 {
115 desc: "Inherit configuration always",
116 mkname: "product.mk",
117 in: `
118ifdef PRODUCT_NAME
119$(call inherit-product, part.mk)
120else # Comment
121$(call inherit-product, $(LOCAL_PATH)/part.mk)
122endif
123`,
124 expected: `load("//build/make/core:product_config.rbc", "rblf")
125load(":part.star", _part_init = "init")
126
127def init(g, handle):
128 cfg = rblf.cfg(handle)
129 if g.get("PRODUCT_NAME") != None:
130 rblf.inherit(handle, "part", _part_init)
131 else:
132 # Comment
133 rblf.inherit(handle, "./part", _part_init)
134`,
135 },
136 {
137 desc: "Inherit configuration if it exists",
138 mkname: "product.mk",
139 in: `
140$(call inherit-product-if-exists, part.mk)
141`,
142 expected: `load("//build/make/core:product_config.rbc", "rblf")
143load(":part.star|init", _part_init = "init")
144
145def init(g, handle):
146 cfg = rblf.cfg(handle)
147 if _part_init != None:
148 rblf.inherit(handle, "part", _part_init)
149`,
150 },
151
152 {
153 desc: "Include configuration",
154 mkname: "product.mk",
155 in: `
156ifdef PRODUCT_NAME
157include part.mk
158else
159-include $(LOCAL_PATH)/part.mk)
160endif
161`,
162 expected: `load("//build/make/core:product_config.rbc", "rblf")
163load(":part.star", _part_init = "init")
164
165def init(g, handle):
166 cfg = rblf.cfg(handle)
167 if g.get("PRODUCT_NAME") != None:
168 _part_init(g, handle)
169 else:
170 if _part_init != None:
171 _part_init(g, handle)
172`,
173 },
174
175 {
176 desc: "Synonymous inherited configurations",
177 mkname: "path/product.mk",
178 in: `
179$(call inherit-product, foo/font.mk)
180$(call inherit-product, bar/font.mk)
181`,
182 expected: `load("//build/make/core:product_config.rbc", "rblf")
183load("//foo:font.star", _font_init = "init")
184load("//bar:font.star", _font1_init = "init")
185
186def init(g, handle):
187 cfg = rblf.cfg(handle)
188 rblf.inherit(handle, "foo/font", _font_init)
189 rblf.inherit(handle, "bar/font", _font1_init)
190`,
191 },
192 {
193 desc: "Directive define",
194 mkname: "product.mk",
195 in: `
196define some-macro
197 $(info foo)
198endef
199`,
200 expected: `# MK2RBC TRANSLATION ERROR: define is not supported: some-macro
201# define some-macro
202# $(info foo)
203# endef
204load("//build/make/core:product_config.rbc", "rblf")
205
206def init(g, handle):
207 cfg = rblf.cfg(handle)
208 rblf.warning("product.mk", "partially successful conversion")
209`,
210 },
211 {
212 desc: "Ifdef",
213 mkname: "product.mk",
214 in: `
215ifdef PRODUCT_NAME
216 PRODUCT_NAME = gizmo
217else
218endif
219`,
220 expected: `load("//build/make/core:product_config.rbc", "rblf")
221
222def init(g, handle):
223 cfg = rblf.cfg(handle)
224 if g.get("PRODUCT_NAME") != None:
225 cfg["PRODUCT_NAME"] = "gizmo"
226 else:
227 pass
228`,
229 },
230 {
231 desc: "Simple functions",
232 mkname: "product.mk",
233 in: `
234$(warning this is the warning)
235$(warning)
236$(info this is the info)
237$(error this is the error)
238PRODUCT_NAME:=$(shell echo *)
239`,
240 expected: `load("//build/make/core:product_config.rbc", "rblf")
241
242def init(g, handle):
243 cfg = rblf.cfg(handle)
244 rblf.mkwarning("product.mk", "this is the warning")
245 rblf.mkwarning("product.mk", "")
246 rblf.mkinfo("product.mk", "this is the info")
247 rblf.mkerror("product.mk", "this is the error")
248 cfg["PRODUCT_NAME"] = rblf.shell("echo *")
249`,
250 },
251 {
252 desc: "Empty if",
253 mkname: "product.mk",
254 in: `
255ifdef PRODUCT_NAME
256# Comment
257endif
258`,
259 expected: `load("//build/make/core:product_config.rbc", "rblf")
260
261def init(g, handle):
262 cfg = rblf.cfg(handle)
263 if g.get("PRODUCT_NAME") != None:
264 # Comment
265 pass
266`,
267 },
268 {
269 desc: "if/else/endif",
270 mkname: "product.mk",
271 in: `
272ifndef PRODUCT_NAME
273 PRODUCT_NAME=gizmo1
274else
275 PRODUCT_NAME=gizmo2
276endif
277`,
278 expected: `load("//build/make/core:product_config.rbc", "rblf")
279
280def init(g, handle):
281 cfg = rblf.cfg(handle)
282 if not g.get("PRODUCT_NAME") != None:
283 cfg["PRODUCT_NAME"] = "gizmo1"
284 else:
285 cfg["PRODUCT_NAME"] = "gizmo2"
286`,
287 },
288 {
289 desc: "else if",
290 mkname: "product.mk",
291 in: `
292ifdef PRODUCT_NAME
293 PRODUCT_NAME = gizmo
294else ifndef PRODUCT_PACKAGES # Comment
295endif
296 `,
297 expected: `load("//build/make/core:product_config.rbc", "rblf")
298
299def init(g, handle):
300 cfg = rblf.cfg(handle)
301 if g.get("PRODUCT_NAME") != None:
302 cfg["PRODUCT_NAME"] = "gizmo"
303 elif not g.get("PRODUCT_PACKAGES") != None:
304 # Comment
305 pass
306`,
307 },
308 {
309 desc: "ifeq / ifneq",
310 mkname: "product.mk",
311 in: `
312ifeq (aosp_arm, $(TARGET_PRODUCT))
313 PRODUCT_MODEL = pix2
314else
315 PRODUCT_MODEL = pix21
316endif
317ifneq (aosp_x86, $(TARGET_PRODUCT))
318 PRODUCT_MODEL = pix3
319endif
320`,
321 expected: `load("//build/make/core:product_config.rbc", "rblf")
322
323def init(g, handle):
324 cfg = rblf.cfg(handle)
325 if "aosp_arm" == g["TARGET_PRODUCT"]:
326 cfg["PRODUCT_MODEL"] = "pix2"
327 else:
328 cfg["PRODUCT_MODEL"] = "pix21"
329 if "aosp_x86" != g["TARGET_PRODUCT"]:
330 cfg["PRODUCT_MODEL"] = "pix3"
331`,
332 },
333 {
334 desc: "Check filter result",
335 mkname: "product.mk",
336 in: `
337ifeq (,$(filter userdebug eng, $(TARGET_BUILD_VARIANT)))
338endif
339ifneq (,$(filter userdebug,$(TARGET_BUILD_VARIANT))
340endif
341ifneq (,$(filter plaf,$(PLATFORM_LIST)))
342endif
343ifeq ($(TARGET_BUILD_VARIANT), $(filter $(TARGET_BUILD_VARIANT), userdebug eng))
344endif
345`,
346 expected: `load("//build/make/core:product_config.rbc", "rblf")
347
348def init(g, handle):
349 cfg = rblf.cfg(handle)
350 if g["TARGET_BUILD_VARIANT"] not in ["userdebug", "eng"]:
351 pass
352 if g["TARGET_BUILD_VARIANT"] in ["userdebug"]:
353 pass
354 if "plaf" in g.get("PLATFORM_LIST", []):
355 pass
356 if g["TARGET_BUILD_VARIANT"] in ["userdebug", "eng"]:
357 pass
358`,
359 },
360 {
361 desc: "Get filter result",
362 mkname: "product.mk",
363 in: `
364PRODUCT_LIST2=$(filter-out %/foo.ko,$(wildcard path/*.ko))
365`,
366 expected: `load("//build/make/core:product_config.rbc", "rblf")
367
368def init(g, handle):
369 cfg = rblf.cfg(handle)
370 cfg["PRODUCT_LIST2"] = rblf.filter_out("%/foo.ko", rblf.expand_wildcard("path/*.ko"))
371`,
372 },
373 {
374 desc: "filter $(VAR), values",
375 mkname: "product.mk",
376 in: `
377ifeq (,$(filter $(TARGET_PRODUCT), yukawa_gms yukawa_sei510_gms)
378 ifneq (,$(filter $(TARGET_PRODUCT), yukawa_gms)
379 endif
380endif
381
382`,
383 expected: `load("//build/make/core:product_config.rbc", "rblf")
384
385def init(g, handle):
386 cfg = rblf.cfg(handle)
387 if g["TARGET_PRODUCT"] not in ["yukawa_gms", "yukawa_sei510_gms"]:
388 if g["TARGET_PRODUCT"] in ["yukawa_gms"]:
389 pass
390`,
391 },
392 {
393 desc: "ifeq",
394 mkname: "product.mk",
395 in: `
396ifeq (aosp, $(TARGET_PRODUCT)) # Comment
397else ifneq (, $(TARGET_PRODUCT))
398endif
399`,
400 expected: `load("//build/make/core:product_config.rbc", "rblf")
401
402def init(g, handle):
403 cfg = rblf.cfg(handle)
404 if "aosp" == g["TARGET_PRODUCT"]:
405 # Comment
406 pass
407 elif g["TARGET_PRODUCT"]:
408 pass
409`,
410 },
411 {
412 desc: "Nested if",
413 mkname: "product.mk",
414 in: `
415ifdef PRODUCT_NAME
416 PRODUCT_PACKAGES = pack-if0
417 ifdef PRODUCT_MODEL
418 PRODUCT_PACKAGES = pack-if-if
419 else ifdef PRODUCT_NAME
420 PRODUCT_PACKAGES = pack-if-elif
421 else
422 PRODUCT_PACKAGES = pack-if-else
423 endif
424 PRODUCT_PACKAGES = pack-if
425else ifneq (,$(TARGET_PRODUCT))
426 PRODUCT_PACKAGES = pack-elif
427else
428 PRODUCT_PACKAGES = pack-else
429endif
430`,
431 expected: `load("//build/make/core:product_config.rbc", "rblf")
432
433def init(g, handle):
434 cfg = rblf.cfg(handle)
435 if g.get("PRODUCT_NAME") != None:
436 cfg["PRODUCT_PACKAGES"] = ["pack-if0"]
437 if g.get("PRODUCT_MODEL") != None:
438 cfg["PRODUCT_PACKAGES"] = ["pack-if-if"]
439 elif g.get("PRODUCT_NAME") != None:
440 cfg["PRODUCT_PACKAGES"] = ["pack-if-elif"]
441 else:
442 cfg["PRODUCT_PACKAGES"] = ["pack-if-else"]
443 cfg["PRODUCT_PACKAGES"] = ["pack-if"]
444 elif g["TARGET_PRODUCT"]:
445 cfg["PRODUCT_PACKAGES"] = ["pack-elif"]
446 else:
447 cfg["PRODUCT_PACKAGES"] = ["pack-else"]
448`,
449 },
450 {
451 desc: "Wildcard",
452 mkname: "product.mk",
453 in: `
454ifeq (,$(wildcard foo.mk))
455endif
456ifneq (,$(wildcard foo*.mk))
457endif
458`,
459 expected: `load("//build/make/core:product_config.rbc", "rblf")
460
461def init(g, handle):
462 cfg = rblf.cfg(handle)
463 if not rblf.file_exists("foo.mk"):
464 pass
465 if rblf.file_wildcard_exists("foo*.mk"):
466 pass
467`,
468 },
469 {
470 desc: "ifneq $(X),true",
471 mkname: "product.mk",
472 in: `
473ifneq ($(VARIABLE),true)
474endif
475`,
476 expected: `load("//build/make/core:product_config.rbc", "rblf")
477
478def init(g, handle):
479 cfg = rblf.cfg(handle)
480 if g.get("VARIABLE", "") != "true":
481 pass
482`,
483 },
484 {
485 desc: "Const neq",
486 mkname: "product.mk",
487 in: `
488ifneq (1,0)
489endif
490`,
491 expected: `load("//build/make/core:product_config.rbc", "rblf")
492
493def init(g, handle):
494 cfg = rblf.cfg(handle)
495 if "1" != "0":
496 pass
497`,
498 },
499 {
500 desc: "is-board calls",
501 mkname: "product.mk",
502 in: `
503ifeq ($(call is-board-platform-in-list,msm8998), true)
504else ifneq ($(call is-board-platform,copper),true)
505else ifneq ($(call is-vendor-board-platform,QCOM),true)
506else ifeq ($(call is-product-in-list, $(PLATFORM_LIST)), true)
507endif
508`,
509 expected: `load("//build/make/core:product_config.rbc", "rblf")
510
511def init(g, handle):
512 cfg = rblf.cfg(handle)
513 if g.get("TARGET_BOARD_PLATFORM", "") in ["msm8998"]:
514 pass
515 elif g.get("TARGET_BOARD_PLATFORM", "") != "copper":
516 pass
517 elif g.get("TARGET_BOARD_PLATFORM", "") not in g["QCOM_BOARD_PLATFORMS"]:
518 pass
519 elif g["TARGET_PRODUCT"] in g.get("PLATFORM_LIST", []):
520 pass
521`,
522 },
523 {
524 desc: "findstring call",
525 mkname: "product.mk",
526 in: `
527ifneq ($(findstring foo,$(PRODUCT_PACKAGES)),)
528endif
529`,
530 expected: `load("//build/make/core:product_config.rbc", "rblf")
531
532def init(g, handle):
533 cfg = rblf.cfg(handle)
534 if (cfg.get("PRODUCT_PACKAGES", [])).find("foo") != -1:
535 pass
536`,
537 },
538 {
539 desc: "rhs call",
540 mkname: "product.mk",
541 in: `
542PRODUCT_COPY_FILES = $(call add-to-product-copy-files-if-exists, path:distpath) \
543 $(call find-copy-subdir-files, *, fromdir, todir) $(wildcard foo.*)
544`,
545 expected: `load("//build/make/core:product_config.rbc", "rblf")
546
547def init(g, handle):
548 cfg = rblf.cfg(handle)
549 cfg["PRODUCT_COPY_FILES"] = (rblf.copy_if_exists("path:distpath") +
550 rblf.find_and_copy("*", "fromdir", "todir") +
551 rblf.expand_wildcard("foo.*"))
552`,
553 },
554 {
555 desc: "inferred type",
556 mkname: "product.mk",
557 in: `
558HIKEY_MODS := $(wildcard foo/*.ko)
559BOARD_VENDOR_KERNEL_MODULES += $(HIKEY_MODS)
560`,
561 expected: `load("//build/make/core:product_config.rbc", "rblf")
562
563def init(g, handle):
564 cfg = rblf.cfg(handle)
565 g["HIKEY_MODS"] = rblf.expand_wildcard("foo/*.ko")
566 g.setdefault("BOARD_VENDOR_KERNEL_MODULES", [])
567 g["BOARD_VENDOR_KERNEL_MODULES"] += g["HIKEY_MODS"]
568`,
569 },
570 {
571 desc: "list with vars",
572 mkname: "product.mk",
573 in: `
574PRODUCT_COPY_FILES += path1:$(TARGET_PRODUCT)/path1 $(PRODUCT_MODEL)/path2:$(TARGET_PRODUCT)/path2
575`,
576 expected: `load("//build/make/core:product_config.rbc", "rblf")
577
578def init(g, handle):
579 cfg = rblf.cfg(handle)
580 rblf.setdefault(handle, "PRODUCT_COPY_FILES")
581 cfg["PRODUCT_COPY_FILES"] += (("path1:%s/path1" % g["TARGET_PRODUCT"]).split() +
582 ("%s/path2:%s/path2" % (cfg.get("PRODUCT_MODEL", ""), g["TARGET_PRODUCT"])).split())
583`,
584 },
585 {
586 desc: "misc calls",
587 mkname: "product.mk",
588 in: `
589$(call enforce-product-packages-exist,)
590$(call enforce-product-packages-exist, foo)
591$(call require-artifacts-in-path, foo, bar)
592$(call require-artifacts-in-path-relaxed, foo, bar)
593`,
594 expected: `load("//build/make/core:product_config.rbc", "rblf")
595
596def init(g, handle):
597 cfg = rblf.cfg(handle)
598 rblf.enforce_product_packages_exist("")
599 rblf.enforce_product_packages_exist("foo")
600 rblf.require_artifacts_in_path("foo", "bar")
601 rblf.require_artifacts_in_path_relaxed("foo", "bar")
602`,
603 },
604 {
605 desc: "list with functions",
606 mkname: "product.mk",
607 in: `
608PRODUCT_COPY_FILES := $(call find-copy-subdir-files,*.kl,from1,to1) \
609 $(call find-copy-subdir-files,*.kc,from2,to2) \
610 foo bar
611`,
612 expected: `load("//build/make/core:product_config.rbc", "rblf")
613
614def init(g, handle):
615 cfg = rblf.cfg(handle)
616 cfg["PRODUCT_COPY_FILES"] = (rblf.find_and_copy("*.kl", "from1", "to1") +
617 rblf.find_and_copy("*.kc", "from2", "to2") +
618 [
619 "foo",
620 "bar",
621 ])
622`,
623 },
624 {
625 desc: "Text functions",
626 mkname: "product.mk",
627 in: `
628PRODUCT_COPY_FILES := $(addprefix pfx-,a b c)
629PRODUCT_COPY_FILES := $(addsuffix .sff, a b c)
630PRODUCT_NAME := $(word 1, $(subst ., ,$(TARGET_BOARD_PLATFORM)))
631
632`,
633 expected: `load("//build/make/core:product_config.rbc", "rblf")
634
635def init(g, handle):
636 cfg = rblf.cfg(handle)
637 cfg["PRODUCT_COPY_FILES"] = rblf.addprefix("pfx-", "a b c")
638 cfg["PRODUCT_COPY_FILES"] = rblf.addsuffix(".sff", "a b c")
639 cfg["PRODUCT_NAME"] = ((g.get("TARGET_BOARD_PLATFORM", "")).replace(".", " ")).split()[0]
640`,
641 },
642 {
643 desc: "assignment flavors",
644 mkname: "product.mk",
645 in: `
646PRODUCT_LIST1 := a
647PRODUCT_LIST2 += a
648PRODUCT_LIST1 += b
649PRODUCT_LIST2 += b
650PRODUCT_LIST3 ?= a
651PRODUCT_LIST1 = c
652PLATFORM_LIST += x
653PRODUCT_PACKAGES := $(PLATFORM_LIST)
654`,
655 expected: `load("//build/make/core:product_config.rbc", "rblf")
656
657def init(g, handle):
658 cfg = rblf.cfg(handle)
659 cfg["PRODUCT_LIST1"] = ["a"]
660 rblf.setdefault(handle, "PRODUCT_LIST2")
661 cfg["PRODUCT_LIST2"] += ["a"]
662 cfg["PRODUCT_LIST1"] += ["b"]
663 cfg["PRODUCT_LIST2"] += ["b"]
664 if cfg.get("PRODUCT_LIST3") == None:
665 cfg["PRODUCT_LIST3"] = ["a"]
666 cfg["PRODUCT_LIST1"] = ["c"]
667 g.setdefault("PLATFORM_LIST", [])
668 g["PLATFORM_LIST"] += ["x"]
669 cfg["PRODUCT_PACKAGES"] = g["PLATFORM_LIST"][:]
670`,
671 },
672 {
673 desc: "assigment flavors2",
674 mkname: "product.mk",
675 in: `
676PRODUCT_LIST1 = a
677ifeq (0,1)
678 PRODUCT_LIST1 += b
679 PRODUCT_LIST2 += b
680endif
681PRODUCT_LIST1 += c
682PRODUCT_LIST2 += c
683`,
684 expected: `load("//build/make/core:product_config.rbc", "rblf")
685
686def init(g, handle):
687 cfg = rblf.cfg(handle)
688 cfg["PRODUCT_LIST1"] = ["a"]
689 if "0" == "1":
690 cfg["PRODUCT_LIST1"] += ["b"]
691 rblf.setdefault(handle, "PRODUCT_LIST2")
692 cfg["PRODUCT_LIST2"] += ["b"]
693 cfg["PRODUCT_LIST1"] += ["c"]
694 rblf.setdefault(handle, "PRODUCT_LIST2")
695 cfg["PRODUCT_LIST2"] += ["c"]
696`,
697 },
698 {
699 desc: "string split",
700 mkname: "product.mk",
701 in: `
702PRODUCT_LIST1 = a
703local = b
704local += c
705FOO = d
706FOO += e
707PRODUCT_LIST1 += $(local)
708PRODUCT_LIST1 += $(FOO)
709`,
710 expected: `load("//build/make/core:product_config.rbc", "rblf")
711
712def init(g, handle):
713 cfg = rblf.cfg(handle)
714 cfg["PRODUCT_LIST1"] = ["a"]
715 _local = "b"
716 _local += " " + "c"
717 g["FOO"] = "d"
718 g["FOO"] += " " + "e"
719 cfg["PRODUCT_LIST1"] += (_local).split()
720 cfg["PRODUCT_LIST1"] += (g["FOO"]).split()
721`,
722 },
723 {
724 desc: "apex_jars",
725 mkname: "product.mk",
726 in: `
727PRODUCT_BOOT_JARS := $(ART_APEX_JARS) framework-minus-apex
728`,
729 expected: `load("//build/make/core:product_config.rbc", "rblf")
730
731def init(g, handle):
732 cfg = rblf.cfg(handle)
733 cfg["PRODUCT_BOOT_JARS"] = (g.get("ART_APEX_JARS", []) +
734 ["framework-minus-apex"])
735`,
736 },
737 {
738 desc: "strip function",
739 mkname: "product.mk",
740 in: `
741ifeq ($(filter hwaddress,$(PRODUCT_PACKAGES)),)
742 PRODUCT_PACKAGES := $(strip $(PRODUCT_PACKAGES) hwaddress)
743endif
744`,
745 expected: `load("//build/make/core:product_config.rbc", "rblf")
746
747def init(g, handle):
748 cfg = rblf.cfg(handle)
749 if "hwaddress" not in cfg.get("PRODUCT_PACKAGES", []):
750 cfg["PRODUCT_PACKAGES"] = (rblf.mkstrip("%s hwaddress" % " ".join(cfg.get("PRODUCT_PACKAGES", [])))).split()
751`,
752 },
753 {
754 desc: "strip func in condition",
755 mkname: "product.mk",
756 in: `
757ifneq ($(strip $(TARGET_VENDOR)),)
758endif
759`,
760 expected: `load("//build/make/core:product_config.rbc", "rblf")
761
762def init(g, handle):
763 cfg = rblf.cfg(handle)
764 if rblf.mkstrip(g.get("TARGET_VENDOR", "")) != "":
765 pass
766`,
767 },
768 {
769 desc: "ref after set",
770 mkname: "product.mk",
771 in: `
772PRODUCT_ADB_KEYS:=value
773FOO := $(PRODUCT_ADB_KEYS)
774ifneq (,$(PRODUCT_ADB_KEYS))
775endif
776`,
777 expected: `load("//build/make/core:product_config.rbc", "rblf")
778
779def init(g, handle):
780 cfg = rblf.cfg(handle)
781 g["PRODUCT_ADB_KEYS"] = "value"
782 g["FOO"] = g["PRODUCT_ADB_KEYS"]
783 if g["PRODUCT_ADB_KEYS"]:
784 pass
785`,
786 },
787 {
788 desc: "ref before set",
789 mkname: "product.mk",
790 in: `
791V1 := $(PRODUCT_ADB_KEYS)
792ifeq (,$(PRODUCT_ADB_KEYS))
793 V2 := $(PRODUCT_ADB_KEYS)
794 PRODUCT_ADB_KEYS:=foo
795 V3 := $(PRODUCT_ADB_KEYS)
796endif`,
797 expected: `load("//build/make/core:product_config.rbc", "rblf")
798
799def init(g, handle):
800 cfg = rblf.cfg(handle)
801 g["V1"] = g.get("PRODUCT_ADB_KEYS", "")
802 if not g.get("PRODUCT_ADB_KEYS", ""):
803 g["V2"] = g.get("PRODUCT_ADB_KEYS", "")
804 g["PRODUCT_ADB_KEYS"] = "foo"
805 g["V3"] = g["PRODUCT_ADB_KEYS"]
806`,
807 },
808}
809
810var known_variables = []struct {
811 name string
812 class varClass
813 starlarkType
814}{
815 {"PRODUCT_NAME", VarClassConfig, starlarkTypeString},
816 {"PRODUCT_MODEL", VarClassConfig, starlarkTypeString},
817 {"PRODUCT_PACKAGES", VarClassConfig, starlarkTypeList},
818 {"PRODUCT_BOOT_JARS", VarClassConfig, starlarkTypeList},
819 {"PRODUCT_COPY_FILES", VarClassConfig, starlarkTypeList},
820 {"PRODUCT_IS_64BIT", VarClassConfig, starlarkTypeString},
821 {"PRODUCT_LIST1", VarClassConfig, starlarkTypeList},
822 {"PRODUCT_LIST2", VarClassConfig, starlarkTypeList},
823 {"PRODUCT_LIST3", VarClassConfig, starlarkTypeList},
824 {"TARGET_PRODUCT", VarClassSoong, starlarkTypeString},
825 {"TARGET_BUILD_VARIANT", VarClassSoong, starlarkTypeString},
826 {"TARGET_BOARD_PLATFORM", VarClassSoong, starlarkTypeString},
827 {"QCOM_BOARD_PLATFORMS", VarClassSoong, starlarkTypeString},
828 {"PLATFORM_LIST", VarClassSoong, starlarkTypeList}, // TODO(asmundak): make it local instead of soong
829}
830
831func TestGood(t *testing.T) {
832 for _, v := range known_variables {
833 KnownVariables.NewVariable(v.name, v.class, v.starlarkType)
834 }
835 for _, test := range testCases {
836 t.Run(test.desc,
837 func(t *testing.T) {
838 ss, err := Convert(Request{
839 MkFile: test.mkname,
840 Reader: bytes.NewBufferString(test.in),
841 RootDir: ".",
842 OutputSuffix: ".star",
843 WarnPartialSuccess: true,
844 })
845 if err != nil {
846 t.Error(err)
847 return
848 }
849 got := ss.String()
850 if got != test.expected {
851 t.Errorf("%q failed\nExpected:\n%s\nActual:\n%s\n", test.desc,
852 strings.ReplaceAll(test.expected, "\n", "␤\n"),
853 strings.ReplaceAll(got, "\n", "␤\n"))
854 }
855 })
856 }
857}