blob: bb6484b9a4f62606ed0d1401657401deefbffda8 [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 {
Sasha Smundak9d011ab2021-07-09 16:00:57 -0700643 desc: "subst in list",
644 mkname: "product.mk",
645 in: `
646files = $(call find-copy-subdir-files,*,from,to)
647PRODUCT_COPY_FILES += $(subst foo,bar,$(files))
648`,
649 expected: `load("//build/make/core:product_config.rbc", "rblf")
650
651def init(g, handle):
652 cfg = rblf.cfg(handle)
653 _files = rblf.find_and_copy("*", "from", "to")
654 rblf.setdefault(handle, "PRODUCT_COPY_FILES")
655 cfg["PRODUCT_COPY_FILES"] += rblf.mksubst("foo", "bar", _files)
656`,
657 },
658 {
Sasha Smundakb051c4e2020-11-05 20:45:07 -0800659 desc: "assignment flavors",
660 mkname: "product.mk",
661 in: `
662PRODUCT_LIST1 := a
663PRODUCT_LIST2 += a
664PRODUCT_LIST1 += b
665PRODUCT_LIST2 += b
666PRODUCT_LIST3 ?= a
667PRODUCT_LIST1 = c
668PLATFORM_LIST += x
669PRODUCT_PACKAGES := $(PLATFORM_LIST)
670`,
671 expected: `load("//build/make/core:product_config.rbc", "rblf")
672
673def init(g, handle):
674 cfg = rblf.cfg(handle)
675 cfg["PRODUCT_LIST1"] = ["a"]
676 rblf.setdefault(handle, "PRODUCT_LIST2")
677 cfg["PRODUCT_LIST2"] += ["a"]
678 cfg["PRODUCT_LIST1"] += ["b"]
679 cfg["PRODUCT_LIST2"] += ["b"]
680 if cfg.get("PRODUCT_LIST3") == None:
681 cfg["PRODUCT_LIST3"] = ["a"]
682 cfg["PRODUCT_LIST1"] = ["c"]
683 g.setdefault("PLATFORM_LIST", [])
684 g["PLATFORM_LIST"] += ["x"]
685 cfg["PRODUCT_PACKAGES"] = g["PLATFORM_LIST"][:]
686`,
687 },
688 {
689 desc: "assigment flavors2",
690 mkname: "product.mk",
691 in: `
692PRODUCT_LIST1 = a
693ifeq (0,1)
694 PRODUCT_LIST1 += b
695 PRODUCT_LIST2 += b
696endif
697PRODUCT_LIST1 += c
698PRODUCT_LIST2 += c
699`,
700 expected: `load("//build/make/core:product_config.rbc", "rblf")
701
702def init(g, handle):
703 cfg = rblf.cfg(handle)
704 cfg["PRODUCT_LIST1"] = ["a"]
705 if "0" == "1":
706 cfg["PRODUCT_LIST1"] += ["b"]
707 rblf.setdefault(handle, "PRODUCT_LIST2")
708 cfg["PRODUCT_LIST2"] += ["b"]
709 cfg["PRODUCT_LIST1"] += ["c"]
710 rblf.setdefault(handle, "PRODUCT_LIST2")
711 cfg["PRODUCT_LIST2"] += ["c"]
712`,
713 },
714 {
715 desc: "string split",
716 mkname: "product.mk",
717 in: `
718PRODUCT_LIST1 = a
719local = b
720local += c
721FOO = d
722FOO += e
723PRODUCT_LIST1 += $(local)
724PRODUCT_LIST1 += $(FOO)
725`,
726 expected: `load("//build/make/core:product_config.rbc", "rblf")
727
728def init(g, handle):
729 cfg = rblf.cfg(handle)
730 cfg["PRODUCT_LIST1"] = ["a"]
731 _local = "b"
732 _local += " " + "c"
733 g["FOO"] = "d"
734 g["FOO"] += " " + "e"
735 cfg["PRODUCT_LIST1"] += (_local).split()
736 cfg["PRODUCT_LIST1"] += (g["FOO"]).split()
737`,
738 },
739 {
740 desc: "apex_jars",
741 mkname: "product.mk",
742 in: `
743PRODUCT_BOOT_JARS := $(ART_APEX_JARS) framework-minus-apex
744`,
745 expected: `load("//build/make/core:product_config.rbc", "rblf")
746
747def init(g, handle):
748 cfg = rblf.cfg(handle)
749 cfg["PRODUCT_BOOT_JARS"] = (g.get("ART_APEX_JARS", []) +
750 ["framework-minus-apex"])
751`,
752 },
753 {
754 desc: "strip function",
755 mkname: "product.mk",
756 in: `
757ifeq ($(filter hwaddress,$(PRODUCT_PACKAGES)),)
758 PRODUCT_PACKAGES := $(strip $(PRODUCT_PACKAGES) hwaddress)
759endif
760`,
761 expected: `load("//build/make/core:product_config.rbc", "rblf")
762
763def init(g, handle):
764 cfg = rblf.cfg(handle)
765 if "hwaddress" not in cfg.get("PRODUCT_PACKAGES", []):
766 cfg["PRODUCT_PACKAGES"] = (rblf.mkstrip("%s hwaddress" % " ".join(cfg.get("PRODUCT_PACKAGES", [])))).split()
767`,
768 },
769 {
770 desc: "strip func in condition",
771 mkname: "product.mk",
772 in: `
773ifneq ($(strip $(TARGET_VENDOR)),)
774endif
775`,
776 expected: `load("//build/make/core:product_config.rbc", "rblf")
777
778def init(g, handle):
779 cfg = rblf.cfg(handle)
780 if rblf.mkstrip(g.get("TARGET_VENDOR", "")) != "":
781 pass
782`,
783 },
784 {
785 desc: "ref after set",
786 mkname: "product.mk",
787 in: `
788PRODUCT_ADB_KEYS:=value
789FOO := $(PRODUCT_ADB_KEYS)
790ifneq (,$(PRODUCT_ADB_KEYS))
791endif
792`,
793 expected: `load("//build/make/core:product_config.rbc", "rblf")
794
795def init(g, handle):
796 cfg = rblf.cfg(handle)
797 g["PRODUCT_ADB_KEYS"] = "value"
798 g["FOO"] = g["PRODUCT_ADB_KEYS"]
799 if g["PRODUCT_ADB_KEYS"]:
800 pass
801`,
802 },
803 {
804 desc: "ref before set",
805 mkname: "product.mk",
806 in: `
807V1 := $(PRODUCT_ADB_KEYS)
808ifeq (,$(PRODUCT_ADB_KEYS))
809 V2 := $(PRODUCT_ADB_KEYS)
810 PRODUCT_ADB_KEYS:=foo
811 V3 := $(PRODUCT_ADB_KEYS)
812endif`,
813 expected: `load("//build/make/core:product_config.rbc", "rblf")
814
815def init(g, handle):
816 cfg = rblf.cfg(handle)
817 g["V1"] = g.get("PRODUCT_ADB_KEYS", "")
818 if not g.get("PRODUCT_ADB_KEYS", ""):
819 g["V2"] = g.get("PRODUCT_ADB_KEYS", "")
820 g["PRODUCT_ADB_KEYS"] = "foo"
821 g["V3"] = g["PRODUCT_ADB_KEYS"]
822`,
823 },
824}
825
826var known_variables = []struct {
827 name string
828 class varClass
829 starlarkType
830}{
831 {"PRODUCT_NAME", VarClassConfig, starlarkTypeString},
832 {"PRODUCT_MODEL", VarClassConfig, starlarkTypeString},
833 {"PRODUCT_PACKAGES", VarClassConfig, starlarkTypeList},
834 {"PRODUCT_BOOT_JARS", VarClassConfig, starlarkTypeList},
835 {"PRODUCT_COPY_FILES", VarClassConfig, starlarkTypeList},
836 {"PRODUCT_IS_64BIT", VarClassConfig, starlarkTypeString},
837 {"PRODUCT_LIST1", VarClassConfig, starlarkTypeList},
838 {"PRODUCT_LIST2", VarClassConfig, starlarkTypeList},
839 {"PRODUCT_LIST3", VarClassConfig, starlarkTypeList},
840 {"TARGET_PRODUCT", VarClassSoong, starlarkTypeString},
841 {"TARGET_BUILD_VARIANT", VarClassSoong, starlarkTypeString},
842 {"TARGET_BOARD_PLATFORM", VarClassSoong, starlarkTypeString},
843 {"QCOM_BOARD_PLATFORMS", VarClassSoong, starlarkTypeString},
844 {"PLATFORM_LIST", VarClassSoong, starlarkTypeList}, // TODO(asmundak): make it local instead of soong
845}
846
847func TestGood(t *testing.T) {
848 for _, v := range known_variables {
849 KnownVariables.NewVariable(v.name, v.class, v.starlarkType)
850 }
851 for _, test := range testCases {
852 t.Run(test.desc,
853 func(t *testing.T) {
854 ss, err := Convert(Request{
855 MkFile: test.mkname,
856 Reader: bytes.NewBufferString(test.in),
857 RootDir: ".",
858 OutputSuffix: ".star",
859 WarnPartialSuccess: true,
860 })
861 if err != nil {
862 t.Error(err)
863 return
864 }
865 got := ss.String()
866 if got != test.expected {
867 t.Errorf("%q failed\nExpected:\n%s\nActual:\n%s\n", test.desc,
868 strings.ReplaceAll(test.expected, "\n", "␤\n"),
869 strings.ReplaceAll(got, "\n", "␤\n"))
870 }
871 })
872 }
873}